Tricks of the Windows Game Programming Gurus:Advanced DirectDraw and Bitmapped Graphics

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

#### Clipping a DirectX Window

Now we’re getting somewhere! The next piece of the DirectDraw windowed mode conundrum is to get the clipping working. Make sure that you understand that clipping only matters to the blitter; it has no effect on what you do directly with the primary surface.

You’ve seen the `IDIRECTDRAWCLIPPER` interface before, so I’m not going to belabor it anymore. (I still have the shakes from figuring out the exact nature of the coordinates in a `RECT` structure.) The first thing you need to do is create a DirectDraw clipper, like this:

    LPDIRECTDRAWCLIPPER lpddclipper = NULL; // hold the clipper

    if (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))

        return(0);

Next, you must attach the clipper to your application’s window with `IDIRECTDRAWCLIPPER::SetHWnd()`. This associates the clipper to your window and handles all the details for sizing and movement for you. In fact, you don’t even have to send a clipping list at all; it’s all automatic. The function is so simple. Here’s the prototype:

    HRESULT SetHWnd(DWORD dwFlags, // unused, set to 0

                    HWND hWnd);    // app window handle

Here’s the call to associate the clipper with your main window:

    if (FAILED(lpddclipper->SetHWnd(0, main_window_handle)))

        return(0);

> Warning: Now you’re ready to rock. There’s one little DirectX problem, though. The reference count on the clipper is now at 2—1 for the creation, 2 for the call to `SetClipper()`. This is fine, but destroying the surface won’t kill the clipper. You must make another call to `lpddclipper->Release()` to kill it, after releasing the surface with a call to `lpddsprimary->Release()`. The bottom line is you might think that you killed the clipper with a call to `lpddclipper->Release()`, but that only reduces the reference count to 1. Alas, Microsoft recommends that you make a call to `lpddclipper->Release()` right after the preceding code sequence, so that the reference count of `lpddclipper` is 1 as it should be—Whatever!

Next you have to associate the clipper with the surface you want to clip—in this case, the primary surface. To do this, you use `SetClipper()`, which you’ve already seen:

    if (FAILED(lpddsprimary->SetClipper(lpddclipper)))

        return(0);

Remember that the clipping that’s attached to the window only matters for blits to the primary surface—that is, the contents of the window. But in most cases, you’ll create an offscreen surface to simulate a double buffer, blit to that, and then copy the offscreen surface to the primary buffer using the blitter—a crude form of page flipping. Alas, attaching the blitter to the primary buffer only helps if the blits you make to it (the offscreen buffer) go out of bounds. And this will only occur if the user resizes.

#### Working with 8-Bit Windowed Modes

The last topic I want to touch upon is 8-bit windowed mode and the palette. To make a long story short, you can’t just create a palette, do anything you want with it, and then attach it to the primary surface. You must work a little with the Windows Palette Manager. Window palette management under GDI is beyond the scope of this book (I always wanted to say that), and I don’t feel like boring you with all the stupid details. The bottom line is, if you run your game in windowed 256-color mode, you’re going to have fewer than 256 colors at your disposal.

Each application running on the desktop has a logical palette that contains the desired colors of the application. However, the physical palette is the one that really matters. The physical palette reflects the actual hardware palette, and this is the compromise that Windows works with. When your application gets the focus, your logical palette is realized—in other words, the Windows Palette Manager starts mapping your colors to the physical palette as best it can. Sometimes it does a good job, and sometimes it doesn’t.

Moreover, the way you set up your logical palette’s flags determines how much slack Windows has to work with. Finally, at the very least, Windows needs 20 colors out of the palette: the first and last 10. These are reserved for Windows colors and are the bare minimum to make Windows applications look reasonable. The trick to creating a 256-color mode windowed application is restraining your artwork to 236 colors or less—so you have room for the Windows colors—and then setting the palette flags of your logical palette appropriately. Windows will then leave them alone when your palette is realized.

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.