Open GL Super Bible

Previous Table of Contents Next


Chapter 15
Buffers: Not Just for Animation

What you’ll learn in this chapter:

How to... Functions You’ll Use

Set up buffers ChoosePixelFormat/SetPixelFormat
Use the depth buffer glEnable/glDepthFunc/glDepthRange
Use the stencil buffer glEnable/glStencilFunc
Use the accumulation buffer glEnable/glAccum

In the previous chapters, we’ve used buffers for color and depth information. OpenGL provides several kinds of buffers that are linked by the OpenGL graphics context:

  Color buffer
  Depth buffer
  Stencil buffer
  Accumulation buffer

Each buffer has specific capabilities beyond simple double-buffering for animation and depth-buffering for hidden surface removal as described in this chapter.

What Are Buffers?

A buffer in OpenGL is essentially a two-dimensional array of values that correspond to a pixel in a window or off-screen image. Each buffer has the same number of columns and rows (width and height) as the current client area of a window but holds a different range and type of values. See Figure 15-1.


Figure 15-1  OpenGL buffer organization

Configuring Buffers

Before using OpenGL, you must configure the window’s hardware device context (HDC) for the buffers and color mode you require. The PIXELFORMATDESCRIPTOR structure contains this information. Here’s the typical way this buffer is set up:

// This structure holds buffer, layer, and color mode information.
PIXELFORMATDESCRIPTOR pfd;

// First initialize the pfd size and version...
pfd.nSize        = sizeof(pfd);
pfd.nVersion     = 1;

// Next, layer and buffering information...
pfd.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
pfd.dwLayerMask  = PFD_MAIN_PLANE;
pfd.iLayerType   = PFD_MAIN_PLANE;

// The pixel type indicates whether we use color indices or RGBA
pfd.iPixelType   = PFD_TYPE_RGBA;

// Now we specify the *minimum* number of bitplanes we need for
// each buffer.  Windows will choose the closest pixel format
// satisfying our minimum requirements.
pfd.cColorBits   = 8;
pfd.cDepthBits   = 16;
pfd.cAccumBits   = 0;
pfd.cStencilBits = 0;

The dwFlags bitfield specifies that we want to draw into the window using OpenGL. It also tells Windows the number of color buffers we require. See Table 15-1.

Table 15-1 PIXELFORMATDESCRIPTOR Option Flags

Flag Description

PFD_DRAW_TO_WINDOW Draw into a window.
PFD_DRAW_TO_BITMAP Draw into an off-screen bitmap.
PFD_SUPPORT_GDI The color buffer supports GDI drawing commands.
PFD_SUPPORT_OPENGL The buffers support OpenGL drawing commands.
PFD_DOUBLEBUFFER The color values are double buffered.
PFD_STEREO Two sets of buffers are available (left and right).
PFD_DOUBLE_BUFFER_DONTCARE It doesn’t matter if the color values are double buffered.
PFD_STEREO_DONTCARE It doesn’t matter if the buffers are in stereo.

The dwLayerMask and iLayerType fields specify the drawing planes that are to be used and are usually set to PFD_MAIN_PLANE. Some OpenGL graphics cards provide auxiliary buffers above and below the normal Windows color plane allowing you to draw menus or other graphical constructs without overwriting the main image. The generic implementation provided by Microsoft does not support auxiliary drawing planes.

The iPixelType field specifies how color values are represented and can be one of the two values in Table 15-2.

Table 15-2 PIXELFORMATDESCRIPTOR Pixel Types

Pixel Type Description

PFD_TYPE_RGBA Colors are composed of red, green, blue, and alpha values.
PFD_TYPE_COLORINDEX Colors are composed of an index value in the current logical palette.

The cColorBits, cDepthBits, cAccumBits, and cStencilBits fields specify the size of each buffer for the window. Specifying 0 for a field disables that buffer, except for cColorBits. If you specify 0 for cColorBits, Windows will provide the minimum number of bits available—usually 4 or 8 bits (16 or 256 colors). When iPixelType is set to PFD_TYPE_RGBA, the cColorBits field specifies the total number of red, green, and blue color bits. The current generic implementation of OpenGL provided by Microsoft does not support alpha color bits.

Once you have filled in all the necessary PIXELFORMATDESCRIPTOR information, you can set the pixel format for the window with a few simple calls, as shown here:

// The device context refers to the graphics driver for this window.
HDC                   hdc;

// This integer holds the Windows pixel format code
int                   pf;

// Choose and select the pixel format...
pf = ChoosePixelFormat(hdc, &pfd);
if (pf == 0)
{
  // Could not find the pixel format...
  MessageBox(NULL, "ChoosePixelFormat failed!", "Error", MB_OK);
}
else if (!SetPixelFormat(hdc, pf, &pfd))
{
  // Could not set the pixel format...
  MessageBox(NULL, "SetPixelFormat failed!", "Error", MB_OK);
}


Previous Table of Contents Next