24 Miscellaneous

24.010 How can I render a wireframe scene with hidden lines removed?

The preferred method is to render your geometry in two passes: first in fill mode with color set to the background color, and again in line mode. Use polygon offset so the lines over the polygons render correctly. The polygon offset section may be helpful to you.

Often you need to preserve a nonuniform background, such as a gradient fill or an image. In this case, do the fill pass with glColorMask() set to all GL_FALSE, then perform the line pass as usual. Again, use polygon offset to minimize Z fighting.

24.020 How can I render rubber-band lines?

See this question in the Rasterization section.

24.030 My init code calls glGetString() to find information about the OpenGL implementation, but why doesn't it return a string?

The most likely cause of this problem is that a context hasn't been made current. An OpenGL rendering context must exist and be made current to a window for any OpenGL calls to function and return meaningful values.

24.039 Where can I find 3D model files?

As this has little to do with OpenGL, what follows is by no means an exhaustive list:

http://www.3dfiles.com/
http://www.3dcafe.org/
http://www.saturn-online.de/~cosmo/
http://www.swma.net/

You can make your own 3D models using any package you desire, and then loading the geometry file. ModelMagic3D is shareware and comes with source code. GLScene is also available.

24.040 How can I load geometry files, such as 3DS, OBJ, DEM, etc. and render them with OpenGL?

OpenGL, being a 3D graphics API, has no built-in support for reading application-specific file formats. If you're writing an application that needs to read a specific file type, you'll need to add code to support a particular file type.

Many OpenGL users already have written code to do this, and in some cases, the code is available on the Web. A few are listed here. If you can't find what you are looking for, you might try doing a Web search.

Crossroads can import many file formats and output the data as C/C++ compilable data that is suitable for use with vertex arrays.

This file format information covers a variety of different file formats.

3DWinOGL is shareware that reads in any file format and returns OpenGL primitive data.

If you're using 3D Studio MAX, you should see an export format called ASE, which is ASCII (i.e., large file sizes), but is very easy to parse.

Download the GLUT source distribution and look in progs/demos/smooth. The file glm.c contains routines for reading in Wavefront OBJ files.

glElite reads DXF, ASCII, and LightWave files. Information on glElite can be found at the following addresses: http://www.helsinki.fi/~tksuoran/lw.html and http://www.cs.helsinki.fi/~tksuoran/glelite/.

3D Exploration imports and exports several different file formats, including exporting to C/C++ source.

A 3DS import library in Delphi designed for use with OpenGL can be found here.

24.050 How can I save my OpenGL rendering as an image file, such as GIF, TIF, JPG, BMP, etc.?

The easiest method is to use any of a number of image utilities that let you capture the screen or window, and save it is a file.

To accomplish this programmatically, you read your image with glReadPixels(), and use the image data as input to a routine that creates image files.

This file format information covers a variety of different file formats.

The Independent JPEG Group has a free library for reading and writing JPEG files.

The gd library lets you create JPG and PNG files from within your program.

Imlib is a wrapper library that allows a program to write out JPEG, GIF, PNG, and TIFF files.

An image loader library in Delphi can be found here.

24.060 Can I use a BSP tree with OpenGL?

BSP trees can be useful in OpenGL applications.

OpenGL applications typically use the depth test to perform hidden surface removal. However, depending on your application and the nature of your geometry database, a BSP tree can enhance performance when used in conjunction with the depth test or when used in place of the depth test.

BSP trees also may be used to cull non-visible geometry from the database.

When rendering translucent primitives with blending enabled, BSP trees provide an excellent sorting method to ensure back-to-front rendering.

More information on BSP trees can be found at the BSP FAQ.

24.070 Can I use an octree with OpenGL?

Yes. Nothing in OpenGL prevents you from using an octree. An octree is especially helpful when used in conjunction with occlusion culling extensions (such as HP's GL_HP_occlusion_test).

24.080 Can I do radiosity with OpenGL?

OpenGL doesn't contain any direct support for radiosity, it doesn't prevent you from displaying a database containing precomputed radiosity values.

An application needs to perform its own radiosity iterations over the database to be displayed. After sufficient color values are computed at each vertex, the application renders the database as normal OpenGL primitives, specifying the computed color at each vertex. glShadeModel() should be set to GL_SMOOTH and lighting should be disabled.

24.090 Can I raytrace with OpenGL?

OpenGL contains no direct support for raytracing.

You might want to use raytracing to produce realistic shadows and reflections. However, you can simulate in many ways these effects in OpenGL without raytracing. See the section on shadows or the section on texture mapping for some algorithms.

You can use OpenGL as part of the ray intersection test. For example, a scene can be rendered with a unique color assigned to each primitive in the scene. This color can be read back to determine the primitive intersected by a ray at a given pixel. If the exact geometry is used in this algorithm, some aliasing may result. To reduce these aliasing artifacts, you can render bounding volumes instead.

Also, by changing the viewpoint and view direction, you can use this algorithm for intersection testing of secondary rays.

A ray tracing application might also use OpenGL for displaying the final image. In this case, the application is responsible for computing the color value of each pixel. The pixels then can be rendered as individual GL_POINTS primitives or stored in an array and displayed via a call to glDrawPixels().

24.100 How can I perform CSG with OpenGL?

The Opengl Programming Guide, Third Edition, describes some techniques for displaying the results of CSG operations on geometric data.

The GLUT 3.7 distribution contains an example program called csg.c that may be informative.

24.110 How can I perform collision detection with OpenGL?

OpenGL contains no direct support for collision detection. Your application needs to perform this operation itself.

OpenGL can be used to evaluate potential collisions the same way it can evaluate ray intersections (i.e., the scene is rendered from the object's point of view, looking in the direction of motion, with an orthographic projection and a field-of-view restricted to the object's bounding rectangle.) Visible primitives are potential collision candidates. You can examine their Z values to determine range.

There's a free library for collision detection called I_COLLIDE available that you might find useful.

24.120 I understand OpenGL might cache commands in an internal buffer. Can I perform an abort operation, so these buffers are simply emptied instead of executed?

No. After you issue OpenGL commands, inevitably they'll be executed.

24.130 What's the difference between glFlush() and glFinish() and why would I want to use these routines?

The OpenGL spec allows an implementation to store commands and data in buffers, which are awaiting execution. glFlush() causes these buffers to be emptied and executed. Thus, any pending rendering commands will be executed, but glFlush() may return before their execution is complete. glFinish() instructs an implementation to not return until the effects of all commands are executed and updated.

A typical use of glFlush() might be to ensure rendering commands are exected when rendering to the front buffer.

glFinish() might be particularly useful if an app draws using both OpenGL and the window system's drawing commands. Such an application would first draw OpenGL, then call glFinish() before proceeding to issue the window system's drawing commands.

24.140 How can I print with OpenGL?

OpenGL currently provides no services for printing. The OpenGL ARB has discussed a GLS stream protocol, which would enable a more common interface for printing, but for now, printing is only accomplished by system-specific means.

On a Microsoft Windows platform, ALT-PrintScreen copies the active window to the clipboard. (To copy the entire screen, make the desktop active by clicking on it, then use ALT-PrintScreen.) Then you can paste the contents of the clipboard to any 2D image processing software, such as Microsoft Paint, and print from there.

You can capture an OpenGL rendering with any common 2D image processing packages that provide a screen or window capture utility, and print from there.

Also, can print programatically using any method available on your platform. For example in Microsoft Windows, you might use glReadPixels() to read your window, write the pixel data to a DIB, and submit the DIB for printing.

24.150 Can I capture or log the OpenGL calls an application makes?

IBM has a product called ZAPdb which does this. It ships with many UNIX implementations, including IBM and HP. It was available on Windows NT in the past, but its current status is unknown. A non-IBM web page appears to have ZAPdb available for download.

There's a free utility called GLTrace2, which appears to contain similar functionality to ZAPdb. More info on GLTrace2 can be found here.

In theory, you could code a simple library that contains OpenGL function entry points, and logs function calls and parameters passed. Name this library opengl32.dll and store it in your Windows system folder (first, be careful to save the existing opengl32.dll). This shouldn't be a difficult programming task, but it might be tedious and time consuming. This solution is not limited to Microsoft Windows; using the appropriate library name, you can code this capture utility on any platform, provided your application is linked with a dynamically loadable library.

24.160 How can I render red-blue stereo pairs?

  1. glColorMask (GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE)
  2. Assuming the red image is the left image, set the projection and model-view matrices for the left image.
  3. Clear color and depth buffers, and render the left image.
  4. glColorMask (GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE)
  5. Set the projection and model-view matrices for the right image.
  6. Clear color and depth buffers and render the right image.
  7. Swap buffers.

There is a GLUT 3.7 demo that shows how to do this.