Tga常见的格式有非压缩RGB和压缩RGB两种格式,文件的第三个Byte位作为标记:2为非压缩RGB格式,10为压缩RGB格式。这里的类只实现读取非压缩格式的tga文件。

先给出tga文件的文件格式:

名称

偏移

长度

说明

图像信息字段长度

0

1

本字段是 1 字节无符号整型,指出图像信息字段(见本子表的后面)长度,其取值范围是 0 255 ,当它为 0 时表示没有图像的信息字段。

颜色表类型

1

1

0 表示没有颜色表,1 表示颜色表存在。由于本格式是无颜色表的,因此此项通常被忽略。

图像类型码

2

1

该字段总为 2 ,这也是此类型为格式 2 的原因。

颜色表规格字段

颜色表首址

3

2

颜色表首的入口索引,整型(低位-高位)

如果颜色表字段为0,则忽略该字段

颜色表的长度

5

2

颜色表的表项总数,整型(低位高位)

颜色表项位数

7

1

位数(bit),16 代表 16 TGA 24 代表 24 TGA 32 代表 32 TGA

图像规格字段

图像 X 坐标起始位置

8

2

图像左下角 X坐标的整型(低位高位)值

图像 Y 坐标起始位置

10

2

图像左下角 Y坐标的整型(低位高位)值

图像宽度

12

2

以像素为单位,图像宽度的整型(低位高位)

图像高度

14

2

以像素为单位,图像宽度的整型(低位高位)

图像每像素存储占用位数

16

2

它的值为1624 32 等等。决定了该图像是 TGA 16TGA24,TGA 32 等等。

图像描述符字节

17

1

bits 3-0 – 每像素对应的属性位的位数;

对于TGA 16,该值为 0 1,对于 TGA                     24,该值为 0,对于 TGA 32,该值为 8

 

bit 4    – 保留,必须为 0

 

bit 5    – 屏幕起始位置标志

0 = 原点在左下角

1 = 原点在左上角

对于 truevision 图像必须为 0

 

bits 7-6 – 交叉数据存储标志

00 = 无交叉

01 = 两路奇/偶交叉

10 = 四路交叉

11 = 保留

图像信息字段

18

可变

包含一个自由格式的,长度是图像由“图像信息字段”指定。它常常被忽略(即偏移 0 处值为 0 ),注意其最大可以含有 255 个字符。如果需要存储更多信息,可以放在图像数据之后。

颜色表数据

可变

可变

如果颜色表类型为 0,则该域不存在,否则越过该域直接读取图像颜色表规格中描述了每项的字节数,为 234 之一。

图像数据

可变

可变

RGB颜色数据,存放顺序为:BBB GGG RRR (AAA)

 

代码如下:

  1. //========================================================
  2. /**
  3. *  @file      TGALoader.h
  4. *
  5. *  项目描述: TGA文件载入类
  6. *  文件描述:  纹理映射  
  7. *  适用平台: Windows98/2000/NT/XP
  8. *  
  9. *
  10. */     
  11. //========================================================
  12. #ifndef __TGALOADER_H__
  13. #define __TGALOADER_H__
  14. #include “stdafx.h”
  15. /** TGA文件载入类 */
  16. class CTGALoader
  17. {
  18.    public:
  19.       
  20.       CTGALoader();                             /**< 构造函数 */
  21.       ~CTGALoader();
  22.       bool LoadTGA(const char *file);          /**< 载入TGA文件 */
  23.       void FreeImage();                        /**< 释放内存 */ 
  24.       bool Load(const char* fileName); /**< 载入TGA文件为纹理 */
  25.       unsigned int ID;                        /**< 生成纹理的ID号 */
  26.       int imageWidth;                         /**< 图像宽度 */
  27.       int imageHeight;                        /**< 图像高度 */
  28.       unsigned char *image;                   /**< 指向图像数据的指针 */
  29.       unsigned int type;                      /**< 图象类型GL_RGB 或GL_RGBA */
  30. };
  31. #endif
  1. //========================================================
  2. /**
  3. *  @file      TGALoader.cpp
  4. *
  5. *  项目描述: 纹理映射
  6. *  文件描述:  TGA文件载入  
  7. *  适用平台: Windows98/2000/NT/XP
  8. *  
  9. *
  10. */     
  11. //========================================================
  12. #include “TGALoader.h”
  13. /** 构造函数 */
  14. CTGALoader::CTGALoader()
  15. {
  16.   /** 设置为默认值 */
  17.   image = 0;
  18.   type = 0;
  19.   ID = -1;
  20.   imageWidth = 0;
  21.   imageHeight = 0;
  22. }
  23. /** 析构函数 */
  24. CTGALoader::~CTGALoader()
  25. {
  26.    FreeImage();           /**< 释放内存 */
  27. }
  28. /** 载入TGA文件 */
  29. bool CTGALoader::LoadTGA(const char* file)
  30. {
  31.    FILE *pfile;
  32.    unsigned char tempColor;              /**< 用于交换颜色分量 */
  33.    unsigned char bitCount;               /**< 每象素的bit位数 */
  34.    int colorMode;                        /**< 颜色模式 */
  35.    long tgaSize;                         /**< TGA文件大小 */
  36.    unsigned char unCompressHeader[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /**< 未压缩TGA文件头 */
  37.    unsigned char tgaHeader[12];          /**< 文件头 */
  38.    unsigned char header[6];              /**< 文件头前6个字节 */
  39.    /** 检查文件名是否为空 */
  40.    if(!file) 
  41.        return false;
  42.    
  43.    /** 打开文件 */
  44.    pfile = fopen(file, “rb”);
  45.    if(!pfile) 
  46.        return false;
  47.    /** 读取文件头前12个字节 */
  48.    fread(tgaHeader, 1, sizeof(tgaHeader), pfile);
  49.    /** 比较文件是否为未压缩文件 */
  50.    if(memcmp(unCompressHeader, tgaHeader, sizeof(unCompressHeader)) != 0)
  51.        {
  52.            MessageBox(NULL,”文件类型错误!”,”错误”,MB_OK);
  53.            fclose(pfile);
  54.            return false;
  55.        }
  56.    /** 读取6个字节(从上面读取的12个字节后再取6个字节) */
  57.    fread(header, 1, sizeof(header), pfile);
  58.    /** 计算图像的宽度和高度 */
  59.    imageWidth = header[1] * 256 + header[0];    
  60.    imageHeight = header[3] * 256 + header[2];   
  61.    /** 获取每象素的bit位数 */
  62.    bitCount = header[4];
  63.    /** 计算颜色模式和图像大小 */
  64.    colorMode = bitCount / 8;
  65.    tgaSize = imageWidth * imageHeight * colorMode;
  66.    /** 分配内存 */
  67.    image = new unsigned char[sizeof(unsigned char) * tgaSize];
  68.    /** 读取数据 */
  69.    fread(image, sizeof(unsigned char), tgaSize, pfile);
  70.    /** 将BGA格式转化为RGA格式 */
  71.    for(long index = 0; index < tgaSize; index += colorMode)
  72.        {
  73.            tempColor = image[index];
  74.            image[index] = image[index + 2];
  75.            image[index + 2] = tempColor;
  76.        }
  77.    /** 关闭文件 */
  78.    fclose(pfile);
  79.    /** 设置图象类型 */
  80.    if(colorMode == 3) 
  81.        type = GL_RGB;
  82.    else 
  83.        type = GL_RGBA;
  84.    return true;
  85. }
  86. /** 载入TGA文件并创建纹理 */
  87. bool CTGALoader::Load(const char* fileName)
  88. {
  89.     if(!LoadTGA(fileName))
  90.     {
  91.         MessageBox(NULL,”载入TGA文件失败!”,”错误”,MB_OK);
  92.         exit(0);
  93.     }
  94.     /** 生成纹理对象名称 */
  95.     glGenTextures(1, &ID);
  96.    
  97.     /** 创建纹理对象 */
  98.     glBindTexture(GL_TEXTURE_2D, ID);
  99.     
  100.     /** 控制滤波 */
  101.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  102.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  103.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  104.     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  105.    
  106.     /** 创建纹理 */
  107.     gluBuild2DMipmaps(GL_TEXTURE_2D, type, imageWidth,
  108.                       imageHeight, type, GL_UNSIGNED_BYTE,
  109.                       image);
  110.    return true;
  111. }
  112. void CTGALoader::FreeImage()
  113. {
  114.    /** 释放内存 */
  115.    if(image)
  116.       {
  117.          delete[] image;
  118.          image = 0;
  119.       }
  120. }