Loading a BMP into an OpenGL textures switches the red and blue colors. (C++/Windows)

7.1k views Asked by At

I'm trying to load a bitmap into an OpenGL texture and display it to the screen, but when I do so, the red and blue values seem to switch (e.g.: a blue image appears orange, green images remain unchanged, etc..). This problem only exists when loading bitmaps, I can load .pngs relatively error free.

This is the code I'm using to load the bitmaps and set the textures. I'm using DevIl, but I'm not sure how relevant that is, as the problem existed when I used a different system (I don't quite remember what, it was a function in window.h, I believe):

ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
ilEnable(IL_ORIGIN_SET);
ILuint image;
ilGenImages(1, &image);
ilBindImage(image);
ilLoad(IL_BMP, "Data/NeHe.bmp"); // Incidentally, loading a png, although it fixes the problem,
                                 // rotates the image 180 degrees.  Not sure if that's important or not,
                                 // But it's why I added the first line of code

glGenTextures(3, &_texture[0]);
glBindTexture(GL_TEXTURE_2D, _texture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), \
    0, GL_RGB, GL_UNSIGNED_BYTE, ilGetData());

ilInit() and glEnable(GL_TEXTURE_2D) are both called earlier in the program, among other less relevant functions. Any help finding the cause of (and hopefully fixing) the problem would be much appreciated.

5

There are 5 answers

3
David Yaw On BEST ANSWER

You've got your RGB and BGR backwards.

glTexImage2D(GL_TEXTURE_2D, 0, 3, ilGetInteger(IL_IMAGE_WIDTH), ilGetInteger(IL_IMAGE_HEIGHT), \
    0, GL_RGB, GL_UNSIGNED_BYTE, ilGetData());

Is there a GL_BGR you can specify on the second line, instead of GL_RGB? That should fix it.

The reason a PNG causes the image to flip is because of how a BMP is stored: BMPs are stored bottom up, the first pixels in the file are the bottom row of the image.

0
red On

I had a similar issue a while back. Try setting GL_RBG in glTexImage2D to GL_BGR.

0
Jerry Coffin On

You'll normally have a call to glTexImage2D that specifies the external format of the pixels. From the sounds of things, you need to check that and switch from GL_RGB to GL_BGR.

0
Shaotim On

I know this is an old topic but I found the easiest way was to flip the z and x in the vec4 that texture2D returns in the fragment shader, not glTexture2d. It doesn't rely on extensions that may not exist. Solved it on an GLES 2 project im working on.

                "varying vec2 v_texCoord;                         "
                "uniform sampler2d s_texture;                     "
                "vec4 v_bgr;                                      "
                "void main()                                      "
                "{                                                "
                "    v_bgr = texture2D( s_texture, v_texCoord );  "
                "  gl_FragColor = v_bgr.zyxw;                     "
                "}                                                ";
0
magnavimaras On

You can switch GL_RGB to GL_BGR_EXT. In some cases GL_BGR isn't recognized.