如何在多视口OpenGL VC ++应用程序中正确渲染纹理?

时间:2011-05-22 14:20:31

标签: visual-c++ opengl

已更新

如果您想要询问此应用程序的完整源代码,可以从我的github存储库中分叉它:OpenGLModeler

我已经构建了一个显示三个视口的Visual C ++。NET 2008应用程序。一切都很好,直到我实现纹理功能。正如您在此处的屏幕截图中所看到的,只有前视口才能渲染其纹理。这是我根据定义的视口类型处理其绘图方法的代码。如果您愿意,我可以为您提供完整的源代码,但这里是代码段:

public:
        GLvoid ReSizeGLScene(GLsizei width, GLsizei height){        // Resize and initialise the gl window
        MySetCurrentGLRC();
        if (height==0)                                      // Prevent A Divide By Zero By
        {
            height=1;                                       // Making Height Equal One
        }

        glViewport(0,0,width,height);                       // Reset The Current Viewport

        glMatrixMode(GL_PROJECTION);                        // Select The Projection Matrix
        glLoadIdentity();                                   // Reset The Projection Matrix


        // Calculate The Aspect Ratio Of The Window
        switch(cameraType){
            case 1:                 
                gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f); 
                gluLookAt(
                    -4,4,4,//eye
                    0,0,0,//center
                    0,1,0);//up
                break;
            case 2://front : texture rendered correctly
                glOrtho(-2,2,-2,2,-50,50);
                gluLookAt(
                    0,0,2,//eye 0,0,2
                    0,0,0,//center 0,0,0
                    0,1,0);//up 0,1,0
                break;
            case 3://top
                glOrtho(-2,2,-2,2,-50,50);
                gluLookAt(
                    0,2,0,//eye
                    0,0,0,//center, 0
                    0,0,-1);//up
                break;
        }


        glMatrixMode(GL_MODELVIEW);                         // Select The Modelview Matrix
        glLoadIdentity();                                   // Reset The Modelview Matrix


        UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
        SetWindowPos((HWND)this->Handle.ToPointer() , 0, 0, 0, 
                   width, height, flags);

    }

已编辑:解释修改后的代码 我从codeproject借用此代码,并将其修改为具有多视口功能。这些是我认为的重要修改:首先,OpenGL视口的实例化:

    glPerspective = gcnew COpenGL(picPerspective, picPerspective->Width, picPerspective->Height,1);
        glFront = gcnew COpenGL(picFront, picFront->Width, picFront->Height,2);
        glTop = gcnew COpenGL(picTop, picTop->Width , picTop->Height,3);            

COpenGL的最后一个参数是视口的类型:perspective(1),front(2)和top(3)。第二个修改是我绘制场景的方式。它使用计时器,如下所示:

    private: System::Void timerRefreshPicture_Tick(System::Object^  sender, System::EventArgs^  e) {
             UNREFERENCED_PARAMETER(sender);
             UNREFERENCED_PARAMETER(e);

             glPerspective->Render(daftarObject);
             glPerspective->SwapOpenGLBuffers();

             glTop->Render(daftarObject);
             glTop->SwapOpenGLBuffers();

             glFront->Render(daftarObject);
             glFront->SwapOpenGLBuffers();
         }

我尝试禁用绘制glFront的代码,是的,glTop正确地进行了纹理化。如果我禁用了glTop,也会发生同样的情况。我怀疑这段代码:

virtual System::Void MySetCurrentGLRC()
    {
        if(m_hDC)
        {

            if((wglMakeCurrent(m_hDC, m_hglrc)) == NULL)
            {
            MessageBox::Show("wglMakeCurrent Failed");
            }
            //wglShareLists(m_hglrc,m_hglrc);<== not working
        }
    }

如何在此代码中使用wlgShareList?谢谢

An OpenGL Scene with Two Objects

2 个答案:

答案 0 :(得分:1)

只是一个建议:不要在多个功能上拆分OpenGL状态设置。始终在需要时设置所需的OpenGL状态。因此,在您的情况下,而不是在调整大小处理程序中设置视口和投影,请在显示功能中执行此操作。类似地,以这种方式启用/禁用纹理。

答案 1 :(得分:1)

如果您有多个GL上下文,则需要在上下文之间共享纹理,以便在上下文中创建它们并在另一个上下文中显示。

您可以查看在创建“辅助”上下文后要调用的wglShareLists(“主要”上下文是创建的第一个上下文)。

您可以在创建各种上下文后调用wglShareLists:

glPerspective = gcnew COpenGL(picPerspective, picPerspective->Width, picPerspective->Height,1);
glFront = gcnew COpenGL(picFront, picFront->Width, picFront->Height,2);
glTop = gcnew COpenGL(picTop, picTop->Width , picTop->Height,3);

wglShareLists( glPerspective->m_hglrc, glFront->m_hglrc );            
wglShareLists( glPerspective->m_hglrc, glTop->m_hglrc );            

请注意,调用wglShareLists时,'glFront'和'glTop'上下文不包含任何现有纹理非常重要。