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

Of course, when you get to multithreaded programming techniques later in the book, you might want to add the multithreading flag `DDSCL_MULTITHREADED` to play it safe. Anyway, let’s see how you would create a DirectDraw object and set the cooperation level together:

    LPDIRECTDRAW lpdd  = NULL; // standard DirectDraw 1.0

    LPDIRECTDRAW lpdd4 = NULL; // DirectDraw 6.0 interface 4

    // first create base IDirectDraw interface

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

       {

       // error

       } // end if

    // now query for IDirectDraw4

    if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4,

                                   (LPVOID *)&lpdd4)))

       {

       // error

       } // end if

    // now set the cooperation level for windowed directdraw

    // since we aren't going to do any drawing yet

    if (FAILED(lpdd4->SetCooperativeLevel(hwnd, DDSCL_NORMAL)))

       {

       // error

       } // end if

> Note: I may start leaving out the error handling calls to `FAILED()` and/or `SUCCEEDED()` to save space, but remember that you should always check for errors!

At this point, you have enough information to create a complete DirectX application that creates a window, starts up DirectDraw, and sets the cooperation level. Although you don’t know how to draw, it’s a start. As an example, take a look at `DEMO6_1.CPP` on the CD, along with its executable `DEMO6_1.EXE`. When you run the program, you’ll see something like what’s shown in Figure 6.5. I based the program on the T3D Game Console template, so the only changes I made were in the `Game_Init()` and `Game_Shutdown()` to create and set the cooperation level for DirectDraw.

Figure 6.5 `DEMO6_1.EXE` in action.

Here are those functions with the added DirectDraw code from `DEMO6_1.CPP`, so you can see how simple DirectDraw is to set up:

    int Game_Init(void *parms = NULL, int num_parms = 0)

    {

    // this is called once after the initial window is created and

    // before the main event loop is entered, do all your initialization

    // here

    // first create base IDirectDraw interface

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

       {

       // error

       return(0);

       } // end if

    // now query for IDirectDraw4

    if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4,

                                   (LPVOID *)&lpdd4)))

       {

       // error

       return(0);

       } // end if

    // set cooperation to normal since this will be a windowed app

    lpdd4->SetCooperativeLevel(main_window_handle, DDSCL_NORMAL);

    // return success or failure or your own return code here

    return(1);

    } // end Game_Init

    /////////////////////////////////////////////////////////////

    int Game_Shutdown(void *parms = NULL, int num_parms = 0)

    {

    // this is called after the game is exited and the main event

    // loop while is exited, do all you cleanup and shutdown here

    // simply blow away the IDirectDraw4 interface

    if (lpdd4)

       {

       lpdd4->Release();

       lpdd4 = NULL;

       } // end if

    // return success or failure or your own return code here

    return(1);

    } // end Game_Shutdown

> Tip: If you’re about to jump in head-first and try to compile `DEMO6_1.CPP`, please remember to manually include `DDRAW.LIB` from the DirectX 6.0 SDK `LIB\` directory, along with adding the DirectX header paths to your compiler’s `.H` search directories as the first directory! And of course, you should build a Win32 `.EXE`. I get at least 10 emails a day from rookie compiler users who forget to include the `.LIB` files, so don’t be another statistic...

### Getting into the Mode of Things

The next step in setting up DirectDraw is probably the coolest of all. Normally, in DOS setting the video mode is fairly reasonable for the basic ROM BIOS modes, but in Windows it’s nearly impossible due to the aftershocks of the mode switch. However, with DirectX, it’s a snap. One of the main goals of DirectDraw was to make video mode switching trivial and transparent to the programmer. No more VGA/CRT control register programming just to make a single call. Presto—the mode will be set to whatever you desire (if the card can do it, of course).

The function to set the video mode is called `SetVideoMode()` and is a method of the `IDirectDraw4` interface, or, in C++-speak, `IDirectDraw4::SetVideoMode()`. Here’s its prototype:

    HRESULT SetDisplayMode(DWORD dwWidth,  // width of mode in pixels

                   DWORD dwHeight, // height if mode in pixels

                   DWORD dwBPP,    // bits per pixel, 8,16,24, etc.

                   DWORD dwRefreshRate, // desired refresh, 0 for default

                   DWORD dwFlags); // extra flags (advanced) 0 for default

As usual, the function returns `DD_OK` if successful.

All you should be saying is, “Wow, this is too good to be true!” Have you ever tried to set up a Mode X mode like 320×400 or 800×600 mode? Even if you’re successful, good luck trying to render to the video buffer! With this DirectDraw function, you just send the width, height, and color depth, and bam! DirectDraw handles all the idiosyncrasies of whichever video card is plugged in, and if the requested mode can be built, it is. Moreover, the mode is guaranteed to have a linear memory buffer... but more on that later. Take a look at Table 6.3 for a brief refresher on the most commonly used video modes and their color depths.

Table 6.3 Common Video Mode Resolutions

Width | Height | BPP | Mode X
--- | --- | --- | ---

320 | 200 | 8 | *
320 | 240 | 8 | *
320 | 400 | 8 | *
512 | 512 | 8,16,24,32 |
640 | 480 | 8,16,24,32 |
800 | 600 | 8,16,24,32 |
1024 | 768 | 8,16,24,32 |
1280 | 1024 | 8,16,24,32 |

Interestingly enough, you can request any mode you wish. For example, you can choose 400×400, and if the video driver can build it, it will work. However, it’s best to stick to the modes listed in Table 6.3 because they are the most common.

Actually, there is a Win32 API function to set the video mode that I have used before, but it wreaks havoc on the system and really messes things up.

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.