reorganized the code to put the logic in wxGLContext-derived class but keep the state in the window

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45476 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-04-15 00:54:32 +00:00
parent 43c05cf8e1
commit 50f5d508a8
2 changed files with 104 additions and 118 deletions

View File

@@ -66,79 +66,29 @@ int MyApp::OnExit()
return wxApp::OnExit();
}
void MyApp::SetCurrent(wxGLCanvas *canvas)
TestGLContext& MyApp::GetContext(wxGLCanvas *canvas)
{
wxCHECK_RET( canvas, _T("canvas can't be NULL") );
if ( !m_glContext )
m_glContext = new wxGLContext(canvas);
m_glContext = new TestGLContext(canvas);
m_glContext->SetCurrent(*canvas);
return *m_glContext;
}
// ----------------------------------------------------------------------------
// TestGLCanvas
// TestGLContext
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
EVT_SIZE(TestGLCanvas::OnSize)
EVT_PAINT(TestGLCanvas::OnPaint)
EVT_KEY_DOWN(TestGLCanvas::OnKeyDown)
END_EVENT_TABLE()
static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
TestGLCanvas::TestGLCanvas(wxWindow *parent)
: wxGLCanvas(parent, wxID_ANY, NULL /* attribs */)
TestGLContext::TestGLContext(wxGLCanvas *canvas)
: wxGLContext(canvas)
{
m_gllist = 0;
// notice that we can't call InitGL() from here: we must wait until the
// window is shown on screen to be able to perform OpenGL calls
}
// this function is called on each repaint so it should be fast
void TestGLCanvas::Render()
void TestGLContext::Init()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glCallList(m_gllist);
glFlush();
SwapBuffers();
}
void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxGetApp().SetCurrent(this);
// initialize if not done yet
InitGL();
wxPaintDC dc(this);
Render();
}
void TestGLCanvas::OnSize(wxSizeEvent& event)
{
// don't prevent default processing from taking place
event.Skip();
if ( !IsInitialized() )
return;
// set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
int w, h;
GetClientSize(&w, &h);
wxGetApp().SetCurrent(this);
glViewport(0, 0, w, h);
}
void TestGLCanvas::InitGL()
{
if ( IsInitialized() )
if ( m_gllist )
return;
/* set viewing projection */
@@ -146,21 +96,12 @@ void TestGLCanvas::InitGL()
glLoadIdentity();
glFrustum(-0.5f, 0.5f, -0.5f, 0.5f, 1.0f, 3.0f);
/* position viewer */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -2.0f);
/* position object */
glRotatef(30.0f, 1.0f, 0.0f, 0.0f);
glRotatef(30.0f, 0.0f, 1.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// create the list of commands to draw the cube: then we can just (quickly)
// execute it in Render() later
// execute it in DrawRotatedCube() later
m_gllist = glGenLists(1);
glNewList(m_gllist, GL_COMPILE);
@@ -194,11 +135,69 @@ void TestGLCanvas::InitGL()
glEndList();
}
void TestGLContext::DrawRotatedCube(float xangle, float yangle)
{
Init();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -2.0f);
glRotatef(xangle, 1.0f, 0.0f, 0.0f);
glRotatef(yangle, 0.0f, 1.0f, 0.0f);
glCallList(m_gllist);
glFlush();
}
// ----------------------------------------------------------------------------
// TestGLCanvas
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
EVT_SIZE(TestGLCanvas::OnSize)
EVT_PAINT(TestGLCanvas::OnPaint)
EVT_KEY_DOWN(TestGLCanvas::OnKeyDown)
END_EVENT_TABLE()
TestGLCanvas::TestGLCanvas(wxWindow *parent)
: wxGLCanvas(parent, wxID_ANY, NULL /* attribs */)
{
m_xangle =
m_yangle = 30;
}
void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
wxGetApp().GetContext(this).DrawRotatedCube(m_xangle, m_yangle);
SwapBuffers();
}
void TestGLCanvas::OnSize(wxSizeEvent& event)
{
// don't prevent default processing from taking place
event.Skip();
if ( !IsShown() )
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 )
{
GLfloat x = 0,
y = 0,
z = 0;
float *p = NULL;
bool inverse = false;
@@ -209,8 +208,8 @@ void TestGLCanvas::OnKeyDown( wxKeyEvent& event )
// fall through
case WXK_LEFT:
// rotate around Z axis
z = 1;
// rotate around Y axis
p = &m_yangle;
break;
case WXK_DOWN:
@@ -218,8 +217,8 @@ void TestGLCanvas::OnKeyDown( wxKeyEvent& event )
// fall through
case WXK_UP:
// rotate around Y axis
y = 1;
// rotate around X axis
p = &m_xangle;
break;
default:
@@ -231,19 +230,9 @@ void TestGLCanvas::OnKeyDown( wxKeyEvent& event )
if ( inverse )
angle = -angle;
wxGetApp().SetCurrent(this);
*p += angle;
glMatrixMode(GL_MODELVIEW);
glRotatef(angle, x, y, z);
// refresh all cubes
for ( wxWindowList::const_iterator i = wxTopLevelWindows.begin();
i != wxTopLevelWindows.end();
++i )
{
MyFrame *frame = (MyFrame *)*i;
frame->RefreshCanvas();
}
Refresh(false);
}
// ----------------------------------------------------------------------------
@@ -256,10 +245,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
END_EVENT_TABLE()
MyFrame::MyFrame()
: wxFrame(NULL, wxID_ANY, _T("wxWidgets OpenGL Cube Sample"),
wxDefaultPosition, wxSize(400, 300))
: wxFrame(NULL, wxID_ANY, _T("wxWidgets OpenGL Cube Sample"))
{
m_canvas = new TestGLCanvas(this);
new TestGLCanvas(this);
SetIcon(wxICON(sample));
@@ -275,6 +263,7 @@ MyFrame::MyFrame()
CreateStatusBar();
SetClientSize(400, 400);
Show();
}
@@ -289,7 +278,3 @@ void MyFrame::OnNewWindow( wxCommandEvent& WXUNUSED(event) )
(void) new MyFrame();
}
void MyFrame::RefreshCanvas()
{
m_canvas->Refresh(false);
}