The mapping mechanism of OpenGL is
OpenGL's drawing style differs from that of windows in general, and the main differences are as follows:
(1) Windows uses GDI (Graphy device Interface Graphics Device interface) to draw on the device Description table DC .
(2) OpenGL uses OpenGL- related functions (OGL commands) to draw on the render description table RC .
(3) OpenGL uses a special pixel format .
When you use GDI drawing in Windows, you must specify which device environment the DC is drawn in, and you must also specify a so-called rendering environment when using OpenGL functions. Just as DC wants to store GDI's drawing environment information such as pens, brushes and fonts,RC must also save the rendering information needed for OpenGL such as pixel format .
First use OpenGL's drawing context rendering Contex (render context), and use the GL command to draw the diagram well. The Swapbuffer () function is passed to the Winos device context DEVICECONTEX,DC (drawing device context) by Winos The result of the drawing.
In general, there may be multiple DCS while the program is running, but OpenGL has only one RC. So when a DC completes the drawing operation, release RC immediately so that other device context DCs can also be drawn.
OpenGL Rendering Environment RC (render Contex) creation-related functions :
The rendering environment is mainly managed by the following six WGL functions:
(1) HGLRC Wglcreatecontext (hdc hdc), this creation process is time-consuming, typically in the process of initializing the prophecy creation
This function is used to create an OpenGL-usable rendering environment.does not specify that this RC is the current thread's active RC。 HDC must be aLegal support for at least 16-bit color screen device Description table DC or memory device description table handle。 Before the function is called, the device description tablethe appropriate pixel format must be set.。 Successafter creating the render description table RC, the HDC can be released or deleted (at this point the HDC is not associated with the RC and other functions need to be used) .。 The function returns a null value indicating failure, otherwise the return value is a handle to the render context.
(2) BOOL Wgldeletecontex (HGLRC HGLRC)
The function deletes an RC,The general application should make it a non-active RC before removing the RC, however, deleting an existing RC is also available. At this point, the OpenGL system flushes the waiting drawing command and makes it a non-current RC, and then deletes it. Attention: Deleting an rc that belongs to another thread can cause a failure, so you can only manage RC for this thread.
(3) HGLRC wglgetcurrentcontext (void)
The function returns the current RC of the thread and returns NULL if the thread has no active RC
(4) HDC wglgetcurrentdc (void)
The function returns the DC associated with the thread's current RC and returns NULL if the thread has no active RC.
(5) BOOLWglmakecurrent (hdc hdc, HGLRC HGLRC)
This function associates the HDC with the HGLRC and makes HGLRC the active RC of the calling thread., if you passThe value to HGLRC is null, the function is de-associative, and the current RC for the collocated thread is not the active RC, the test ignores the HDC parameter. Note: The HDC passed to this function may not be the value used when calling Wglcreatecontext , but the device they are associated with must be the same and have the same pixel format because creating RC means creating RC with the basic configuration of the DC, The associated DC has not been specified at the time of creation.
Attention:
For threads, a thread can create (own) multiple RC, an RC can be shared by multiple threads, but only one RC can be "Current RC", "current RC" must be associated with a DC, otherwise RC cannot be the current RC.
A thread will not be able to draw at the same time when it owns the current RC , as the current RC is occupied. When using RC, you should not release or delete the DC associated with it. If an application maintains an active RC throughout its lifetime, the application also occupies a DC resource. Windows systems have limited DC resources.
MFC manages the way RC and DC:
(1) Create RC when wm_create message response ( because creating RC is time-consuming, create RC at creation time), release DC immediately after creation(unbind this RC against DC, causing other drawings not to use DC) when the WM_PAINT message arrives, the program acquires the DC handle and associates it with RC (only when the window is redrawn, the associated DC and RC, which occupies the DC at the time of use, is reasonable), immediately after the drawing is completed, the RC is associated with the DC and the DC is released (IBID.); When the Wm_destroy message arrives, the program simply deletes RC(if the OGL command executes during window destruction, it needs to be associated again, then the RC is removed, and the DCs created by this thread are eliminated, freeing the resources) .
(2) RC is created at the beginning of the program and becomes the current RC. It will remain in the current RC until the end of the program. Accordingly, GetDC is called at the beginning of the program and ReleaseDC at the end of the program. The advantage of this method is that you do not need to call a very time consuming wglmakecurrent function when you wm_paint the message accordingly. Typically it consumes thousands of clock cycles. However, in order to avoid the "RC" exclusive DC phenomenon, as well as multi-threaded multiple RC drawing influence, generally used: Create, release the association; drawing: associating, releasing; destroying: Releasing
Specific MFC management RC and DC programs are shown below:
Www.cmblog.com/icmzn
OpenGL several functions related to the specific system:
Glflush: Sends commands from the GL command queue to the video card and empties the command queue. Once sent, return immediately. There is no guarantee that the previous video card commands for these command queues will be completed (the graphics card may not have been drawn). Glflush is forced flush, knowing that OpenGL is using a rendering pipeline to process commands linearly, in general, The instructions we submit to OpenGL are not immediately sent to the graphics driver to be executed by the GPU, but instead put into a buffer, and wait until the buffer is full and then send the to the driver again, and many times only a few instructions are filled with that buffer. This means that these instructions are not sent to the driver at all, so we call Glflush to force the instructions to be sent to the driver for processing.
Glfinish: Sends commands from the GL command queue to the video card and empties the command queue. GL needs to wait until the graphics card finishes executing the command completely (the graphics card completes the drawing), and then returns.
OpenGL, it is recommended that in the case of a lengthy drawing command GL, you can call Glflush in segments, empty the command queue and send it to the video card first to execute these commands, and finally call Glfinish for synchronous processing. For example, in some of the scene drawing process, if there are more than one renderer, render execution from Shader0, always render to Shadern, if the use of all the amount of command after the call glfinish, it will cause the CPU to wait for the GPU to draw, causing the CPU is not fully utilized, Reflected in the effect is the graphics card, or other effects on the CPU, such as the impact of the program's clock system, because the program in the main thread stopped in the waiting for the GPU feedback signal, and other modules have an impact. understand!
Can optimize this scenario by invoking a glflush once each shader completes, forcing the GPU to start executing the GL drawing command in the command queue so that after the final shader render, Glfinish, finish drawing and synchronizing the contents of the current frame , because the GPU has already executed the previous GL command almost, so this approach is more efficient for GL verbose scenarios.
How to improve CPU efficiency when using OpenGL rendering:
(1) Use multithreading.
Update and render as thread A, auxiliary calculation into AI (intelligent control) policy, map generation as thread B. When thread A is blocked by glfinish, turn on thread B to pre-compute the CPU. Until thread B finishes, make the appropriate action based on the result of B.
(2) Use the CPU time budgeting method. First give a frame of time budget required, and then before calling Glfinish to determine if there is more time to wait, if there is, then call Glflush after the direct "auxiliary calculation", completed or exceeded the budget time, after the call Glfinish. (All the commands for the GPU's rendered frame have been drawn, requiring only one glfinish for synchronization).
For Swapbuffer's understanding:
Swapbuffer commands to the foreground and the background of the "buffer" pointer exchange, that is, the content of the front desk programming background, the background of the content to change to the foreground. But, however, this function does not perform the converted buffer cleanup work.
Therefore, the OpenGL mode method for drawing the current frame is: (1) Each frame must be called once before the Glclear function is drawn, and then the contents of the current frame are drawn. (2) using the GL command to draw the contents of the current frame, here has taken into account the various optimizations of Glflush,glfinish, the current frame content of the GL command at the end, the need to perform glfinish to complete the GL command and the current frame drawing of all the synchronization work, only wait for the cache exchange of the front and back to perform the display. (3) After the GL command is drawn, the last call to Swapbuffer, the front and rear display.
The understanding of Wglmakecurrent
The Wglmakecurrent function sets the rendering environment for the current thread of OpenGL . All OpenGL calls for this thread later are drawn on the device identified by this HDC. You can also use the wglmakecurrent function to change the current rendering environment of the calling thread so that it is no longer the current rendering environment . But, however, as mentioned above, generally by more than one DC, the competition uses an RC, then after using this function to obtain a DC, after the completion of this DC, you need to release the RC at the end, not exclusive RC.
The function prototypes are as follows:
BOOL wglmakecurrent (hdc hdc,//device context of device that OpenGL calls is//to is drawn on,Handle to the device environment (drawing context).the thread that called the functionAll subsequent OpenGL calls will be drawn on the device identified by this HDC.specifies the current thread. HGLRC HGLRC//OpenGL Rendering Context to be made the calling//The thread's current rendering context function sets the handle to the OpenGL rendering environment as the rendering environment for the present thread . Only the current thread is qualified. );
Note: If HGLRC is null,function will makeCalling ThreadThe current rendering environment is no longer used as the current rendering environment and frees the device environment used by this rendering environment. In this scenario, the HDC parameter is ignored.
// link the Win Device context with the OGL Rendering context generate OGL RC based on drawing device context
Wglcreatecontext (m_pcdc->getsafehdc ()); // Specify the target devicecontext (window) of the subsequent OGL calls sets the target DC for the current OGL render environment RC
Wglmakecurrent (m_pcdc->getsafehdc (), M_HRC); // Free the target devicecontext (window), freeing the DC for use with this RC for other DCs release the DC so that the other DC can use this RC
Wglmakecurrent (Null,null);
Note: (1) The drawing surface of the HDC parameter must be OpenGL-capable.
it does not need to be the HDC that was passed in when Wglcreatecontext created HGLRC, but it must be the same device and have the same pixel format . The GDI-converted HDC will not be supported by the rendering environment. The current rendering environment will always use the HDC device environment until it is no longer the current rendering environment.
(2) OpenGL will flush out all rendering environments before the current calling thread before switching to the new rendering environment .
(3) a thread can have a render environment (RC). So a multithreaded process can have multiple rendering environments. A thread must set a current render environment (RC)before invoking any OpenGL function. Otherwise all OpenGL calls will be ignored because the current RC does not have a DC that can execute the GL command, which must be ignored.
(4) At some point the rendering environment (RC) can only belong to one thread, you cannot make a render environment belong to multiple threads at the same time, because RC has only one.
(5) An application can produce multiple drawings by different pre- render environments (RC) in different threads , which support the device environment (DC)in which each thread has its own rendering environment.
(6) If an error occurs, the Wglmakecurrent function will make the rendering environment not the current rendering environment for the thread before returning . To avoid the individual possession of exceptional circumstances.
Before the view views are created, it is necessary to set the device environment to the rendering environment of the current thread: In addition, the global settings of the OGL need to be processed, such as opening the depth cache and setting the background color to clear the depth cache information.
1 intCglenabledview::OnCreate(lpcreatestruct lpcreatestruct)2 {3 if(Cview::oncreate (lpcreatestruct) = =-1)return-1;4 //OpenGL Rendering Context Creation5 pixelformatdescriptor PFD;6 intN;7 //Initialize the private member8M_pcdc=NewCCLIENTDC ( This); //When the front window corresponds to the device drawing context that is DC 9 //Choose the requested video modeTen if(!bsetuppixelformat ())return 0; One //Ask the system if the video mode is supported AN=::getpixelformat (m_pcdc->GETSAFEHDC ()); -::D Escribepixelformat (M_PCDC->GETSAFEHDC (), N,sizeof(PFD),&PFD); - //Create a palette if the requested video mode has a colors (indexed mode) the Creatergbpalette (); - //link the Win Device context with the OGL Rendering context - M_HRC = Wglcreatecontext (M_pcdc->getsafehdc ()); Create RC - //Specify the target devicecontext (window) of the subsequent OGL calls + wglmakecurrent (M_PCDC->GETSAFEHDC (), M_HRC); Sets the DC for the current RC - //performs default setting of rendering Mode,etc. + Oncreategl ();//ogl the configuration properties that need to be set in advance. A //Free the target devicecontext (window) at wglmakecurrent (null,null); Release DC - return 0; -}
1 voidCglenabledview::oncreategl ()//The global setting of RC is performed2 {3 //Perform hidden line/surface removal (enabling Z-buffer)4 glenable (gl_depth_test);5 //set background color to black6Glclearcolor (0. F,0. F,0. F,1.0f );7 //set Clear Z-buffer value8Glcleardepth (1.0f);9}
In the view OnDraw, each time to draw processing, each processing process is the same, so that the user only need to execute the ONDRAWGL (),, the default value and the aftermath has been set to complete.
voidCglenabledview::ondraw (cdc*PDC) {//prepare a semaphore flag bit StaticBOOL bbusy =FALSE;//Use the semaphore-enter this critic section if(bbusy)return; Bbusy=TRUE;//Specify the target devicecontext of the subsequent OGL calls wglmakecurrent (M_PCDC->GETSAFEHDC (), M_HRC);//simply perform a switchover function without the need to perform a time-consuming creation process//Clear Background Empty cacheGlclear (Gl_color_buffer_bit |gl_depth_buffer_bit);//Call the virtual drawing procedure (to being overridden by user)//Template Method ModeONDRAWGL ();//Execute OGL commands (flush the OGL graphical pipeline)//after all the draw commands, you must perform the Glfinish synchronization command for this GLglfinish ();//If double buffering is used it's time to swap the buffers, you must use dual-cache if (M_bdoublebuffer) Swapbuffer S (M_PCDC->GETSAFEHDC ());//turn the semaphore "green"Bbusy =FALSE;//Free the target devicecontext (window), freeing the DC for use with this RC for other DCs wglmakecurrent (null,null);}
The action of the View's OnDestroy window destruction process:
voidCglenabledview::ondestroy () {ondestroygl ();//Specify the target devicecontext (window) of the subsequent OGL callsWglmakecurrent (m_pcdc->Getsafehdc (), M_HRC);//Remove all Display lists for(intC=0; c<max_lists;c++)if(M_displistvector[c]) gldeletelists (M_displistvector[c],1);//release definitely OGL Rendering Context if(m_hrc!=NULL):: Wgldeletecontext (M_HRC);//Select Our palette out of the DCCPalette Paldefault; Paldefault.createstockobject (Default_palette); M_PCDC->selectpalette (&Paldefault, FALSE);//destroy Win Device Context if(M_PCDC) Delete m_pcdc;//finally call the base functionCview::ondestroy (); }
End
The principle of OpenGL Understanding 1---A view needs to support OGL needs to be configured, Glenbalview understanding