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

#### Getting an Interface Lift

As I said, you can use the basic `IDirectDraw` interface stored in `lpdd` from the call to `DirectDrawCreate()`. Or you can upgrade it to the latest version (whatever it may be) by querying for a new interface via the `IUnknown` interface method `QueryInterface(),` which is part of every DirectDraw interface implementation. The latest DirectDraw interface as of DirectX version 6.0 is `IDirectDraw4`, so here’s how you retrieve the interface pointer:

    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, here are the important things to pay attention to:

  • The way that `QueryInterface()` is called.
  • The constant used to request the `IDirectDraw4` interface, which is `IID_IDirectDraw4`.

In general, all calls from an interface are in the form

    interface_pointer->method(parms...);

And all Interface Identifiers are in the form

    IID_IDirectCD

Here, `C` refers to the component: `Draw` for DirectDraw, `Sound` for DirectSound, `Input` for DirectInput, and so on. `D` is a number, from 2 to n, indicating the interface you desire. In addition, you can find all these constants within the `DDRAW.H` file.

Moving on with this example, you now have a bit of a dilemma—you have both a `IDirectDraw` interface and a `IDirectDraw4` interface. What to do? Simply blow the old interface away since you don’t need it, like this:

    lpdd->Release();

    lpdd = NULL; // set to NULL for safety

And from this point on, do all method calls using the new interface `IDirectDraw4`.

> Warning: Along with the new functionality of `IDirectDraw4` comes a little housekeeping and responsibility. The problem is that not only is the `IDirectDraw4` interface more sophisticated and advanced, but in many cases it needs and returns new data structures rather than the base structures defined for DirectX 1.0. The only way to be sure about these anomalies is to take a look at the DirectX SDK documentation and verify the version of the data structure that any specific function needs and/or returns. However, this is just a warning in general. I’ll show you the correct structures for all the examples that you work through in this book—because I’m that kind of guy! By the way, my birthday is on June 14th.

In addition to using the `QueryInterface()` function from the initial `IDirectDraw` interface pointer (`lpdd`), there is a more direct “COM way” of getting the `IDirectDraw4` interface directly. Under COM, you can retrieve an interface pointer to any interface as long as you have the Interface ID, or IID, that represents the interface that you desire. In most cases, I personally prefer not to use low-level COM functions because I already have enough drama in my life. Nevertheless, when you get to DirectMusic there will be no way around using low-level COM stuff, so this is a good place to at least introduce the process to you. Here’s how you would directly obtain an `IDirectDraw4` interface:

    // first initialize COM, this will load the COM libraries

    // if they aren't already loaded

    if (FAILED(CoInitialize(NULL)))

       {

       // error

       } // end if

    // Create the DirectDraw object by using the

    // CoCreateInstance() function

    if (FAILED(CoCreateInstance(&CLSID_DirectDraw,

                                 NULL,

                                 CLSCTX_ALL,

                                 &IID_IDirectDraw4,

                                 &lpdd4)))

       {

       // error

       } // end if

    // now before using the DirectDraw object, it must

    // be initialized using the initialize method

    if (FAILED(IDirectDraw4_Initialize(lpdd4, NULL)))

       {

       // error

       } // end if

    // now that we're done with COM, uninitialize it

    CoUninitialize();

The preceding code is the Microsoft-recommended way to create a DirectDraw object. However, the technique does cheat a bit and use one macro:

    IDirectDraw4_Initialize(lpdd4, NULL);

You can get rid of this and be totally COM by replacing it with

    lpdd4->Initialize(NULL);

where the `NULL` in both calls is the video device, which in this case is the default driver. (That’s why it’s been left `NULL.`) In any case, it’s not hard to see how the macro expands out into the code in the preceding line. Just makes life easier, I guess? But then, why doesn’t Microsoft continue to make macros to create new interfaces like

    DirectDrawCreate4(...);

That would be nice, but why ask why? My point is that you might want to do this yourself so that all your code looks fairly uniform.

Now that you know how to create a DirectDraw object and obtain the latest interface, let’s move on to the next step in the sequence of getting DirectDraw working, which is setting the cooperation level.

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.