update the samples to use new (non-deprecated) wxGLCanvas API; added more comments; some cleanup (modified patch 1882679)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@51630 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-02-10 13:26:01 +00:00
parent 845035287a
commit 451c13c85c
7 changed files with 247 additions and 214 deletions

View File

@@ -118,40 +118,6 @@ static wxImage DrawDice(int size, unsigned num)
// implementation // implementation
// ============================================================================ // ============================================================================
// ----------------------------------------------------------------------------
// MyApp: the application object
// ----------------------------------------------------------------------------
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
// Create the main window
new MyFrame();
return true;
}
int MyApp::OnExit()
{
delete m_glContext;
return wxApp::OnExit();
}
TestGLContext& MyApp::GetContext(wxGLCanvas *canvas)
{
if ( !m_glContext )
m_glContext = new TestGLContext(canvas);
else
m_glContext->SetCurrent(*canvas);
return *m_glContext;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// TestGLContext // TestGLContext
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -167,7 +133,7 @@ TestGLContext::TestGLContext(wxGLCanvas *canvas)
glEnable(GL_LIGHT0); glEnable(GL_LIGHT0);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
// add slightly more light, the default lightning is rather dark // add slightly more light, the default lighting is rather dark
GLfloat ambient[] = { 0.5, 0.5, 0.5, 0.5 }; GLfloat ambient[] = { 0.5, 0.5, 0.5, 0.5 };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
@@ -272,19 +238,61 @@ void TestGLContext::DrawRotatedCube(float xangle, float yangle)
CheckGLError(); CheckGLError();
} }
// ----------------------------------------------------------------------------
// MyApp: the application object
// ----------------------------------------------------------------------------
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
new MyFrame();
return true;
}
int MyApp::OnExit()
{
delete m_glContext;
return wxApp::OnExit();
}
TestGLContext& MyApp::GetContext(wxGLCanvas *canvas)
{
if ( !m_glContext )
{
// Create the OpenGL context for the first window which needs it:
// subsequently created windows will all share the same context.
m_glContext = new TestGLContext(canvas);
}
m_glContext->SetCurrent(*canvas);
return *m_glContext;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// TestGLCanvas // TestGLCanvas
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
EVT_SIZE(TestGLCanvas::OnSize)
EVT_PAINT(TestGLCanvas::OnPaint) EVT_PAINT(TestGLCanvas::OnPaint)
EVT_KEY_DOWN(TestGLCanvas::OnKeyDown) EVT_KEY_DOWN(TestGLCanvas::OnKeyDown)
END_EVENT_TABLE() END_EVENT_TABLE()
TestGLCanvas::TestGLCanvas(wxWindow *parent) TestGLCanvas::TestGLCanvas(wxWindow *parent)
: wxGLCanvas(parent, wxID_ANY, NULL /* attribs */) // With perspective OpenGL graphics, the wxFULL_REPAINT_ON_RESIZE style
// flag should always be set, because even making the canvas smaller should
// be followed by a paint event that updates the entire canvas with new
// viewport settings.
: wxGLCanvas(parent, wxID_ANY, NULL /* attribs */,
wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE)
{ {
m_xangle = m_xangle =
m_yangle = 30; m_yangle = 30;
@@ -292,29 +300,24 @@ TestGLCanvas::TestGLCanvas(wxWindow *parent)
void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{ {
// This is required even though dc is not used otherwise.
wxPaintDC dc(this); wxPaintDC dc(this);
// Set the OpenGL viewport according to the client size of this canvas.
// This is done here rather than in a wxSizeEvent handler because our
// OpenGL rendering context (and thus viewport setting) is used with
// multiple canvases: If we updated the viewport in the wxSizeEvent
// handler, changing the size of one canvas causes a viewport setting that
// is wrong when next another canvas is repainted.
const wxSize ClientSize = GetClientSize();
glViewport(0, 0, ClientSize.x, ClientSize.y);
// Render the graphics and swap the buffers.
wxGetApp().GetContext(this).DrawRotatedCube(m_xangle, m_yangle); wxGetApp().GetContext(this).DrawRotatedCube(m_xangle, m_yangle);
SwapBuffers(); SwapBuffers();
} }
void TestGLCanvas::OnSize(wxSizeEvent& event)
{
// don't prevent default processing from taking place
event.Skip();
if ( !IsShownOnScreen() )
return;
// set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
int w, h;
GetClientSize(&w, &h);
wxGetApp().GetContext(this);
glViewport(0, 0, w, h);
}
void TestGLCanvas::OnKeyDown( wxKeyEvent& event ) void TestGLCanvas::OnKeyDown( wxKeyEvent& event )
{ {
float *p = NULL; float *p = NULL;
@@ -355,6 +358,7 @@ void TestGLCanvas::OnKeyDown( wxKeyEvent& event )
Refresh(false); Refresh(false);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// MyFrame: main application window // MyFrame: main application window
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -400,6 +404,6 @@ void MyFrame::OnClose(wxCommandEvent& WXUNUSED(event))
void MyFrame::OnNewWindow( wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnNewWindow( wxCommandEvent& WXUNUSED(event) )
{ {
(void) new MyFrame(); new MyFrame();
} }

View File

@@ -29,12 +29,13 @@ private:
}; };
// Define a new application type // Define a new application type
class MyApp: public wxApp class MyApp : public wxApp
{ {
public: public:
MyApp() { m_glContext = NULL; } MyApp() { m_glContext = NULL; }
// get the context we use creating it on demand (and set it as current) // Returns the shared context used by all frames and sets it as current for
// the given canvas.
TestGLContext& GetContext(wxGLCanvas *canvas); TestGLContext& GetContext(wxGLCanvas *canvas);
// virtual wxApp methods // virtual wxApp methods
@@ -47,7 +48,7 @@ private:
}; };
// Define a new frame type // Define a new frame type
class MyFrame: public wxFrame class MyFrame : public wxFrame
{ {
public: public:
MyFrame(); MyFrame();
@@ -55,8 +56,6 @@ public:
private: private:
void OnClose(wxCommandEvent& event); void OnClose(wxCommandEvent& event);
void OnNewWindow(wxCommandEvent& event); void OnNewWindow(wxCommandEvent& event);
void OnDefRotateLeftKey(wxCommandEvent& event);
void OnDefRotateRightKey(wxCommandEvent& event);
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
@@ -68,7 +67,6 @@ public:
private: private:
void OnPaint(wxPaintEvent& event); void OnPaint(wxPaintEvent& event);
void OnSize(wxSizeEvent& event);
void OnKeyDown(wxKeyEvent& event); void OnKeyDown(wxKeyEvent& event);
// angles of rotation around x- and y- axis // angles of rotation around x- and y- axis
@@ -79,4 +77,3 @@ private:
}; };
#endif // _WX_CUBE_H_ #endif // _WX_CUBE_H_

View File

@@ -47,8 +47,9 @@
#undef GL_EXT_vertex_array #undef GL_EXT_vertex_array
#endif #endif
#include "isosurf.h" #include <fstream>
#include "isosurf.h"
#include "../../sample.xpm" #include "../../sample.xpm"
// The following part is taken largely unchanged from the original C Version // The following part is taken largely unchanged from the original C Version
@@ -72,31 +73,24 @@ static GLfloat xrot;
static GLfloat yrot; static GLfloat yrot;
static void read_surface( const wxChar *filename ) static void read_surface(const char *filename)
{ {
FILE *f = wxFopen(filename,_T("r")); std::ifstream inFile(filename);
if (!f) numverts = 0;
if ( !inFile )
{ {
wxString msg = _T("Couldn't read "); wxLogError("Couldn't read \"%s\"", filename);
msg += filename;
wxMessageBox(msg);
return; return;
} }
numverts = 0; while ((inFile >> verts[numverts][0] >> verts[numverts][1] >> verts[numverts][2]
while (!feof(f) && numverts<MAXVERTS) >> norms[numverts][0] >> norms[numverts][1] >> norms[numverts][2]) && numverts<MAXVERTS)
{ {
fscanf( f, "%f %f %f %f %f %f",
&verts[numverts][0], &verts[numverts][1], &verts[numverts][2],
&norms[numverts][0], &norms[numverts][1], &norms[numverts][2] );
numverts++; numverts++;
} }
numverts--;
wxPrintf(_T("%d vertices, %d triangles\n"), numverts, numverts-2); wxPrintf(_T("%d vertices, %d triangles\n"), numverts, numverts-2);
fclose(f);
} }
@@ -134,7 +128,7 @@ static void draw1()
glPopMatrix(); glPopMatrix();
glFlush(); glFlush(); // Not really necessary: buffer swapping below implies glFlush()
} }
@@ -238,8 +232,6 @@ static GLenum Args(int argc, wxChar **argv)
return GL_TRUE; return GL_TRUE;
} }
// The following part was written for wxWidgets 1.66
MyFrame *frame = NULL;
IMPLEMENT_APP(MyApp) IMPLEMENT_APP(MyApp)
@@ -252,16 +244,37 @@ bool MyApp::OnInit()
Args(argc, argv); Args(argc, argv);
// Create the main frame window // Create the main frame window
frame = new MyFrame(NULL, wxT("wxWidgets OpenGL Isosurf Sample"), new MyFrame(NULL, wxT("wxWidgets OpenGL Isosurf Sample"),
wxDefaultPosition, wxDefaultSize); wxDefaultPosition, wxDefaultSize);
read_surface("isosurf.dat");
Init();
return true;
}
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
END_EVENT_TABLE()
// My frame constructor
MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
const wxSize& size, long style)
: wxFrame(frame, wxID_ANY, title, pos, size, style),
m_canvas(NULL)
{
SetIcon(wxICON(sample));
// Make a menubar // Make a menubar
wxMenu *fileMenu = new wxMenu; wxMenu *fileMenu = new wxMenu;
fileMenu->Append(wxID_EXIT, _T("E&xit")); fileMenu->Append(wxID_EXIT, _T("E&xit"));
wxMenuBar *menuBar = new wxMenuBar; wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(fileMenu, _T("&File")); menuBar->Append(fileMenu, _T("&File"));
frame->SetMenuBar(menuBar); SetMenuBar(menuBar);
// Make a TestGLCanvas // Make a TestGLCanvas
@@ -288,31 +301,11 @@ bool MyApp::OnInit()
doubleBuffer = GL_FALSE; doubleBuffer = GL_FALSE;
} }
frame->m_canvas = new TestGLCanvas(frame, wxID_ANY, wxDefaultPosition, // Show the frame
wxDefaultSize, 0, _T("TestGLCanvas"), gl_attrib ); Show(true);
// Show the frame m_canvas = new TestGLCanvas(this, wxID_ANY, wxDefaultPosition,
frame->Show(true); GetClientSize(), 0, _T("TestGLCanvas"), gl_attrib );
frame->m_canvas->SetCurrent();
read_surface( _T("isosurf.dat") );
Init();
return true;
}
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(wxID_EXIT, MyFrame::OnExit)
END_EVENT_TABLE()
// My frame constructor
MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
const wxSize& size, long style)
: wxFrame(frame, wxID_ANY, title, pos, size, style)
{
m_canvas = NULL;
SetIcon(wxICON(sample));
} }
MyFrame::~MyFrame() MyFrame::~MyFrame()
@@ -336,16 +329,23 @@ BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
EVT_PAINT(TestGLCanvas::OnPaint) EVT_PAINT(TestGLCanvas::OnPaint)
EVT_CHAR(TestGLCanvas::OnChar) EVT_CHAR(TestGLCanvas::OnChar)
EVT_MOUSE_EVENTS(TestGLCanvas::OnMouseEvent) EVT_MOUSE_EVENTS(TestGLCanvas::OnMouseEvent)
EVT_ERASE_BACKGROUND(TestGLCanvas::OnEraseBackground)
END_EVENT_TABLE() END_EVENT_TABLE()
TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id, TestGLCanvas::TestGLCanvas(wxWindow *parent,
const wxPoint& pos, const wxSize& size, long style, wxWindowID id,
const wxString& name, int* gl_attrib) const wxPoint& pos,
: wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name, gl_attrib) const wxSize& size,
long style,
const wxString& name,
int* gl_attrib)
: wxGLCanvas(parent, id, gl_attrib, pos, size,
style | wxFULL_REPAINT_ON_RESIZE, name)
{ {
parent->Show(true); // Explicitly create a new rendering context instance for this canvas.
SetCurrent(); m_glRC = new wxGLContext(this);
// Make the new context current (activate it for use) with this canvas.
SetCurrent(*m_glRC);
/* Make sure server supports the vertex array extension */ /* Make sure server supports the vertex array extension */
char* extensions = (char *) glGetString( GL_EXTENSIONS ); char* extensions = (char *) glGetString( GL_EXTENSIONS );
@@ -355,6 +355,10 @@ TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id,
} }
} }
TestGLCanvas::~TestGLCanvas()
{
delete m_glRC;
}
void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) ) void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
{ {
@@ -362,11 +366,9 @@ void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
// OnPaint handlers must always create a wxPaintDC. // OnPaint handlers must always create a wxPaintDC.
wxPaintDC dc(this); wxPaintDC dc(this);
#ifndef __WXMOTIF__ // This is normally only necessary if there is more than one wxGLCanvas
if (!GetContext()) return; // or more than one wxGLContext in the application.
#endif SetCurrent(*m_glRC);
SetCurrent();
draw1(); draw1();
SwapBuffers(); SwapBuffers();
@@ -374,19 +376,15 @@ void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
void TestGLCanvas::OnSize(wxSizeEvent& event) void TestGLCanvas::OnSize(wxSizeEvent& event)
{ {
// this is also necessary to update the context on some platforms // This is normally only necessary if there is more than one wxGLCanvas
wxGLCanvas::OnSize(event); // or more than one wxGLContext in the application.
SetCurrent(*m_glRC);
// set GL viewport (not called by wxGLCanvas::OnSize on all platforms...) // It's up to the application code to update the OpenGL viewport settings.
int w, h; // This is OK here only because there is only one canvas that uses the
GetClientSize(&w, &h); // context. See the cube sample for that case that multiple canvases are
#ifndef __WXMOTIF__ // made current with one context.
if (GetContext()) glViewport(0, 0, event.GetSize().x, event.GetSize().y);
#endif
{
SetCurrent();
glViewport(0, 0, (GLint) w, (GLint) h);
}
} }
void TestGLCanvas::OnChar(wxKeyEvent& event) void TestGLCanvas::OnChar(wxKeyEvent& event)
@@ -450,7 +448,10 @@ void TestGLCanvas::OnMouseEvent(wxMouseEvent& event)
static int dragging = 0; static int dragging = 0;
static float last_x, last_y; static float last_x, last_y;
//printf("%f %f %d\n", event.GetX(), event.GetY(), (int)event.LeftIsDown()); // Allow default processing to happen, or else the canvas cannot gain focus
// (for key events).
event.Skip();
if(event.LeftIsDown()) if(event.LeftIsDown())
{ {
if(!dragging) if(!dragging)
@@ -467,12 +468,8 @@ void TestGLCanvas::OnMouseEvent(wxMouseEvent& event)
last_y = event.GetY(); last_y = event.GetY();
} }
else else
{
dragging = 0; dragging = 0;
}
}
void TestGLCanvas::OnEraseBackground( wxEraseEvent& WXUNUSED(event) )
{
// Do nothing, to avoid flashing.
} }

View File

@@ -13,54 +13,58 @@
#define _WX_ISOSURF_H_ #define _WX_ISOSURF_H_
// Define a new application type // Define a new application type
class MyApp: public wxApp class MyApp : public wxApp
{ {
public: public:
bool OnInit(); virtual bool OnInit();
}; };
#if wxUSE_GLCANVAS
class TestGLCanvas: public wxGLCanvas class TestGLCanvas : public wxGLCanvas
{ {
public: public:
TestGLCanvas(wxWindow *parent, wxWindowID id = wxID_ANY, TestGLCanvas(wxWindow *parent,
const wxPoint& pos = wxDefaultPosition, wxWindowID id = wxID_ANY,
const wxSize& size = wxDefaultSize, long style = 0, const wxPoint& pos = wxDefaultPosition,
const wxString& name = _T("TestGLCanvas"), int *gl_attrib = NULL); const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = _T("TestGLCanvas"),
int *gl_attrib = NULL);
~TestGLCanvas(){}; virtual ~TestGLCanvas();
void OnPaint(wxPaintEvent& event); void OnPaint(wxPaintEvent& event);
void OnSize(wxSizeEvent& event); void OnSize(wxSizeEvent& event);
void OnEraseBackground(wxEraseEvent& event);
void OnChar(wxKeyEvent& event); void OnChar(wxKeyEvent& event);
void OnMouseEvent(wxMouseEvent& event); void OnMouseEvent(wxMouseEvent& event);
private:
wxGLContext* m_glRC;
DECLARE_NO_COPY_CLASS(TestGLCanvas)
DECLARE_EVENT_TABLE()
};
class MyFrame : public wxFrame
{
public:
MyFrame(wxFrame *frame,
const wxString& title,
const wxPoint& pos,
const wxSize& size,
long style = wxDEFAULT_FRAME_STYLE);
virtual ~MyFrame();
TestGLCanvas *m_canvas;
private :
void OnExit(wxCommandEvent& event);
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
#endif // #if wxUSE_GLCANVAS #endif // _WX_ISOSURF_H_
class MyFrame: public wxFrame
{
public:
MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
const wxSize& size, long style = wxDEFAULT_FRAME_STYLE);
virtual ~MyFrame();
#if wxUSE_GLCANVAS
TestGLCanvas *m_canvas;
#endif
private :
void OnExit(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
#endif // #ifndef _WX_ISOSURF_H_

View File

@@ -33,6 +33,8 @@
#include <GL/glu.h> #include <GL/glu.h>
#endif #endif
#include <sstream>
#include "dxfrenderer.h" #include "dxfrenderer.h"
#include "wx/listimpl.cpp" #include "wx/listimpl.cpp"
@@ -435,6 +437,22 @@ bool DXFRenderer::ParseTables(wxInputStream& stream)
return false; return false;
} }
// This method is used instead of numStr.ToDouble(d) because the latter
// (wxString::ToDouble()) takes the systems proper locale into account,
// whereas the implementation below works with the default locale.
// (Converting numbers that are formatted in the default locale can fail
// with system locales that use e.g. the comma as the decimal separator.)
static double ToDouble(const wxString& numStr)
{
double d;
std::string numStr_(numStr.c_str());
std::istringstream iss(numStr_);
iss >> d;
return d;
}
// parse entities section: save 3DFACE and LINE entities // parse entities section: save 3DFACE and LINE entities
bool DXFRenderer::ParseEntities(wxInputStream& stream) bool DXFRenderer::ParseEntities(wxInputStream& stream)
{ {
@@ -490,8 +508,8 @@ bool DXFRenderer::ParseEntities(wxInputStream& stream)
state = 2; state = 2;
else if (state > 0) else if (state > 0)
{ {
double d; const double d=ToDouble(line2);
line2.ToDouble(&d);
if (line1 == wxT("10")) if (line1 == wxT("10"))
v[0].x = d; v[0].x = d;
else if (line1 == wxT("20")) else if (line1 == wxT("20"))

View File

@@ -94,8 +94,10 @@ MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
menuBar->Append(helpMenu, wxT("&Help")); menuBar->Append(helpMenu, wxT("&Help"));
SetMenuBar(menuBar); SetMenuBar(menuBar);
Show(true);
m_canvas = new TestGLCanvas(this, wxID_ANY, wxDefaultPosition, m_canvas = new TestGLCanvas(this, wxID_ANY, wxDefaultPosition,
wxSize(300, 300), wxSUNKEN_BORDER); GetClientSize(), wxSUNKEN_BORDER);
} }
// File|Open... command // File|Open... command
@@ -139,10 +141,21 @@ BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
EVT_MOUSE_EVENTS(TestGLCanvas::OnMouse) EVT_MOUSE_EVENTS(TestGLCanvas::OnMouse)
END_EVENT_TABLE() END_EVENT_TABLE()
TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id, TestGLCanvas::TestGLCanvas(wxWindow *parent,
const wxPoint& pos, const wxSize& size, long style, const wxString& name) wxWindowID id,
: wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name) const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name)
: wxGLCanvas(parent, id, NULL, pos, size,
style | wxFULL_REPAINT_ON_RESIZE, name)
{ {
// Explicitly create a new rendering context instance for this canvas.
m_glRC = new wxGLContext(this);
// Make the new context current (activate it for use) with this canvas.
SetCurrent(*m_glRC);
m_gldata.initialized = false; m_gldata.initialized = false;
// initialize view matrix // initialize view matrix
@@ -154,6 +167,7 @@ TestGLCanvas::TestGLCanvas(wxWindow *parent, wxWindowID id,
TestGLCanvas::~TestGLCanvas() TestGLCanvas::~TestGLCanvas()
{ {
delete m_glRC;
} }
void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) ) void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
@@ -161,11 +175,7 @@ void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
// must always be here // must always be here
wxPaintDC dc(this); wxPaintDC dc(this);
#ifndef __WXMOTIF__ SetCurrent(*m_glRC);
if (!GetContext()) return;
#endif
SetCurrent();
// Initialize OpenGL // Initialize OpenGL
if (!m_gldata.initialized) if (!m_gldata.initialized)
@@ -195,11 +205,11 @@ void TestGLCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
SwapBuffers(); SwapBuffers();
} }
void TestGLCanvas::OnSize(wxSizeEvent& event) void TestGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
{ {
// this is also necessary to update the context on some platforms // Reset the OpenGL view aspect.
wxGLCanvas::OnSize(event); // This is OK only because there is only one canvas that uses the context.
// Reset the OpenGL view aspect // See the cube sample for that case that multiple canvases are made current with one context.
ResetProjectionMode(); ResetProjectionMode();
} }
@@ -293,18 +303,21 @@ void TestGLCanvas::InitGL()
void TestGLCanvas::ResetProjectionMode() void TestGLCanvas::ResetProjectionMode()
{ {
// This is normally only necessary if there is more than one wxGLCanvas
// or more than one wxGLContext in the application.
SetCurrent(*m_glRC);
int w, h; int w, h;
GetClientSize(&w, &h); GetClientSize(&w, &h);
#ifndef __WXMOTIF__
if ( GetContext() ) // It's up to the application code to update the OpenGL viewport settings.
#endif // In order to avoid extensive context switching, consider doing this in
{ // OnPaint() rather than here, though.
SetCurrent(); glViewport(0, 0, (GLint) w, (GLint) h);
glViewport(0, 0, (GLint) w, (GLint) h);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
gluPerspective(45.0f, (GLfloat)w/h, 1.0, 100.0); gluPerspective(45.0f, (GLfloat)w/h, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();
}
} }

View File

@@ -31,6 +31,7 @@ extern "C"
#include "dxfrenderer.h" #include "dxfrenderer.h"
// OpenGL view data // OpenGL view data
struct GLData struct GLData
{ {
@@ -40,40 +41,40 @@ struct GLData
float zoom; // field of view in degrees float zoom; // field of view in degrees
}; };
// Define a new application type // Define a new application type
class MyApp: public wxApp class MyApp : public wxApp
{ {
public: public:
bool OnInit(); virtual bool OnInit();
}; };
// Define a new frame type // Define a new frame type
class TestGLCanvas; class TestGLCanvas;
class MyFrame: public wxFrame
class MyFrame : public wxFrame
{ {
public: public:
MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
const wxSize& size, long style = wxDEFAULT_FRAME_STYLE); const wxSize& size, long style = wxDEFAULT_FRAME_STYLE);
void OnMenuFileOpen(wxCommandEvent& event); void OnMenuFileOpen(wxCommandEvent& event);
void OnMenuFileExit(wxCommandEvent& event); void OnMenuFileExit(wxCommandEvent& event);
void OnMenuHelpAbout(wxCommandEvent& event); void OnMenuHelpAbout(wxCommandEvent& event);
#if wxUSE_GLCANVAS void SetCanvas(TestGLCanvas *canvas) { m_canvas = canvas; }
void SetCanvas( TestGLCanvas *canvas ) { m_canvas = canvas; }
TestGLCanvas *GetCanvas() { return m_canvas; } TestGLCanvas *GetCanvas() { return m_canvas; }
private: private:
TestGLCanvas *m_canvas; TestGLCanvas *m_canvas;
#endif
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
#if wxUSE_GLCANVAS
class TestGLCanvas: public wxGLCanvas class TestGLCanvas : public wxGLCanvas
{ {
public: public:
TestGLCanvas(wxWindow *parent, wxWindowID id = wxID_ANY, TestGLCanvas(wxWindow *parent, wxWindowID id = wxID_ANY,
@@ -81,7 +82,7 @@ public:
const wxSize& size = wxDefaultSize, long style = 0, const wxSize& size = wxDefaultSize, long style = 0,
const wxString& name = wxT("TestGLCanvas")); const wxString& name = wxT("TestGLCanvas"));
~TestGLCanvas(); virtual ~TestGLCanvas();
void LoadDXF(const wxString& filename); void LoadDXF(const wxString& filename);
@@ -95,13 +96,12 @@ private:
void InitGL(); void InitGL();
void ResetProjectionMode(); void ResetProjectionMode();
GLData m_gldata; wxGLContext* m_glRC;
DXFRenderer m_renderer; GLData m_gldata;
DXFRenderer m_renderer;
DECLARE_NO_COPY_CLASS(TestGLCanvas)
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
#endif // #if wxUSE_GLCANVAS
#endif // #ifndef _WX_PENGUIN_H_ #endif // #ifndef _WX_PENGUIN_H_