TGA文件用作纹理较BMP文件的优势在于:TGA文件的载入不需要使用aux库,并且TGA纹理可以拥有ALPHA通道。而载入TGA文件作为纹理必须要了解的是TGA文件的文件结构。TGA文件的文件结构如下面的表所示
|
偏移 |
长度 |
描述 |
32位常用图像文件各个字节的值 |
|
0 |
1 |
指出图像信息字段的长度,其取值范围是 0 到 255 ,当它为 0 时表示没有图像的信息字段。 |
0 |
|
1 |
1 |
是否使用颜色表,0 表示没有颜色表,1 表示颜色表存在 |
0 |
|
2 |
1 |
该字段总为 2。图像类型码,tga一共有6种格式,2表示无颜色表 rgb 图像 |
2 |
|
3 |
5 |
颜色表规格,总为0。 |
0 |
|
4 |
0 |
||
|
5 |
0 |
||
|
6 |
0 |
||
|
7 |
0 |
||
|
8 10 图像规格说明 开始 |
|||
|
8 |
2 |
图像 x 坐标起始位置,一般为0 |
0 |
|
9 |
|||
|
10 |
2 |
图像 y 坐标起始位置,一般为0 |
0 |
|
11 |
|||
|
12 |
2 |
图像宽度,以像素为单位 |
256 |
|
13 |
|||
|
14 |
2 |
图像高度,以像素为单位 |
256 |
|
15 |
|||
|
16 |
1 |
图像每像素存储占用位(bit)数 |
32 |
|
17 |
1 |
图像描述符字节 bits 3-0 - 每像素对应的属性位的位数,对于 TGA 24,该值为 0 bit 4 - 保留,必须为 0 bit 5 - 屏幕起始位置标志,0 = 原点在左下角,1 = 原点在左上角 一般这个字节设为0x00即可 |
00100000(2) |
|
18 |
可变 |
图像数据域 这里存储了(宽度)x(高度)个像素,每个像素中的 rgb 色值该色值包含整数个字节 |
... |
在读入TGA文件时最重要的是对TGA文件的文件头信息的分析。我们可以看到TGA文件的前12个字节可以作为TGA文件的特征来使用,如果读取的一个文件前12个字节为0,0,2,0...那么我们可以判断这个文件确实是一个TGA文件。而总共18个字节的后6个字节提供了TGA文件的包括宽、高、每个位所包含的位数等等的信息,在确信是TGA文件并且读取这个文件以后我们需要从这个部分提取关于这个TGA文件的这些信息,然后根据这些信息构件一个TGA文件的结构,这个结构的通用样式如下所示。
struct Texture
...{
GLuint ImageSize;
GLuint BitPerPixel;
GLuint Width;
GLuint Height;
GLubyte *Data;
};
当我们将TGA文件载入到内存以后,我们象一般的纹理一样进行处理,申明纹理句柄,绑定以后利用glTexImage2D来加载,之后在我们的渲染阶段进行绑定以后指定纹理坐标,然后进行一般步骤的渲染。
下面是一个载入TGA文件的函数。
bool LoadTexture(const char * filename)
...{
if (!filename)
return false;
FILE *file = fopen(filename,"r");
if (file)
...{
GLubyte fileheader[12];
GLubyte Compare[12] = ...{0,0,2,0};
GLubyte info[6];
if (fread(fileheader,1,12,file) != 12 || memcmp(fileheader,Compare,sizeof (Compare)))
return false;
if (fread(info,1,6,file) != 6)
return false;
Texture tex;
tex.Width = 256 * info[1] + info[0];
tex.Height = 256 * info[3] + info[2];
tex.BitPerPixel = info[4];
GLuint type;
if (tex.BitPerPixel == 24)
type = GL_RGB;
else
type = GL_RGBA;
tex.ImageSize = tex.Width * tex.Height * tex.BitPerPixel / 8;
tex.Data = new GLubyte[tex.ImageSize];
if (fread(tex.Data,1,tex.ImageSize,file) != tex.ImageSize)
...{
fclose(file);
delete[] tex.Data;
return false;
}
fclose(file);
for (int i = 0;i < (int) tex.ImageSize;i++)
...{
GLubyte temp = tex.Data[i];
tex.Data[i] = tex.Data[i + 2];
tex.Data[i + 2] = temp;
}
glGenTextures(1,&TexHandle);
glBindTexture(GL_TEXTURE_2D,TexHandle);
glTexImage2D(GL_TEXTURE_2D,0,type,tex.Width,tex.Height,0,type,GL_UNSIGNED_BYTE,tex.Data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
if (tex.Data)
free(tex.Data);
return true;
}
return false;
}

浙公网安备 33010602011771号