0

我正在创建一个包含两个 OpenGL 渲染上下文的 Windows 程序(如下所示)。通常当我使用 OpenGL 进行编程时,我使用 GLUT 库函数来为我的绘图上下文创建和回调注册。

然而,当我将这些上下文嵌入到 Windows 窗体中时(GLUT 会使用自己的主窗口创建它们,每个窗口都带有窗口最小、最大和 X 按钮),我被迫在不使用 GLUT 的情况下创建窗口,因为 System::Windows ::Forms::NativeWindow(s) 已使用 wgl 函数作为 OpenGL 上下文启用。

我正在使用的 OGL 视图类型

然而,我现在需要使用 glutMouseFunc 和 glutPassiveMotionFunc 之类的函数来处理这些视图中的用户输入(这些是我通常用于处理鼠标输入的函数)。但是因为这些窗口不是使用 glutCreateWindow 创建的,所以我严重怀疑我是否能够结合使用这些 GLUT 函数。(我尝试了 glutCreatSubwindow 但这只会创建另一个 GLUT 创建的窗口的子窗口)

我目前正在寻找的是一种在这些启用了 OpenGL 的表单/NativeWindow(s) 上处理鼠标点击、坐标和移动的方法。无论是使用 System 命名空间,还是我不知道的另一个 GL 或 GLUT 函数,还是其他任何东西。我还将包括两个视图都继承其构造函数的代码父类,以便您可以看到它们是如何创建的。

public ref class COpenGL:
        public System::Windows::Forms::NativeWindow
        {
        public:
            COpenGL(System::Windows::Forms::Form ^ parentForm, GLsizei iWidth, GLsizei iHeight)
        {
            CreateParams^ cp = gcnew CreateParams;



            //set it's position on the parent form
            cp->X = 12;
            cp->Y = 27;
            cp->Height = iHeight;
            cp->Width = iWidth;

            //set the height and width for the benefit of the derived classes,
            //so that they can find out their own size using the getHeight & width funcs
            currentWidth = cp->Width;
            currentHeight = cp->Height;

            //Specify the form as the parent
            cp->Parent = parentForm->Handle;

            //create as a child of the specified parent
            //and make OPENGL compliant
            cp->Style = WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN;

            //create the window
            this->CreateHandle(cp);

            m_hDC = GetDC((HWND)this->Handle.ToPointer());

            if(m_hDC)
            {
                wglMakeCurrent(m_hDC,NULL);
                MySetPixelFormat(m_hDC);
                ReSizeGLScene(iWidth,iHeight);
                InitGL();
            }


        }

        virtual void Render()
        {
            //simple render, just refresh the buffers for now
            glClearColor(1.0f,0.5f,0.5f,1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
        }

        void SwapOpenGLBuffers()
        {
            SwapBuffers(m_hDC);
        }

    protected:
        HDC m_hDC;
        HGLRC m_hglrc; 

GLint MySetPixelFormat(HDC hdc)
        {
            PIXELFORMATDESCRIPTOR pfd = { 
                sizeof(PIXELFORMATDESCRIPTOR),    // size of this pfd 
                1,                                // version number 
                PFD_DRAW_TO_WINDOW |              // support window 
                PFD_SUPPORT_OPENGL |              // support OpenGL 
                PFD_DOUBLEBUFFER,                 // double buffered 
                PFD_TYPE_RGBA,                    // RGBA type 
                24,                               // 24-bit color depth 
                0, 0, 0, 0, 0, 0,                 // color bits ignored 
                0,                                // no alpha buffer 
                0,                                // shift bit ignored 
                0,                                // no accumulation buffer 
                0, 0, 0, 0,                       // accum bits ignored 
                32,                               // 32-bit z-buffer     
                0,                                // no stencil buffer 
                0,                                // no auxiliary buffer 
                PFD_MAIN_PLANE,                   // main layer 
                0,                                // reserved 
                0, 0, 0                           // layer masks ignored 
            }; 

            GLint  iPixelFormat; 

            // get the device context's best, available pixel format match 
            if((iPixelFormat = ChoosePixelFormat(hdc, &pfd)) == 0)
            {
                MessageBox::Show("ChoosePixelFormat Failed");
                return 0;
            }

            // make that match the device context's current pixel format 
            if(SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE)
            {
                MessageBox::Show("SetPixelFormat Failed");
                return 0;
            }

            if((m_hglrc = wglCreateContext(m_hDC)) == NULL)
            {
                MessageBox::Show("wglCreateContext Failed");
                return 0;
            }

            if((wglMakeCurrent(m_hDC, m_hglrc)) == NULL)
            {
                MessageBox::Show("wglMakeCurrent Failed");
                return 0;
            }

            return 1;
        }



        bool InitGL(GLvoid)                                     // All setup for opengl goes here
        {

            glMatrixMode(GL_PROJECTION);    
            glLoadIdentity();
            gluOrtho2D(0,currentWidth,0,currentHeight); //these will be set be now so it's safe to use them
                                                        //also makes sure we're drawing from the bottom left
            //glShadeModel(GL_SMOOTH);                          // Enable smooth shading
            glClearColor(0.0f, 0.0f, 0.0f, 0.5f);               // Black background
            //glClearDepth(1.0f);                                   // Depth buffer setup
            glDepthFunc(GL_LEQUAL);                             // The type of depth testing to do
            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Really nice perspective calculations
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//activate the alpha blending functionality
            glLineWidth(2);         // Width of the drawing line
            glDisable(GL_DEPTH_TEST);
            glMatrixMode(GL_MODELVIEW);

            return TRUE;                                        // Initialisation went ok
        }     
4

1 回答 1

0

First question:

I'm creating a windows program (shown below) that contains two OpenGL rendering contexts.

Why are you doing this? Creating multiple contexts I mean? It's perfectly possible to use a single OpenGL context with multiple windows of compatible PIXELFORMATDESCRIPTOR.

But more importantly: Why are you using two separate windows at all? Just use glScissor and glViewport to select a portion of the window for rendering and use that to draw multiple panes. Switch projection and modelview for each pane appropriately. I'd start by moving the code in your InitGL function to the drawing code.

于 2013-06-26T19:34:40.063 回答