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

📄 gltexture.cpp

📁 实战粒子系统例程
💻 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 + -