C++ 带有两个OpenGL图形视图的MFC MDI拆分器不工作

C++ 带有两个OpenGL图形视图的MFC MDI拆分器不工作,c++,opengl,mfc,views,mdi,C++,Opengl,Mfc,Views,Mdi,我想创建一个应用程序,其中应用程序视图将与OpenGL 3d模型在两个不同的视图中分割,并使用拆分器连接到子框架。为此,我从一个视图类扩展了一个父类,在这个类中我初始化了opengl所需的所有代码 例如 #pragma once #include <gl/gl.h> #include <gl/glu.h> #define IL //when you dont want to use image library and you want to load everyt

我想创建一个应用程序,其中应用程序视图将与OpenGL 3d模型在两个不同的视图中分割,并使用拆分器连接到子框架。为此,我从一个视图类扩展了一个父类,在这个类中我初始化了opengl所需的所有代码

例如

#pragma once

#include <gl/gl.h>
#include <gl/glu.h>

#define IL   //when you dont want to use image library and you want to load everything by your self then remove this

// COpenGlView view

class COpenGlView : public CView
{
    DECLARE_DYNCREATE(COpenGlView)

protected:
    void oglBeginRendering();
    COpenGlView();           // protected constructor used by dynamic creation
    virtual ~COpenGlView();

/*******************/
        /* Private Members */
        /*******************/
        // Window information
        CWnd  *hWnd;
        HDC   hdc;          
        HGLRC hrc;          
        int   m_nPixelFormat;
        CRect m_rect;
        CRect m_oldWindow;
        CRect m_originalRect;
public:
        /******************/
        /* Public Members */
        /******************/
        UINT_PTR m_unpTimer;
        // View information variables
        float    m_fLastX;
        float    m_fLastY;
        float    m_fPosX;
        float    m_fPosY;
        float    m_fZoom;
        float    m_fRotX;
        float    m_fRotY;
        bool     m_bIsMaximized;

        float    m_fZoomSpeed;
        float    m_fRotateSpeed;
        GLuint texture[1];


        void oglCreate(CRect rect, CWnd *parent,CString strWindowName=L"OpenGl");
        virtual void oglInitialize(void);
        virtual void oglDrawScene(void);
        float   randFloat(const float& min, const float& max);
        int     randInt(const int& min, const int& max);

        void Reset();


        virtual void OnDraw(CDC* pDC);      // overridden to draw this view

#ifdef _DEBUG
    virtual void AssertValid() const;
#ifndef _WIN32_WCE
    virtual void Dump(CDumpContext& dc) const;
#endif
#endif

protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnPaint();
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnTimer(UINT_PTR nIDEvent);
    virtual void OnInitialUpdate();
};

然后在childframe类中,我添加了拆分器代码,并在拆分器窗口中调用了这两个类。问题是两个opengl视图代码都工作正常,但是如果我停止opengl的一个初始化,那么另一个就会显示出来。我尝试了一切,但我无法在这两个不同的视图中显示两个不同的图形化opengl动画。我已经检查了HDC内存映射,看起来这两个类都在使用父类来处理它们的动态HDC对象,但是如果我停止一个类的代码,那么其他视图就会正确显示

详情如下

class C3dRightView : public COpenGlView
{
    DECLARE_DYNCREATE(C3dRightView)

protected:
    GLuint m_left_texture[53];

    C3dRightView();           // protected constructor used by dynamic creation
    virtual ~C3dRightView();

public:
    virtual void OnDraw(CDC* pDC);      // overridden to draw this view
#ifdef _DEBUG
    virtual void AssertValid() const;
#ifndef _WIN32_WCE
    virtual void Dump(CDumpContext& dc) const;
#endif
#endif


protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnPaint();
    virtual void OnInitialUpdate();

    void oglDrawScene(void);
    void oglInitialize(void);
    afx_msg void OnTimer(UINT_PTR nIDEvent);
};


void C3dRightView::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO: Add your message handler code here
    // Do not call CView::OnPaint() for painting messages
}



void C3dRightView::OnInitialUpdate()
{
    hdc = C3dRightView::GetDC()->m_hDC;

    /** If i open below code then left view stop displaying model **/
        COpenGlView::OnInitialUpdate();
        oglInitialize();
    //-=-=-=-=-=-=-==--=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

    oglBeginRendering();
    // TODO: Add your specialized code here and/or call the base class
}


void C3dRightView::oglInitialize(void)
{
    COpenGlView::oglInitialize();

}
void C3dRightView::oglDrawScene(void)
{
    // Wireframe Mode

    glShadeModel(GL_SMOOTH);    

    glClearColor(0.0f, 1.0f, 1.0f, 0.0f);

    glLoadIdentity();
    //glTranslatef(0.0f, 0.0f, -m_fZoom);//this is for zoom using left mouse click but no placing
    glTranslatef(m_fPosX, m_fPosY,-m_fZoom); // this is for placing + zooming using middle scroll button mouse click

    glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);//these two for mouse movement
    glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
    glRotated(90,0.0f, 0.0f, -1.0f);
    glRotatef(180,1.0f,0,0.0f);
    GLenum a = glGetError();

    glBegin(GL_TRIANGLES);                              // Start Drawing A Triangle
        glColor3f(1.0f,0.0f,0.0f);                      // Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Front)
        glColor3f(0.0f,1.0f,0.0f);                      // Green
        glVertex3f(-1.0f,-1.0f, 1.0f);                  // Left Of Triangle (Front)
        glColor3f(0.0f,0.0f,1.0f);                      // Blue
        glVertex3f( 1.0f,-1.0f, 1.0f);                  // Right Of Triangle (Front)
        glColor3f(1.0f,0.0f,0.0f);                      // Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Right)
        glColor3f(0.0f,0.0f,1.0f);                      // Blue
        glVertex3f( 1.0f,-1.0f, 1.0f);                  // Left Of Triangle (Right)
        glColor3f(0.0f,1.0f,0.0f);                      // Green
        glVertex3f( 1.0f,-1.0f, -1.0f);                 // Right Of Triangle (Right)
        glColor3f(1.0f,0.0f,0.0f);                      // Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Back)
        glColor3f(0.0f,1.0f,0.0f);                      // Green
        glVertex3f( 1.0f,-1.0f, -1.0f);                 // Left Of Triangle (Back)
        glColor3f(0.0f,0.0f,1.0f);                      // Blue
        glVertex3f(-1.0f,-1.0f, -1.0f);                 // Right Of Triangle (Back)
        glColor3f(1.0f,0.0f,0.0f);                      // Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Left)
        glColor3f(0.0f,0.0f,1.0f);                      // Blue
        glVertex3f(-1.0f,-1.0f,-1.0f);                  // Left Of Triangle (Left)
        glColor3f(0.0f,1.0f,0.0f);                      // Green
        glVertex3f(-1.0f,-1.0f, 1.0f);                  // Right Of Triangle (Left)
    glEnd();    

}
第二个视图文件如下所示

class C3dLeftView : public COpenGlView
{
    DECLARE_DYNCREATE(C3dLeftView)

protected:
    GLuint m_left_texture[53];
    C3dLeftView();           // protected constructor used by dynamic creation
    virtual ~C3dLeftView();

public:
    virtual void OnDraw(CDC* pDC);      // overridden to draw this view
#ifdef _DEBUG
    virtual void AssertValid() const;
#ifndef _WIN32_WCE
    virtual void Dump(CDumpContext& dc) const;
#endif
#endif

protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnPaint();
    virtual void OnInitialUpdate();

    void oglDrawScene(void);
    void oglInitialize(void);
    afx_msg void OnTimer(UINT_PTR nIDEvent);
};


void C3dLeftView::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    // TODO: Add your message handler code here
    // Do not call CView::OnPaint() for painting messages
}

void C3dLeftView::OnInitialUpdate()
{
    hdc = C3dLeftView::GetDC()->m_hDC;
    COpenGlView::OnInitialUpdate();
    oglInitialize();
    oglBeginRendering();
    // TODO: Add your specialized code here and/or call the base class
}


void C3dLeftView::oglInitialize(void)
{
    COpenGlView::oglInitialize();


}
void C3dLeftView::oglDrawScene(void)
{
    glShadeModel(GL_SMOOTH);    

    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);

    glLoadIdentity();
    //glTranslatef(0.0f, 0.0f, -m_fZoom);//this is for zoom using left mouse click but no placing
    glTranslatef(m_fPosX, m_fPosY,-m_fZoom); // this is for placing + zooming using middle scroll button mouse click

    glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);//these two for mouse movement
    glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
    glRotated(90,0.0f, 0.0f, -1.0f);
    glRotatef(180,1.0f,0,0.0f);
    GLenum a = glGetError();

    glBegin(GL_TRIANGLES);                              // Start Drawing A Triangle
        glColor3f(1.0f,0.0f,0.0f);                      // Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Front)
        glColor3f(0.0f,1.0f,0.0f);                      // Green
        glVertex3f(-1.0f,-1.0f, 1.0f);                  // Left Of Triangle (Front)
        glColor3f(0.0f,0.0f,1.0f);                      // Blue
        glVertex3f( 1.0f,-1.0f, 1.0f);                  // Right Of Triangle (Front)
        glColor3f(1.0f,0.0f,0.0f);                      // Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Right)
        glColor3f(0.0f,0.0f,1.0f);                      // Blue
        glVertex3f( 1.0f,-1.0f, 1.0f);                  // Left Of Triangle (Right)
        glColor3f(0.0f,1.0f,0.0f);                      // Green
        glVertex3f( 1.0f,-1.0f, -1.0f);                 // Right Of Triangle (Right)
        glColor3f(1.0f,0.0f,0.0f);                      // Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Back)
        glColor3f(0.0f,1.0f,0.0f);                      // Green
        glVertex3f( 1.0f,-1.0f, -1.0f);                 // Left Of Triangle (Back)
        glColor3f(0.0f,0.0f,1.0f);                      // Blue
        glVertex3f(-1.0f,-1.0f, -1.0f);                 // Right Of Triangle (Back)
        glColor3f(1.0f,0.0f,0.0f);                      // Red
        glVertex3f( 0.0f, 1.0f, 0.0f);                  // Top Of Triangle (Left)
        glColor3f(0.0f,0.0f,1.0f);                      // Blue
        glVertex3f(-1.0f,-1.0f,-1.0f);                  // Left Of Triangle (Left)
        glColor3f(0.0f,1.0f,0.0f);                      // Green
        glVertex3f(-1.0f,-1.0f, 1.0f);                  // Right Of Triangle (Left)
    glEnd();    

    /*************************************************************************************/


}
若在视图的initialupdate函数中的代码下面有注释,那个么其他视图代码可以正常工作

    COpenGlView::OnInitialUpdate();
    oglInitialize();

父代码的initialupdate代码是如何为其一个子代码而不是两个子代码工作的。

编辑:否原因不可能是
wglMakeCurrent()
,就像我最初认为的那样,您似乎已经足够调用它了

原因可能是您调用您的
oglInitialize()
的次数太多。这取决于您如何创建视图和拆分器,但您没有发布这些代码。一种解决方法是限制视图实际“初始更新”的次数

将构造函数中的
hdc
成员初始化为0(实际上总是初始化构造函数中的所有成员):

hdc
为0时,仅执行一次ogl初始化:

void C3dRightView::OnInitialUpdate()
{
    if ( hdc == 0 )
    {
        hdc = GetDC()->m_hDC;
        COpenGlView::OnInitialUpdate();
        oglBeginRendering();
    }
}
这里也是:

void C3dLeftView::OnInitialUpdate()
{
    if ( hdc == 0 )
    {
        hdc = GetDC()->m_hDC;
        COpenGlView::OnInitialUpdate();
        oglBeginRendering();
    }
}
我相信这会管用的

Edit2:尝试了您的代码<代码>C3dRightView::OnInitialUpdate与我上面发布的不同。我不确定是什么搞砸了初始化。例如,以下对
CChildFrame::OnCreateClient
的修复似乎有效:

if (!m_wndSplitter.CreateView( 0, 1, RUNTIME_CLASS(C3dRightView), CSize(cr.Width()/2, cr.Height()), pContext))
{
    MessageBox(L"Error setting up splitter frames!", L"Init Error!", MB_OK | MB_ICONERROR);
    return FALSE;
}

// had to add this line here:
m_wndSplitter.GetPane( 0, 1 )->SendMessage(WM_INITIALUPDATE);

return TRUE;

虽然可能已经晚了,但以下是我的答案,可以在将来帮助你:)


在Ontimer函数中调用
pdoc->UpdateAll(NULL,NULL,NULL)
函数。pdoc是指向文档类的指针。它将请求更新所有视图,并且您将使两个窗口都工作:)。

我正在调用wglMakeCurrent in Timer函数,其中所有内容都将被渲染。但它不工作,请检查我的代码,并告诉我你认为我在哪里丢失wglMaleCurrent?由子类和父类激活的计时器负责处理计时器线程,并在计时器线程内打开wglMakeCurrent之间的gl绘图occours…但在一个窗口中它仍然显示为空。@wolvorinePk您的意思是一个窗口不显示您渲染的棱锥体吗?然后有东西隐藏了它,我相信,因为你初始化太多次了。我更新了答案。我尝试了与你的建议相同的方法,但仍然没有同时显示它们。如果假设我评论了这个视图的初始化,然后其他的作品,我已经在dropbox上上传了一个代码,请你看看为什么它仍然不工作@wolvorinePk似乎只需稍加修改即可工作。我现在没有时间调试到底是什么搞砸了初始化。。。刚刚编辑了我的答案。@ÖöTiib谢谢你的好伙伴。。。。出于某种原因,这不是电话,也不知道为什么,但你的处方方式解决了我的工作。当你们有时间在这里解释的时候,这样会对其他人有帮助,是什么把这件事搞砸了。再次感谢
COpenGlView::COpenGlView()
{
    hdc = 0;
    // ... etc your stuff
}
void C3dRightView::OnInitialUpdate()
{
    if ( hdc == 0 )
    {
        hdc = GetDC()->m_hDC;
        COpenGlView::OnInitialUpdate();
        oglBeginRendering();
    }
}
void C3dLeftView::OnInitialUpdate()
{
    if ( hdc == 0 )
    {
        hdc = GetDC()->m_hDC;
        COpenGlView::OnInitialUpdate();
        oglBeginRendering();
    }
}
if (!m_wndSplitter.CreateView( 0, 1, RUNTIME_CLASS(C3dRightView), CSize(cr.Width()/2, cr.Height()), pContext))
{
    MessageBox(L"Error setting up splitter frames!", L"Init Error!", MB_OK | MB_ICONERROR);
    return FALSE;
}

// had to add this line here:
m_wndSplitter.GetPane( 0, 1 )->SendMessage(WM_INITIALUPDATE);

return TRUE;