Course 24: OpenGL and Window System Integration
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
- 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
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
glRasterPos() doesn't put the raster position at the window coordinate I
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
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 );
glMatrixMode( GL_MODELVIEW );
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 */
glMatrixMode( GL_PROJECTION );
- 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.
- If texture minification is happening and the GL_MIN_FILTER
is not GL_NEAREST or GL_LINEAR then you must have a
complete set of mipmaps defined.
If you don't it is as if texturing were disabled.
- Be sure your texture sizes are powers of two. Some
OpenGL implementations fail to generate an error for
- 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.
- Overall slow performance
Be sure a direct rendering context is being selected so that
graphics hardware is accessed directly.
- 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
- 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.
- 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
structure passed to
Last edited on April 20, 1997 by Brian Paul.