参考http://www.codeguru.com/forum/archive/index.php/t-133409.html
第一:对函数wglMakeCurrent有一个新的认识。
使指定的颜色上下文(rendering context)成为当前线程正调用的地颜色上下文(rendering context)。在该线程中的所有opengl调用命令都将被画在被指定的hdc上。所以,你可以使用wglMakeCurrent来改变当前线程调用的颜色上下文(rendering context),也可以使用它来改变线程对应的设备上下文(hdc)。
因此,当在使用mfc的单文档模板来分割窗口时,可以有多种选择:http://apps.hi.baidu.com/share/detail/39554638
- 使用动态分割窗口。不可以,因为,动态拆分窗口时,并没创建多个CView类的实体,而只是创建了一个实例,然后通过拆分及scroll bar的拖动达到对视图的不同部位的现实。可以通过设置断点来进行验证。如:使用CSplitterWnd的成员函数create创建多个拆分窗口后,在该行设置断点逐行追踪,观察CSplitterWnd的成员变量m_Rows和m_nCols即可发现他们的值都是1,从而验证了并没有创建多个窗口实例。所以,当使用动态拆分窗口时,修改view类当对所有窗口产生修改,因此不能使用。
- 使用静态分割窗口。其基本流程是:当更新一个子窗口时,使用wglMakeCurrent来把当前的颜色上下文与该子窗口的设备上下文进行绑定,当改换跟新另一个窗口时,再对新的窗口的设备上下文与当前颜色上下文进行绑定。由于一个线程只能有一个颜色上下文(http://msdn.microsoft.com/en-us/library/dd369039(v=vs.85).aspx),所以在单文档中不可以出现多个颜色上下文(rendering context),除非创建多线程。因此只能一个用完之后另一个用。(以上是个人理解,如有不对请指正)在静态拆分窗口过程中根据需要可以创建多个View类或者使用一个View类。在上论坛中使用了一个View类。
在CMainFrame类中重载方法OnCreateClient
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // TODO: Add your specialized code here and/or call the base class if (!m_wndSplitter.CreateStatic(this, 2, 2)) return FALSE; CRect rect; GetClientRect(rect); CSize paneSize(rect.right/2, rect.bottom/2); if( !(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(COpenGL13View),paneSize, pContext)&& m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(COpenGL13View),paneSize, pContext)&& m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(COpenGL13View),paneSize, pContext)&& m_wndSplitter.CreateView(1, 1, RUNTIME_CLASS(COpenGL13View),paneSize, pContext)) ) { m_wndSplitter.DestroyWindow(); return false; } p00 = (CView*) m_wndSplitter.GetPane(0, 0); p01 = (CView*) m_wndSplitter.GetPane(0, 1); p10 = (CView*) m_wndSplitter.GetPane(1, 0); p11 = (CView*) m_wndSplitter.GetPane(1, 1); m_wndSplitter.RecalcLayout(); return true; }
其中p00,p01,p10,p11位全局变量,在View类中有关键用处。
第三:View类中onDraw函数的修改
extern CView *p00, *p01, *p10, *p11; void COpenGL13View::OnDraw(CDC* pDC) { wglMakeCurrent(pDC->GetSafeHdc(), m_opengl.m_hRC); COpenGL13Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: add draw code for native data here ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0f,0.0f,-50.0f); //m_opengl.RenderScene(); if(p00 == this) { //显示修改 } if(p01 == this) { //显示修改 } if(p10 == this) { //显示修改 } if(p11 == this) { //显示修改 } pDoc->m_loadObj.Draw(); //CDC* pDC = new CClientDC(this); ::SwapBuffers(pDC->GetSafeHdc()); }
因为程序中并没有要显示新的数据,只是实现对原数据的不同角度的显示,因此不必创建多个视图类,当然也可以显示多个3d模型只要创建多个视图类的话。注意函数wglMakeCurrent(pDC->GetSafeHdc(), m_opengl.m_hRC);
实现切换对HDC与GLHRC的映射关系。