IDirectDraw::CreateSurface

HRESULT CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc,

LPDIRECTDRAWSURFACE FAR * lplpDDSurface,

IUnknown FAR * pUnkOuter);

Creates a DirectDrawSurface object for this DirectDraw object.

·Returns DD_OK if successful, or one of the following error values otherwise:

DDERR_INCOMPATIBLEPRIMARY

DDERR_INVALIDCAPS

DDERR_INVALIDOBJECT

DDERR_INVALIDPARAMS

DDERR_INVALIDPIXELFORMAT

DDERR_NOALPHAHW

DDERR_NOCOOPERATIVELEVELSET

DDERR_NODIRECTDRAWHW

DDERR_NOEMULATION

DDERR_NOEXCLUSIVEMODE

DDERR_NOFLIPHW

DDERR_NOMIPMAPHW

DDERR_NOZBUFFERHW

DDERR_OUTOFMEMORY

DDERR_OUTOFVIDEOMEMORY

DDERR_PRIMARYSURFACEALREADYEXISTS

DDERR_UNSUPPORTEDMODE

lpSurfaceDesc

Address of the DDSURFACEDESC structure that describes the requested surface.

lplpDDSurface

Address of a pointer to be initialized with a valid DirectDrawSurface pointer if the call succeeds.

pUnkOuter

Allows for future compatibility with COM aggregation features. Presently, however, IDirectDraw::CreateSurface will return an error if this parameter is anything but NULL.

The DirectDrawSurface object represents a surface (pixel memory) that usually resides in the display card memory, but can exist in system memory if display memory is exhausted or if it is explicitly requested. If the hardware cannot support the capabilities requested or if it previously allocated those resources to another DirectDrawSurface object, the call to IDirectDraw::CreateSurface will fail.

This method usually creates one DirectDrawSurface object. If the DDSCAPS_FLIP flag in the dwCaps member of the DDSCAPS structure is set, IDirectDraw::CreateSurface will create several DirectDrawSurface objects, referred to collectively as a complex structure. The additional surfaces created are also referred to as implicit surfaces.

DirectDraw does not permit the creation of display memory surfaces wider than the primary surface.

The following are examples of valid surface creation scenarios:

Scenario 1

The primary surface is the surface currently visible to the user. When you create a primary surface, you are actually creating a DirectDrawSurface object to access an already existing surface being used by GDI. Consequently, while all other types of surfaces require dwHeight and dwWidth values, a primary surface must not have them specified, even if you know they are the same dimensions as the existing surface.

The members of the DDSURFACEDESC structure (ddsd below) relevant to the creation of the primary surface are then filled in.

DDSURFACEDESC ddsd;

ddsd.dwSize = sizeof( ddsd );

//Tell DDRAW which fields are valid

ddsd.dwFlags = DDSD_CAPS;

//Ask for a primary surface

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

Scenario 2

Create a simple off-screen surface of the type that might be used to cache bitmaps that will later be composed with the blitter. A height and width are required for all surfaces except primary surfaces. The members in the DDSURFACEDESC structure (ddsd below) relevant to the creation of a simple off-screen surface are then filled in.

DDSURFACEDESC ddsd;

ddsd.dwSize = sizeof( ddsd );

//Tell DDRAW which fields are valid

ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;

//Ask for a simple off-screen surface, sized

//100 by 100 pixels

ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;

dwHeight = 100;

dwWidth = 100;

DirectDraw creates this surface in display memory unless it will not fit, in which case the surface is created in system memory. If the surface must be created in one or the other, use the flags DDSCAPS_SYSTEMMEMORY or DDSCAPS_VIDEOMEMORY in dwCaps to specify system memory or display memory, respectively. An error is returned if the surface cannot be created in the specified location.

DirectDraw also allows for the creation of complex surfaces. A complex surface is a set of surfaces created with a single call to the IDirectDraw::CreateSurface method. If the DDSCAPS_COMPLEX flag is set in the IDirectDraw::CreateSurface call, one or more implicit surfaces will be created by DirectDraw in addition to the surface explicitly specified. Complex surfaces are managed as a single surface—a single call to the IDirectDraw::Release method will release all surfaces in the structure, and a single call to the IDirectDrawSurface::Restore method will restore them all.

Scenario 3

One of the most useful complex surfaces you can specify is composed of a primary surface and one or more back buffers that form a surface flipping environment. The members in the DDSURFACEDESC structure (ddsd below) relevant to complex surface creation are filled in to describe a flipping surface that has one back buffer.

DDSURFACEDESC ddsd;

ddsd.dwSize = sizeof( ddsd );

//Tell DDRAW which fields are valid

ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;

//Ask for a primary surface with a single

//back buffer

ddsd.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP |

DDSCAPS_PRIMARYSURFACE;

ddsd.dwBackBufferCount = 1;

The previous statements construct a double-buffered flipping environment—a single call to the IDirectDrawSurface::Flip method exchanges the surface memory of the primary surface and the back buffer. If a BackBufferCount of 2 is specified, two back buffers are created, and each call to IDirectDrawSurface::Flip rotates the surfaces in a circular pattern, providing a triple-buffered flipping environment.