3
\$\begingroup\$

I don't know what I'm doing wrong but I'm having a big a problem with GL_TEXTURE_MIN_FILTER when loading textures for my scene.

I'm doing a skybox, but that's irrelevant because the problem exists even if I just load the textures and don't do anything with them. Meaning, the code to draw the skybox and attach the textures to the box quads is disabled.

My current code to load textures is the following:

typedef struct sGameTextures {
    unsigned int skybox[6];
} GameTextures;

GameTextures gameTextures;

unsigned int loadImageTexture(const char *filepath, int glFormat, int pWrap, int pFilter) {
    int texDimension, texWidth, texHeight, texPixelSize;
    unsigned int texID, texImage;
    unsigned char *texPixels;
    unsigned int ilFormat;

    switch(glFormat) {
        case GL_LUMINANCE:
            ilFormat = IL_LUMINANCE;
            break;
        case GL_RGB:
            ilFormat = IL_RGB;
            break;
        case GL_RGBA:
            ilFormat = IL_RGBA;
            break;
        default:
            return -1;
    }

    ilGenImages(1, &texImage);
    ilBindImage(texImage);

    if(!ilLoadImage((ILstring)filepath)) {
        ilDeleteImages(1, &texImage);
        return -1;
    }

    texWidth = ilGetInteger(IL_IMAGE_HEIGHT);
    texHeight = ilGetInteger(IL_IMAGE_WIDTH);
    texPixelSize = ilGetInteger(IL_IMAGE_BPP);

    // stop if image width or height is not power of 2
    if(!texWidth & (texWidth - 1) || !texHeight & (texHeight -1)) {
        ilDeleteImages(1, &texImage);
        return -1;
    }

    texDimension = texWidth * texHeight * texPixelSize;
    texPixels = new unsigned char[texDimension];

    ilCopyPixels(0, 0, 0, texWidth, texHeight, 1, ilFormat, IL_UNSIGNED_BYTE, texPixels);
    ilDeleteImages(1, &texImage);

    if((texPixelSize * texWidth) % 4 == 0) {
        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
    } else {
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    }

    glGenTextures(1, &texID);
    glBindTexture(GL_TEXTURE_2D, texID);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, pWrap);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, pWrap);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, pFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, pFilter);

    glTexImage2D(GL_TEXTURE_2D, 0, glFormat, texWidth, texHeight, 0, glFormat, GL_UNSIGNED_BYTE, texPixels);

    return texID;
}

void loadGameTextures(void) {
    char *boxFace[] = { "front", "back", "left", "right", "top", "bottom" };
    char boxTexture[FILENAME_MAX];

    for(int i = 0; i < 6; i++) {
        sprintf_s(boxTexture, "Resources/Textures/Skybox/Set%d/%s.jpg", 1, boxFace[i]);
        gameTextures.skybox[i] = loadImageTexture(boxTexture, GL_RGB, GL_CLAMP, GL_LINEAR);
    }
}

void main(int argc, char **argv) {

    (...)

    ilInit();
    ilEnable(IL_ORIGIN_SET);
    ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

    loadGameTextures();

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_TEXTURE_2D);

    glutMainLoop();
}

This is how my scene looks like when I don't load any textures (ie: loadGameTextures() is never called): https://i.stack.imgur.com/1cCZp.png. Look how the floor is light green and now compare to the following which is much darker: https://i.stack.imgur.com/NYeqD.png.

At first I pinpointed the problem to glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, pFilter); more exactly when pFilter = GL_LINEAR. When I commented this line, or replaced pFilter with GL_LINEAR_MIPMAP_LINEAR the floor was light green again. However, this was without using the textures, I was just loading them. When I tried to use them, it didn't work, it looked like this: https://i.stack.imgur.com/JRAFJ.png.

The sky now looks white because that's the clear color I use when drawing the skybox quads. We only see white because the textures are not properly working. They are loaded but that option I selected for GL_TEXTURE_MIN_FILTER, helps on the darkening issue but doesn't display any textures.

Another thing I noticed is that I'm enabling GL_TEXTURE_2D globally and if I only enable it when I need it (drawing the skybox) and disable it when finished, it will work. The scene won't be dark anymore. But the skybox is just an example, I'll be using textures all over the place and it's a pain to keep enabling/disabling GL_TEXTURE_2D every time I need to draw some texture. Surely there must be another way around this problem?

\$\endgroup\$
1
  • \$\begingroup\$ I'm sure you have solved this, since this was 11 years ago, but the algorithm showed me this question and I couldn't help wondering whether the problem might have been to do with gamma correction ? I had the opposite problem, where my textures were too bright, because I had accidentally gamma-corrected an already gamma-corrected texture bitmap. In the exceedingly unlikely event that you still need help, and that my comment seems plausible, please let me know and I will supply details. \$\endgroup\$
    – Simon
    May 31, 2022 at 21:30

1 Answer 1

3
\$\begingroup\$

You can try to 'unbind' any texture if you want to keep GL_TEXTURE_2D enabled (which is fine).

glBindTexture(GL_TEXTURE_2D, 0); // Bind the default (empty) texture
\$\endgroup\$
4
  • \$\begingroup\$ So I should just call that (I think you meant glBindTexture) in in the end of every draw function which maps textures to objects? \$\endgroup\$
    – rfgamaral
    Apr 7, 2011 at 17:22
  • \$\begingroup\$ Nitpick: glBindTexture(x, 0) doesn't disable texturing, but actually binds what is called the OpenGL default texture, which is for most API purposes a "real" texture; you can change its parameters, prioritize it, sample it, etc. \$\endgroup\$
    – user744
    Apr 7, 2011 at 20:12
  • \$\begingroup\$ Yeah, I know it doesn't disable texturing, but it does the trick. I was just disabling texturing before because that was the solution I could find. Ideally, I don't want to keep enabling/disabling texturing; I want to enable it once and done. "Unbinding" the previous texture seems to be enough. \$\endgroup\$
    – rfgamaral
    Apr 7, 2011 at 20:16
  • \$\begingroup\$ funnily enough I had the same bug in my code recently \$\endgroup\$
    – Will
    Apr 11, 2011 at 19:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .