Wednesday, September 16, 2009

Missing Textures in OpenGL

I had an interesting problem the other day. In our OpenGL application, we had problems with our texture-mapping. For some reason, two of my textures would render fine, but upon introducing a third texture, one of the others would disappear. They would render as white squares (which makes sense, since we use a lot of square meshes). This drove me crazy for a couple of days, until I came across this post in the Apple discussion forum.

The problem is that I had failed to notice that the texture minification and magnification filters are associated with individual texture objects. I had wrongly assumed that they were associated with the whole OpenGL context and, as a result, was only setting them once. On my system, the default minification filter was GL_NEAREST_MIPMAP_LINEAR. Since I never set up any mipmaps, textures that were being scaled down weren't drawing at all.

Unfortunately, the man pages for glBindTexture and glTexParameter aren't completely clear about where the associated state is stored - in the GL context or in the texture object. There is this quote:

While a texture is bound, GL operations on the target to which it is bound affect the bound texture, and queries of the target to which it is bound return state from the bound texture.
Obviously, there are some exceptions to this rule (like glBindTexture itself), but it seems that we can derive a good rule of thumb. If an OpenGL command takes a texture target parameter (i.e. GL_TEXTURE_1D or GL_TEXTURE_2D), assume that it will affect the currently bound texture object unless you know otherwise. For example, glPrioritizeTextures takes a list of textures to prioritize, so it doesn't necessarily affect the currently bound texture.

It turns out that there is a lot of state that is stored on the texture object. My ancient copy of the OpenGL Red Book indicates that the texture object holds the raw image bytes, image format information, mipmaps, filters, wrapping modes, priority, and some other bits of data as well. It has been a long time since I have done any OpenGL programming. I don't remember if I ever really knew this (or if I was just lucky in the past).

So kids, remember; if you're not seeing your textures, check whether you have correctly configured the texture object.