Section D.3. Debugging a Blank Window


D.3. Debugging a Blank Window

Bugs in your application occasionally cause OpenGL to render nothing, rather than the intended scene. There are many possible causes for a blank window, and enumerating all of them is impossible. This section discusses a few of the more common causes.

D.3.1. Use Good Code Development Practices

To avoid having to consider all the possible causes for a blank window or to examine every line of your application, start simple, and verify correct rendering incrementally as you develop your application. Developers who encounter a blank window while using this strategy know that the bug was introduced in a recent code change, which speeds locating and resolving the issue.

D.3.2. Use glGetError()

If you issue an OpenGL command that generates an error other than GL_OUT_OF_MEMORY, OpenGL ignores the offending command so that it has no effect on framebuffer contents or OpenGL state. As an example of how this could result in a blank window, consider what would happen if your application passed incorrect enumerants to vertex array drawing commands. Each command would generate a GL_INVALID_ENUM error; therefore, OpenGL would ignore them. The final rendered image would contain no primitives at all.

See the section "OpenGL Errors" earlier in this appendix for additional information.

D.3.3. Enable Vertex Arrays

If your application issues a vertex array rendering command, OpenGL uses only vertex array data from enabled vertex arrays. To render with vertex, texture coordinate, and normal data, for example, use the following code:

 glEnableClientState( GL_VERTEX_ARRAY ); glEnableClientState( GL_TEXTURE_COORD_ARRAY ); glEnableClientState( GL_NORMAL_ARRAY ); 


If you issue a vertex array rendering command while GL_VERTEX_ARRAY is disabled, OpenGL will render nothing.

D.3.4. Set Appropriate Clip Planes

If your application sets the near and far clip planes incorrectly, OpenGL could clip part or all of your geometry, resulting in a blank or partially rendered image. To avoid this problem, start with liberal values for the near and far clip planes, and tighten their range later to maximize depth buffer precision. Using too tight a range could clip geometry that is more distant than the far plane or closer than the near plane.

Note that if your application uses an orthographic projection, the near and far parameters to glOrtho() are distances from the eye-coordinate origin to the near and far clip planes. Because the viewer is at infinity, near and far can be negative. If near= far, however, glOrtho() generates GL_INVALID_VALUE.

Typically, gluPerspective() is implemented as a wrapper around glMultMatrixd() and doesn't generate an error,[1] even when passed absurd values for near or far. You should always pass positive (nonzero and non-negative) values for near and far. Negative or zero value could cause a blank window or other incorrect rendering.

[1] Because gluPerspective() calls glMultMatrixd(), it generates GL_INVALID_OPERATION if called between glBegin() and glEnd().

D.3.5. Use Correct Transformations

If your application sets incorrect model or view transformations, the resulting model-view matrix could translate your geometry outside the view volume. There are multiple ways that model and view transformations could go wrong.

Typical frame-based applications set the model-view matrix to identity at the start of each frame, then multiply a view transformation, then push and pop the matrix stack around local model transformations. New OpenGL developers sometimes fail to set the model-view matrix to identity with glLoadIdentity(). As a result, the first frame might render correctly, but subsequent frames would erroneously accumulate transformations on the model-view matrix, resulting in a blank window or other incorrect rendering.

The fact that OpenGL postmultiplies matrices on the current top of matrix stack can confuse new developers. If you write code that assumes your translate will occur before your scale, for example, but OpenGL actually performs the concatenation in the opposite order, your geometry will not render in the expected location.

Because OpenGL provides no facilities for positioning the viewer, setting the correct view transformation is often problematic for new developers. Use the gluLookAt() function to establish the view transformation initially, because it has an intuitive interface. Develop code for managing more-complex view transformations later.

When developing transformation code, start simply, and test incrementally. This will help you isolate transformation bugs to the most recently added code.

Review Chapter 3, "Transformation and Viewing," for information on this topic.

D.3.6. Swap Buffers

In a double-buffered application, OpenGL renders all your geometry, but the final image is stored in the back buffer and invisible until you swap buffers. If your application uses GLUT, call glutSwapBuffers() at the end of each frame; otherwise, call the platform-specific routine for swapping buffers.

D.3.7. Call glClear()

If your application fails to call glClear(), the initial contents of the color and depth buffers are undefined. This usually results in incorrect rendering for frame-based, double-buffered applications.

Failing to clear the color buffer could cause successive frames to accumulate, as shown in Figure D-1. Because the contents of the color buffer are undefined after a swap, however, OpenGL doesn't guarantee that previously rendered frames remain intact. For this reason, applications shouldn't count on this behavior to accumulate multiple frames.

Figure D-1. Failing to clear the color buffer with glClear( GL_COLOR_BUFFER_BIT ) could cause multiple frames to accumulate.


If your application actually needs to accumulate multiple frames, you should draw into the front buffer; see "glDrawBuffer" in OpenGL® Reference Manual.

Failing to clear the depth buffer with glClear( GL_DEPTH_BUFFER_BIT ) could cause a blank window. Each frame of a depth-buffered application usually requires the depth buffer initialized to the maximum depth value, allowing fragments with smaller depth values to pass the default depth test. If the application fails to clear the depth buffer, OpenGL leaves the contents undefined. The depth buffer might contain depth values left over from the previous frame, or it could contain random values. The result is that part or all of your current frame rendering could be missing.




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