opengl中TGA图像加载技术

2023-05-11

TGA格式图像是游戏中十分常见的一种图像格式,所以有必要了解其内部格式以及编程实现。

TGA图像一般有非压缩和压缩两种格式,下面分别进行介绍。

一、非压缩TGA图像

注:前面的标记绿色的部分(共12字节)表示对于所有的非压缩TGA格式图像值都是相同的!所以通常用来在读取数据时鉴别是否为TGA图像。

下面的程序实现了绘制一个立方体,并进行纹理贴图。

需要注意的是:TGA图像中数据存放的顺序是BGR(A),而在OpenGL中顺序是RGB(A),所以在进行纹理生成的时候必须先进行格式的转化。

在OpenGL中只能加载24位或者32位的TGA图像生成纹理。

TGATexture.h定义了一些结构体以及函数声明:

[cpp] view plain copy print?

  1. #ifndef TGATEXTURE_H  

  2. #define TGATEXTURE_H  

  3.   

  4. #include <GL/glut.h>  

  5. #include <iostream>  

  6.   

  7. using namespace std;  

  8.   

  9. //纹理结构体定义  

  10. typedef struct  

  11. {  

  12.     GLubyte *p_w_picpathData;//图像数据  

  13.     GLuint bpp;//像素深度  

  14.     GLuint width;//图像宽度  

  15.     GLuint height;//图像高度  

  16.     GLuint texID;//对应的纹理ID  

  17. }TextureImage;  

  18.   

  19. //加载TGA图像,生成纹理  

  20. bool LoadTGA(TextureImage *texture,char *fileName);  

  21.   

  22. #endif  

TGATexture.cpp则包含加载TGA图像生成纹理的函数具体实现:

[cpp] view plain copy print?

  1. #include "TGATexture.h"  

  2.   

  3. //加载TGA图像(无压缩格式),生成纹理  

  4. bool LoadTGA(TextureImage *texture, char *filename)         // Loads A TGA File Into Memory  

  5. {      

  6.     GLubyte     TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};    // Uncompressed TGA Header  

  7.     GLubyte     TGAcompare[12];                             // Used To Compare TGA Header  

  8.     GLubyte     header[6];                                  // First 6 Useful Bytes From The Header  

  9.     GLuint      bytesPerPixel;                              // Holds Number Of Bytes Per Pixel Used In The TGA File  

  10.     GLuint      p_w_picpathSize;                                  // Used To Store The Image Size When Setting Aside Ram  

  11.     GLuint      temp;                                       // Temporary Variable  

  12.     GLuint      type=GL_RGBA;                               // Set The Default GL Mode To RBGA (32 BPP)  

  13.   

  14.     FILE *file = fopen(filename, "rb");                     // Open The TGA File  

  15.   

  16.     if( file==NULL ||                                       // Does File Even Exist?  

  17.         fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) ||  // Are There 12 Bytes To Read?  

  18.         memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0               ||  // Does The Header Match What We Want?  

  19.         fread(header,1,sizeof(header),file)!=sizeof(header))                // If So Read Next 6 Header Bytes  

  20.     {  

  21.         if (file == NULL)                                   // Did The File Even Exist? *Added Jim Strong*  

  22.             return false;                                   // Return False  

  23.         else  

  24.         {  

  25.             fclose(file);                                   // If Anything Failed, Close The File  

  26.             return false;                                   // Return False  

  27.         }  

  28.     }  

  29.   

  30.     texture->width  = header[1] * 256 + header[0];           // Determine The TGA Width  (highbyte*256+lowbyte)  

  31.     texture->height = header[3] * 256 + header[2];           // Determine The TGA Height (highbyte*256+lowbyte)  

  32.   

  33.     //OpenGL中纹理只能使用24位或者32位的TGA图像  

  34.     if( texture->width   <=0  ||                              // Is The Width Less Than Or Equal To Zero  

  35.         texture->height  <=0  ||                              // Is The Height Less Than Or Equal To Zero  

  36.         (header[4]!=24 && header[4]!=32))                   // Is The TGA 24 or 32 Bit?  

  37.     {  

  38.         fclose(file);                                       // If Anything Failed, Close The File  

  39.         return false;                                       // Return False  

  40.     }  

  41.   

  42.     texture->bpp = header[4];                            // Grab The TGA's Bits Per Pixel (24 or 32)  

  43.     bytesPerPixel   = texture->bpp/8;                        // Divide By 8 To Get The Bytes Per Pixel  

  44.     p_w_picpathSize       = texture->width*texture->height*bytesPerPixel;   // Calculate The Memory Required For The TGA Data  

  45.   

  46.     texture->p_w_picpathData=(GLubyte *)malloc(p_w_picpathSize);     // Reserve Memory To Hold The TGA Data  

  47.   

  48.     if( texture->p_w_picpathData==NULL ||                          // Does The Storage Memory Exist?  

  49.         fread(texture->p_w_picpathData, 1, p_w_picpathSize, file)!=p_w_picpathSize)    // Does The Image Size Match The Memory Reserved?  

  50.     {  

  51.         if(texture->p_w_picpathData!=NULL)                     // Was Image Data Loaded  

  52.             free(texture->p_w_picpathData);                        // If So, Release The Image Data  

  53.   

  54.         fclose(file);                                       // Close The File  

  55.         return false;                                       // Return False  

  56.     }  

  57.   

  58.     //RGB数据格式转换,便于在OpenGL中使用  

  59.     for(GLuint i=0; i<int(p_w_picpathSize); i+=bytesPerPixel)      // Loop Through The Image Data  

  60.     {                                                       // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)  

  61.         temp=texture->p_w_picpathData[i];                          // Temporarily Store The Value At Image Data 'i'  

  62.         texture->p_w_picpathData[i] = texture->p_w_picpathData[i + 2];    // Set The 1st Byte To The Value Of The 3rd Byte  

  63.         texture->p_w_picpathData[i + 2] = temp;                    // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)  

  64.     }  

  65.   

  66.     fclose (file);                                          // Close The File  

  67.   

  68.     // Build A Texture From The Data  

  69.     glGenTextures(1, &texture[0].texID);                    // Generate OpenGL texture IDs  

  70.   

  71.     glBindTexture(GL_TEXTURE_2D, texture[0].texID);         // Bind Our Texture  

  72.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);   // Linear Filtered  

  73.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);   // Linear Filtered  

  74.   

  75.     if (texture[0].bpp==24)                                 // Was The TGA 24 Bits  

  76.     {  

  77.         type=GL_RGB;                                        // If So Set The 'type' To GL_RGB  

  78.     }  

  79.   

  80.     glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].p_w_picpathData);  

  81.   

  82.     return true;                                            // Texture Building Went Ok, Return True  

  83. }  

main.cpp主程序:

[cpp] view plain copy print?

  1. #include "TGATexture.h"  

  2.   

  3. TextureImage texture[1];  

  4.   

  5. GLfloat xRot,yRot,zRot;//control cube's rotation  

  6.   

  7. int init()  

  8. {  

  9.     if(!LoadTGA(&texture[0],"GSK1.tga"))  

  10.         return GL_FALSE;  

  11.     glEnable(GL_TEXTURE_2D);  

  12.     glShadeModel(GL_SMOOTH);  

  13.     glClearColor(0.0f,0.0f,0.0f,0.5f);  

  14.     glClearDepth(1.0f);  

  15.     glEnable(GL_DEPTH_TEST);  

  16.     glDepthFunc(GL_LEQUAL);  

  17.     glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);  

  18.     return GL_TRUE;  

  19. }  

  20.   

  21. void display()  

  22. {  

  23.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  

  24.     glLoadIdentity();  

  25.     glTranslatef(0.0f,0.0f,-5.0f);  

  26.     glRotatef(xRot,1.0f,0.0f,0.0f);  

  27.     glRotatef(yRot,0.0f,1.0f,0.0f);  

  28.     glRotatef(zRot,0.0f,0.0f,1.0f);  

  29.   

  30.     glBindTexture(GL_TEXTURE_2D,texture[0].texID);  

  31.   

  32.     glBegin(GL_QUADS);   

  33.     // Front Face   

  34.     // Bottom Left Of The Texture and Quad   

  35.     glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);   

  36.     // Bottom Right Of The Texture and Quad   

  37.     glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);   

  38.     // Top Right Of The Texture and Quad   

  39.     glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);   

  40.     // Top Left Of The Texture and Quad   

  41.     glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);   

  42.     glEnd();   

  43.   

  44.     glBindTexture(GL_TEXTURE_2D,texture[0].texID);  

  45.     glBegin(GL_QUADS);   

  46.     // Back Face   

  47.     // Bottom Right Of The Texture and Quad   

  48.     glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);   

  49.     // Top Right Of The Texture and Quad   

  50.     glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);   

  51.     // Top Left Of The Texture and Quad   

  52.     glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);   

  53.     // Bottom Left Of The Texture and Quad   

  54.     glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);   

  55.     glEnd();   

  56.   

  57.     glBindTexture(GL_TEXTURE_2D,texture[0].texID);  

  58.     glBegin(GL_QUADS);   

  59.     // Top Face   

  60.     // Top Left Of The Texture and Quad   

  61.     glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);   

  62.     // Bottom Left Of The Texture and Quad   

  63.     glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);   

  64.     // Bottom Right Of The Texture and Quad   

  65.     glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);   

  66.     // Top Right Of The Texture and Quad   

  67.     glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);   

  68.     glEnd();   

  69.   

  70.     glBindTexture(GL_TEXTURE_2D,texture[0].texID);  

  71.     glBegin(GL_QUADS);   

  72.     // Bottom Face   

  73.     // Top Right Of The Texture and Quad   

  74.     glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);   

  75.     // Top Left Of The Texture and Quad   

  76.     glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);   

  77.     // Bottom Left Of The Texture and Quad   

  78.     glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);   

  79.     // Bottom Right Of The Texture and Quad   

  80.     glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);   

  81.     glEnd();   

  82.   

  83.     glBindTexture(GL_TEXTURE_2D,texture[0].texID);  

  84.     glBegin(GL_QUADS);   

  85.     // Right face   

  86.     // Bottom Right Of The Texture and Quad   

  87.     glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);   

  88.     // Top Right Of The Texture and Quad   

  89.     glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);   

  90.     // Top Left Of The Texture and Quad   

  91.     glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);   

  92.     // Bottom Left Of The Texture and Quad   

  93.     glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);   

  94.     glEnd();   

  95.   

  96.     glBindTexture(GL_TEXTURE_2D,texture[0].texID);  

  97.     glBegin(GL_QUADS);   

  98.     // Left Face   

  99.     // Bottom Left Of The Texture and Quad   

  100.     glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);   

  101.     // Bottom Right Of The Texture and Quad   

  102.     glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);   

  103.     // Top Right Of The Texture and Quad   

  104.     glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);   

  105.     // Top Left Of The Texture and Quad   

  106.     glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);   

  107.     glEnd();   

  108.   

  109.     glutSwapBuffers();  

  110. }  

  111.   

  112. void reshape(int w,int h)  

  113. {  

  114.     if (0 == h)  

  115.         h = 1;  

  116.       

  117.     glViewport(0,0,(GLsizei)w,(GLsizei)h);  

  118.     glMatrixMode(GL_PROJECTION);  

  119.     glLoadIdentity();  

  120.     gluPerspective(60.0f,(GLfloat)w / (GLfloat)h,1,100);  

  121.     glMatrixMode(GL_MODELVIEW);  

  122.     glLoadIdentity();  

  123. }  

  124.   

  125. void keyboard(unsigned char key,int x,int y)  

  126. {  

  127.     switch(key){  

  128.         case 'x':  

  129.             xRot += 1.0f;  

  130.             glutPostRedisplay();  

  131.             break;  

  132.         case 'y':  

  133.             yRot += 1.0f;  

  134.             glutPostRedisplay();  

  135.             break;  

  136.         case 'z':  

  137.             zRot += 1.0f;  

  138.             glutPostRedisplay();  

  139.             break;  

  140.         default:  

  141.             break;  

  142.     }  

  143. }  

  144.   

  145. int main(int argc,char** argv)  

  146. {  

  147.     glutInit(&argc,argv);  

  148.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  

  149.     glutInitWindowSize(400,400);  

  150.     glutInitWindowPosition(100,100);  

  151.     glutCreateWindow("Texture Map");  

  152.     init();  

  153.     glutDisplayFunc(display);  

  154.     glutReshapeFunc(reshape);  

  155.     glutKeyboardFunc(keyboard);  

  156.     glutMainLoop();  

  157.     return 0;  

  158. }  


《opengl中TGA图像加载技术.doc》

下载本文的Word格式文档,以方便收藏与打印。