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

#### Loading a 16-Bit Bitmap

Loading a 16-bit bitmap is almost identical to loading an 8-bit image. However, you don’t need to worry about the palette because there isn’t one. Also, very few paint programs can generate 16-bit `.BMP` files, so if you want to use a 16-bit DirectDraw mode, you may have to load a 24-bit bitmap and then manually convert the bits to 16-bit by using a color-scaling algorithm. In general, you would perform the following operations to convert a 24-bit image to a 16-bit image:

  1. Create a buffer that’s m×n `WORD`s, where each `WORD` is 16-bit. This will hold your 16-bit final image.
  2. Access the image buffer after loading the 24-bit image into your `BITMAP_FILE` structure, and convert each 24-bit pixel to 16-bit by using the following crude color transform:

         // each pixel in BITMAP_FILE.buffer[] is encoded as 3-bytes

         // in BGR order, or BLUE, GREEN, RED

         // assuming index is pointing to the next pixel...

         UCHAR blue  = (bitmap.buffer[index*3 + 0]) >> 3,

               green = (bitmap.buffer[index*3 + 1]) >> 3,

               red   = (bitmap.buffer[index*3 + 2]) >> 3;

         // build up 16 bit color word

         USHORT color = _RGB16BIT565(red,green,blue);

And then you write `color` into your destination 16-bit buffer. Later in the book, when you see all the library functions, I’ll be sure to write a 24-bit to 16-bit bitmap converter for you (because I’m that kind of guy).

Anyway, assuming that the bitmap is actually in 16-bit format and you don’t need to do this operation, the bitmap load should be identical to the 8-bit load. For example, `DEMO7_11.CPP|EXE` loads a 24-bit image, converts it to 16-bit, and dumps it into the primary buffer.

#### Loading a 24-Bit Bitmap

Loading a 24-bit bitmap is the simplest of all. Just create a 24-bit bitmap file and then load it with the `Load_Bitmap_File()` function. Then `BITMAP_FILE.buffer[]` will hold the data in 3-byte pixels left to right, row by row, but in BGR (blue, green, red) format. Remember this, because it matters when you extract the data. Furthermore, many graphics cards don’t support 24-bit graphics; they support 32-bit because they don’t like the odd byte addressing (multiples of 3). So an extra byte is used for padding or alpha channeling. In either case, when you read out each pixel from `BITMAP_FILE.buffer[]` and write it to the primary surface or an offscreen DirectDraw surface that’s 32-bit, you’ll have to do this padding yourself. Here’s an example:

    // each pixel in BITMAP_FILE.buffer[] is encoded as 3-bytes

    // in BGR order, or BLUE, GREEN, RED

    // assuming index is pointing to the next pixel…

    UCHAR blue  = (bitmap.buffer[index*3 + 0]),

          green = (bitmap.buffer[index*3 + 1]),

          red   = (bitmap.buffer[index*3 + 2]);

    // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)

    _RGB32BIcxT(0,red,green,blue);

And you’ve seen this macro, so don’t freak out. Here it is again to refresh your memory:

    // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)

    #define _RGB32BIT(a,r,g,b) ( + ((g) << 8) + ((r) << 16) + ( << 24))

For an example of loading and displaying a nice 24-bit image, take a look at `DEMO7_12.CPP|EXE`. It loads a full 24-bit image, sets the display mode for 32-bit color, and copies the image to the primary surface. Looks sweet, huh?

#### Last Word on Bitmaps

Well, that’s it for loading bitmaps in 8-, 16-, or 24-bit format. However, you can see that a lot of utility functions will have to be written here! I’ll do the dirty work, so don’t worry. In addition, you might want to be able to load Targa files with the `.TGA` extension, because a number of 3D modelers can render animation sequences only to files with the name `filenamennnn.tga`, where `nnnn` varies from 0000 to 9999. You’re probably going to need to be able to load animation sequences like this, so when I dump the library functions on you, I’ll show you a `.TGA` load. It’s much easier than the `.BMP` format.

### Offscreen Surfaces

The whole point of DirectDraw is to take advantage of hardware acceleration. Alas, you can’t do that unless you use DirectDraw data structures and objects to hold bitmaps. DirectDraw surfaces are the key to using the blitter. You’ve already seen how to create a primary surface along with a secondary back buffer to create a page flipping animation chain, but you still need to learn how to create general m×n offscreen surfaces in either system memory or VRAM. With surfaces like this, you can stuff bitmaps into them and then blit the surfaces to the screen using the blitter.

At this point in the game, you can load bitmaps and get the bits out of them, so that problem is solved (minus some cell extraction software). The only piece missing is how to create a general offscreen DirectDraw surface that’s neither a primary surface nor a back buffer.

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.