Some notes about OpenGL Textures, Mipmaps and black screens

Posted at 12 Nov 2014
Tags: opengl, ios

I recently came across the beloved OpenGL black screen when working on offscreen texture rendering for an iOS application using OpenGL ES 2.0. This once again showed to me that OpenGL is very hard to debug.

The main problem was that calling texture2D() in a fragment shader would always return black color values ([0, 0, 0, 1] RGBA floats), although I was sure that I uploaded a valid texture to the GPU. However, it turned out that the texture was actually incomplete. By default, OpenGL requires the texture to provide a complete mipmap for minification. This is because GL_TEXTURE_MIN_FILTER is initially set to GL_LINEAR_MIPMAP_LINEAR, one of four minifying functions that require a mipmap. I noticed that texture2D() always needs a complete mipmap in such a case, even if it should display a texture of mipmap level “0” – which means the original texture.

One solution to this is obviously to generate the mipmap, which can be done automatically with glGenerateMipmap(). However, many mobile devices still have only limited Non Power of Two (NPOT) texture support. As explained in this helpful blog post, limited support means that it is possible to use NPOT textures (with texture wrap mode “clamp”), but mipmaps cannot be generated. It will result in an OpenGL error 1282 (GL_INVALID_OPERATION) upon calling glGenerateMipmap() and the screen will stay black.

Another solution is to disable mipmapping, which can lead to visible aliasing artifacts. For this, GL_TEXTURE_MIN_FILTER must be set to GL_LINEAR or GL_NEAREST for this after activating the correct texture unit with glActiveTexture() and binding the texture with glBindTexture(). Don’t forget to set the texture wrapping to GL_CLAMP_TO_EDGE in order to use NPOT textures as explained before.

If you spotted a mistake or want to comment on this post, please contact me: post -at- mkonrad -dot- net.
← “Resolving the 'unresolved inclusion' error in Eclipse CDT for standard library headers of the Android NDK
View all posts
OSX Yosemite Phoning Home” →