opengltexturesstb-image

Why can glGenerateMipmap(GL_TEXTURE_2D) and setting GL_TEXTURE_MIN_FILTER to GL_LINEAR solve the black texture problem?


I have tried to load an image into an OpenGL texture use stb_image, and here is the code:

unsigned int texture;
glGenTextures(1, &texture);

int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true);
unsigned char* data = stbi_load("awesomeface.png", &width, &height, &nrChannels, 0);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

stbi_image_free(data);

I think this code could work, but it give me a black texture, which should be the image.

After spending a lot of time on solving this problem, I finally found two ways to solve it:

  1. add glGenerateMipmap(GL_TEXTURE_2D) after glTexImage2D()
  2. add glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) after glBindTexture()

Either of these two methods will solve the problem, but I don't know why.

Can anyone explain how it works?


Solution

  • It's due a combination of two default values:

    Since there is only one texture level present, the texture is considered incomplete.

    The fixes work because either of them solves one of the problems. Generating mipmaps solves the problem that the mipmaps are missing while setting the minification filter to GL_NEAREST (or GL_LINEAR for that purpose) sets the filter to a mode where mipmaps are not required.

    This is a very common problem, and is also mentioned in the Common Mistakes article of the OpenGL wiki.