Tricks of the Windows Game Programming Gurus:First Contact: DirectDraw

All ITKnowledge Source Code Search Tips Advanced Search |

| Tricks of the Windows Game Programming Gurus by Andre LaMothe Sams, Macmillan Computer Publishing ISBN: 0672313618 Pub Date: 09/27/99

Search this book:

Previous | Table of Contents | Next

#### Using the Interfaces Together

Next, I want to briefly run down how all the interfaces are used together to create a DirectDraw application:

  1. Create the main DirectDraw object and retrieve a `IDirectDraw4` interface. Using this interface, set both the cooperation level and video mode.
  2. Using the `IDirectDrawSurface` interface, create at least a primary surface to draw on. Based on the color depth of the surface and the video mode itself, a palette will be needed if the video mode is 8 bits per pixel or less.
  3. Create a palette using the `IDirectDrawPalette` interface, initialize it with RGB triples, and attach it to the surface of interest.
  4. If the DirectDraw application is going to be windowed, or if you’re going to render bitmaps that could potentially go out of bounds of the visible DirectDraw surface, at least create a single clipper and size it to the extents of the visible window. See Figure 6.4.

  Figure 6.4 DirectDraw clippers.

  5. Draw on the primary surface.

Of course, there are about a bazillion (yes, that’s a technical term) little details I’ve left out, but that’s the gist of using the different interfaces. With that in mind, let’s get down to details and really make these interfaces work...

> Tip: You might want to have both the `DDRAW.H` header file and the DirectX SDK Help system open for reference during the remainder of the chapter.

### Creating a DirectDraw Object

To create a DirectDraw object with C++, all you need to do is call `DirectDrawCreate()`, shown here:

    HRESULT WINAPI DirectDrawCreate(GUID FAR *lpGUID,   // guid of object

                     LPDIRECTDRAW FAR *lplpDD, // receives interface

                     IUnknown     FAR *pUnkOuter ); // com stuff

`lpGUID`—This is the GUID (Globally Unique Identifier) of the display driver that you want to use. In most cases, you’ll simply send `NULL` to represent the default hardware.

`lplpDD`—This is a pointer to a pointer that receives the `IDirectDraw` interface pointer if the call is successful. Note that the function returns a `IDirectDraw` interface, not a `IDirectDraw4` interface!

`pUnkOuter`—Advanced feature; always send `NULL`.

Here’s how you would use the function to create a default DirectDraw object based on the `IDirectDraw` interface:

    LPDIRECTDRAW lpdd = NULL; // storage for IDirectDraw

    // create the DirectDraw object

    DirectDrawCreate(NULL, &lpdd, NULL);

If the function is successful, `lpdd` will be a valid `IDirectDraw` object interface. However, you still would like that latest interface, `IDirectDraw4`. But before you learn how to do that—what about error handling?

#### Error Handling with DirectDraw

Error handling in DirectX is very clean. There are a number of macros that can test the results of any function for general success or failure. The Microsoft-endorsed way of testing for errors with DirectX functions is to use these two macros:

  `FAILED()`—Tests for failure.
  `SUCCEEDED()`—Tests for success.

Based on this new information, you could do something smart by adding the following error handling code:

    if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL)))

       {

       // error

       } // end if

Or similarly, you could test for success:

    if (SUCCEEDED(DirectDrawCreate(NULL, &lpdd, NULL)))

       {

       // move onto next step

       } // end if

    else

       {

       // error

       } // end else

I usually use the `FAILED()` macro because I don’t like having two different logic paths, but whatever lights your fusion reactor... The only problem with the macros is that they don’t tell you much; they are more to detect a general problem. If you want to know the exact problem, you can always take a look at the return code for the function. In this case, Table 6.1 lists the possible return codes for DirectX version 6.0 `DirectDrawCreate()`.

Table 6.1 Return Codes for `DirectDrawCreate()`

Return Code | Description
--- | ---

`DD_OK` | Total Success.
`DDERR_DIRECTDRAWALREADYCREATED` | DirectDraw object has already been created.
`DDERR_GENERIC` | DirectDraw has no idea what’s wrong.
`DDERR_INVALIDDIRECTDRAWGUID` | The device GUID is unknown.
`DDERR_INVALIDPARAMS` | Something is wrong with the parameters you sent.
`DDERR_NODIRECTDRAWHW` | There isn’t any hardware.
`DDERR_OUTOFMEMORY` | Take a wild guess?

The only problem with using the constants along with conditional logic is that Microsoft doesn’t guarantee that they won’t completely change all the error codes. However, I think that you’ll be pretty safe with

    if (DirectDrawCreate(...)!=DD_OK)

       {

       // error

       } // end if

in all cases. Moreover, `DD_OK` is defined for all DirectDraw functions, so you can use it safely without worrying.

Previous | Table of Contents | Next

Copyright © Macmillan Computer Publishing, Inc.

Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.