B.1. StateOpenGL is a state machine, and when your application puts OpenGL in a certain state, OpenGL stays in that state until code changes it to another state. Often, this is the behavior you want. Many applications typically enable depth testing with glEnable( GL_DEPTH_TEST ) at init time, for example, and leave it enabled for the duration of their program execution. If state isn't set the way you want it, however, OpenGL probably won't produce the results you want. Consider an application that renders a combination of texture mapped and nontexture mapped primitives. If the code that renders the texture mapped primitives leaves texture mapping enabled with glEnable( GL_TEXTURE_2D ), the primitives that are supposed to be nontexture mapped probably will render in the wrong color. This happens because the application code for rendering the nontexture mapped primitives probably doesn't bother to send texture coordinates. The primitive is rendered with texture mapping enabled, but OpenGL uses a single texture coordinate to obtain texture colors for the entire primitive. Because the result doesn't look like texture mapping, this type of bug typically stumps many developers. In this type of situation, you need a mechanism to put OpenGL back into some known state. The best way to do this is to wrap code that changes OpenGL server state with glPushAttrib() and glPopAttrib(), and similarly use glPushClientAttrib() and glPopClientAttrib() to wrap code that changes client state. Applications typically place OpenGL in a known state that the application will most frequently require at init time and then wrap rendering code with calls to push and pop the attribute stacks. There are several benefits to using the attribute stack:
When you push and pop state, consider using GL_ALL_ATTRIB_BITS and GL_CLIENT_ALL_ATTRIB_BITS for the mask parameter to increase maintainability. Pushing all state is more expensive than pushing a small subset of state, so use this flag with caution. If you push all state during development, you can revisit the code later during performance tuning. |