How do I load textures to OpenGL using FreeImage library?

Razican picture Razican · Jun 15, 2013 · Viewed 12.9k times · Source

I'm learning OpenGL in C++ using NeHe tutorials, but I'm trying to do them with FreeImage library, instead of Glaux or SOIL. The good point I see in using FreeImage is thar it's last update was in October last year, while SOIL hasn't been updated in 5 years. The problem I have is that I'm not able to load textures correctly.

Here is my code:

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);
}

Using this code, the texture I get is wrong: it's black, with coloured dots and strips, and changing the image gives the same result, so I assume I'm not loading the texture correctly.

I've tried to swap the red and blue bits (read that FreeImage loads in BGR) with no better result. Finally, if I change the *FreeImage_ConvertTo32Bits(bitmap)* by *FreeImage_GetBits(bitmap)* I get a segfault.

What I'm doing wrong?

Answer

Roger Rowland picture Roger Rowland · Jun 15, 2013

There are two problems with your code - one is that you are converting to image to 32 bits but you specify a 24 bit texture format to openGL (GL_RGB). The second is that you are passing the FreeImage object itself to the texture rather than the converted bits.

You need to do something like this instead

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);