使用FreeImage库读图片,通过OpenGL显示出来
先介绍一些FreeImage的基本函数
/*
得到图像格式函数
FREE_IMAGE_FORMST fif = FreeImage_GetFileType(filename);
读图像函数
FIBITMAP *dib = FreeImage_Load(fif, filename, 0);
写图像函数
FreeImage_Save(fif, dib, filename, 0);
卸载图像函数
FreeImage_Unload(dib);
得到图像高度
int H = FreeImage_GetHeight(dib);
得到图像宽度
int W = FreeImage_GetWidth(dib);
得到图像像素
BYTE *data = FreeImage_GetBits(dib);
得到图像位深
int bpp = FreeImage_GetBPP(dib);
*/
下面是读取图片的代码
bool Texture2D::LoadTexture(const char* filename)
{
#ifdef FREEIMAGE_LIB
FreeImage_Initialise();
#endif
//1.FreeImage读数据
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; //图像类型 //tif/png/jpg/bmp...
FREE_IMAGE_TYPE imatype = FIT_UNKNOWN;//图像格式 //RGB16/RGBA16/FLOAT/DOUBLE...
FIBITMAP *dib(0); //图像指针
BYTE* bits(0); //图像数据指针
int width = 0; //图像的宽和高
int height = 0;
int bpp = 0; //图像位深度//每个像素占几个bit
fif = FreeImage_GetFileType(filename, 0);//识别图像类型
if (fif == FIF_UNKNOWN) //如果没识别出来,就从图像的文件扩展名识别图像类型
fif = FreeImage_GetFIFFromFilename(filename);
if (fif == FIF_UNKNOWN) //若仍然不能识别,则无法识别,
return false;
if (FreeImage_FIFSupportsReading(fif))//若果是可以支持的图像类型,则读出来
dib = FreeImage_Load(fif, filename);
if (!dib)//读取失败
return false;
bits = FreeImage_GetBits(dib);//获取图像数据
width = FreeImage_GetWidth(dib);//获取图像宽和高
height = FreeImage_GetHeight(dib);
if ((bits == 0) || (width == 0) || (height == 0))//获取数据失败
return false;
unsigned int byte_per_pixel = FreeImage_GetLine(dib) / width;
bpp = FreeImage_GetBPP(dib);
imatype = FreeImage_GetImageType(dib);
//OpenGL创建图像要用到的参数
GLint inFormat = 0; // 读到显存中的格式。
GLenum exFormat = 0; // 读进内存中的格式。
GLenum exType = 0; // 源图的数据类型
//2.将FreeImage的格式转换成OpenGL的格式
switch (imatype)
{
case FIT_UINT16:
inFormat = GL_R16UI;//shader中采样器需使用 usampler2D
exFormat = GL_RED;
exType = GL_UNSIGNED_SHORT;
break;
case FIT_INT16:
inFormat = GL_R16I;//采样器 isampler2D
exFormat = GL_RED;
exType = GL_SHORT;
break;
case FIT_UINT32:// array of unsigned long : unsigned 32-bit
inFormat = GL_R32UI;//采样器 usampler2D
exFormat = GL_RED;
exType = GL_UNSIGNED_INT;
break;
case FIT_INT32:// array of long : signed 32-bit
inFormat = GL_R32I;//采样器 isampler2D
exFormat = GL_RED;
exType = GL_INT;
break;
case FIT_FLOAT:// array of float : 32-bit IEEE floating point
inFormat = GL_R32F;
exFormat = GL_RED;
exType = GL_FLOAT;
break;
case FIT_DOUBLE:// array of double : 64-bit IEEE floating point
exType = GL_DOUBLE;
assert(inFormat);
break;
case FIT_COMPLEX:// array of FICOMPLEX : 2 x 64-bit IEEE floating point
exType = GL_DOUBLE;
assert(inFormat);
break;
case FIT_RGB16: // 48-bit RGB image : 3 x 16-bit
inFormat = GL_RGB16;
exFormat = GL_RGB;
exType = GL_UNSIGNED_SHORT;
break;
case FIT_RGBA16:// 64-bit RGBA image : 4 x 16-bit
inFormat = GL_RGBA16;
exFormat = GL_RGBA;
exType = GL_UNSIGNED_SHORT;
break;
case FIT_RGBF:// 96-bit RGB float image : 3 x 32-bit IEEE floating point
inFormat = GL_RGB32F;
exFormat = GL_RGB;
exType = GL_FLOAT;
break;
case FIT_RGBAF:// 128-bit RGBA float image : 4 x 32-bit IEEE floating point
inFormat = GL_RGBA32F;
exFormat = GL_RGBA;
exType = GL_FLOAT;
break;
case FIT_BITMAP:// standard image : 1-, 4-, 8-, 16-, 24-, 32-bit
exType = GL_UNSIGNED_BYTE;
if (bpp / 8 == 4)//32-bit
{
inFormat = GL_RGBA8;
exFormat = GL_BGRA;
}
else if (bpp / 8 == 3)//24-bit
{
inFormat = GL_RGB8;
exFormat = GL_BGR;
}
else//OpenGL不支持 //待定...
assert(inFormat);
break;
default://OpenGL不支持 //待定...
assert(inFormat);
break;
}
glGenTextures(1, &m_Texture);
glBindTexture(GL_TEXTURE_2D, m_Texture);
{
//3.加载数据到显存
glTexImage2D(GL_TEXTURE_2D, 0, inFormat, width, height, 0, exFormat, exType, bits);
//4.设置采样器
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
glBindTexture(GL_TEXTURE_2D, 0);
FreeImage_Unload(dib);//一定要先加载到显存再去卸载FreeImage
#ifdef FREEIMAGE_LIB
FreeImage_DeInitialise();
#endif
return true;
}