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:
glGenerateMipmap(GL_TEXTURE_2D)
after glTexImage2D()
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?
It's due a combination of two default values:
GL_MIN_FILTER
has a default value of GL_LINEAR_MIPMAP_LINEAR
andGL_TEXTURE_MAX_LEVEL
has a default value of 1000.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.