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

5

8

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.

Oliver answered 25/2, 2011 at 22:26 Comment(0)
M
10

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.

Monah answered 25/2, 2011 at 22:32 Comment(3)
Thanks. I tried GL_BGR, but I get an error saying it doesn't exist. I also don't see why a bitmap would be stored with BGR data in the first place, would it?Oliver
@Keand64: BMP files, or to be precise are in fact stored in BGR order. Actually on modern systems also the frambuffer bitplanes are in BGR(A) order, so supplying textures in BGR format usually is faster than RGB format. GL_BGR is a token from OpenGL versions >1.1, however the Windows Platform SDK ships only with headers for OpenGL-1.1 - anything beyond must be accessed through extensions. Just get GLEW glew.sourceforge.net or GLee, used the headers from those an be done with it.Cloying
You can also try "#include <GL/glext.h>" but maybe need to get a recent version of glext.h from opengl.org/registry/api/glext.hHaematin
H
2

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

Hardenberg answered 25/2, 2011 at 22:30 Comment(0)
T
2

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

Thornberry answered 22/3, 2014 at 22:7 Comment(0)
B
0

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.

Bloem answered 25/2, 2011 at 22:31 Comment(0)
V
0

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;                     "
                "}                                                ";
Venuti answered 29/1, 2016 at 23:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.