www.pudn.com > Particles1.zip > textures.cpp
#include "Textures.h" #include#define EIGHT_BIT_FORMAT GL_ALPHA //************** //Only for loading bmps: void COGLTexture::LoadFromFile(char *filename) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1,&ID); glBindTexture( GL_TEXTURE_2D, ID); Image = auxDIBImageLoadA( (const char*) filename ); Width = Image->sizeX; Height = Image->sizeY; gluBuild2DMipmaps( GL_TEXTURE_2D, 3, Image->sizeX, Image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, Image->data); delete Image; } //////////////////////////////////////////////////////////////////////////// /// /// CODE FROM NEHE'S "LESSON 25": Loading a TGA /// (modified) /// //////////////////////////////////////////////////////////////////////////// bool LoadTGA(STGAData *TGAData, const char *filename) // Loads A TGA File Into Memory { GLubyte TGAheader1[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header for RGB / RGBA GLubyte TGAheader2[12]={0,1,1,0,0,0,1,24,0,0,0,0}; // Uncompressed TGA Header for Grayscale GLubyte TGAcompare[12]; // Used To Compare TGA Header GLubyte header[6]; // First 6 Useful Bytes From The Header GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP) FILE *file = fopen(filename, "rb"); // Open The TGA File if( file==NULL) return false; // Does File Exist? if (fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read? ( memcmp(TGAheader1,TGAcompare,sizeof(TGAheader1))!=0 &&memcmp(TGAheader2,TGAcompare,sizeof(TGAheader2)) ) || // Does The Header Match What We Want? fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes { if (file == NULL) // Did The File Even Exist? *Added Jim Strong* return false; // Return False else { //fclose(file); // If Anything Failed, Close The File //return false; // Return False } } TGAData->Width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte) TGAData->Height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte) //I don't need to check here for the bpp. This will be done by //the calling function. TGAData->BitsPerPixel = header[4]; // Grab The TGA's Bits Per Pixel bytesPerPixel = TGAData->BitsPerPixel/8; // Divide By 8 To Get The Bytes Per Pixel imageSize = TGAData->Width*TGAData->Height*bytesPerPixel; // Calculate The Memory Required For The TGA Data if (bytesPerPixel == 1) { GLubyte DummyData[768]; fread(DummyData,1,768,file); } TGAData->Data=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data if( TGAData->Data==NULL || // Does The Storage Memory Exist? fread(TGAData->Data, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved? { if(TGAData->Data!=NULL) // Was Image Data Loaded free(TGAData->Data); // If So, Release The Image Data fclose(file); // Close The File return false; // Return False } //I also do not swap Red and Blue values (this may only be done //with 24/32-bpp-images). Again it's the calling routine's task. fclose (file); // Close The File return true; } bool COGLTexture::LoadFromTGA(const char *filename,const char *AlphaMap, bool bMipMaps) { STGAData TGAData; //Used to load the TGA-Texture STGAData AlphaData; //Used to load the Alpha-Map (if specified) GLubyte * RGBAData = NULL; //RGBA Data. This can be the TGA file (if it contains 32bpp) //or it is the combination of TGA and alpha map. //If no alpha map is requested, it contains RGB data GLuint RGBADataLength; //Length of RGBA Data type = GL_RGB; char * LogStr; if (filename != NULL) { if (!LoadTGA(&TGAData,filename)) //Load the texture file into memory { LogStr = new char[2000]; sprintf(LogStr,"Failed to load Texture (%s, %s). Reason: Failed to load RGB file."); return false; //failed. Return false. } if (TGAData.BitsPerPixel == 32) { type = GL_RGBA; //TGA is a 32 bit file (i.e. it contains the alpha information) RGBAData = TGAData.Data; //The TGA Data can be used to create the texture RGBADataLength = TGAData.Height*TGAData.Height*TGAData.BitsPerPixel/8; } Width = TGAData.Width; Height = TGAData.Height; } else type = EIGHT_BIT_FORMAT; if (type != GL_RGBA) //ignore Alphamap if TGA has 32 bpp { if (AlphaMap != NULL) //Alphamap specified {//AlphaMap requested: if (!LoadTGA(&AlphaData,AlphaMap)) //Load alpha map from file into memory { LogStr = new char[2000]; sprintf(LogStr,"Failed to load Texture (%s, %s). Reason: Failed to load alpha file."); return false; //failed. Return false. } //Check if the TGA has 24 bpp: (if it even exists) if ((type == GL_RGB) && (TGAData.BitsPerPixel != 24)) { LogStr = new char[2000]; sprintf(LogStr,"Failed to load Texture (%s, %s). Reason: RGB file not in 8 Bit format!"); return false; } //Check if the Alpha Map has 8 bpp (grayscale): if (AlphaData.BitsPerPixel != 8) { LogStr = new char[2000]; sprintf(LogStr,"Failed to load Texture (%s, %s). Reason: Alpha file not in 8 bit format."); return false; } //Check if the size of AlphaData and TGAData is equal: (if the TGA exists) if ((type == GL_RGB) && ((AlphaData.Width != TGAData.Width)||(AlphaData.Height != TGAData.Height))) { LogStr = new char[2000]; sprintf(LogStr,"Failed to load Texture (%s, %s). Reason: Alpha size does not eqal RGB size."); return false; } if (type == GL_RGB) { type = GL_RGBA; Width = TGAData.Width; Height = TGAData.Height; //Now comes the tricky part: Combine the TGAData and the alpha map. RGBADataLength = TGAData.Width*TGAData.Height*4; //4 = (24+8)/8; we need RGBA! RGBAData=(GLubyte *)malloc(RGBADataLength); //Check if malloc succeeded: if (RGBAData==NULL) { LogStr = new char[2000]; sprintf(LogStr,"Failed to load Texture (%s, %s). Reason: Out of memory."); return false; } //Loop. Copy three bytes of the TGA, then one byte of the alpha map. //We do not swap R and B here, this is done at the end. for (GLuint i = 0; i < RGBADataLength/4; i++) { RGBAData[i*4+0] = TGAData.Data[i*3+0]; RGBAData[i*4+1] = TGAData.Data[i*3+1]; RGBAData[i*4+2] = TGAData.Data[i*3+2]; RGBAData[i*4+3] = AlphaData.Data[i]; } } else //if type == EIGHT_BIT_FORMAT { RGBADataLength = AlphaData.Width*AlphaData.Height; RGBAData=(GLubyte *)malloc(RGBADataLength); for (GLuint i = 0; i < RGBADataLength; i++) { RGBAData[i] = AlphaData.Data[i]; } type = GL_ALPHA; Width = AlphaData.Width; Height = AlphaData.Height; } } else //No Alphamap specified { //Store the TGAData in the local variables. This is RGB Data! RGBAData = TGAData.Data; RGBADataLength = TGAData.Height*TGAData.Height*TGAData.BitsPerPixel/8; } } //Now swap the R and B values. Be careful. Do not forget to check if we have RGBA or RGB data! GLuint SwapC; //Counter for swapping int TempR; //To Swap we need a temporary variable. This var here will store the temp R value. int BytesPerPixel = 3; if (type == GL_RGBA) BytesPerPixel = 4; if (type == EIGHT_BIT_FORMAT) BytesPerPixel = 1; if (BytesPerPixel > 1) for (SwapC = 0; SwapC < RGBADataLength/BytesPerPixel;SwapC++) { TempR = RGBAData[SwapC*BytesPerPixel+0]; RGBAData[SwapC*BytesPerPixel+0] = RGBAData[SwapC*BytesPerPixel+2]; RGBAData[SwapC*BytesPerPixel+2] = TempR; } if (bMipMaps) { glGenTextures(1,&ID); glBindTexture( GL_TEXTURE_2D, ID); GLuint res = gluBuild2DMipmaps( GL_TEXTURE_2D, BytesPerPixel, //computed earlier, Width, Height, type, GL_UNSIGNED_BYTE, RGBAData); if (res != 0) { return false; } } else { glGenTextures(1, &ID); // Generate OpenGL texture IDs glBindTexture(GL_TEXTURE_2D, ID); // Bind Our Texture glTexImage2D(GL_TEXTURE_2D, 0, BytesPerPixel, Width,Height, 0, type, GL_UNSIGNED_BYTE, RGBAData); } //Store the filenames: if (filename == NULL) m_TexFilename = NULL; else { m_TexFilename = new char[strlen(filename)+2]; strcpy(m_TexFilename,filename); } if (AlphaMap == NULL) m_AlphaFilename = NULL; else { m_AlphaFilename = new char[strlen(AlphaMap)+2]; strcpy(m_AlphaFilename,AlphaMap); } return true; } void COGLTexture::SetActive() { glBindTexture( GL_TEXTURE_2D, ID); } unsigned int COGLTexture::GetID() { return ID; } GLuint COGLTexture::GetWidth() { return Width; } GLuint COGLTexture::GetHeight() { return Height; }