Step 3: Creating an Overlay Surface
Now that you know that the driver supports overlay surfaces, you can try to create one. Because there is no standard dictating how devices must support overlay surfaces, you can't count on being able to create overlays of any particular size or pixel format. Additionally, you can't expect to succeed in creating an overlay surface on the first try. Therefore, be prepared to attempt creation multiple times starting with the most desirable characteristics, falling back on less desirable (but possibly less hardware intensive) configurations until one works.
(You can call the IDirectDraw2::GetFourCCCodes method to retrieve a list of FOURCC codes that describe non-RGB pixel formats that the driver will likely support for overlay surfaces. However, in you want to try using RGB overlay surfaces, it is recommended that you attempt to creating surfaces in various common RGB formats, falling back on another format if you fail.)
The Mosquito sample follows a "best case to worst case" philosophy when creating an overlay surface. Mosquito first tries to create a triple-buffered page flipping complex overlay surface. If the creation attempt fails, the sample tries the configuration with other common pixel formats. The following code fragment shows how this can be done:
ZeroMemory(&ddsdOverlay, sizeof(ddsdOverlay));
ddsdOverlay.dwSize = sizeof(ddsdOverlay);
ddsdOverlay.dwFlags= DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH |
DDSD_BACKBUFFERCOUNT| DDSD_PIXELFORMAT;
ddsdOverlay.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP |
DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY;
ddsdOverlay.dwWidth =320;
ddsdOverlay.dwHeight =240;
ddsdOverlay.dwBackBufferCount=2;
// Try to create an overlay surface using one of the pixel formats in our
// global list.
i=0;
do{
ddsdOverlay.ddpfPixelFormat=g_ddpfOverlayFormats[i];
// Try to create the overlay surface
ddrval = g_lpdd->CreateSurface(&ddsdOverlay, &g_lpddsOverlay, NULL);
} while( FAILED(ddrval) && (++i < NUM_OVERLAY_FORMATS) );
The preceding example sets the flags and values within a DDSURFACEDESC structure to reflect a triple-buffered page flipping complex overlay surface. Then, the sample performs a loop during which it attempts to create the requested surface in a variety of common pixel formats, in order of most desirable to least desirable pixel formats. If the attempt succeeds, the loop ends. If all the attempts fail, it's likely that the display hardware doesn't have enough memory to support a triple-buffered scheme or that it doesn't support flipping overlay surfaces. In this case, the sample falls back on a less desirable configuration using a single non-flipping overlay surface, as shown in the following example:
// If we failed to create a triple buffered complex overlay surface, try
// again with a single non-flippable buffer.
if(FAILED(ddrval))
{
ddsdOverlay.dwBackBufferCount=0;
ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT;
// Try to create the overlay surface
ddrval = g_lpdd->CreateSurface(&ddsdOverlay, &g_lpddsOverlay, NULL);
i=0;
do{
ddsdOverlay.ddpfPixelFormat=g_ddpfOverlayFormats[i];
ddrval = g_lpdd->CreateSurface(&ddsdOverlay, &g_lpddsOverlay, NULL);
} while( FAILED(ddrval) && (++i < NUM_OVERLAY_FORMATS) );
// We couldn't create an overlay surface. Exit, returning failure.
if (FAILED(ddrval))
return FALSE;
}
The code above resets the flags and values in the DDSURFACEDESC structure to reflect a single non-flipping overlay surface. Again, the example loops through pixel formats attempting to create the surfaces, stopping the loop if an attempt succeeded. If the attempts still didn't work, the sample returns FALSE to indicate failure.
After you've successfully created your overlay surface or surfaces, you can load bitmaps onto them in preparation for display.