Add code showing stereo support to the OpenGL cube sample.
Show how WX_GL_STEREO attribute can be used, if available. See #15434. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74819 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		@@ -268,22 +268,38 @@ bool MyApp::OnInit()
 | 
			
		||||
int MyApp::OnExit()
 | 
			
		||||
{
 | 
			
		||||
    delete m_glContext;
 | 
			
		||||
    delete m_glStereoContext;
 | 
			
		||||
 | 
			
		||||
    return wxApp::OnExit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TestGLContext& MyApp::GetContext(wxGLCanvas *canvas)
 | 
			
		||||
TestGLContext& MyApp::GetContext(wxGLCanvas *canvas, bool useStereo)
 | 
			
		||||
{
 | 
			
		||||
    if ( !m_glContext )
 | 
			
		||||
    TestGLContext *glContext;
 | 
			
		||||
    if ( useStereo )
 | 
			
		||||
    {
 | 
			
		||||
        // 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);
 | 
			
		||||
        if ( !m_glStereoContext )
 | 
			
		||||
        {
 | 
			
		||||
            // Create the OpenGL context for the first stereo window which needs it:
 | 
			
		||||
            // subsequently created windows will all share the same context.
 | 
			
		||||
            m_glStereoContext = new TestGLContext(canvas);
 | 
			
		||||
        }
 | 
			
		||||
        glContext = m_glStereoContext;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        if ( !m_glContext )
 | 
			
		||||
        {
 | 
			
		||||
            // Create the OpenGL context for the first mono window which needs it:
 | 
			
		||||
            // subsequently created windows will all share the same context.
 | 
			
		||||
            m_glContext = new TestGLContext(canvas);
 | 
			
		||||
        }
 | 
			
		||||
        glContext = m_glContext;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_glContext->SetCurrent(*canvas);
 | 
			
		||||
    glContext->SetCurrent(*canvas);
 | 
			
		||||
 | 
			
		||||
    return *m_glContext;
 | 
			
		||||
    return *glContext;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
@@ -296,18 +312,30 @@ BEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas)
 | 
			
		||||
    EVT_TIMER(SpinTimer, TestGLCanvas::OnSpinTimer)
 | 
			
		||||
END_EVENT_TABLE()
 | 
			
		||||
 | 
			
		||||
TestGLCanvas::TestGLCanvas(wxWindow *parent)
 | 
			
		||||
TestGLCanvas::TestGLCanvas(wxWindow *parent, int *attribList)
 | 
			
		||||
    // 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 */,
 | 
			
		||||
    : wxGLCanvas(parent, wxID_ANY, attribList,
 | 
			
		||||
                 wxDefaultPosition, wxDefaultSize,
 | 
			
		||||
                 wxFULL_REPAINT_ON_RESIZE),
 | 
			
		||||
      m_xangle(30.0),
 | 
			
		||||
      m_yangle(30.0),
 | 
			
		||||
      m_spinTimer(this,SpinTimer)
 | 
			
		||||
      m_spinTimer(this,SpinTimer),
 | 
			
		||||
      m_useStereo(false),
 | 
			
		||||
      m_stereoWarningAlreadyDisplayed(false)
 | 
			
		||||
{
 | 
			
		||||
    if ( attribList )
 | 
			
		||||
    {
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        while ( attribList[i] != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            if ( attribList[i] == WX_GL_STEREO )
 | 
			
		||||
                m_useStereo = true;
 | 
			
		||||
            ++i;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
 | 
			
		||||
@@ -323,11 +351,36 @@ void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
 | 
			
		||||
    // is wrong when next another canvas is repainted.
 | 
			
		||||
    const wxSize ClientSize = GetClientSize();
 | 
			
		||||
 | 
			
		||||
    TestGLContext& canvas = wxGetApp().GetContext(this);
 | 
			
		||||
    TestGLContext& canvas = wxGetApp().GetContext(this, m_useStereo);
 | 
			
		||||
    glViewport(0, 0, ClientSize.x, ClientSize.y);
 | 
			
		||||
 | 
			
		||||
    // Render the graphics and swap the buffers.
 | 
			
		||||
    canvas.DrawRotatedCube(m_xangle, m_yangle);
 | 
			
		||||
    GLboolean quadStereoSupported;
 | 
			
		||||
    glGetBooleanv( GL_STEREO, &quadStereoSupported);
 | 
			
		||||
    if ( quadStereoSupported )
 | 
			
		||||
    {
 | 
			
		||||
        glDrawBuffer( GL_BACK_LEFT );
 | 
			
		||||
        glMatrixMode(GL_PROJECTION);
 | 
			
		||||
        glLoadIdentity();
 | 
			
		||||
        glFrustum(-0.47f, 0.53f, -0.5f, 0.5f, 1.0f, 3.0f);
 | 
			
		||||
        canvas.DrawRotatedCube(m_xangle, m_yangle);
 | 
			
		||||
        CheckGLError();
 | 
			
		||||
        glDrawBuffer( GL_BACK_RIGHT );
 | 
			
		||||
        glMatrixMode(GL_PROJECTION);
 | 
			
		||||
        glLoadIdentity();
 | 
			
		||||
        glFrustum(-0.53f, 0.47f, -0.5f, 0.5f, 1.0f, 3.0f);
 | 
			
		||||
        canvas.DrawRotatedCube(m_xangle, m_yangle);
 | 
			
		||||
        CheckGLError();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        canvas.DrawRotatedCube(m_xangle, m_yangle);
 | 
			
		||||
        if ( m_useStereo && !m_stereoWarningAlreadyDisplayed )
 | 
			
		||||
        {
 | 
			
		||||
            m_stereoWarningAlreadyDisplayed = true;
 | 
			
		||||
            wxLogError("Stereo not supported by the graphics card.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    SwapBuffers();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -379,6 +432,21 @@ void TestGLCanvas::OnSpinTimer(wxTimerEvent& WXUNUSED(event))
 | 
			
		||||
    Spin(0.0, 4.0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
wxString glGetwxString(GLenum name)
 | 
			
		||||
{
 | 
			
		||||
    const GLubyte *v = glGetString(name);
 | 
			
		||||
    if ( v == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        // The error is not important. It is GL_INVALID_ENUM.
 | 
			
		||||
        // We just want to clear the error stack.
 | 
			
		||||
        glGetError();
 | 
			
		||||
 | 
			
		||||
        return wxString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return wxString((const char*)v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
// MyFrame: main application window
 | 
			
		||||
@@ -386,19 +454,23 @@ void TestGLCanvas::OnSpinTimer(wxTimerEvent& WXUNUSED(event))
 | 
			
		||||
 | 
			
		||||
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
 | 
			
		||||
    EVT_MENU(wxID_NEW, MyFrame::OnNewWindow)
 | 
			
		||||
    EVT_MENU(NEW_STEREO_WINDOW, MyFrame::OnNewStereoWindow)
 | 
			
		||||
    EVT_MENU(wxID_CLOSE, MyFrame::OnClose)
 | 
			
		||||
END_EVENT_TABLE()
 | 
			
		||||
 | 
			
		||||
MyFrame::MyFrame()
 | 
			
		||||
MyFrame::MyFrame( bool stereoWindow )
 | 
			
		||||
       : wxFrame(NULL, wxID_ANY, wxT("wxWidgets OpenGL Cube Sample"))
 | 
			
		||||
{
 | 
			
		||||
    new TestGLCanvas(this);
 | 
			
		||||
    int stereoAttribList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_STEREO, 0 };
 | 
			
		||||
 | 
			
		||||
    new TestGLCanvas(this, stereoWindow ? stereoAttribList : NULL);
 | 
			
		||||
 | 
			
		||||
    SetIcon(wxICON(sample));
 | 
			
		||||
 | 
			
		||||
    // Make a menubar
 | 
			
		||||
    wxMenu *menu = new wxMenu;
 | 
			
		||||
    menu->Append(wxID_NEW);
 | 
			
		||||
    menu->Append(NEW_STEREO_WINDOW, "New Stereo Window");
 | 
			
		||||
    menu->AppendSeparator();
 | 
			
		||||
    menu->Append(wxID_CLOSE);
 | 
			
		||||
    wxMenuBar *menuBar = new wxMenuBar;
 | 
			
		||||
@@ -415,6 +487,15 @@ MyFrame::MyFrame()
 | 
			
		||||
    static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
 | 
			
		||||
    wxLogStatus("Double-buffered display %s supported",
 | 
			
		||||
                wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not");
 | 
			
		||||
 | 
			
		||||
    if ( stereoWindow )
 | 
			
		||||
    {
 | 
			
		||||
        const wxString vendor = glGetwxString(GL_VENDOR).Lower();
 | 
			
		||||
        const wxString renderer = glGetwxString(GL_RENDERER).Lower();
 | 
			
		||||
        if ( vendor.find("nvidia") != wxString::npos &&
 | 
			
		||||
                renderer.find("quadro") == wxString::npos )
 | 
			
		||||
            ShowFullScreen(true);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MyFrame::OnClose(wxCommandEvent& WXUNUSED(event))
 | 
			
		||||
@@ -428,3 +509,7 @@ void MyFrame::OnNewWindow( wxCommandEvent& WXUNUSED(event) )
 | 
			
		||||
    new MyFrame();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MyFrame::OnNewStereoWindow( wxCommandEvent& WXUNUSED(event) )
 | 
			
		||||
{
 | 
			
		||||
    new MyFrame(true);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user