WGL and the Wiggle Functions in C++


By RoD
The simple fact that OpenGL is only a graphics API means that any user interaction, or things like screen and window issues needs to be handled by the operating system. Most operating systems come with a set of extensions that tie OpenGL together with user interaction and window management. This tends to make our lives a little bit easier, but only if we know how to take advantage of this option. In Windows this set of functions are called the wiggle functions. Each of these functions is prefixed with wgl.

To maintain the portability of OpenGL, each operating system must supply functionality for specifying the rendering window before OpenGL can use it. In Windows the Graphics Device Interface uses a device context to remember settings about drawing modes and commands, but in OpenGL the rendering context is used to remember these things. You need to remember, however, that the device context is not a rendering context. The device context MUST be specified in a GDI call, unlike a rendering context, which is specified in an OpenGL call.

If you wish to render more than one window at once, multiple rendering contexts are allowed. You must ensure, however, that the proper rendering context is being used on the proper window. Another thing to remember is that OpenGL is thread-safe. You can have multiple threads rendering to the same device context at one time.

As I mentioned to you earlier, wiggle functions bring Windows API support into OpenGL. Well let's take this time to have a look at a few common wiggle functions:
  • wglCreateContext();
  • wglDeleteContext();
  • wglMakeCurrent();
The wglCreateContext() function creates a handle to the OpenGL rendering context while being passed like a handle to a GDI device context. The correct prototype for this function is:
	HGLRC	wglCreateContext(HDC hDC);
This function should only be called after the pixel format for the device context has been set. Don't worry, pixel format is coming into teaching shortly.

Keep in mind that as with a device context, a rendering context must be deleted after you are finished with it. This is where the wglDeleteContext() function comes into play. Let's have a look at the prototype for good measure:
	BOOL		wglDeleteContext(HGLRC hRC);
The name wglMakeCurrent() is highly accurate to what the function does. The function makes the rendering context passed to it the current rendering context. Makes a lot of sense, doesn't it? The device context used must have the same pixel format characteristics as the device context that was used to create the rendering context. This means that the device context used to create the rendering context does not need to be the same as the device context assigned to the wglMakeCurrent() function. Without further delay, let's see the prototype!
	BOOL		wglMakeCurrent(HDC hDC, HGLRC hRC);
You need to ensure that the device context and the rendering context passed to the function have the same pixel format, or the function will not work. To deselect the rendering context you can simply pass NULL for the hRC parameter, or simply pass another rendering context.

Both the wglCreateContext() and the wglMakeCurrent() functions should be called upon window creation. Let's look at a code snippet for an example of these in use:
LRESULT CALLBACK WndProc (HWND hwnd, UNIT message, WPARAM wParam, LPARAM lParam)
{
	static HGLRC	hRC;	//rendering context
	static HDC	hDC;	//device context
	switch (message)
	{
	case WM_CREATE:
	hDC = GetDC(hwnd);	//get the device context for window
	hRC = wglCreateContext(hDC);	//create rendering context
	wglMakeCurrent(hDC,hRC);	//make rendering context current
	break;
	case WM_DESTROY:
	wglMakeCurrent(hDC,NULL);	//deselect rendering context
	wglDeleteContext(hRC);		//delete rendering context
	PostQuitMessage(0);		//send wm_quit
	break;
	} } 
This code creates and destroys your OpenGL window. Before you actually do this, however, we must first discuss the PIXELFORMATDESCRIPTOR, which we will do in lesson 5. Happy Coding!


Previous: Your First Windows Application
Next: Getting Started Using OpenGL
Back to OpenGL tutorial index