About the OpenGL/GLUT Display Callback:
So some of you may be confused about what goes into the display callback, and how it works.
The idea of this page is to clarify what I think should go in there. Obviously, this is not set in
stone -- this is just my suggestion. You may approach it another way.
What does the display callback do? I think of the display callback as the "draw the frame" function.
If you think of it that way, you need the following things:
- Clear various buffers (e.g., the color buffer, the depth buffer, etc.)
- You drew to them in the last frame, you'd better clear them so you aren't drawing over the old stuff.
- Set up your viewpoint.
- Note: this affects the modelview matrix, but you may still think of it as "setting the viewpoint."
- Most intitively (for me), this would involve a call to glLoadIdentity() followed by a call gluLookAt().
- If using lighting (and not simple RGB colors), set up your lights.
- Why should this go here? Because you probably want to specify your lights in some global "world space"
not in eye space or in object space.
- Using gluLookAt() above sets up this "world space" that you'll position your objects (and lights) in.
- If you used something other than gluLookAt() above, you may want to rethink where to setup the light positions.
- Enable effects (such as culling, depth testing, shade mode, etc.) to be applied to all objects in
the scene.
- Perhaps there are transformations to be applied to all objects (but not lights). Put them here.
- Draw objects. This involves a number of substeps:
- I suggest you call glPushMatrix() so that you do not mistakenly apply transformations to the
wrong objects. This certainly isn't always necessary, especially if you really understand
how OpenGL matrices work.
- Enable effects for this single object (things like the object texture, special shaders for this object, etc)
- Apply per-object transformations.
- Since each call to glMultMatrixf(), glTranslatef(), glScalef(), et cetera
multiplies the current matrix on the right (i.e., C = C * M_new), they are applied in the
reverse of the order you specify them.
- Start drawing ( with glBegin(...) ). For each vertex, call the appropriate function to
set up vertex attributes:
- Vertex color ( use glColor*() )
- Vertex normal ( use glNormal*() )
- Vertex texture coordinate ( use glTexCoord*() )
- Vertex position ( use glVertex*(), note all other vertex attributes should come before glVertex() )
- Finish drawing ( with glEnd() ).
- Disable effects applied to only this object.
- Call glPopMatrix() if you called glPushMatrix() in Step 6-1.
- Perform cleanup.
- Make sure the OpenGL state finishes the frame the way you want it to start the next frame!
- This may involve disabling effects you enabled earlier in Step 4.
- Flush the GL buffer so all your geometry is drawn (optional, but it does not hurt, and can avoid some problems).
- If you're using a doubled-buffered window make sure to call glutSwapBuffers() so what you just drew appears on screen.
Last Modified: Thursday, September 23, 2004
Chris Wyman (cwyman@cs.uiowa.edu)