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

Most new video boards support what are called linear memory modes and have addressing hardware, so this property holds true, but it’s not guaranteed. Therefore, you can’t assume that a 640×480×8 video mode has 640 bytes per line. This is what the `lPitch` field is for. You must refer to it to make your memory addressing calculations correct, so that you can move from line to line. For example, to access any pixel in a 640×480×8 (256-color) display mode, you can use the following code, assuming you’ve already requested DirectDraw to give you `lPitch` and `lpSurface` is pointing to the surface memory (which I’ll explain next):

    ddsd.lpSurface[x + y*ddsd.lPitch] = color;

Simple, isn’t it? In most cases, `ddsd.lPitch` would be 640 for a 640×480×8 mode, and for a 640×480×16 mode, `ddsd.lPitch` would be 1280 (two bytes per pixel = 640×2). But for some cards, this may not be the case due to the way memory is stored on the card, the internal cache for the card, or whatever... The moral of the story is: Always use `lPitch` for your memory calculations and you’ll always be safe.

Even though `lPitch` may not equal the horizontal resolution of the mode that you set, it may be worth it to test for it so that you can switch to more optimized functions. For example, during the initialization of your code, you might get `lPitch` and compare it to the selected horizontal resolution. If they are equal, you might switch to highly optimized code that hard-codes the number of bytes per line.

  `lpSurface`—This field is used to retrieve a pointer to the actual memory that the surface you create resides in. The memory may be in VRAM or system memory, but you don’t need to worry about it. Once you have the pointer to it, you can manipulate it as you would any other memory—write to it, read from it, and so on. This is exactly how you’re going to implement pixel plotting. Alas, making this pointer valid takes a little work, but we’ll get there in a minute. Basically, you must “lock” the surface memory and tell DirectX that you’re going to muck with it and that no other process should attempt to read or write from it. Furthermore, when you do get this pointer, depending on the color depth—8, 16, 24, 32 bpp—you will usually cast and assign it to a working alias pointer.
  `dwBackBufferCount`—This field is used to set or read the number of back buffers or secondary offscreen flipping buffers that are chained to the primary surface. If you’ll recall, back buffers are used to implement smooth animation by creating one or more virtual primary buffers (buffers with the same geometry and color depth) that are offscreen. Then you draw on the back buffer, which is invisible to the user, and then quickly flip or copy the back buffer(s) to the primary buffer for display. If you have only one back buffer, the technique is called double buffering. Using two back buffers is called triple buffering, which is a little better but memory-intensive. To keep things simple, in most cases you’ll create flipping chains that contain a single primary surface and one back buffer.
  `ddckCKDestBlt`—This field is used to control the destination color key, which is used in blitting operations to control the color(s) that can be written to. More on this later in the Chapter 7, “Advanced DirectDraw and Bitmapped Graphics.”
  `ddckCKSrcBlt`—This field is used to indicate the source color key, which is basically the colors that you don’t want to be blitted when you’re performing bitmapping operations. This is how you set the transparent colors for your bitmaps. More on this in Chapter 7.
  `ddpfPixelFormat`—This field is used to retrieve the pixel format of a surface, which is quite important if you’re trying to figure out what the properties of a surface are. The following is the general structure, but you’ll have to look at the DirectX SDK for all the details because they’re lengthy and not really relevant right now:

      typedef struct _DDPIXELFORMAT

              {

              DWORD dwSize;

              DWORD dwFlags;

              DWORD dwFourCC;

              union

              {

              DWORD dwRGBBitCount;

              DWORD dwYUVBitCount;

              DWORD dwZBufferBitDepth;

              DWORD dwAlphaBitDepth;

              DWORD dwLuminanceBitCount; // new for DirectX 6.0

              DWORD dwBumpBitCount;      // new for DirectX 6.0

              } DUMMYUNIONNAMEN(1);

              union

              {

              DWORD dwRBitMask;

              DWORD dwYBitMask;

              DWORD dwStencilBitDepth;   // new for DirectX 6.0

              DWORD dwLuminanceBitMask;  // new for DirectX 6.0

              DWORD dwBumpDuBitMask;     // new for DirectX 6.0

              } DUMMYUNIONNAMEN(2);

              union

              {

              DWORD dwGBitMask;

              DWORD dwUBitMask;

              DWORD dwZBitMask;          // new for DirectX 6.0

              DWORD dwBumpDvBitMask;     // new for DirectX 6.0

              } DUMMYUNIONNAMEN(3);

              union

              {

              DWORD dwBBitMask;

              DWORD dwVBitMask;

              DWORD dwStencilBitMask;    // new for DirectX 6.0

              DWORD dwBumpLuminanceBitMask;  // new for DirectX 6.0

              } DUMMYUNIONNAMEN(4);

              union

              {

              DWORD dwRGBAlphaBitMask;

              DWORD dwYUVAlphaBitMask;

              DWORD dwLuminanceAlphaBitMask; // new for DirectX 6.0

              DWORD dwRGBZBitMask;

              DWORD dwYUVZBitMask;

              } DUMMYUNIONNAMEN(5);

              } DDPIXELFORMAT, FAR* LPDDPIXELFORMAT;

  > Note: I have bolded some of the more commonly used fields.

  `ddsCaps`—This field is used to indicate the requested properties of the surface that haven’t been defined elsewhere. In reality, this field is another data structure. `DDSCAPS2` is shown here:

      typedef struct _DDSCAPS2

              {

              DWORD    dwCaps;   // Surface capabilities

              DWORD    dwCaps2;  // More surface capabilities

              DWORD    dwCaps3;  // future expansion

              DWORD    dwCaps4;  // future expansion

              } DDSCAPS2, FAR* LPDDSCAPS2;

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.