Use of OpenGL in VC multi-document applicationsNational Defense University computer department Zhou Lu---- Many articles about the combination of OpenGL and MFC indicate that OpenGL can only be used in single-document applications. ---- However, in an application, sometimes it is expected that a data can be expressed in multiple ways at the same time, and the SDI application can not achieve this requirement; while in an MDI application, multiple Views can be opened at the same time, and different attributes of data are displayed in each view. ---- There are two key points for using OpenGL in MDI: ---- 1. Set and manage global variables correctly. ---- 2. associations between the correct device context (DC: device context) and the draw context (RC: rendering context). Each view manages a device context, the rendering context is only one during the entire program running. Therefore, you must associate the rendering context correctly to display the Rendering scenario in each view. ---- Here is a simple example (testmdi) to illustrate these two points. The function of this example is to calculate the number of open views. a circle and a square are displayed in the view with an odd number. The m_icount counter is defined in the application class ctestmdiapp and initialized to 0. Because the application class manages the entire program, including the initialization of the program, global data should be defined here. You also need to add a message response function onfilenew () in the ctestmdiapp (): void CTestMdiApp::OnFileNew() { m_iCount++; CWndApp::OnFileNew(); } ---- The Message Processing Mechanism of MFC sends messages to each object in the order of cview> cdoc> cmainframe> cwndapp, it is processed by the first object with a response to the message. Onfilenew () is implemented in cwndapp to generate a new file. In this example, the file class does not have its own variables. in actual application, there are usually some parameters that control view attributes. ---- Make the following changes to the view object ctestmdiview: ---- 1) Add member variables Hglrc m_hrc; draw the context handle; CDC * m_pcdc; device context pointer; int m_iid; view ID, which is the view created in the application; ---- 2) Modify oncreate (maid: Int cteshortdiview: oncreate (maid ){......... // todo: add your specialized creation code here // OpenGL rendering context creation pixelformatdescriptor PFD; int N; // initialize the private member m_pcdc = new cclientdc (this ); // bsetuppixelformat () establishes the pixel format required by the application and associates it with the current device context if (! Bsetuppixelformat () return 0; n =: getpixelformat (m_pcdc-> getsafehdc ();: describepixelformat (m_pcdc-> getsafehdc (), N, sizeof (PFD ), & PFD); // link the win device context with the OGL rendering context m_hrc = wglcreatecontext (m_pcdc-> getsafehdc (); // specify the target devicecontext (window) of the subsequent ogl cils wglmakecurrent (m_pcdc-> getsafehdc (), m_hrc); // note: this name is not required in SDI applications, while wglmakecurrent (null, null); // obtain the global variable: Counter cte1_diapp * PAPP = (cte1_diapp *) afxgetapp (); m_iid = PAPP-> m_icount; return 0;} return 0; ---- 3) modify the ondestroy function: Void cte1_diview: ondestroy () {// ensure that the view is deleted correctly and Its rendering context wglmakecurrent (m_pcdc-> getsafehdc (), m_hrc); If (m_hrc! = NULL): wgldeletecontext (m_hrc); // destroy win device contextif (m_pcdc) delete m_pcdc; ...... // todo :.....} ---- 4) The ondraw () function is modified as follows: Void cte1_diview: ondraw (){..... // todo :.... wglmakecurrent (m_pcdc-> getsafehdc (), m_hrc); If (PAPP-> m_icount % 2 = 0) {// draw a square drawsquare ();} else {// the odd number of views, draw the circle drawcircle ();} // note that the association between DC and RC is immediately broken after painting, correctly associate other views with RC when activating wglmakecurrent (null, null );} ---- 5) precreatewindow (createstruct & CS) function: Bool cte1_diview: precreatewindow (createstruct & CS) {// todo: Modify the window class or styles here by modifying // The createstruct CS // requirements for OpenGL: CS. style | = ws_clipsiblings | ws_clipchildren; // MDI Application Requirements: CS. lpszclass = afxregisterwndclass (cs_owndc | cs_hredraw | cs_vredraw); Return cview: precreatewindow (CS );} |