opengl中TGA图像加载技术-创新互联

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

创新互联公司长期为千余家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为仓山企业提供专业的做网站、成都网站制作仓山网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制开发。

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

一、非压缩TGA图像

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


























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

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

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

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

[cpp] view plain?

  1. #ifndef TGATEXTURE_H

  2. #define TGATEXTURE_H

  3. #include 

  4. #include 

  5. using namespace std;

  6. //纹理结构体定义

  7. typedef struct

  8. {

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

  10.     GLuint bpp;//像素深度

  11.     GLuint width;//图像宽度

  12.     GLuint height;//图像高度

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

  14. }TextureImage;

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

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

  17. #endif

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

[cpp] view plain?

  1. #include "TGATexture.h"

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

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

  4. {

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

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

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

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

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

  10.     GLuint      temp;                                       // Temporary Variable

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

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

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

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

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

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

  17.     {

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

  19.             return false;                                   // Return False

  20.         else

  21.         {

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

  23.             return false;                                   // Return False

  24.         }

  25.     }

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

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

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

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

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

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

  32.     {

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

  34.         return false;                                       // Return False

  35.     }

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

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

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

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

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

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

  42.     {

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

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

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

  46.         return false;                                       // Return False

  47.     }

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

  49.     for(GLuint i=0; i

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

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

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

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

  54.     }

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

  56.     // Build A Texture From The Data

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

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

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

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

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

  62.     {

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

  64.     }

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

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

  67. }

main.cpp主程序:

[cpp] view plain?

  1. #include "TGATexture.h"

  2. TextureImage texture[1];

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

  4. int init()

  5. {

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

  7.         return GL_FALSE;

  8.     glEnable(GL_TEXTURE_2D);

  9.     glShadeModel(GL_SMOOTH);

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

  11.     glClearDepth(1.0f);

  12.     glEnable(GL_DEPTH_TEST);

  13.     glDepthFunc(GL_LEQUAL);

  14.     glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);

  15.     return GL_TRUE;

  16. }

  17. void display()

  18. {

  19.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  20.     glLoadIdentity();

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

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

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

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

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

  26.     glBegin(GL_QUADS);

  27.     // Front Face

  28.     // Bottom Left Of The Texture and Quad

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

  30.     // Bottom Right Of The Texture and Quad

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

  32.     // Top Right Of The Texture and Quad

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

  34.     // Top Left Of The Texture and Quad

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

  36.     glEnd();

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

  38.     glBegin(GL_QUADS);

  39.     // Back Face

  40.     // Bottom Right Of The Texture and Quad

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

  42.     // Top Right Of The Texture and Quad

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

  44.     // Top Left Of The Texture and Quad

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

  46.     // Bottom Left Of The Texture and Quad

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

  48.     glEnd();

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

  50.     glBegin(GL_QUADS);

  51.     // Top Face

  52.     // Top Left Of The Texture and Quad

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

  54.     // Bottom Left Of The Texture and Quad

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

  56.     // Bottom Right Of The Texture and Quad

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

  58.     // Top Right Of The Texture and Quad

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

  60.     glEnd();

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

  62.     glBegin(GL_QUADS);

  63.     // Bottom Face

  64.     // Top Right Of The Texture and Quad

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

  66.     // Top Left Of The Texture and Quad

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

  68.     // Bottom Left Of The Texture and Quad

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

  70.     // Bottom Right Of The Texture and Quad

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

  72.     glEnd();

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

  74.     glBegin(GL_QUADS);

  75.     // Right face

  76.     // Bottom Right Of The Texture and Quad

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

  78.     // Top Right Of The Texture and Quad

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

  80.     // Top Left Of The Texture and Quad

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

  82.     // Bottom Left Of The Texture and Quad

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

  84.     glEnd();

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

  86.     glBegin(GL_QUADS);

  87.     // Left Face

  88.     // Bottom Left Of The Texture and Quad

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

  90.     // Bottom Right Of The Texture and Quad

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

  92.     // Top Right Of The Texture and Quad

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

  94.     // Top Left Of The Texture and Quad

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

  96.     glEnd();

  97.     glutSwapBuffers();

  98. }

  99. void reshape(int w,int h)

  100. {

  101.     if (0 == h)

  102.         h = 1;

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

  104.     glMatrixMode(GL_PROJECTION);

  105.     glLoadIdentity();

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

  107.     glMatrixMode(GL_MODELVIEW);

  108.     glLoadIdentity();

  109. }

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

  111. {

  112.     switch(key){

  113.         case 'x':

  114.             xRot += 1.0f;

  115.             glutPostRedisplay();

  116.             break;

  117.         case 'y':

  118.             yRot += 1.0f;

  119.             glutPostRedisplay();

  120.             break;

  121.         case 'z':

  122.             zRot += 1.0f;

  123.             glutPostRedisplay();

  124.             break;

  125.         default:

  126.             break;

  127.     }

  128. }

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

  130. {

  131.     glutInit(&argc,argv);

  132.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

  133.     glutInitWindowSize(400,400);

  134.     glutInitWindowPosition(100,100);

  135.     glutCreateWindow("Texture Map");

  136.     init();

  137.     glutDisplayFunc(display);

  138.     glutReshapeFunc(reshape);

  139.     glutKeyboardFunc(keyboard);

  140.     glutMainLoop();

  141.     return 0;

  142. }

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


本文题目:opengl中TGA图像加载技术-创新互联
URL地址:http://myzitong.com/article/dcdsji.html