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 | 它的值为16,24 或 32 等等。决定了该图像是 TGA 16,TGA24,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,则该域不存在,否则越过该域直接读取图像颜色表规格中描述了每项的字节数,为 2,3,4 之一。 | ||
图像数据 | 可变 | 可变 | RGB颜色数据,存放顺序为:BBB GGG RRR (AAA) |
代码如下:
- //========================================================
- /**
- * @file TGALoader.h
- *
- * 项目描述: TGA文件载入类
- * 文件描述: 纹理映射
- * 适用平台: Windows98/2000/NT/XP
- *
- *
- */
- //========================================================
- #ifndef __TGALOADER_H__
- #define __TGALOADER_H__
- #include "stdafx.h"
- /** TGA文件载入类 */
- class CTGALoader
- {
- public:
- CTGALoader(); /**< 构造函数 */
- ~CTGALoader();
- bool LoadTGA(const char *file); /**< 载入TGA文件 */
- void FreeImage(); /**< 释放内存 */
- bool Load(const char* fileName); /**< 载入TGA文件为纹理 */
- unsigned int ID; /**< 生成纹理的ID号 */
- int imageWidth; /**< 图像宽度 */
- int imageHeight; /**< 图像高度 */
- unsigned char *image; /**< 指向图像数据的指针 */
- unsigned int type; /**< 图象类型GL_RGB 或GL_RGBA */
- };
- #endif
- //========================================================
- /**
- * @file TGALoader.cpp
- *
- * 项目描述: 纹理映射
- * 文件描述: TGA文件载入
- * 适用平台: Windows98/2000/NT/XP
- *
- *
- */
- //========================================================
- #include "TGALoader.h"
- /** 构造函数 */
- CTGALoader::CTGALoader()
- {
- /** 设置为默认值 */
- image = 0;
- type = 0;
- ID = -1;
- imageWidth = 0;
- imageHeight = 0;
- }
- /** 析构函数 */
- CTGALoader::~CTGALoader()
- {
- FreeImage(); /**< 释放内存 */
- }
- /** 载入TGA文件 */
- bool CTGALoader::LoadTGA(const char* file)
- {
- FILE *pfile;
- unsigned char tempColor; /**< 用于交换颜色分量 */
- unsigned char bitCount; /**< 每象素的bit位数 */
- int colorMode; /**< 颜色模式 */
- long tgaSize; /**< TGA文件大小 */
- unsigned char unCompressHeader[12] = {0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /**< 未压缩TGA文件头 */
- unsigned char tgaHeader[12]; /**< 文件头 */
- unsigned char header[6]; /**< 文件头前6个字节 */
- /** 检查文件名是否为空 */
- if(!file)
- return false;
- /** 打开文件 */
- pfile = fopen(file, "rb");
- if(!pfile)
- return false;
- /** 读取文件头前12个字节 */
- fread(tgaHeader, 1, sizeof(tgaHeader), pfile);
- /** 比较文件是否为未压缩文件 */
- if(memcmp(unCompressHeader, tgaHeader, sizeof(unCompressHeader)) != 0)
- {
- MessageBox(NULL,"文件类型错误!","错误",MB_OK);
- fclose(pfile);
- return false;
- }
- /** 读取6个字节(从上面读取的12个字节后再取6个字节) */
- fread(header, 1, sizeof(header), pfile);
- /** 计算图像的宽度和高度 */
- imageWidth = header[1] * 256 + header[0];
- imageHeight = header[3] * 256 + header[2];
- /** 获取每象素的bit位数 */
- bitCount = header[4];
- /** 计算颜色模式和图像大小 */
- colorMode = bitCount / 8;
- tgaSize = imageWidth * imageHeight * colorMode;
- /** 分配内存 */
- image = new unsigned char[sizeof(unsigned char) * tgaSize];
- /** 读取数据 */
- fread(image, sizeof(unsigned char), tgaSize, pfile);
- /** 将BGA格式转化为RGA格式 */
- for(long index = 0; index < tgaSize; index += colorMode)
- {
- tempColor = image[index];
- image[index] = image[index + 2];
- image[index + 2] = tempColor;
- }
- /** 关闭文件 */
- fclose(pfile);
- /** 设置图象类型 */
- if(colorMode == 3)
- type = GL_RGB;
- else
- type = GL_RGBA;
- return true;
- }
- /** 载入TGA文件并创建纹理 */
- bool CTGALoader::Load(const char* fileName)
- {
- if(!LoadTGA(fileName))
- {
- MessageBox(NULL,"载入TGA文件失败!","错误",MB_OK);
- exit(0);
- }
- /** 生成纹理对象名称 */
- glGenTextures(1, &ID);
- /** 创建纹理对象 */
- glBindTexture(GL_TEXTURE_2D, ID);
- /** 控制滤波 */
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
- /** 创建纹理 */
- gluBuild2DMipmaps(GL_TEXTURE_2D, type, imageWidth,
- imageHeight, type, GL_UNSIGNED_BYTE,
- image);
- return true;
- }
- void CTGALoader::FreeImage()
- {
- /** 释放内存 */
- if(image)
- {
- delete[] image;
- image = 0;
- }
- }