逛奔的蜗牛

我不聪明,但我会很努力

   ::  :: 新随笔 ::  ::  :: 管理 ::
用 Targa(TGA) 图像文件,因为它简单并且支持 alpha 通道,它可以使你更容易的创建酷的效果。
TGA 文件与 BMP 文件一样,图像数据都是按 BGR 存储,而 OpenGL 的图像是按 RGB 来使用的。
这里用了一个很好的方法,一次性读入所有的图像数据,然后再进行转换 R 与 B,而不是每次读一个 R,G,B,A,这种读法很省时间。fread(buffer, size, number, file);按块读取文件内容
size 为每次读取几个 byte,如按字节读取,这里使用的一样,size == 1;
number 为一共读取多少个 size 的内容,number = width * height * bytesPerPixel;(整个图像的数据内容)
这个方法只能读取无压缩的 TGA 文件
TGA 开始为 12 字节的内容为描述文件的一般信息,接下来的 6 字节为最重要的信息,文件宽,高,每个像素的位数, 从第 18 个字节开始,就是图像的数据内容。
更重要的一点,这个程序进行了各种出错处理。
 
#ifndef _TGALOAD_H_
#define _TGALOAD_H_
#include <stdio.h>
 
typedef struct {
       GLubyte* data;
        GLuint width;
        GLuint height;
        GLuint rgbType;
} TextureImage;
 
GLboolean loadTGA(char* fileName, TextureImage* textureImage) {
        GLubyte TGAheader[12]= { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 无压缩的TGA文件头
        GLubyte TGAcompare[12]; // 保存读入的文件头信息
        GLubyte header[6]; // 保存最有用的图像信息,宽,高,位深
        GLuint bytesPerPixel; // 记录每个颜色所占用的字节数
        GLuint imageSize; // 记录文件大小
        GLuint temp; 
// 临时变量
 
        FILE *file = fopen(fileName, "rb"); // 打开一个TGA文件
        if (file==NULL || // 文件存在么?
                      fread(TGAcompare, 1, sizeof(TGAcompare), file)!= sizeof(TGAcompare) ||
                      // 是否包含12个字节的文件头?
                      memcmp(TGAheader, TGAcompare, sizeof(TGAheader))!= 0 ||
                      // 是否是我们需要的格式?
                      fread(header, 1, sizeof(header), file)!= sizeof(header)) {
                      // 如果是读取下面六个图像信息
                if (file == NULL) // 文件不存在返回错误
                        return false;
                else {
                        fclose(file); // 关闭文件返回错误
                        return false;
                }
        }
 
        textureImage->width = header[1] * 256 + header[0]; // 记录文件宽度
        textureImage->height = header[3] * 256 + header[2]; 
// 记录文件高度
        if (textureImage->width <= 0 || // 宽度是否小于0
                      textureImage->height <= 0 || // 高度是否小于0
                      (header[4] != 24 && header[4] != 32)) { // TGA文件是24/32位?
                fclose(file); // 如果失败关闭文件,返回错误
                return false;
        }
        bytesPerPixel = header[4] >> 3; // 记录每个象素所占的字节数
        textureImage->rgbType = bytesPerPixel; // 记录每个象素所占的字节数
 
        imageSize = textureImage->width *textureImage->height * bytesPerPixel;
        // 计算TGA文件加载所需要的内存大小
        textureImage->data = (GLubyte*)malloc(imageSize); // 分配内存去保存TGA数据
        if (textureImage->data == NULL || // 系统是否分配了足够的内存?
                      fread(textureImage->data, 1, imageSize, file)!= imageSize) {
                      // 是否成功读入内存?
                if (textureImage->data != NULL) { // 是否有数据被加载
                        free(textureImage->data); // 如果是,则释放载入的数据
                }
                fclose(file); // 关闭文件
                return false; // 返回错误
        }
 
        for (GLuint i=0; i<GLuint(imageSize); i+=bytesPerPixel) {
                // 循环所有的像素
                // 交换R和B的值
                temp = textureImage->data[i];
                textureImage->data[i] = textureImage->data[i + 2];
                textureImage->data[i + 2] = temp;
        }
 
        fclose(file); // 关闭文件
        
return true;
}
 
#endif
 
posted on 2010-12-17 17:32 逛奔的蜗牛 阅读(570) 评论(0)  编辑 收藏 引用 所属分类: OpenGL

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理