![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Cutting Edge Direct 3D Programming
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 FunctionsThe 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. Well 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. Well 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 images 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. Well 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. Well 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 isnt 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 arent 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; }
|
![]() |
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. |