Chester的小院

无印良品

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

  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;

}

posted on 2011-04-13 00:32  chester_lp  阅读(635)  评论(0)    收藏  举报