With the advent of the OpenGL 1.1 specification, texture objects became part of the API. These texture objects have been available for quite some time as extensions to OpenGL 1.0 because of their incredible performance benefits. However, not everyone is aware of what texture objects are and why they are useful. Texture objects can improve your textured rendering performance by more than 10 times using the same hardware. That's a pretty bold claim, and I can demonstrate it with ease.
Typically, you load a texture image from either a disk file or a memory resource, or you generate it procedurally. You then upload the texture to OpenGL with a call to glTexImage2D(). Although I'm using 2D textures for this working example, everything that this article discusses applies equally well to 1D and 3D (OpenGL 1.2 only) textures. A typical scenario would go something like this:
1. Load texture image bits from a disk file.
2. Set the OpenGL texture parameters and environment (filters, border modes, and so on).
3. Call glTexImage2D (for 2D textures) to load the texture into OpenGL.
4. Draw some geometry with texture coordinates.
However, you wouldn't want to perform each of these steps for every frame of an animated scene. Repeatedly accessing a disk file can be pretty expensive, time wise. If you were using a single texture, you might first load the disk file and call glTexImage2D() after creating the rendering context. Then you'd render the geometry or scene while repeatedly changing the viewer's position or the object's orientation (whichever is appropriate). With a run-of-the-mill 3D card with OpenGL acceleration, you would get a reasonably good frame rate and thus a smooth animation.
Now suppose that a given scene contains multiple textured objects, each using one or more textures; or perhaps a single object with multiple textures. For our example, we'll use a spinning cube with a different texture on each face, plus a marble texture for the floor beneath this cube. This scene has a total of seven textures that need to be loaded.
Naturally, we don't want to access the disk seven times for every frame of our animation, as this would slow our rendering considerably. One popular technique is to combine all seven textures into one large texture that gets loaded once. Then, by tweaking the texture coordinates, you can effectively put different portions of the same texture on each side of the cube. The problem with this technique is that texture filtering will often introduce unsightly artifacts along the edges of your polygons. Another practical consideration is that most hardware imposes some limit on the maximum texture size for a single texture. You could quickly exhaust your available texture space without making much of a dent in your actual available texture memory.
So artistically, it's better to keep textures separate. How then do we avoid a texture load every time we need to change textures? A reasonable and intuitive choice would be to use display lists. Each display list would contain a call to glTexture2D() (or 1D or 3D) with the appropriate pointer for the given texture. This approach would save considerable time because it only accesses the disk seven times to read in the textures and does so before the animation loop. Saving seven or more disk accesses per frame seems to be a substantial optimization. Let's see what happens.