SIGGRAPH '97

Course 24: OpenGL and Window System Integration

OpenGL "Gotchas"



Even though OpenGL is a well organized and has a simple API there some common pitfalls which new (and experienced) programmers can run into.

This document describes many such pitfalls and offers explanations or work-arounds.


glDrawPixels problems.

glDrawPixels draws a skewed image
Be sure the GL_UNPACK_ALIGNMENT value is set correctly. The default is four and if you're drawing GLubyte GL_RGB images it may have to be set to one.
glDrawPixels() draws the wrong colors
Be sure texture mapping is disabled as texturing is applied even to glDrawPixels. Also, be sure you're using the correct data type for your imagery. A common mistake is to use GLuint instead of GLubyte when drawing images with single-byte red, green, blue and alpha components.
glDrawPixels() of imagery obtained from glReadPixels() looks different than the original image
Try disabling dithering with glDisable(GL_DITHER).
glDrawPixels isn't as fast as expected
Some older graphics systems handle ABGR-order pixels faster than RGBA-order. Try the GL_EXT_abgr extension. Also, be sure to disable rasterization options such as depth testing, fog, stenciling, scissoring, pixel scaling, dithering and biasing, if you don't need them. GL_UNSIGNED_BYTE is typically the fastest data type.
How can I make glDrawPixels() draw an image flipped upside down?
Try glPixelZoom( 1.0, -1.0 ). Similarly, an image can be flipped left to right with glPixelZoom(). Note that you may have to adjust your raster position to position the image correctly.

glRasterPos Problems

glRasterPos() doesn't put the raster position at the window coordinate I specify
glRasterPos transforms coordinates by the modelview and projection matrices just like vertices. Set your matrices appropriately.
Why can't I position a bitmap outside of the window?
If glRasterPos() evaluates to a position outside of the viewport the raster position becomes invalid. Subsequent glBitmap() and glDrawPixels() calls will have no effect.

Solution; extend the viewport beyond the window bounds or use glBitmap() with an NULL bitmap and your desired delta X,Y movement from the current, valid raster position. Be sure to restore the viewport to a normal position before rendering other primitives.

The following function will set the raster position to an arbitrary window coordinate:

void window_pos( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
{
   GLfloat fx, fy;

   /* Push current matrix mode and viewport attributes */
   glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT );

   /* Setup projection parameters */
   glMatrixMode( GL_PROJECTION );
   glPushMatrix();
   glLoadIdentity();
   glMatrixMode( GL_MODELVIEW );
   glPushMatrix();
   glLoadIdentity();

   glDepthRange( z, z );
   glViewport( (int) x - 1, (int) y - 1, 2, 2 );

   /* set the raster (window) position */
   fx = x - (int) x;
   fy = y - (int) y;
   glRasterPos4f( fx, fy, 0.0, w );

   /* restore matrices, viewport and matrix mode */
   glPopMatrix();
   glMatrixMode( GL_PROJECTION );
   glPopMatrix();

   glPopAttrib();
}
The sequence of glRasterPos(), glColor(), glBitmap() doesn't result in the desired bitmap color
Call glColor() before glRasterPos().

Texture Mapping Problems

Texturing just isn't working
There are several possible explanations.
Textures with borders don't work
Several implementations of OpenGL have bugs which prevent textures with borders from working correctly. OpenGL on SGI Infinite Reality systems is an example.
Texturing isn't working on a Reality Engine 2 system
There's a known bug which requires glEnable(GL_TEXTURE_2D) be called before glTexImage2D() in some situations.

Performance Problems

Overall slow performance
Be sure a direct rendering context is being selected so that graphics hardware is accessed directly.

Motif/OpenGL Problems

Problems with glViewport and window resizing with Motif
In the resize callback for your application you should put a call to glXWaitX before the glViewport call to be sure the X server has actually resized the window before glViewport is called.

Lighting and Coloring Problems

glColor3b( 255, 255, 255 ) doesn't give me white
Be careful with color values and data types. The correct function in this case is glColor3ub( 255, 255, 255 ).
When lighting is enabled, the colors are not what's expected
Try glEnable( GL_NORMALIZE ) to scale your normal vectors to unit length. glScale() effects normal vectors, not just vertices.
Lines and points aren't colored as expected
Lighting may be enabled. All vertices are lit if lighting is enabled, even when drawing points and lines.
In color index mode glClearIndexi(0) doesn't clear the window to black.
There is no guarantee that color index 0 corresponds to black in the colormap. It is up to you to be sure the colormap entries are correctly loaded in your application.

Miscellaneous Problems

Nothing is drawn when in single-buffer mode
Call glFlush() after rendering. Your drawing commands may accumulate in a buffer and not be executed until you explicitly issue a flush.
How do I draw outlined polygons?
If you've tried this you've probably seen the "shimmer" effect caused by erroneous depth buffering of the polygon vs the outline. There are several solutions. The polygon offset extension, standard in OpenGL 1.1, is one. A slightly more complex solution is to use stenciling as described in the OpenGL Programming Guide.
Be sure no errors are being generated
Use glGetError() inside your rendering/event loop to catch errors. With Mesa, set the MESA_DEBUG environment variable.
Can I restrict SwapBuffers to a subregion of a window?
No. However, you may be able to use glCopyPixels to copy pixels from the back to front buffer or create subwindows for the regions you want swapped.
Depth testing isn't working
If you've called glEnable(GL_DEPTH_TEST) and depth testing still isn't happening be sure that you've requested a visual (GLX) or pixel format (WGL) which has a depth buffer. This is done by specifying the GLX_DEPTH_SIZE parameter to glxChooseVisual() or specifying a non-zero cDepthBits value in the PIXELFORMATDESCRIPTOR structure passed to ChoosePixelFormat().



Last edited on April 20, 1997 by Brian Paul.