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

Before you move on to clipping, I’d like to show you a demo of blitting from the back buffer to the primary surface. Take a look at `DEMO7_7.CPP|EXE` on the CD. The only problem is that I haven’t shown you how to load bitmaps from disk yet, so I can’t really blit anything cool—bummer! So what I did was draw a gradient of green in 16-bit color mode from top to bottom on the back buffer, and then use this as the source data. You’ll see a bunch of gradient rectangles copied to the primary surface at warp speed. Here’s the source from `Game_Main()` for your review:

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

    {

    // this is the main loop of the game, do all your processing

    // here

    RECT source_rect, // used to hold the destination RECT

         dest_rect;  // used to hold the destination RECT

    // make sure this isn’t executed again

    if (window_closed)

       return(0);

    // for now test if user is hitting ESC and send WM_CLOSE

    if (KEYDOWN(VK_ESCAPE))

       {

       PostMessage(main_window_handle,WM_CLOSE,0,0);

       window_closed = 1;

       } // end if

    // get a random rectangle for source

    int x1 = rand()%SCREEN_WIDTH;

    int y1 = rand()%SCREEN_HEIGHT;

    int x2 = rand()%SCREEN_WIDTH;

    int y2 = rand()%SCREEN_HEIGHT;

    // get a random rectangle for destination

    int x3 = rand()%SCREEN_WIDTH;

    int y3 = rand()%SCREEN_HEIGHT;

    int x4 = rand()%SCREEN_WIDTH;

    int y4 = rand()%SCREEN_HEIGHT;

    // now set up the RECT structure to fill the region from

    // (x1,y1) to (x2,y2) on the source surface

    source_rect.left   = x1;

    source_rect.top    = y1;

    source_rect.right  = x2;

    source_rect.bottom = y2;

    // now set up the RECT structure to fill the region from

    // (x3,y3) to (x4,y4) on the destination surface

    dest_rect.left   = x3;

    dest_rect.top    = y3;

    dest_rect.right  = x4;

    dest_rect.bottom = y4;

    // make the blitter call

    if (FAILED(lpddsprimary->Blt(&dest_rect,  // pointer to dest RECT

                      lpddsback,   // pointer to source surface

                      &source_rect,// pointer to source RECT

                      DDBLT_WAIT,  // control flags

                      NULL)))      // pointer to DDBLTFX holding info

       return(0);

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

    return(1);

    } // end Game_Main

Also, in `Game_Init()` I used a little inline assembly to do a `DWORD` or 32-bit line of two 16-bit pixels at once in `RGB.RGB` format instead of a slower 8-bit fill. Here’s that code:

    _asm

        {

        CLD                        ; clear direction of copy to forward

        MOV EAX, color             ; color goes here

        MOV ECX, (SCREEN_WIDTH/2)  ; number of DWORDS goes here

        MOV EDI, video_buffer      ; address of line to move data

        REP STOSD                  ; send the Pentium X on its way...

        } // end asm

Basically, the preceding code implements the following C/C++ loop:

    for (DWORD ecx = 0, DWORD *edi = video_buffer;

         ecx < (SCREEN_WIDTH/2); ecx++)

        edi[ecx] = color;

If you don’t know assembly language, don’t freak out. I just like to use it now and then for little things like this. Also, it’s good practice to use the inline assembler; it keeps you on your toes!

As an exercise, see if you can make the program work only on the primary surface. Simply delete the back buffer code, draw the image on the primary surface, and then run the blitter with the source and destination as the same surface. Watch what happens...

### Clipper Fundamentals

I’m going to talk about clipping over and over in this book. Pixel clipping, bitmap clipping, 2D clipping, 3D clipping, and I’m sure I’ll think of some more <BG>. Right now, though, the theme is DirectDraw. I want to focus on pixel clipping and bitmap clipping to help you ease into the subject, which I guarantee is going to get very complex when you do it in 3D!

Clipping is generally defined as “not drawing pixels or image elements that are out of bounds of the view port or window.” Just like Windows clips anything you draw to the client area of your window, you need to do this in a game that runs under DirectX. Now, as far as 2D graphics go, the only thing that DirectDraw accelerates are bitmaps and bit blitting. Sure, many cards know how to draw lines, circles, and other conic sections, but DirectDraw doesn’t support these primitives, so you don’t get access to them (hopefully you will soon, though).

What this all means is that if you write a graphics engine that draws pixels, lines, and bitmaps, you have to do the clipping yourself for the pixel and line drawing algorithms. However, DirectDraw can help with the bitmaps—as long as the bitmaps are in the form of DirectDraw surfaces, or `IDirectDrawSurface`s to be exact.

The help that DirectDraw gives is in the form of DirectDraw clippers under the `IDirectDrawClipper` interface. What you do is create an `IDirectDrawClipper`, give it valid regions to clip to, and then attach it to a surface. Then, when you use the blitter function, `Blt()`, it will clip to the clipping regions and you won’t have any out-of-bounds blitting or performance hits—if you have the proper hardware, of course. But first, take a look at how to clip pixels and do a rewrite of the `Blit8x8()` function that does clip.

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.