Do not count on the error behavior of an OpenGL implementation - it might change in a future release of OpenGL. For example, OpenGL 1.0 ignores matrix operations invoked between glBegin() and glEnd() commands, but OpenGL 1.1 might not. Put another way, OpenGL error semantics may change between upward-compatible revisions.
Use the projection matrix to collapse all geometry to a single plane. If the modelview matrix is used, OpenGL features that operate in eye coordinates (such as lighting and application-defined clipping planes) might fail.
Do not make extensive changes to a single matrix. For example, do not animate a rotation by continually calling glRotate() with an incremental angle. Rather, use glLoadIdentity() to initialize the given matrix for each frame, then call glRotate() with the desired complete angle for that frame.
Count on multiple passes through a rendering database to generate the same pixel fragments only if this behavior is guaranteed by the invariance rules established for a compliant OpenGL implementation. (See Appendix I, "OpenGL Invariance"
for details on the invariance rules.) Otherwise, a different set of fragments might be generated.
Do not expect errors to be reported while a display list is being defined. The commands within a display list generate errors only when the list is executed.
Place the near frustum plane as far from the viewpoint as possible to optimize the operation of the depth buffer.
Call glFlush() to force all previous OpenGL commands to be executed. Do not count on glGet*() or glIs*() to flush the rendering stream. Query commands flush as much of the stream as is required to return valid data but don't guarantee to complete all pending rendering commands.
Turn dithering off when rendering predithered images (for example, when glCopyPixels() is called).
Make use of the full range of the accumulation buffer. For example, if accumulating four images, scale each by one-quarter as it's accumulated.
If exact two-dimensional rasterization is desired, you must carefully specify both the orthographic projection and the vertices of primitives that are to be rasterized. The orthographic projection should be specified with integer coordinates, as shown in the following example:
gluOrtho2D(0, width, 0, height);
where width and height are the dimensions of the viewport. Given this projection matrix, polygon vertices and pixel image positions should be placed at integer coordinates to rasterize predictably. For example, glRecti(0, 0, 1, 1) reliably fills the lower left pixel of the viewport, and glRasterPos2i(0, 0) reliably positions an unzoomed image at the lower left of the viewport. Point vertices, line vertices, and bitmap positions should be placed at half-integer locations, however. For example, a line drawn from (x1, 0.5) to (x2, 0.5) will be reliably rendered along the bottom row of pixels int the viewport, and a point drawn at (0.5, 0.5) will reliably fill the same pixel as glRecti(0, 0, 1, 1).
An optimum compromise that allows all primitives to be specified at integer positions, while still ensuring predictable rasterization, is to translate x and y by 0.375, as shown in the following code fragment. Such a translation keeps polygon and pixel image edges safely away from the centers of pixels, while moving line vertices close enough to the pixel centers.
glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, width, 0, height); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.375, 0.375, 0.0); /* render all primitives at integer positions */
Avoid using negative w vertex coordinates and negative q texture coordinates. OpenGL might not clip such coordinates correctly and might make interpolation errors when shading primitives defined by such coordinates.
OpenGL Programming Guide