wxGLCanvas Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
GotenXiao
In need of some credit
In need of some credit
Posts: 8
Joined: Tue Oct 11, 2005 8:40 pm

Post by GotenXiao »

...Diiiiie.

Code: Select all

Compiler: Default compiler
Building Makefile: "M:\Code\CPP\mayhem\Makefile.win"
Finding dependencies for file: M:\Code\CPP\mayhem\base.cpp
Executing  make...
make.exe -f "M:\Code\CPP\mayhem\Makefile.win" all
g++.exe -c base.cpp -o build/base.o -I"lib/gcc/mingw32/3.4.2/include"  -I"include/c++/3.4.2/backward"  -I"include/c++/3.4.2/mingw32"  -I"include/c++/3.4.2"  -I"include"  -I"E:/Dev-Cpp/lib/wx/include/msw-ansi-release-static-2.6"  -I"E:/Dev-Cpp/include/wx-2.6"  -I"E:\Dev-Cpp\\include\..\lib\wx\include\msw-ansi-release-static-2.6" -I"E:\Dev-Cpp\\include\wx-2.6" -D__WXMSW__ -mthreads -DNO_GCC_PRAGMA   -fexpensive-optimizations -O3 -march=i686 -msse2

windres.exe -i mayhem_private.rc --input-format=rc -o build/mayhem_private.res -O coff  --include-dir E:/Dev-Cpp/include/wx-2.6

g++.exe build/base.o build/mayhem_private.res -o "build\mayhem.exe" -L"lib" -mwindows -mthreads -Wl,--subsystem,windows -mwindows -lwx_msw-2.6 -lpng -lz -ljpeg -ltiff -lz -lrpcrt4 -loleaut32 -lole32 -luuid -lodbc32 -lole32 -loleaut32 -lwinspool -lwinmm -lshell32 -lcomctl32 -lcomdlg32 -lctl3d32 -ladvapi32 -lwsock32 -lgdi32 -lopengl32  -s -march=i686 -msse2 

build/base.o(.text+0x5b7):base.cpp: undefined reference to `wxGLCanvas::wxGLCanvas(wxWindow*, int, wxPoint const&, wxSize const&, long, wxString const&, int*, wxPalette const&)'
build/base.o(.text+0x5eb):base.cpp: undefined reference to `wxGLCanvas::SetCurrent()'
build/base.o(.text+0x619):base.cpp: undefined reference to `wxGLCanvas::~wxGLCanvas()'
build/base.o(.text+0x78d):base.cpp: undefined reference to `wxGLCanvas::wxGLCanvas(wxWindow*, int, wxPoint const&, wxSize const&, long, wxString const&, int*, wxPalette const&)'

build/base.o(.text+0x7c1):base.cpp: undefined reference to `wxGLCanvas::SetCurrent()'
build/base.o(.text+0x866):base.cpp: undefined reference to `wxGLCanvas::~wxGLCanvas()'
build/base.o(.text+0x9c7):base.cpp: undefined reference to `wxGLCanvas::wxGLCanvas(wxWindow*, int, wxPoint const&, wxSize const&, long, wxString const&, int*, wxPalette const&)'
build/base.o(.text+0x9fb):base.cpp: undefined reference to `wxGLCanvas::SetCurrent()'
build/base.o(.text+0xa29):base.cpp: undefined reference to `wxGLCanvas::~wxGLCanvas()'
build/base.o(.text+0xa53):base.cpp: undefined reference to `wxGLCanvas::~wxGLCanvas()'
build/base.o(.text+0xa73):base.cpp: undefined reference to `wxGLCanvas::~wxGLCanvas()'
build/base.o(.text+0xa94):base.cpp: undefined reference to `wxGLCanvas::~wxGLCanvas()'
build/base.o(.text+0xc65):base.cpp: undefined reference to `wxGLCanvas::SetCurrent()'
build/base.o(.text+0xc73):base.cpp: undefined reference to `wxGLCanvas::SwapBuffers()'

build/base.o(.text+0xd35):base.cpp: undefined reference to `wxGLCanvas::OnSize(wxSizeEvent&)'
build/base.o(.text+0xd62):base.cpp: undefined reference to `wxGLCanvas::SetCurrent()'
build/base.o(.text+0x1679):base.cpp: undefined reference to `Mayhem::OnChar(wxKeyEvent&)'
build/base.o(.text+0x16b6):base.cpp: undefined reference to `Mayhem::OnMouseEvent(wxMouseEvent&)'
build/base.o(.text+0x190b):base.cpp: undefined reference to `Mayhem::OnEraseBackground(wxEraseEvent&)'
build/base.o(.rdata$_ZTV6Mayhem[vtable for Mayhem]+0x8):base.cpp: undefined reference to `wxGLCanvas::GetClassInfo() const'
build/base.o(.rdata+0x0):base.cpp: undefined reference to `wxGLCanvas::sm_eventTable'

collect2: ld returned 1 exit status

make.exe: *** [build/mayhem.exe] Error 1

Execution terminated
base.h:

Code: Select all

#ifndef __BASE_H
#define __BASE_H

#define MAXPLAYERS 16

#define SHIPSDIR "ships/"
#define SHIPSMAXLINES 64
#define SHIPSDEFAULTAMMO 500
#define SHIPSDEFAULTFUEL 100
#define SHIPSDEFAULTHEALTH 100

#define MAPSDIR "maps/"

typedef struct
{
	int x[2];
	int y[2];
} LINE;

typedef struct
{
	LINE l[SHIPSMAXLINES];
} SHIPMODEL;

typedef struct
{
	int r;
	int g;
	int b;
} COLOUR;

class Ship;
class Player;
class Game;
class Mayhem;

class MyApp : public wxApp
{
	public:
		virtual bool OnInit();
	
	private:       
		void InitFrame();                   
};

class MainFrame : public wxFrame
{
	public:
		MainFrame(wxFrame *frame, const wxString& title, int xpos, int ypos, 
			int width, int height);
		~MainFrame();
		Mayhem *gp_GLCanvas;
	private:
		void OnExit(wxCommandEvent& event);
		DECLARE_EVENT_TABLE()
};

#if wxUSE_GLCANVAS
class Mayhem : public wxGLCanvas
{
	public:
    Mayhem(wxWindow *parent, wxWindowID id = wxID_ANY,
	    const wxPoint& pos = wxDefaultPosition,
			const wxSize& size = wxDefaultSize, long style = 0,
			const wxString& name = _T("Mayhem"), int *gl_attrib = NULL);
    ~Mayhem();
    
    void render();
		void drawShip(const Ship theShip, GLint originX, GLint originY, 
			GLfloat angle);
		//void drawMap(const Map theMap);
    void OnPaint(wxPaintEvent& event);
    void OnSize(wxSizeEvent& event);
    void OnEraseBackground(wxEraseEvent& event);
    void OnChar(wxKeyEvent& event);
    void OnMouseEvent(wxMouseEvent& event);
    void OnIdleLoop(wxIdleEvent& event);

    DECLARE_EVENT_TABLE()
};
#endif // #if wxUSE_GLCANVAS

class Ship
{
	public:
		Ship(wxChar *model);
		~Ship();
		int getRotation() { return m_rotation; }
		int getPosX() { return m_posX; }
		int getPosY() { return m_posY; }
		void loadModel(wxChar *model);
		SHIPMODEL m_shipModel;
		COLOUR m_colour;
		
	private:
		int m_rotation;
		int m_posX;
		int m_posY;
		int m_ammo;
		int m_fuel;
		int m_health;
};

class Player
{
	public:
		Player(wxString name, wxChar *model);
		~Player();
		Ship *m_ship;
		wxString m_name;
		
	private:
		
};

class Game
{
	public:
		Game();
		~Game();
		int getPlayerCount() { return m_playerCount; }
		void addPlayer(Player *new_player);
		void remPlayer(int playerNum);
		
	private:
		int m_playerCount;
		Player *m_players[MAXPLAYERS];
};
#endif // __BASE_H
base.cpp:

Code: Select all

#ifdef __GNUG__
	#pragma implementation
	#pragma interface
#endif

#include <wx/wxprec.h>

#ifdef __BORLANDC__
	#pragma hdrstop
#endif

#ifndef WX_PRECOMP
	#include <wx/wx.h>
#endif

#if !wxUSE_GLCANVAS
    #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif

//Standard C/C++
#include <stdio.h>

//OpenGL
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>

//WxWidgets
#include <wx/glcanvas.h>

#include "base.h"

IMPLEMENT_APP(MyApp);

bool MyApp::OnInit()
{
	InitFrame();
	return true;
}

void MyApp::InitFrame()
{
	MainFrame* frame = new MainFrame(0L, "Mayhem", 0, 0, 640, 480);
	frame->gp_GLCanvas = new Mayhem(frame, wxID_ANY, wxDefaultPosition, 
		wxDefaultSize, 0, "Mayhem");
	frame->Show(true);
	frame->Maximize(true);
} 

BEGIN_EVENT_TABLE(MainFrame, wxFrame)
	EVT_MENU(wxID_EXIT, MainFrame::OnExit)       
END_EVENT_TABLE()

MainFrame::MainFrame(wxFrame *frame, const wxString& title, int xpos, int ypos,
	int width, int height)
: wxFrame(frame, wxID_ANY, title, wxPoint(xpos, ypos), wxSize(width, height))
{
	gp_GLCanvas = NULL;
}

MainFrame::~MainFrame()
{
	
}

void MainFrame::OnExit(wxCommandEvent& event)
{
	Close(true);
} 


BEGIN_EVENT_TABLE(Mayhem, wxGLCanvas)
	EVT_PAINT(Mayhem::OnPaint)
	EVT_SIZE(Mayhem::OnSize)
	EVT_CHAR(Mayhem::OnChar)
	EVT_MOUSE_EVENTS(Mayhem::OnMouseEvent)
	EVT_ERASE_BACKGROUND(Mayhem::OnEraseBackground)
	EVT_IDLE(Mayhem::OnIdleLoop)
END_EVENT_TABLE()

Mayhem::Mayhem(wxWindow *parent, wxWindowID id,
    const wxPoint& pos, const wxSize& size, long style,
    const wxString& name, int* gl_attrib)
    : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name, gl_attrib)
{
    parent->Show(true);
    SetCurrent();
    
  /*//Test code
	Player player1 = new Player(_("GotenXiao"));
	player1.m_ship.loadModel(1);
	addPlayer(player1);
	//End of test code*/
}

Mayhem::~Mayhem()
{
	
}

void Mayhem::render() {
	
		
	glFlush();
	wxSleep(5);	
}

void Mayhem::drawShip(const Ship theShip, GLint originX, GLint originY, 
	GLfloat angle)
{
	int i;
	GLint x1, x2, y1, y2;
	
	glPushMatrix();
	glColor3i(theShip.m_colour.r, theShip.m_colour.g, theShip.m_colour.b);
	glRotatef(angle, 0.0f, 0.0f, 1.0f);
	glBegin(GL_LINES);
	for (i=0;i<64;i++) {
		if (theShip.m_shipModel.l[i].x[0] > 0
			&& theShip.m_shipModel.l[i].x[1] > 0
			&& theShip.m_shipModel.l[i].y[0] > 0
			&& theShip.m_shipModel.l[i].y[1] > 0)
		{
			x1 = theShip.m_shipModel.l[i].x[0] + originX;
			y1 = theShip.m_shipModel.l[i].y[0] + originY;
			x2 = theShip.m_shipModel.l[i].x[1] + originX;
			y2 = theShip.m_shipModel.l[i].y[1] + originY;
			glVertex2i(x1, y1);
			glVertex2i(x2, y2);
  	}
	}
	glEnd();
	glPopMatrix();
}

/*
void Mayhem::drawMap(const Map theMap)
{
	
}
*/

void Mayhem::OnPaint(wxPaintEvent& WXUNUSED(event))
{
    // This is a dummy, to avoid an endless succession of paint messages.
    // OnPaint handlers must always create a wxPaintDC.
    wxPaintDC dc(this);

		#ifndef __WXMOTIF__
			if (!GetContext()) return;
		#endif
    
		SetCurrent();
    SwapBuffers();
}

void Mayhem::OnSize(wxSizeEvent& event)
{
    // this is also necessary to update the context on some platforms
    wxGLCanvas::OnSize(event);

    // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
    int w, h;
    GetClientSize(&w, &h);
#ifndef __WXMOTIF__
    if (GetContext())
#endif
    {
        SetCurrent();
        glViewport(0, 0, (GLint) w, (GLint) h);
    }
}

void Mayhem::OnIdleLoop(wxIdleEvent& event)
{
	this->render();
}

Ship::Ship(wxChar *model)
{
	m_rotation = 0;
	m_posX = 0;
	m_posY = 0;
	m_ammo = SHIPSDEFAULTAMMO;
	m_fuel = SHIPSDEFAULTFUEL;
	m_health = SHIPSDEFAULTHEALTH;
	loadModel(model);
}

Ship::~Ship()
{
	
}

void Ship::loadModel(wxChar *model)
{
	const char *filename = *SHIPSDIR + *model + ".shp";
	FILE *f = fopen(filename, "r");
	if (!f) {
		wxString msg = _T("Couldn't read ");
    msg += filename;
    wxMessageBox(msg);
		return;
	}
	
	int lines = 0;
	while (!feof(f) && lines < SHIPSMAXLINES) {
		fscanf(f, "[%i %i][%i %i]",
			m_shipModel.l[lines].x[0],
			m_shipModel.l[lines].y[0],
			m_shipModel.l[lines].x[1],
			m_shipModel.l[lines].y[1]);
		lines++;
	}
	fclose(f);
}

Player::Player(wxString name, wxChar *model)
{
	m_name = name;
	m_ship = new Ship(model);
}

Player::~Player()
{
	
}

Game::Game()
{
	
}

Game::~Game()
{
	
}

void Game::addPlayer(Player *new_player)
{
	m_playerCount++;
	m_players[m_playerCount] = new_player;	
}

void Game::remPlayer(int playerNum)
{
	m_playerCount--;
	delete m_players[playerNum];
	m_players[playerNum] = NULL;
}
Can anyone spot something wrong with either the linker commands or the code that could cause this? I checked out the commands and compared them to a default project template, but the only difference that I could spot is the -lopengl32.
Image
kornerr
Experienced Solver
Experienced Solver
Posts: 66
Joined: Wed Oct 12, 2005 2:43 pm
Location: Russia
Contact:

Question

Post by kornerr »

Well, there's one annoying problem, maybe only under Linux.
When the maximize button is pressed, a window maximizes and... wxGLCanvas doesn't repaint. It happens even in wxWidgets OpenGL examples.
(And the same happens when minimizing)
How to get rid of that?

Thanks.
Open Source all the way, baby ;)
OpenGameStudio
Image
sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson »

Well you have to build wx with USE_OPENGL=1. :) AND your OnPaint should be like this.

Code: Select all

wxPaintDC dc(this);

#ifndef __WXMOTIF__
    if (!GetContext()) 
    {
    	return;
    }
#endif
	
	SetCurrent();
	
    Render();
    
    SwapBuffers();
Note the call to Render();

Also you OnIdle isn't right.

Code: Select all

void MainGLCanvas::OnIdle(wxIdleEvent& event)
{
	this->Refresh();
}

Call refresh. wich totally re-paints the window. Which then calls OnPaint() your paint handler. :)

EDIT:

make sure you link glu32 too or glu*() calls will fail.
Last edited by sethjackson on Wed Oct 12, 2005 3:25 pm, edited 1 time in total.
sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Re: Question

Post by sethjackson »

kornerr wrote:Well, there's one annoying problem, maybe only under Linux.
When the maximize button is pressed, a window maximizes and... wxGLCanvas doesn't repaint. It happens even in wxWidgets OpenGL examples.
(And the same happens when minimizing)
How to get rid of that?

Thanks.
When you create your wxGLCanvas. Set the style to

Code: Select all

wxFULL_REPAINT_ON_RESIZE
:)

EDIT:

Maybe we should start a new thread next time. :)
kornerr
Experienced Solver
Experienced Solver
Posts: 66
Joined: Wed Oct 12, 2005 2:43 pm
Location: Russia
Contact:

Post by kornerr »

Maximizing now works, but minimizing still doesn't work.

Thanks.
Open Source all the way, baby ;)
OpenGameStudio
Image
GotenXiao
In need of some credit
In need of some credit
Posts: 8
Joined: Tue Oct 11, 2005 8:40 pm

Post by GotenXiao »

Still getting linker errors after making those changes. By the way, the MSW binary build I got via Dev-C++ devpaks came with wxUSE_OPENGL = 1.
Image
sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson »

GotenXiao wrote:Still getting linker errors after making those changes. By the way, the MSW binary build I got via Dev-C++ devpaks came with wxUSE_OPENGL = 1.
so you did glu32?

and are you sure that the library was built with USE_OPENGL=1.

If setup.h says wxUSE_OPENGL = 1 the lib may not have been built with USE_OPENGL=1. You have to build the library with USE_OPENGL=1.

Go here.

http://wiki.codeblocks.org/index.php/Co ... _%28MSW%29

Here is the command I used to build wx2.6.2 with OpenGL support.

Code: Select all

mingw32-make -f makefile.gcc USE_XRC=1 USE_OPENGL=1 SHARED=1 MONOLITHIC=1 BUILD=release UNICODE=0
You also need to link wxmsw26_gl.

@kornerr

What do you mean by minimizing you can't see anything when the window is minimized. :)

Anyways if you can't get it to work I can post the full code for you...
GotenXiao
In need of some credit
In need of some credit
Posts: 8
Joined: Tue Oct 11, 2005 8:40 pm

Post by GotenXiao »

Code: Select all

#if !wxUSE_OPENGL
	#error "OpenGL required: set wxUSE_OPENGL to 1 and rebuild the library"
#endif
No error. glu32 is in the linker parameters, still no joy.
Equally this code:

Code: Select all

#if !wxUSE_GLCANVAS
  #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif
produces no error.
Image
GotenXiao
In need of some credit
In need of some credit
Posts: 8
Joined: Tue Oct 11, 2005 8:40 pm

Post by GotenXiao »

Guh. Undocumented: wx_msw_gl-2.6
Fixed the wxGLCanvas linker errors, now I'm just left with:

Code: Select all

build/base.o(.text+0x1699):base.cpp: undefined reference to `Mayhem::OnChar(wxKeyEvent&)'
build/base.o(.text+0x16d6):base.cpp: undefined reference to `Mayhem::OnMouseEvent(wxMouseEvent&)'
build/base.o(.text+0x192b):base.cpp: undefined reference to `Mayhem::OnEraseBackground(wxEraseEvent&)'
Image
sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson »

GotenXiao wrote:Guh. Undocumented: wx_msw_gl-2.6
Fixed the wxGLCanvas linker errors, now I'm just left with:

Code: Select all

build/base.o(.text+0x1699):base.cpp: undefined reference to `Mayhem::OnChar(wxKeyEvent&)'
build/base.o(.text+0x16d6):base.cpp: undefined reference to `Mayhem::OnMouseEvent(wxMouseEvent&)'
build/base.o(.text+0x192b):base.cpp: undefined reference to `Mayhem::OnEraseBackground(wxEraseEvent&)'
You have included the file with those function declarations in the file where you are trying to use the functions right?
GotenXiao
In need of some credit
In need of some credit
Posts: 8
Joined: Tue Oct 11, 2005 8:40 pm

Post by GotenXiao »

Yeah, the wxGLCanvas header is included. I just commented them out as a quick fix; I'm trying to get wxTextFile to play nice now XD

Note: the debugger is a pain in the rear.
Image
kornerr
Experienced Solver
Experienced Solver
Posts: 66
Joined: Wed Oct 12, 2005 2:43 pm
Location: Russia
Contact:

Post by kornerr »

Well, I was mistaken - IT DOESN'T WORK AT ALL.
Take a look at Cube example in wx/samples/opengl/cube
It has wxFULL_REPAINT_ON_RESIZE, but it doesn't work. It get repainted only when an event occurs, e.g., mouse click.

Thanks.
Open Source all the way, baby ;)
OpenGameStudio
Image
sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson »

Ok I'll post the full code again. Bear with me it is long. Create a new project or something of that nature a compile my code as is. It works perfectly on Windows. :)

main.cpp

Code: Select all

#include <wx/glcanvas.h>
#include "opengl.h"
#include "main.h"

BEGIN_EVENT_TABLE(MainFrame, wxFrame)

	EVT_MENU(wxID_EXIT, MainFrame::OnExit)	

END_EVENT_TABLE()

MainFrame::MainFrame(wxFrame *frame, const wxString& title,
                     int xpos, int ypos, int width, int height)
	: wxFrame(frame, wxID_ANY, title, wxPoint(xpos, ypos), wxSize(width, height))
{
	g_GLCanvas = 0;		
}

MainFrame::~MainFrame()
{
    
}

void MainFrame::OnExit(wxCommandEvent& event)
{
    Close(true);
}

main.h

Code: Select all

#ifndef MAIN_H
#define MAIN_H

#include <wx/wxprec.h>

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif

class MainFrame : public wxFrame
{
	public:

		MainFrame(wxFrame *frame, const wxString& title,
                  int xpos, int ypos, int width, int height);
		~MainFrame();
		
		MainGLCanvas* g_GLCanvas;

	private:

        void OnExit(wxCommandEvent& event);        

        DECLARE_EVENT_TABLE()
};

#endif // MAIN_H

app.cpp

Code: Select all

#include <wx/glcanvas.h>
#include "opengl.h"
#include "main.h"
#include "app.h"

IMPLEMENT_APP(MyApp);

bool MyApp::OnInit()
{
	InitFrame();

	return true;
}

void MyApp::InitFrame()
{
	MainFrame* frame = new MainFrame(0L, "3D Cube",
	                                 50, 50, 760, 530);
    
    
    frame->g_GLCanvas = new MainGLCanvas(frame, wxID_ANY, wxDefaultPosition, 
                                         wxDefaultSize, 0, "MainGLCanvas");
    
    
	frame->Show(true);
}

app.h

Code: Select all

#ifndef APP_H
#define APP_H

#include <wx/wxprec.h>

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif

class MyApp : public wxApp
{
    public:
    
        virtual bool OnInit();
        
    private:        
        
        void InitFrame();                    
};

#endif // APP_H

opengl.cpp

Code: Select all

#include <wx/glcanvas.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include "opengl.h"

BEGIN_EVENT_TABLE(MainGLCanvas, wxGLCanvas)    
    
    EVT_IDLE(MainGLCanvas::OnIdle)
    
    EVT_SIZE(MainGLCanvas::OnSize)

    EVT_PAINT(MainGLCanvas::OnPaint)

    EVT_ERASE_BACKGROUND(MainGLCanvas::OnEraseBackground)

    EVT_ENTER_WINDOW(MainGLCanvas::OnEnterWindow)

END_EVENT_TABLE()

MainGLCanvas::MainGLCanvas(wxWindow *parent, wxWindowID id,
                           const wxPoint& pos, const wxSize& size, 
                           long style, const wxString& name)
    : wxGLCanvas(parent, id, pos, size, style | wxFULL_REPAINT_ON_RESIZE, name)
{
    m_init = false;
    m_rquad = 0.0f;       
}

MainGLCanvas::~MainGLCanvas()
{

}

void MainGLCanvas::OnIdle(wxIdleEvent& event)
{
	this->Refresh();
}

void MainGLCanvas::OnSize(wxSizeEvent& event)
{    
    wxGLCanvas::OnSize(event);    
    
    int width, height;
    
    GetClientSize(&width, &height);
    
    if(height <= 0)
    {
        height = 1;    
    }
    
#ifndef __WXMOTIF__
    if (GetContext())
#endif
    {
        SetCurrent();
        
        glViewport(0, 0, width, height);
        
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        
        gluPerspective(45.0f, width / height, 1.0f, 100.0f);
        
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();    
    }
}

void MainGLCanvas::OnPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);

#ifndef __WXMOTIF__
    if (!GetContext()) 
    {
    	return;
    }
#endif
	
    SetCurrent();
	
    Render();
    
    SwapBuffers();	
}

void MainGLCanvas::OnEraseBackground(wxEraseEvent& event)
{
    
}


void MainGLCanvas::OnEnterWindow(wxMouseEvent& event)
{
    SetFocus();
}

void MainGLCanvas::InitGL()
{   
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);    
    glClearDepth(1.0f);   
    
    glEnable(GL_DEPTH_TEST);    
    glShadeModel(GL_SMOOTH);
    glDepthFunc(GL_LEQUAL);   
}

void MainGLCanvas::Render()
{
    if(!m_init)
    {
        InitGL();
        
        m_init = true;
    }      
    
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
    glPushMatrix();
    
    glTranslatef(0.0f, 0.0f, -7.0f);
    
    glRotatef(m_rquad, 1.0f, 1.0f, 1.0f);
    
    glBegin(GL_QUADS);

        // Top face of 3D Cube.

        glColor3f(0.0f, 1.0f, 0.0f);
        
        glVertex3f(1.0f, 1.0f, -1.0f);
        glVertex3f(-1.0f, 1.0f, -1.0f);
        glVertex3f(-1.0f, 1.0f, 1.0f);
        glVertex3f(1.0f, 1.0f, 1.0f);

        // Bottom face of 3D Cube.

        glColor3f(1.0f, 0.5f, 0.0f);
        
        glVertex3f(1.0f, -1.0f, 1.0f);
        glVertex3f(-1.0f, -1.0f, 1.0f);
        glVertex3f(-1.0f, -1.0f, -1.0f);
        glVertex3f(1.0f, -1.0f, -1.0f);

        // Front face of 3D Cube.

        glColor3f(1.0f, 0.0f, 0.0f);
        
        glVertex3f(1.0f, 1.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, 1.0f);
        glVertex3f(-1.0f, -1.0f, 1.0f);
        glVertex3f(1.0f, -1.0f, 1.0f);

        // Back face of 3D Cube.

        glColor3f(1.0f, 1.0f, 0.0f);
        
        glVertex3f(1.0f, -1.0f, -1.0f);
        glVertex3f(-1.0f, -1.0f, -1.0f);
        glVertex3f(-1.0f, 1.0f, -1.0f);
        glVertex3f(1.0f, 1.0f, -1.0f);

        // Left face of 3D Cube.

        glColor3f(0.0f, 0.0f, 1.0f);
        
        glVertex3f(-1.0f, 1.0f, 1.0f);
        glVertex3f(-1.0f, 1.0f, -1.0f);
        glVertex3f(-1.0f, -1.0f, -1.0f);
        glVertex3f(-1.0f, -1.0f, 1.0f);

        // Right face of 3D Cube.

        glColor3f(1.0f, 0.0f, 1.0f);
        
        glVertex3f(1.0f, 1.0f, -1.0f);
        glVertex3f(1.0f, 1.0f, 1.0f);
        glVertex3f(1.0f, -1.0f, 1.0f);
        glVertex3f(1.0f, -1.0f, -1.0f);

    glEnd();
    
    glPopMatrix();    
    
    m_rquad += 1.0f;    
}

opengl.h

Code: Select all

#ifndef OPENGL_H
#define OPENGL_H

#include <wx/wxprec.h>

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include <wx/wx.h>
#endif

#if !wxUSE_GLCANVAS
    #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif

class MainGLCanvas : public wxGLCanvas
{
	public:

        MainGLCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos,
                     const wxSize& size, long style, const wxString& name);
        ~MainGLCanvas();        

    private:        
        
        void OnIdle(wxIdleEvent& event);
        void OnPaint(wxPaintEvent& event);
        void OnSize(wxSizeEvent& event);
        void OnEraseBackground(wxEraseEvent& event);
        void OnEnterWindow(wxMouseEvent& event);
        
        void InitGL();
        void Render();

        bool m_init;

        float m_rquad;

        DECLARE_EVENT_TABLE()
};

#endif // OPENGL_H

kornerr
Experienced Solver
Experienced Solver
Posts: 66
Joined: Wed Oct 12, 2005 2:43 pm
Location: Russia
Contact:

Post by kornerr »

I didn't know of wxIdleEvent :)
Thanks for that, now all works fine.

PS: I wonder why those who wrote OpenGL samples hadn't added this helpful event.
Open Source all the way, baby ;)
OpenGameStudio
Image
sethjackson
Super wx Problem Solver
Super wx Problem Solver
Posts: 396
Joined: Wed Oct 05, 2005 1:19 am

Post by sethjackson »

kornerr wrote:I didn't know of wxIdleEvent :)
Thanks for that, now all works fine.

PS: I wonder why those who wrote OpenGL samples hadn't added this helpful event.
Because they aren't animated (I think). If you don't need to continually redraw then you don't. :)
Post Reply