使用FreeImage在OpenGL中生成影象貼圖的方法
這是之前做本科畢設時碰到的問題,拖到現在才有時間整理,沒想到一轉眼已經在研究生實驗室了,時間飛逝啊~
言歸正傳,當時我需要在OpenGL中重繪FBX格式的三維模型,由於不同美工人員給人物模型貼的圖可能是不同格式的,因此需要解析不同格式的貼圖,然後將該貼圖的長、寬以及畫素資訊傳給OpenGL函式以供處理。
三維模型常用的貼圖格式有png、dds、tga、jpg、bmp等,這些影象格式所使用的協議都是不同的,對這些格式分別進行解析幾乎難以實現。例如,dds作為一種紋理壓縮非常高的影象格式,能夠降低50%甚至更多的紋理記憶體消耗,因此廣泛應用於遊戲模型中,但是其壓縮格式包含DXT1、DXT3以及DXT5三種,在解析時需要對其分別處理,導致紋理資訊難以提取;bmp格式被稱為點陣圖
為解決該問題,我向當時的導師詢問能獲取所有格式資訊的影象處理庫,導師丟給了我一個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