typedef struct TGAImage { GLubyte *imageData; // 图像数据 GLuint bpp; // 像素颜色深度 GLuint width; // 图像宽度 GLuint height; // 图像高度 GLuint texID; // 纹理ID } TGAImage; bool LoadTGA(TGAImage *texture, char *filename) { GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header 不压缩的TGA头 GLubyte TGAcompare[12]; // Used To Compare TGA Header 压缩的 GLubyte header[6]; // First 6 Useful Bytes From The Header TGA头的前6个有用的字节 GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File TGA文件每个像素使用的字节 GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram GLuint temp; // Temporary Variable 临时变量 GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP) 默认的GL模式 FILE *file = fopen(filename, "rb"); // Open The TGA File printf("TGA_file=%d/n",file); if( file==NULL || // Does File Even Exist? fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read? 是否读到12字节数据 memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want? 是否是压缩的,压缩的就读取失败,关闭file fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes 再读6个字节 { if (file == NULL) // Did The File Even Exist? *Added Jim Strong* return false; // Return False else // Otherwise { fclose(file); // If Anything Failed, Close The File return false; // Return False } } //12到17字节前四字节是图像宽高,第五字节是图像位深度 texture->width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte)//低字节,高字节 texture->height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte) if( texture->width <=0 || // Is The Width Less Than Or Equal To Zero texture->height <=0 || // Is The Height Less Than Or Equal To Zero (header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit? { fclose(file); // If Anything Failed, Close The File return false; // Return False } texture->bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32) bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel 每个像素使用的字节数 imageSize = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data 申请内存 if( texture->imageData==NULL || // Does The Storage Memory Exist? fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved? 图像数据保存到纹理结构数据缓存imageData中 {//失败情况下释放资源 if(texture->imageData!=NULL) // Was Image Data Loaded free(texture->imageData); // If So, Release The Image Data fclose(file); // Close The File return false; // Return False } for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel) // Loop Through The Image Data { // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i' texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) } fclose (file); // Close The File glGenTextures(1, &texture->texID); // Generate生产,产生 OpenGL texture IDs printf("纹理ID=%d/n",texture->texID ); glBindTexture(GL_TEXTURE_2D, texture->texID); // Bind 绑定Our Texture glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); if (texture[0].bpp==24) // Was The TGA 24 Bits { type=GL_RGB; // If So Set The 'type' To GL_RGB } //创建纹理 glTexImage2D(GL_TEXTURE_2D, 0, type, texture->width, texture->height, 0, type, GL_UNSIGNED_BYTE, texture->imageData); return true; } bool LoadBMP(TGAImage *texture, char *filename) { BITMAPFILEHEADER bmpFileHeader; //bmp文件头 BITMAPINFOHEADER bmpInfoHeader; //bmp格式头 GLuint imageSize; //纹理数据大小 GLuint temp; // 临时变量 GLuint type=GL_RGB; FILE *file = fopen(filename, "rb"); printf("BMP_file=%d/n",file); if( file==NULL) // Does File Even Exist? return false; fread(&bmpFileHeader,1,sizeof(BITMAPFILEHEADER),file); //读取文件头 if(bmpFileHeader.bfType!=0x4d42) //判断是否是BM return false; else printf("是bmp图像/n"); fread(&bmpInfoHeader,1,sizeof(BITMAPINFOHEADER),file); // 读取信息头 texture->width = bmpInfoHeader.biWidth; //图片宽度 texture->height = bmpInfoHeader.biHeight; //图片高度 texture->bpp = bmpInfoHeader.biBitCount; //位深度 imageSize = bmpInfoHeader.biSizeImage ; //图像数据的大小,用作申请纹理缓存 if( texture->width <=0 || texture->height <=0 || texture->bpp!=24) // bmp不是24位图 { fclose(file); return false; } //BITMAPFILEHEADER.bfOffBits从文件头开始到颜色数据的偏移量 fseek(file,bmpFileHeader.bfOffBits,SEEK_SET); //移动指针到图像数据 texture->imageData=(GLubyte *)malloc(imageSize); if( texture->imageData==NULL || // Does The Storage Memory Exist? fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved? 图像数据保存到纹理结构数据缓存imageData中 { //失败情况下释放资源 if(texture->imageData!=NULL) // Was Image Data Loaded free(texture->imageData); // If So, Release The Image Data fclose(file); // Close The File return false; // Return False } for(GLuint i=0; i<int(imageSize); i+=texture->bpp/8) // Loop Through The Image Data { // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue) temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i' texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value) } fclose (file); // Close The File glGenTextures(1, &texture->texID); // Generate生产,产生 OpenGL texture IDs printf("纹理ID=%d/n",texture->texID ); glBindTexture(GL_TEXTURE_2D, texture->texID); // Bind 绑定Our Texture glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //创建纹理 glTexImage2D(GL_TEXTURE_2D, 0, type, texture->width, texture->height, 0, type, GL_UNSIGNED_BYTE, texture->imageData); return true; } 使用: /*LoadTGA(&MainImage,"//NAND//skyworth//tga//main.tga/0"); LoadTGA(&MovieImage,"//NAND//skyworth//tga//movie.tga");*/ LoadBMP(&MainImage,"//USER//tv.bmp/0"); LoadBMP(&MovieImage,"//USER//music.bmp/0");