Section B.3. Precision


B.3. Precision

The OpenGL specification requires implementations to provide floating-point accuracy to about 1 part in 105. This is slightly less than the accuracy of a single-precision IEEE floating-point number. For details, see Section 2.1.1, "Floating-Point Computation," of The OpenGL Graphics System.

B.3.1. Magnitude

Avoid rendering situations that require great precision with large-magnitude vertex coordinates. If your application uses geometry with large-magnitude coordinates, you could encounter the following problems:

  • Depth offset with reasonable parameters, such as glPolygonOffset ( 1.f, 1.f ), could fail if the object-coordinate vertices lack the precision to make them suitably co-planar. Larger factor and units parameters might solve some of the issues but aren't a general solution.[1]

    [1] Stencil might be an alternative to depth offset. See the section "Stencil" in appendix A, "Other Features," or refer to OpenGL® Programming Guide for more information.

  • Small translations could fail to produce any results or could produce large apparent jumps in geometry location or viewer position.

B.3.2. Round-Off

Note that OpenGL isn't immune to floating point round-off. Accumulated floating-point operations often reduce the precision of internal OpenGL floating point numbers.

Repeated successive matrix multiplications can dramatically reduce the precision of the resulting matrix, for example. For this reason, you shouldn't structure your code to render multiple frames by accumulating successive matrices. Avoid the following code structure:

 // DO NOT USE THIS CODE STRUCTURE const float rotationAngle( 1.f ); For each frame {   glRotatef( rotationAngle, x, y, z );   Render. } 


Instead, design your application to clear the model-view matrix each frame. Applications that load a new viewing transformation each frame easily avoid this issue. At the start of each frame:

 glLoadIdentity(); Multiply in a view matrix. 


To render each primitive or group of primitives with the same modeling transformation:

 glPushMatrix();   Multiply in some matrices using glRotatef, glMultMatrix, etc.   Render. glPopMatrix(); 


The glLoadIdentity() call at the start of the frame effectively cleans the model-view matrix slate. Likewise, wrapping local modeling transformations with glPushMatrix() and glPopMatrix() restores the model-view matrix to the viewing transformation. This technique minimizes accumulated round-off.

B.3.3. Depth Buffer

In a perspective projection, objects are larger when they're close to the viewer and smaller when they're farther away. In other words, near objects occupy more x and y window-coordinate space, and distant objects occupy less. The perspective divide causes this effect.

Note, however, that OpenGL specifies that the perspective division occur on z as well as x and y. As a result, objects that are close occupy more depth buffer space, and distant objects occupy less depth buffer space. In other words, due to the perspective divide, the depth buffer is exponential rather than linear.

For this reason, applications should always try to place the near clip plane as distant as possible without intersecting geometry in the scene. Keeping the far plane close is also important, but not as important as keeping the near plane distant.

As a general rule of thumb, maintain a far/near ratio of no more than 50 for a 16-bit depth buffer and no more than 10,000 for a 24-bit depth buffer. With a maximized near plane distance, these ratios should provide enough depth buffer precision to resolve at least one world-coordinate unit.




OpenGL Distilled
OpenGL Distilled
ISBN: 0321336798
EAN: 2147483647
Year: 2007
Pages: 123
Authors: Paul Martz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net