Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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): http://i.stack.imgur.com/1cCZp.png. Look how the floor is light green and now compare to the following which is much darker: http://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: http://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?

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

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
share|improve this answer
    
So I should just call that (I think you meant glBindTexture) in in the end of every draw function which maps textures to objects? –  Ricardo Amaral Apr 7 '11 at 17:22
    
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. –  user744 Apr 7 '11 at 20:12
    
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. –  Ricardo Amaral Apr 7 '11 at 20:16
    
@Joe: thanks for the details. –  jv42 Apr 11 '11 at 11:53
    
funnily enough I had the same bug in my code recently –  Will Apr 11 '11 at 19:06
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.