如何使用FreeImage库将纹理加载到OpenGL?

Raz*_*can 9 c++ opengl textures freeimage

我正在使用NeHe教程在C++中学习OpenGL,但我正在尝试使用FreeImage库,而不是Glaux或SOIL.我在使用FreeImage时看到的好处是,它的最后一次更新发生在去年10月,而SOIL在5年内没有更新.我遇到的问题是我无法正确加载纹理.

这是我的代码:

static GLuint texture = 0;
if (texture == 0)
{
    FIBITMAP* bitmap = FreeImage_Load(
        FreeImage_GetFileType("textures/test/nehe_06.png", 0),
        "textures/test/nehe_06.png");

    glGenTextures(1, &texture);

    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, 3, FreeImage_GetWidth(bitmap), FreeImage_GetHeight(bitmap),
        0, GL_RGB, GL_UNSIGNED_BYTE, FreeImage_ConvertTo32Bits(bitmap));

    FreeImage_Unload(bitmap);
}
Run Code Online (Sandbox Code Playgroud)

使用这个代码,我得到的纹理是错误的:它是黑色的,有彩色的点和条带,更改图像给出相同的结果,所以我假设我没有正确加载纹理.

我试图交换红色和蓝色位(读取FreeImage在BGR中加载)没有更好的结果.最后,如果我通过*FreeImage_GetBits(位图)更改*FreeImage_ConvertTo32Bits(位图)**我得到一个段错误.

我做错了什么?

Rog*_*and 17

您的代码有两个问题 - 一个是您将图像转换为32位,但是您为openGL(GL_RGB)指定了一个24位纹理格式.第二个是你将FreeImage对象本身传递给纹理而不是转换后的位.

你需要做这样的事情

FIBITMAP *pImage = FreeImage_ConvertTo32Bits(bitmap);
int nWidth = FreeImage_GetWidth(pImage);
int nHeight = FreeImage_GetHeight(pImage);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight,
    0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage));

FreeImage_Unload(pImage);
Run Code Online (Sandbox Code Playgroud)


Ser*_* K. 13

扩展以前的答案:

FreeImage_GetBits()函数将返回指向以FreeImage内部格式存储的数据的指针.每条扫描线通常与4字节边界对齐.当你有两个纹理时,这将正常工作.但是,对于NPOT纹理,您需要为OpenGL指定正确的解包对齐.

FreeImage中还有另一个函数可以让你获得未对齐紧密排列的像素数组: FreeImage_ConvertToRawBits()