📄 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -