Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP's Implementation of OpenGL: HP 9000 Workstations > Chapter 6 Programming Hints

OpenGL Performance Hints

» 

Technical documentation

Complete book in PDF
» Feedback
Content starts here

 » Table of Contents

Hints provided in this section are intended to help improve your applications performance when using HP's implementation of OpenGL.

Display List Performance

The topics covered here are areas where you can gain substantial improvements in program performance when using OpenGL display lists. Here is a list of the topics that are covered:

  • Geometric Primitives

  • GL_COMPILE_AND_EXECUTE Mode

  • Textures

  • State Changes and their Effects on Display Lists

  • Regular Primitive Data

Geometric Primitives

Geometric primitives will typically be faster if put in a display list. As a general rule, larger primitives will be faster than smaller ones. Performance gains here can be dramatic. For example, it is possible that a single GL_TRIANGLES primitive with 20 or so triangles will render 3-times faster than 20 GL_TRIANGLES primitives with a single triangle in each one.

GL_COMPILE_AND_EXECUTE Mode

Due to the pre-processing of the display list, and execution performance enhancements, creating a display list using the GL_COMPILE_AND_EXECUTE mode will reduce program performance. If you need to improve your programs performance, do not create a display list using the GL_COMPILE_AND_EXECUTE mode. You will find that it is easier and faster to create the display list using the GL_COMPILE mode, and then execute the list after it is created.

Textures

If calls to glTexImage are put into a display list, they may be cached. Note that if you are going to use the same texture multiple times, you may gain better performance if you put the texture in a display list. Another solution would be to use texture objects. Since 3D textures can potentially become very large, they are not cached.

State Changes and Their Effects on Display Lists

If there are several state changes in a row, it is possible, in some circumstances, for the display list to optimize them.

It is more efficient to put a state change before a glBegin, than after it. For example, this is always more efficient:

glColor3f(1,2,3);
glBegin(GL_TRIANGLES);
glVertex3f(...);
...many more vertices...
glEnd();

than this:

glBegin(GL_TRIANGLES);
glColor3f(1,2,3);
glVertex3f(...);
...many more vertices...
glEnd();

Regular Primitive Data

If the vertex data that you give to a display list is regular (i.e. every vertex has the same data associated with it), it is possible for the display list to optimize the primitive much more effectively than if the data is not regular.

For example if you wanted to give only a single normal for each face in a GL_TRIANGLES primitive, the most intuitive way to get the best performance would look like this:

glBegin(GL_TRIANGLES);
glNormal3fv(&v);
glVertex3fv(&p1); glVertex3fv(&p2); glVertex3fv(&p3);
glNormal3fv(&v);
glVertex3fv(&p1); glVertex3fv(&p2); glVertex3fv(&p3);
...
glEnd();

In immediate mode, this would give you the best performance. However, if you are putting these calls into a display list, you will get much better performance by duplicating the normal for each vertex, thereby giving regular data to the display list:

glBegin(GL_TRIANGLES);
glNormal3fv(&v); glVertex3fv(&p1);
glNormal3fv(&v); glVertex3fv(&p2);
glNormal3fv(&v); glVertex3fv(&p3);
...
glEnd();

The reason this is faster is the display list can optimize this type of primitive into a single, very efficient structure. The small cost of adding extra data is offset by this optimization.

Texture Downloading Performance

This section includes some helpful hints for improving the performance of your program when downloading textures.

  • If you are downloading MIP maps, always begin with the base level (level 0) first.

  • If it is possible, you should use texture objects to store and bind textures.

  • If you are doing dynamic downloading of texture maps, you will get better performance by replacing the current texture with a texture of the same width, height, border size, and format. This should be done instead of deleting the old texture and creating a new one.

Selection Performance

To increase the performance of selection (glRenderMode GL_SELECTION) it is recommended that the following capabilities be disabled before entering the selection mode.

GL_TEXTURE_*
GL_TEXTURE_GEN_*
GL_FOG
GL_LIGHTING

State Change

OpenGL state setting commands can be classified into to two different categories. The first category is vertex-data commands. These are the calls that can occur between a glBegin/glEnd pair:

glVertex
glColor
glIndex
glNormal
glEdgeFlag
glMaterial
glTexCoord

The processing of these calls is very fast. Restructuring a program to eliminate some vertex data commands will not significantly improve performance.

The second category is modal state-setting commands, or sometimes referred to as "mode changes." These are the commands that:

  • Turn on/off capabilities,

  • Change attribute settings for capabilities,

  • Define lights,

  • Change matrices, etc.

These calls cannot occur between a glBegin/glEnd pair. Examples of such commands are:

glEnable(GL_LIGHTING);
glFogf(GL_FOG_MODE, GL_LINEAR);
glLightf(..);
glLoadMatrixf(..);

Changes to the modal state are significantly more expensive to process than simple vertex-data commands. Also, application performance can be optimized by grouping modal state changes, and by minimizing the number of modal state changes:

  • Grouping your state changes together (that is, several modal state changes at one time), and then rendering primitives, will provide better performance than doing the modal state changes one by one and intermixing them with primitives.

  • Grouping primitives that require the same modal state together to minimize modal state changes. For example, if only part of a scene's primitives are lighted, draw all the lighted primitives, then turn off lighting and draw all the unlighted primitives, rather than enabling/disabling lighting many times.

Lighting Space

OpenGL specifies that lighting operations should be done in Eye Coordinte space. However, if the model-view matrix is isotropic, equivalent lighting calculations can be performed in Object Coordinate space, by transforming stored light positions to Object Coordinates. If there are many vertices between model-view matrix changes, Object-Coordinate space lighting is faster than Eye Coordinate space lighting since the transformation of vertices and normals from Object- to Eye Coordinates can be skipped.

Whether or not Object Coordinate lighting is faster than Eye Coordinate lighting depends on the command mode (immediate mode vs. execution of a display list or vertex array) as well as the number of vertices between model-view matrix changes.

The selection of a lighting space occurs at the start of the next primitive (glBegin or vertex array) after any GL calls that could affect the choice of lighting space. The choice of lighting space can be affected by those GL calls that:

  • Change Object Coordinates to Eye Coordinates (model-view matrix)

  • Turn on/off fog

  • Turn on/off generation of spherical texture coordinates.

If the model-view matrix is anisotropic, lighting must be done in Eye Coordinates. Lighting will also be done in Eye Coordinates when fogging and spherical-texture-coordinate generation are done in Eye Coordinates.

If none of the above conditions which force Eye Coordinate lighting are true, then HP's implementation of OpenGL chooses the lighting space depending on how OpenGL commands are being executed at the time a choice must be made. If commands are being executed in immediate mode, eye space lighting is chosen. If commands are being executed from a display list or if a vertex array is being executed, object space lighting is chosen.

Eye-space lighting works well when commands are executed in immediate mode, and object-space lighting works well when:

  • There are many (8 or more) vertices between changes to light definitions or to the model-view matrix.

  • A display list or vertex array is used.

You can override the above lighting space selection rules by setting the environment variable HPOGL_LIGHTING_SPACE. To set this environment variable, execute the following command:

export HPOGL_LIGHTING_SPACE=EC

when any of the following are true:

  • The application uses display lists or vertex arrays, but makes frequent changes to the model-view matrix or to light definitions (using glLight).

  • The application uses display lists or vertex arrays, but frequently turns fogging or spherical-texture-coordinate generation on/off.

  • The application uses 4D data (for example, vertices, light positions) and the w values are near the floating point limits. See the section below on 4D values for more information.

It is appropriate to use

export HPOGL_LIGHTING_SPACE=OC

when:

  • There are many (eight or more) vertices between light changes or model-view matrix changes.

  • Display lists or vertex arrays are used extensively.

and any of the following are true:

  • There is a lot of switching between immediate mode and display-list execution (or vertex arrays) while lighting is on, and intermixed with state changes that affect choice of lighting space (these were listed above).

  • Display lists are used predominantly, but the first glBegin after commands that affect choice of lighting space (which were listed above) is an immediate mode command.

    For example, in a scenario like the following:

       (Load a model View Matrix)
    (Define lights)
    (Enable lights and lighting)

    glBegin(..); /* Some simple immediate-mode rendering.
    Lighting space gets chosen at this point.*/
    ...
    glEnd();

    (Execution of many display lists or vertex arrays, with no changes to the model-view matrix or light definitions)

    Here the default lighting space chosen at the time of the first glBegin is eye-space lighting. The display lists could have benefited from setting HPOGL_LIGHTING_SPACE=OC.

When tuning an application, first use just the default lighting-space selection (do not set HPOGL_LIGHTING_SPACE). If the application matches the conditions listed above that indicate the need for setting HPOGL_LIGHTING_SPACE, then experiment with setting the environment variable.

Optimization of Lighting

HP's implementation of OpenGL optimizes the lighting case such that the performance degradation from one light to two or more lights is linear. Lighting performance does not degrade noticeably when you enable a second light. In addition, the GL_SHININESS material parameter is not particularly expensive to change.

Occlusion Culling

The proper use of HP's occlusion culling extension can dramatically improve rendering performance. This extension defines a mechanism for determining the non-visibility of complex geometry based on the non-visibility of a bounding geometry. This feature can greatly reduce the amount of geometry processing and rendering required by an application, thereby, increasing the applications performance. For more information on occlusion culling, see the section "Occlusion Extension" found in Chapter 1.

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 1996 Hewlett-Packard Development Company, L.P.