How do I load textures to OpenGL using FreeImage library?

风流意气都作罢 提交于 2019-12-20 10:44:07

问题


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?


回答1:


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



回答2:


To extend the previous answer:

FreeImage_GetBits() function will return a pointer to the data stored in a FreeImage-internal format. Where each scanline is usually aligned to a 4-bytes boundary. This will work fine while you have power-of-two textures. However, for NPOT textures you will need to specify the correct unpack alignment for OpenGL.

There is another function in FreeImage which will allow you to get unaligned tightly packed array of pixels: FreeImage_ConvertToRawBits()



来源:https://stackoverflow.com/questions/17125843/how-do-i-load-textures-to-opengl-using-freeimage-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!