這是之前做大學畢設時碰到的問題,拖到現在才有時間整理,沒想到一轉眼已經在研究所學生實驗室了,時間飛逝啊~
言歸正傳,當時我需要在OpenGL中重繪FBX格式的三維模型,由于不同美勞工員給人物模型貼的圖可能是不同格式的,是以需要解析不同格式的貼圖,然後将該貼圖的長、寬以及像素資訊傳給OpenGL函數以供處理。
三維模型常用的貼圖格式有png、dds、tga、jpg、bmp等,這些圖像格式所使用的協定都是不同的,對這些格式分别進行解析幾乎難以實作。例如,dds作為一種紋理壓縮非常高的圖像格式,能夠降低50%甚至更多的紋理記憶體消耗,是以廣泛應用于遊戲模型中,但是其壓縮格式包含DXT1、DXT3以及DXT5三種,在解析時需要對其分别處理,導緻紋理資訊難以提取;bmp格式被稱為位圖(BitMap),其底層分為檔案頭、資訊頭、調色闆、圖像資料等子產品,提取資料時需要對指針加上特定偏移量才能擷取到像素資訊。
為解決該問題,我向當時的導師詢問能擷取所有格式資訊的圖像處理庫,導師丢給了我一個ImageMagick庫。我在花了很大精力讀完幾乎與提取像素資訊毫無關系的官方文檔并配好環境後,竟然發現這個庫根本提取不到OpenGL需要的圖像資訊。。。
于是我又自行找了一些可能有用的庫,這其中包括 stbi_image 庫。總之,我在經過多番嘗試後發現這個也不能用,有其他需求的同學可以到上述連結下載下傳。此後我試圖一一解析這些圖像,其中成功的是對tga圖像的解析,這用到了tgaParser庫。
最終,我在網上多番查找并測試後,終于找到了一個名為FreeImage的庫,這個庫成功解析出了所有常見圖像格式。
使用該圖像處理庫的步驟如下:
- 下載下傳FreeImage
-
解壓壓縮包,并在VS 的屬性中配置包含目錄、庫目錄并添加lib檔案:
添加包含目錄
添加庫目錄 添加FreeImage.lib檔案 - 在檔案中加入FreeImage.h 頭檔案,其解析圖像的核心代碼如下所示:
#include "FreeImage.h"
//.....
FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(filePath, ); //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(), );
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, , GL_RGB, width, height,
, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels); //transfer into OpenGL
FreeImage_Unload(dib); //release the memory