www.pudn.com > airhockey.rar > texture.cpp


#include "texture.h" 
 
// LoadBitmapFile 
// desc: Returns a pointer to the bitmap image of the bitmap specified 
//       by filename. Also returns the bitmap header information. 
//		 No support for 8-bit bitmaps. 
unsigned char *CTexture::LoadBitmapFile(char *filename, BITMAPINFOHEADER *bitmapInfoHeader) 
{ 
	FILE *filePtr;							// the file pointer 
	BITMAPFILEHEADER	bitmapFileHeader;		// bitmap file header 
	unsigned char		*bitmapImage;			// bitmap image data 
	int					imageIdx = 0;		// image index counter 
	unsigned char		tempRGB;				// swap variable 
 
	// open filename in "read binary" mode 
	filePtr = fopen(filename, "rb"); 
	if (filePtr == NULL) 
		return NULL; 
 
	// read the bitmap file header 
	fread(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, filePtr); 
	 
	// verify that this is a bitmap by checking for the universal bitmap id 
	if (bitmapFileHeader.bfType != BITMAP_ID) 
	{ 
		fclose(filePtr); 
		return NULL; 
	} 
 
	// read the bitmap information header 
	fread(bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, filePtr); 
 
	// move file pointer to beginning of bitmap data 
	fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET); 
 
	// allocate enough memory for the bitmap image data 
	bitmapImage = (unsigned char*)malloc(bitmapInfoHeader->biSizeImage); 
 
	// verify memory allocation 
	if (!bitmapImage) 
	{ 
		free(bitmapImage); 
		fclose(filePtr); 
		return NULL; 
	} 
 
	// read in the bitmap image data 
	fread(bitmapImage, 1, bitmapInfoHeader->biSizeImage, filePtr); 
 
	// make sure bitmap image data was read 
	if (bitmapImage == NULL) 
	{ 
		fclose(filePtr); 
		return NULL; 
	} 
 
	// swap the R and B values to get RGB since the bitmap color format is in BGR 
	for (imageIdx = 0; imageIdx < bitmapInfoHeader->biSizeImage; imageIdx+=3) 
	{ 
		tempRGB = bitmapImage[imageIdx]; 
		bitmapImage[imageIdx] = bitmapImage[imageIdx + 2]; 
		bitmapImage[imageIdx + 2] = tempRGB; 
	} 
 
	// close the file and return the bitmap image data 
	fclose(filePtr); 
	return bitmapImage; 
} 
 
// LoadPCXFile() 
// desc: loads a PCX file into memory 
unsigned char *CTexture::LoadPCXFile(char *filename, PCXHEADER *pcxHeader) 
{ 
     int idx = 0;                  // counter index 
     int c;                             // used to retrieve a char from the file 
     int i;                             // counter index 
     int numRepeat;       
     FILE *filePtr;                // file handle 
     int width;                         // pcx width 
     int height;                        // pcx height 
     unsigned char *pixelData;     // pcx image data 
     unsigned char *paletteData;   // pcx palette data 
 
     // open PCX file 
     filePtr = fopen(filename, "rb"); 
     if (filePtr == NULL) 
          return NULL; 
 
     // retrieve first character; should be equal to 10 
     c = getc(filePtr); 
     if (c != 10) 
     { 
          fclose(filePtr); 
          return NULL; 
     } 
 
     // retrieve next character; should be equal to 5 
     c = getc(filePtr); 
     if (c != 5) 
     { 
          fclose(filePtr); 
          return NULL; 
     } 
 
     // reposition file pointer to beginning of file 
     rewind(filePtr); 
 
     // read 4 characters of data to skip 
     fgetc(filePtr); 
     fgetc(filePtr); 
     fgetc(filePtr); 
     fgetc(filePtr); 
 
     // retrieve leftmost x value of PCX 
     pcxHeader->xMin = fgetc(filePtr);       // loword 
     pcxHeader->xMin |= fgetc(filePtr) << 8; // hiword 
 
     // retrieve bottom-most y value of PCX 
     pcxHeader->yMin = fgetc(filePtr);       // loword 
     pcxHeader->yMin |= fgetc(filePtr) << 8; // hiword 
 
     // retrieve rightmost x value of PCX 
     pcxHeader->xMax = fgetc(filePtr);       // loword 
     pcxHeader->xMax |= fgetc(filePtr) << 8; // hiword 
 
     // retrieve topmost y value of PCX 
     pcxHeader->yMax = fgetc(filePtr);       // loword 
     pcxHeader->yMax |= fgetc(filePtr) << 8; // hiword 
 
     // calculate the width and height of the PCX 
     width = pcxHeader->xMax - pcxHeader->xMin + 1; 
     height = pcxHeader->yMax - pcxHeader->yMin + 1; 
 
     // allocate memory for PCX image data 
     pixelData = (unsigned char*)malloc(width*height); 
 
     // set file pointer to 128th byte of file, where the PCX image data starts 
     fseek(filePtr, 128, SEEK_SET); 
      
     // decode the pixel data and store 
     while (idx < (width*height)) 
     { 
          c = getc(filePtr); 
          if (c > 0xbf) 
          { 
               numRepeat = 0x3f & c; 
               c = getc(filePtr); 
 
               for (i = 0; i < numRepeat; i++) 
               { 
                    pixelData[idx++] = c; 
               } 
          } 
          else 
               pixelData[idx++] = c; 
 
          fflush(stdout); 
     } 
 
     // allocate memory for the PCX image palette 
     paletteData = (unsigned char*)malloc(768); 
 
     // palette is the last 769 bytes of the PCX file 
     fseek(filePtr, -769, SEEK_END); 
 
     // verify palette; first character should be 12 
     c = getc(filePtr); 
     if (c != 12) 
     { 
          fclose(filePtr); 
          return NULL; 
     } 
 
     // read and store all of palette 
     for (i = 0; i < 768; i++) 
     { 
          c = getc(filePtr); 
          paletteData[i] = c; 
     } 
 
     // close file and store palette in header 
     fclose(filePtr); 
     pcxHeader->palette = paletteData; 
 
     // return the pixel image data 
     return pixelData; 
} 
 
// LoadPCXTexture() 
// desc: loads a PCX image file as a texture 
void CTexture::LoadPCXTexture(char *filename) 
{ 
     PCXHEADER texInfo;            // header of texture 
//     texture_t *thisTexture;       // the texture 
     unsigned char *unscaledData;// used to calculate pcx 
     int i;                             // index counter 
     int j;                             // index counter 
     int width;                         // width of texture 
     int height;                        // height of texture 
 
     // load the PCX file into the texture struct 
     data = LoadPCXFile(filename, &texInfo); 
     if (data == NULL) 
     { 
          free(data); 
     //     return NULL; 
     } 
 
     // store the texture information 
     palette = texInfo.palette; 
     width = texInfo.xMax - texInfo.xMin + 1; 
     height = texInfo.yMax - texInfo.yMin + 1; 
     textureType = PCX; 
 
     // allocate memory for the unscaled data 
     unscaledData = (unsigned char*)malloc(width*height*4); 
 
     // store the unscaled data via the palette 
     for (j = 0; j < height; j++)  
     { 
          for (i = 0; i < width; i++)  
          { 
               unscaledData[4*(j*width+i)+0] = (unsigned char)palette[3*data[j*width+i]+0]; 
               unscaledData[4*(j*width+i)+1] = (unsigned char)palette[3*data[j*width+i]+1]; 
               unscaledData[4*(j*width+i)+2] = (unsigned char)palette[3*data[j*width+i]+2]; 
               unscaledData[4*(j*width+i)+3] = (unsigned char)255; 
          } 
     } 
 
     // find width and height's nearest greater power of 2 
     width = this->width; 
     height = this->height; 
 
     // find width's 
     i = 0; 
     while (width) 
     { 
          width /= 2; 
          i++; 
     } 
     scaledHeight = (long)pow(2, i-1); 
 
     // find height's 
     i = 0; 
     while (height) 
     { 
          height /= 2; 
          i++; 
     } 
     scaledWidth = (long)pow(2, i-1); 
 
     // clear the texture data 
     if (data != NULL) 
     { 
          free(data); 
          data = NULL; 
     } 
 
     // reallocate memory for the texture data 
     data = (unsigned char*)malloc(scaledWidth*scaledHeight*4); 
      
     // use the GL utility library to scale the texture to the unscaled dimensions 
     gluScaleImage(GL_RGBA, width, height, GL_UNSIGNED_BYTE, unscaledData, scaledWidth, scaledHeight, GL_UNSIGNED_BYTE, data); 
 
//     return thisTexture; 
 
} 
 
// LoadBMPTexture() 
// desc: loads a texture of the BMP format 
void CTexture::LoadBMPTexture(char *filename) 
{ 
	BITMAPINFOHEADER texInfo;		// BMP header 
	unsigned char *thisTexture;			// the texture 
 
	// allocate memory for the texture 
	/*thisTexture = (*)malloc(sizeof(texture_t)); 
	if (thisTexture == NULL) 
		return NULL; 
*/ 
	// store BMP data in texture 
	data = LoadBitmapFile(filename, &texInfo); 
	if (data == NULL) 
	{ 
		free(data); 
//		return NULL; 
	} 
	 
	// store texture information 
	width = texInfo.biWidth; 
	height = texInfo.biHeight; 
	palette = NULL; 
	scaledHeight = 0; 
	scaledWidth = 0; 
	textureType = BMP; 
 
//	return thisTexture; 
} 
 
// LoadTexture() 
// desc: loads a texture given the filename 
void CTexture::LoadTexture(char *filename) 
{ 
	char *extStr; 
 
	// get extension from filename 
	extStr = strchr(filename, '.'); 
	extStr++; 
 
	// set the texture type based on extension of filename 
	if ((strcmp(extStr, "BMP") == 0) || (strcmp(extStr, "bmp") == 0)) 
		LoadBMPTexture(filename); 
	else if ((strcmp(extStr, "PCX") == 0) || (strcmp(extStr, "pcx") == 0) ) 
		LoadPCXTexture(filename); 
	/* 
	else if ((strcmp(extStr, "TGA") == 0) || (strcmp(extStr, "tga") == 0) ) 
		thisTexture = LoadTGATexture(filename); 
		//texType = TGA; 
	*/ 
	//return thisTexture; 
}