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

This should look familiar. The only thing hidden is the fact that `lpitch32` is the byte pitch divided by four, so it’s a `DWORD` or 32-bit `WORD` stride. With that all in mind, check out `DEMO7_3.CPP|EXE`. It’s the same pixel-plotting demo, but in 32-bit mode. It should work on your machine because more video cards support 32-bit mode than pure 24-bit mode.

All righty, then! I think I’ve belabored high-color modes enough that you can work with them and convert any 8-bit color code that you want. Remember, I can’t assume that everyone has a Pentium II 450MHz with a Voodoo II 3D Accelerator. Sticking to 8-bit color is a good way to keep the processing power within reach of most people.

### Double Buffering

Thus far you’ve directly modified the contents of the primary surface, which is directly rasterized each frame by the video controller. This is fine for demos and static imagery, but what if you want to perform smooth animation? This is a definite problem; let me explain. As I alluded to earlier in the book, most computer animation is achieved by drawing each frame of animation in an offscreen buffer area and then blasting the image to the visible display surface very quickly, as shown in Figure 7.7.

Figure 7.7 Performing animation with double buffering.

This way the user can’t see you erase images, generate the display, or anything else you might do in each frame. As long as the copying of the offscreen image to the visible surface is very quick, you could theoretically do it 15 times a second, or 15 fps, and still have a reasonably smooth game. However, the standard these days is at least 30 fps, so that has become the minimum to get high-quality animation.

The process of drawing an image in an offscreen area and then copying it to the display surface is called double buffering, and it’s how 99 percent of all games perform animation. However, in the past (under DOS especially), there wasn’t special hardware to help with this process. This obviously changed with the introduction of DirectX/DirectDraw.

If acceleration hardware is present (and enough VRAM memory is on the video card), a process that’s similar to double buffering, called page flipping, can be employed. Page flipping is roughly the same idea as double buffering, except that you draw to one of two potentially visible surfaces and then direct the hardware to make the other surface the active display surface. This basically removes the “copy” step because the hardware addressing system is used to point the video rasterizer to a different portion of memory. The end result is an instantaneous page flip and update of the visual on the screen (hence the term page flipping).

Of course, page flipping has always been possible, and many game programmers used it when programming Mode X modes (320×240, 320×400). However, it’s a down-low-and-direct technique. Assembly language and video controller programming was usually needed to accomplish the task. But with DirectDraw it’s a snap. You’ll get to it in the next section. I just wanted you to have an idea of where this chapter is going before I show you double buffering in detail.

Implementing double buffering is trivial. All you need to do is allocate a portion of memory that has the same geometry as the primary DirectDraw surface, draw each frame of animation on it, and then copy the double buffer memory to the primary display surface. Unfortunately, there’s a problem with this scheme…

Let’s say you’ve decided to create a 640×480×8 DirectDraw mode. Hence, you would need to allocate a double buffer that was 640×480 or a linear array of 307,200 bytes. And keep in mind that the data is mapped in a row-order form, one row for each row on the screen. This is no problem, though. Here’s the code to create the double buffer:

    UCHAR *double_buffer  = (UCHAR *)malloc(640*480);

Or, using the new operator in C++:

    UCHAR *double_buffer = new UCHAR[640*480];

Either way you do it, you have an array of 307,200 bytes linearly addressable in memory that `double_buffer` points to. To address a single pixel at position (x,y), you would use the following code:

    double_buffer[x + 640*y] = …

Seems reasonable because there are 640 bytes per virtual line and you’re assuming a rectangular mapping of 640 bytes per line and 480 lines. Okay, here’s the problem: Assume that you’ve also locked a pointer to the primary display surface and it’s in `primary_buffer`. In addition, assume that during the lock you’ve extracted the memory pitch and stored it in `mempitch`, as shown in Figure 7.8. If `mempitch` is equal to 640, you can use the following code to copy the `double_buffer` to the `primary_buffer`:

    memcpy((void *)primary_buffer, (void *)double_buffer,640*480);

Figure 7.8 Primary display surfaces may have extra memory per line, causing addressing problems.

And almost instantly, the `double_buffer` will show up in the primary buffer.

There’s a potential optimization here. Notice, I’m using `memcpy()`. This function is rather slow because it only copies bytes (on some compilers). A better method would be to write your own `DWORD` or 32-bit copy function to move more data per cycle. You can do this with inline or external assembly language. You’ll see how when you get to optimization theory, but this is a good example if you’re taking advantage of the largest data chunk that the Pentium can process, which is a 32-bit value.

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.