这是之前做本科毕设时碰到的问题,拖到现在才有时间整理,没想到一转眼已经在研究生实验室了,时间飞逝啊~
言归正传,当时我需要在OpenGL中重绘FBX格式的三维模型,由于不同美工人员给人物模型贴的图可能是不同格式的,因此需要解析不同格式的贴图,然后将该贴图的长、宽以及像素信息传给OpenGL函数以供处理。
三维模型常用的贴图格式有png、dds、tga、jpg、bmp等,这些图像格式所使用的协议都是不同的,对这些格式分别进行解析几乎难以实现。例如,dds作为一种纹理压缩非常高的图像格式,能够降低50%甚至更多的纹理内存消耗,因此广泛应用于游戏模型中,但是其压缩格式包含DXT1、DXT3以及DXT5三种,在解析时需要对其分别处理,导致纹理信息难以提取;bmp格式被称为位图(BitMap),其底层分为文件头、信息头、调色板、图像数据等模块,提取数据时需要对指针加上特定偏移量才能获取到像素信息。
为解决该问题,我向当时的导师询问能获取所有格式信息的图像处理库,导师丢给了我一个ImageMagick库。我在花了很大精力读完几乎与提取像素信息毫无关系的官方文档并配好环境后,竟然发现这个库根本提取不到OpenGL需要的图像信息。。。
于是我又自行找了一些可能有用的库,这其中包括 stbi_image 库。总之,我在经过多番尝试后发现这个也不能用,有其他需求的同学可以到上述链接下载。此后我试图一一解析这些图像,其中成功的是对tga图像的解析,这用到了tgaParser库。
最终,我在网上多番查找并测试后,终于找到了一个名为FreeImage的库,这个库成功解析出了所有常见图像格式。
使用该图像处理库的步骤如下:
解压压缩包,并在VS 的属性中配置包含目录、库目录并添加lib文件:
添加包含目录
添加库目录
添加FreeImage.lib文件
在文件中加入FreeImage.h 头文件,其解析图像的核心代码如下所示:
#include "FreeImage.h"
//.....
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(filePath, 0); //Get file type
if (fifmt == FIF_UNKNOWN)
{
fifmt = FreeImage_GetFIFFromFilename(pFilePath.Buffer());
if (fifmt == FIF_UNKNOWN)
return false;
}
FIBITMAP *dib = FreeImage_Load(fifmt, pFilePath.Buffer(), 0);
dib = FreeImage_ConvertTo24Bits(dib); //convert to 24 bits
int width = FreeImage_GetWidth(dib); //get the width of texture
int height = FreeImage_GetHeight(dib); //height
BYTE *pixels = (BYTE*)FreeImage_GetBits(dib); //pixels
if (!pixels)
return false;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0
, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels); //transfer into OpenGL
FreeImage_Unload(dib); //release the memory