OpenGL – How to draw on MFC dialog? – Prepare to draw the Graphics

Through the series of Articles, we are learning how to draw on MFC dialog using OpenGL. In our previous article “OpenGL – How to draw on MFC dialog? – Linking opengl32.lib“, we learned how to link opengl32.lib to our Project. We have executed the Project and no drawing was shown on the MFC dialog; this is because we haven’t prepared our MFC dialog to draw OpenGL drawing. We will learn that, through this article.

OpenGL uses rendering context to draw the graphics. MFC uses Device Context to render the graphics. We need to integrate these to enable OpenGL to render on MFC dialog. How? This is specific to the platform, and Windows provides the API to allow us to integrate OpenGL and MFC Device Contexts.

Before starting, it is VERY important to know that, both these (Device Context and Rendering Context) should have the same Pixel format. Then only, you can see the rendering scene from OpenGL.

What is Pixel format?

The pixel format is nothing but a generic data structure that describes the properties of the OpenGL rendering context. This contains the information about the frame buffer, stencil buffer, depth buffer, etc, would like to have it in the OpenGL rendering context. OpenGL uses this information to render the scene.

Integrate OpenGL with MFC Dialog

Below are the steps that describe the process to integrate OpenGL with MFC Dialog to render the vector graphics.

Step 1. Windows API provides PIXELFORMATDESCRIPTOR structure to describe the Pixel format. Now, we will form our structure with the details of what we are looking to be in the OpenGL context. Here it looks like;

PIXELFORMATDESCRIPTOR pfd = { 
    sizeof(PIXELFORMATDESCRIPTOR),  //  size of this pfd
    1,                     // Version number; this should be set to 1. 
    PFD_DRAW_TO_WINDOW |   // Bit flags specifies the properties of the pixel buffer. support window
    PFD_SUPPORT_OPENGL,    // supports OpenGL drawing
    PFD_TYPE_RGBA,         // RGBA type; Additional component (A - Alpha) for Transparency.
    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; we can ignore this in newer versions of OpenGL
    0,                     // reserved
    0, 0, 0                // layer masks ignored  
    };

Step 2. Now we need to check whether Windows Device Context supports the Pixel format, which we described in our previous step. Windows provides an API for this, ChoosePixelFormat to return the matching pixel format supported by the Device Context. The statement looks like below; where hdc is the handle to the Device Context;

pf = ChoosePixelFormat(hdc, &pfd);

Now, we have the index of the Pixel format in pf; which is supported by Windows Device Context.

Step 3. We will set this pixel format to the Device Context. This is important because we need to create the OpenGL rendering context based on this Pixel format. Here is the API to set the pixel format;

SetPixelFormat(hdc, pf, &pfd);

This API function returns the TRUE value if the Pixel format is successfully set for the Device Context.

Create Rendering Context

Step 4. Now, we need to create the OpenGL rendering context, from the Windows device context. As we already set the Pixel format for the device context; when we create the rendering context, the Pixel formats of rendering context and device context will be the same. We use wgl function, to create the rendering context. Here it looks like;

hglrc = wglCreateContext(hdc);

After the successful function call, we will have an OpenGL rendering context.

Step 5. Before we draw anything on the OpenGL rendering context; we just have to select the rendering context as the current context. That means, all the rendering will happen in the current rendering context.

The important thing, you need to remember here is; current rendering context is thread-specific. You can’t assign the current rendering context for multiple threads. And a single thread should have only one current rendering context associated.

wglMakeCurrent function is used to make specific OpenGL rendering context as the calling thread’s current rendering context. The statement looks like below;

wglMakeCurrent(hdc, hglrc);

Step 6. Now we have everything in place; we have identified the Pixel format which supports the Device Context; we set the Pixel format before we create the rendering context to ensure Pixel formats of both should be the same, and then we make the rendering context as current rendering context for the thread after creating the rendering context.

So, where to place the above code? As our application is dialog-based; we can keep the above code in OnInitDialog()function. And you can keep wglMakeCurrent function call in OnPaint() message handler if you want to use multiple UI Threads in your program.

Step 7. Another important step is, delete the rendering context when it is no longer required. And it is IMPORTANT to know that, the rendering context should NOT be the current rendering context to the calling thread; before deleting it. Then, how to make the rendering context not current? The below statement will do this;

wglMakeCurrent(NULL, NULL);

Once there is no current rendering context, we can use wglDeleteContext function to delete the rendering context. Note that, this will delete the rendering context only; NOT the associated Devices Context. Here is the function call to delete the rendering context;

wglDeleteContext(hglrc);

We will place these function calls, before destroying the MFC dialog; which is in OnDestroy() method.

Step 8. Let’s run our program, and observe that; a rectangle is drawn on the surface of the MFC Dialog. This proves that we have successfully integrated OpenGL with MFC.

// Malin

OpenGL – How to draw on MFC dialog? – Prepare to draw the Graphics

One thought on “OpenGL – How to draw on MFC dialog? – Prepare to draw the Graphics

Leave a Reply

Your email address will not be published.

Scroll to top