⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texture.cpp

📁 一本关于OPenGL的很好的电子书
💻 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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -