Click Here!
home account info subscribe login search My ITKnowledge FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
To access the contents, click the chapter and section titles.

Cutting Edge Direct 3D Programming
(Publisher: The Coriolis Group)
Author(s): Stan Trujillo
ISBN: 1576100502
Publication Date: 11/01/96

Bookmark It

Search this book:
 
Previous Table of Contents Next


The last step is to create the Z-buffer surface and attach it to the backsurf surface:

ddraw->CreateSurface( &desc, &zbufsurf, 0 );
backsurf->AddAttachedSurface( zbufsurf );

Once the Z-buffer surface is attached, Direct3D makes use of it automatically. No further Z-buffer manipulation is required.

The Palette Functions

The RMWin class provides two member functions that facilitate the use of palettes. The UsePalette() function is a protected function that instructs RMWin to use the palette stored in a BMP file. The UsePalette() function is declared in the RMWin class definition:

void UsePalette( CString filename ) { palettefile=filename; }

The function simply stores the supplied file name. The file is used by the RMWin class when a palette must be created.

You may recall that the OnCreate() function calls the private function InstallPalette(). The InstallPalette() function uses the file name supplied by the UsePalette() function to extract and install a palette based on the contents of the BMP file. InstallPalette() is shown in Listing 10.6.

Listing 10.6 The InstallPalette() function.

BOOL RMWin::InstallPalette()
{
    BITMAPFILEHEADER bmpfilehdr;
    BITMAPINFOHEADER bmpinfohdr;
    RGBQUAD quad[256];
    PALETTEENTRY pe[256];
    int ncolors;

    if (palettefile.GetLength()<=0)
        return FALSE;
    if (modedepth!=8)
        return FALSE;

    if (palette)
    {
        palette->Release();
        palette=0;
    }

    ifstream bmp( palettefile, ios::binary | ios::nocreate );

    bmp.read( (char*)&bmpfilehdr, sizeof(bmpfilehdr) );
    bmp.read( (char*)&bmpinfohdr, sizeof(bmpinfohdr) );

    char* ptr=(char*)&bmpfilehdr.bfType;
    if (*ptr!='B' || *++ptr!='M')
    {
        TRACE("invalid bitmap\n");
        return FALSE;
    }

    if (bmpinfohdr.biBitCount!=8)
    {
        TRACE("not 8 bit file!\n");
        return FALSE;
    }

    if (bmpinfohdr.biClrUsed==0)
        ncolors=256;
    else
        ncolors=bmpinfohdr.biClrUsed;

    bmp.read( (char*)quad, sizeof(RGBQUAD)*ncolors );

    for( int i=0; i<ncolors; i++)
    {
        pe[i].peRed    = quad[i].rgbRed;
        pe[i].peGreen = quad[i].rgbGreen;
        pe[i].peBlue   = quad[i].rgbBlue;
        pe[i].peFlags  = D3DPAL_READONLY;
    }

    HRESULT r=ddraw->CreatePalette( DDPCAPS_8BIT, pe, &palette, 0 );
    if (r!=DD_OK)
    {
        TRACE("failed to load palette data from file\n");
        return FALSE;
    }

    primsurf->SetPalette( palette );
    backsurf->SetPalette( palette );

    return TRUE;
}

Before we discuss the InstallPalette() function, it should be mentioned that only the palette portion of the BMP file is extracted. The image data in the file is ignored.

The InstallPalette() function first declares several data instances:

BITMAPFILEHEADER bmpfilehdr;
BITMAPINFOHEADER bmpinfohdr;
RGBQUAD quad[256];
PALETTEENTRY pe[256];

The BITMAPFILEHEADER structure appears at the beginning of every BMP file. We’ll use the structure to load file-specific data from the BMP file. In particular, the BITMAPFILEHEADER structure contains signature data that identifies BMP files. The BITMAPFILEHEADER structure is defined like this:

typedef struct tagBITMAPFILEHEADER {
        WORD      bfType;
        DWORD     bfSize;
        WORD      bfReserved1;
        WORD      bfReserved2;
        DWORD     bfOffBits;
} BITMAPFILEHEADER;

The bfType field contains the characters “BM” in a valid BMP file. If this signature is incorrect, we will know that the file that we are loading is not valid.

The BITMAPINFOHEADER structure appears immediately after the BITMAPFILEHEADER structure in a BMP file. We’ll use this structure to load image-specific data from the file. The BITMAPINFOHEADER structure is defined as follows:

typedef struct tagBITMAPINFOHEADER {
   DWORD   biSize;
   LONG    biWidth;
   LONG    biHeight;
   WORD    biPlanes;
   WORD    biBitCount
   DWORD   biCompression;
   DWORD   biSizeImage;
   LONG    biXPelsPerMeter;
   LONG    biYPelsPerMeter;
   DWORD   biClrUsed;
   DWORD   biClrImportant;
} BITMAPINFOHEADER;

The biWidth and biHeight fields contain the image dimensions. The biBitCount field indicates the image’s bit depth. The biBitCount field is used to ensure that we are loading an 8-bit file.

An array of RGBQUAD structures is declared because BMP files store palette data as RGBQUAD entries. The array is declared with 256 entries because that is the maximum number of color entries that will be stored in the file.

Next, an array of PALETTEENTRY structures is declared. We’ll use this array to create the DirectDraw palette. The RGBQUAD and PALETTEENTRY structures are similar. The definitions look like this:

typedef struct tagRGBQUAD {
    BYTE   rgbBlue;
    BYTE   rgbGreen;
    BYTE   rgbRed;
    BYTE   rgbReserved;
} RGBQUAD;

typedef struct tagPALETTEENTRY {
    BYTE   peRed;
    BYTE   peGreen;
    BYTE   peBlue;
    BYTE   peFlags;
} PALETTEENTRY;

The biggest difference is the order in which the red, green, and blue color elements appear. We’ll use a loop to copy the contents of the RGBQUAD array to the PALETTEENTRY array.

The InstallPalette() first function checks the palettefile string:

if (palettefile.GetLength()<=0)
    return FALSE;

Recall that the palettefile string is assigned by the UsePalette() function. If classes derived from RMWin do not use UsePalette() to announce the name of a BMP file, no palette is created and the InstallPalette() function returns FALSE. This isn’t as bad as it sounds, because only 8-bit modes require a palette. Applications that use only 16-, 24-, and 32-bit modes will execute properly without using the UsePalette() function.

Next, the current display mode depth is checked:

if (modedepth!=8)
    return FALSE;

Palettes aren’t necessary for display mode depths other than eight, so the InstallPalette() function returns if the current display mode depth is not eight.

The InstallPalette() function then releases any existing palette:

if (palette)
{
    palette->Release();
    palette=0;
}


Previous Table of Contents Next


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 whole or in part in any form or medium without express written permission of EarthWeb is prohibited.