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:
		@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user