📄 gltexture.cpp
字号:
/*
gltexture.cpp - Texture class
Copyright (c) HalfLucifer, 2001.7.20
*/
#include "gltexture.h"
// TGA loading function
bool GLtexture::LoadTGA(char *filename)
{
GLubyte UTGAheader[12] = {0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA header
GLubyte CTGAheader[12] = {0,0,10,0,0,0,0,0,0,0,0,0}; // Compressed TGA Header
GLubyte TGAcompare[12]; // Used to compare TGA header
GLubyte header[6]; // The first six useful bytes from the header
GLuint BytesPerPixel; // Holds the bpp of the TGA
GLuint ImageSize; // Used to store image size while in RAM
GLuint type = GL_RGBA; // Set the default OpenGL mode to RGBA (32 bpp)
GLboolean TGAcompressed;
FILE *file = fopen(filename, "rb"); // Open the TGA file
if (file == NULL) // If file didn't exist
{
MessageBox(NULL, "Could not open texture file", "ERROR", MB_OK);
return false;
}
if (fread(TGAcompare, sizeof(TGAcompare), 1, file) == 0) // Attempt to read 12 byte header from file
{
MessageBox(NULL, "Could not read file header", "ERROR", MB_OK);
if (file != NULL)
fclose(file);
return false;
}
if (memcmp(UTGAheader, TGAcompare, sizeof(TGAcompare)) == 0) // Uncompressed TGA image
{
TGAcompressed = false;
}
else if (memcmp(CTGAheader, TGAcompare, sizeof(TGAcompare)) == 0) // Compressed TGA image
{
TGAcompressed = true;
}
else // If header matches neither type
{
MessageBox(NULL, "Could not match TGA file for type 2 or type 10", "ERROR", MB_OK);
fclose(file);
return false;
}
if (fread(header, sizeof(header), 1, file) == 0) // Read TGA header
{
MessageBox(NULL, "Could not read info header", "ERROR", MB_OK);
if (file != NULL)
fclose(file);
return false;
}
width = header[1] * 256 + header[0]; // Determine the TGA width (highbyte*256+lowbyte)
height = header[3] * 256 + header[2]; // Determine the TGA height (highbyte*256+lowbyte)
if (width<=0 || // Is the width less than or equal to zero?
height<=0 || // Is the height less than or equal to zero?
(header[4]!=24 && header[4]!=32)) // Is the TGA 24 or 32 bits?
{
fclose(file);
MessageBox(NULL, "Image format is incompatible", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
return false;
}
bpp = header[4]; // Grab the TGA's bits per pixel
BytesPerPixel = bpp / 8; // Divide by 8 to get the bytes per pixel
ImageSize = width * height * BytesPerPixel; // Calculate the memory required for the TGA data
data = new GLubyte [ImageSize]; // Allocate memory to hold the TGA data
if (data==NULL) // Does the storage memory exist?
{
MessageBox(NULL, "Could not allocate memory for image", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
fclose(file);
return false;
}
if (!TGAcompressed) // Manipulate uncompressed TGA image data
{
if (fread(data, 1, ImageSize, file) != ImageSize) // Does the image size match the memory allocated?
{
MessageBox(NULL, "Could not read image data", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
delete [] data;
fclose(file);
return false;
}
for (GLuint i=0; i<(int)ImageSize; i+=BytesPerPixel) // Swaps the 1st and 3rd bytes using XOR
data[i] ^= data[i+2] ^= data[i] ^= data[i+2];
}
else // Manipulate compressed TGA image data
{
GLuint PixelCount = width * height; // Number of pixels in the image
GLuint CurrentPixel = 0; // Current pixel being read
GLuint CurrentByte = 0; // Current byte
GLubyte *ColorBuffer = new GLubyte [BytesPerPixel]; // Storage for one pixel
do
{
GLubyte ChunkHeader = 0; // Storage for chunk header
if (fread(&ChunkHeader, sizeof(GLubyte), 1, file) == 0) // Read in the 1 byte header
{
MessageBox(NULL, "Could not read RLE header", "ERROR", MB_OK);
if (file != NULL)
fclose(file);
delete [] data;
return false;
}
if (ChunkHeader < 128) // The data is RAW type
{
ChunkHeader++; // Add 1 to get number of following color values
for (short counter=0; counter<ChunkHeader; counter++) // Read RAW color values
{
if(fread(ColorBuffer, 1, BytesPerPixel, file) != BytesPerPixel) // Try to read one pixel
{
MessageBox(NULL, "Could not read image data", "ERROR", MB_OK);
if (file != NULL)
fclose(file);
delete [] ColorBuffer;
delete [] data;
return false;
}
data[CurrentByte] = ColorBuffer[2];
data[CurrentByte+1] = ColorBuffer[1];
data[CurrentByte+2] = ColorBuffer[0];
if (BytesPerPixel == 4)
data[CurrentByte+3] = ColorBuffer[3];
CurrentByte += BytesPerPixel; // Increase thecurrent byte by the number of bytes per pixel
CurrentPixel++; // Increase current pixel by 1
if (CurrentPixel > PixelCount) // Make sure we have not read too many pixels
{
MessageBox(NULL, "Too many pixels read", "ERROR", NULL);
if (file != NULL)
fclose(file);
delete [] ColorBuffer;
delete [] data;
return false;
}
}
}
else // The data is RLE type
{
ChunkHeader -= 127; // Subteact 127 to get rid of the ID bit
if(fread(ColorBuffer, 1, BytesPerPixel, file) != BytesPerPixel) // Attempt to read following color values
{
MessageBox(NULL, "Could not read from file", "ERROR", MB_OK);
if (file != NULL)
fclose(file);
delete [] ColorBuffer;
delete [] data;
return false;
}
for (short counter=0; counter<ChunkHeader; counter++) // Read RLE color values
{
data[CurrentByte] = ColorBuffer[2];
data[CurrentByte+1] = ColorBuffer[1];
data[CurrentByte+2] = ColorBuffer[0];
if (BytesPerPixel == 4)
data[CurrentByte+3] = ColorBuffer[3];
CurrentByte += BytesPerPixel; // Increase thecurrent byte by the number of bytes per pixel
CurrentPixel++; // Increase current pixel by 1
if (CurrentPixel > PixelCount) // Make sure we have not read too many pixels
{
MessageBox(NULL, "Too many pixels read", "ERROR", NULL);
if (file != NULL)
fclose(file);
delete [] ColorBuffer;
delete [] data;
return false;
}
}
}
} while (CurrentPixel < PixelCount); // Loop while there are still pixels left
}
fclose(file);
glGenTextures(1, &TexID); // Build a texture from the data
glBindTexture(GL_TEXTURE_2D, TexID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MaxFilter);
if (bpp==24) // Was the TGA 24 bpp?
type = GL_RGB;
if (MipMap)
gluBuild2DMipmaps(GL_TEXTURE_2D, type, width, height, type, GL_UNSIGNED_BYTE, data);
else
glTexImage2D(GL_TEXTURE_2D, 0, type, width, height, 0, type, GL_UNSIGNED_BYTE, data);
return true;
}
// JPG loading fuction
bool GLtexture::LoadJPG(char *filename)
{
JPEG_CORE_PROPERTIES header;
GLuint ImageSize = 0;
GLubyte* temp = NULL;
ZeroMemory(&header, sizeof(JPEG_CORE_PROPERTIES));
if (ijlInit(&header)!=IJL_OK) // Initialize the image container
{
MessageBox(NULL, "Could not load the image files correctly", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
return false;
}
header.JPGFile = const_cast<char*>(filename);
if (ijlRead(&header, IJL_JFILE_READPARAMS)!=IJL_OK) // Read the params from the file
{
MessageBox(NULL, "Could not load the image files correctly", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
return false;
}
switch(header.JPGChannels) // Check information about the channels
{
case 1:
header.JPGColor = IJL_G;
break;
case 3:
header.JPGColor = IJL_YCBCR;
break;
default:
{
header.DIBColor = (IJL_COLOR)IJL_OTHER;
header.JPGColor = (IJL_COLOR)IJL_OTHER;
break;
}
}
header.DIBWidth = header.JPGWidth;
header.DIBHeight = header.JPGHeight;
header.DIBChannels = 3;
header.DIBPadBytes = IJL_DIB_PAD_BYTES(header.DIBWidth, header.DIBChannels);
ImageSize = (header.DIBWidth * header.DIBChannels + header.DIBPadBytes) * header.DIBHeight;
temp = new byte[ImageSize]; // Allocate memory to store the image bytes
data = new byte[ImageSize];
header.DIBBytes = temp;
if (temp==NULL || data==NULL ||
ijlRead(&header, IJL_JFILE_READWHOLEIMAGE)!=IJL_OK)
{
MessageBox(NULL, "Storage memory for the images corrupted", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
delete [] temp;
delete [] data;
return false;
}
if (ijlFree(&header)!=IJL_OK)
{
MessageBox(NULL, "Could not load the image files correctly", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
delete [] temp;
delete [] data;
return false;
}
width = header.DIBWidth;
height = header.DIBHeight;
for (GLuint j=0; j<height; j++)
{
for (GLuint i=0; i<width; i++)
{
data[(j * width+i) * 3] = temp[((height-1-j) * width+i) * 3+2];
data[(j * width+i) * 3+1] = temp[((height-1-j) * width+i) * 3+1];
data[(j * width+i) * 3+2] = temp[((height-1-j) * width+i) * 3];
}
}
delete [] temp;
glGenTextures(1, &TexID);
glBindTexture(GL_TEXTURE_2D, TexID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MaxFilter);
if (MipMap)
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
return true;
}
// BMP loading function
bool GLtexture::LoadBMP(char *filename)
{
BITMAPFILEHEADER FileHeader; //The bitmap file header
BITMAPINFOHEADER InfoHeader;
GLuint type = GL_RGBA; // Set the default OpenGL mode to RGBA
GLuint ImageSize;
FILE* file = fopen(filename, "rb");
if (file==NULL)
{
MessageBox(NULL, "Could not open texture file", "ERROR", MB_OK);
return false;
}
fread(&FileHeader, sizeof(BITMAPFILEHEADER), 1, file); // Read the bitmap file header
if (FileHeader.bfType != 0x4D42) // Check for the universal bitmap id
{
MessageBox(NULL, "Could not match BMP type", "ERROR", MB_OK);
fclose(file);
return false;
}
fread(&InfoHeader, sizeof(BITMAPINFOHEADER), 1, file); // Read the bitmap information header
fseek(file, FileHeader.bfOffBits, SEEK_SET); // Advance the file pointer to the beginning of the bitmap data
width = InfoHeader.biWidth;
height = InfoHeader.biHeight;
bpp = InfoHeader.biBitCount;
ImageSize = width * height * bpp;
data = new unsigned char [ImageSize]; // Allocate the bitmap image data
if (data==NULL) // Confirm memory allocation
{
MessageBox(NULL, "Could not allocate memory for image", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
fclose(file);
return false;
}
fread(data, 1, ImageSize, file); // Read the bitmap image data
if (data==NULL) // Make sure bitmap image data was read
{
MessageBox(NULL, "Could not read image data", "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
fclose(file);
return false;
}
for (GLuint i=0; i<ImageSize; i+=3) // Swaps the 1st and 3rd bytes using XOR
data[i] ^= data[i+2] ^= data[i] ^= data[i+2];
fclose(file);
glGenTextures(1, &TexID); // Build a texture from the data
glBindTexture(GL_TEXTURE_2D, TexID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MaxFilter);
if (bpp==24) // Was the BMP 24 bpp?
type = GL_RGB;
if (MipMap)
gluBuild2DMipmaps(GL_TEXTURE_2D, type, width, height, type, GL_UNSIGNED_BYTE, data);
else
glTexImage2D(GL_TEXTURE_2D, 0, type, width, height, 0, type, GL_UNSIGNED_BYTE, data);
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -