The opviewer application illustrates the basic structure of an OpenGL Optimizer opViewer application. It is a working application that allows you to use OpenGL Optimizer rendering tools to manipulate complex models. Figure C-1 shows a model rendered by opviewer.
This appendix presents comments and lines of code essentially the same as that of /usr/share/Optimizer/src/sample/opviewer/main.cxx, briefly highlights OpenGL Optimizer features, and refers to detailed discussions that appear in this guide.
| Note: The code presented here may not be exactly the same as the code that ships with OpenGL Optimizer, because of late changes. |
The rest of this chapter is a running commentary on the code in main.cxx.
The following features are not implemented in opviewer:
Explicit mention of tools for tuning the scene-graph database, which are discussed in Part II, “High-Level Strategic Tools for Fast Rendering”
Multiprocessing tools, which are discussed in Chapter 14, “Managing Multiple Processors”
| Note: The opoptimize sample applications contains many of these features. |
Use the versions command to verify that you have installed the following software:
optimizer_eoe
optimizer_dev
cosmo3D_eoe
cosmo3D_dev
For example, to verify optimizer_dev is installed, use the following command:
% versions | grep optimizer_dev |
Install any of these packages if they are missing.
To compile opviewer, enter the command make while in the directory /usr/share/Optimizer/src/sample/opviewer. To list command-line options, invoke the application without options.
To print a list of interactive program controls into your command shell while you run opviewer, place the mouse cursor in the rendering window and enter the h key.
|
| |
In addition to the standard library, opviewer requires two base classes from the Cosmo 3D library, and header files from OpenGL Optimizer. |
| #include <stdio.h>
#include <Cosmo 3D/csFields.h> #include <Cosmo3D/csGroup.h> |
You can set all csAppearances of the csShapes to minimize mode switching. See “Avoiding OpenGL Mode Switching”. |
| #include <Optimizer/opAppStats.h> |
These two headers include the OpenGL Optimizer command-line argument parser, which is discussed in the section “Command-Line Parser: opArgParser”; and the file loading class, discussed in “Saving and Loading Scene-Graph Files”. |
|
#include <Optimizer/opArgs.h> #include <Optimizer/opGenLoader.h> |
This header includes the basic graphics acceleration tools, most of which are discussed in Chapter 3, “Sending Efficient Graphics Data to the Hardware.” |
|
#include <Optimizer/opGFXSpeed.h>
|
The library initialization class is discussed in “Calling opInit()”. |
| #include <Optimizer/opInit.h> |
The basic control of interactive rendering, including the control of occlusion culling or the ability to manipulate selected portions of the scene graph is provided by the classes in these files. These tools are discussed in “Rendering With View-Frustum and Occlusion Culling: opOccDrawImpl”, and “Interacting With a Rendered Object: opPickDrawImpl”. |
|
#include <Optimizer/opOccDrawImpl.h> #include <Optimizer/opPickDrawImpl.h> |
OpenGL Optimizer provides several tools for reflection mapping, discussed in Chapter 8, “Efficient High-Quality Lighting Effects: Reflection Mapping.” |
|
#include <Optimizer/opReflMap.h> |
Inclusions (cont.) |
|
|
Traversal tools are discussed in Chapter 12, “Traversing a Large Scene Graph.” |
|
#include <Optimizer/opTraverse.h> |
You can collect statistics about the number of vertices, triangles, and connected primitives in your scene graph. See “Gathering Triangle Statistics”. |
|
#include <Optimizer/opTriStats.h> |
The next file holds the basic rendering class opViewer, discussed in “Viewing Class: opViewer”. |
|
#include <Optimizer/opViewer.h>
|
|
| |
The tessellators convert abstract geometry into renderable collections of vertices: see “Tessellating Parametric Surfaces”. |
| #include <Optimizer/opTessParaSurfaceAction.h> #include <Optimizer/opTessNurbSurfaceAction.h> |
To guarantee consistent tessellation between adjacent surfaces, that is, rendered surfaces without cracks, OpenGL Optimizer provides topology maintenance tools. See Chapter 10, “Creating and Maintaining Surface Topology.” |
|
#include <Optimizer/opTopo.h> |
You have three ways to develop surface connectivity information. The argument list is from best to worst. See Chapter 10, “Creating and Maintaining Surface Topology.” |
|
enum topologyOption {TOPO_TWO_PASS, TOPO_ONE_PASS, TOPO_NO}; |
|
|
int main(int argc, char *argv[]) { |
See “Calling opInit()”. |
|
opInit(); |
Command-Line Control Parameters |
|
|
The command-line control parameters are read using the methods in the class opArgParser (see “Command-Line Parser: opArgParser”). The command-line parameters set switches that allow you to control these features: |
| opArgParser args; |
Command-Line Control Parameters (cont.) |
|
|
The location on the screen (x, y) of the rendering window, and the dimensions of the window (w,h). The x-coordinate assumes a screen of width 1280, and a rendering window of width 600 with a 10-pixel boundary. |
| bool haveX=-1, haveY=-1, haveW=-1,
|
OpenGL display lists. See “Display Lists”. |
| bool haveDL; |
|
|
bool haveFrameCount; |
Print the scene graph. See “Printing a Scene Graph”. |
| bool havePrint; |
Flatten the scene graph, that is, place all leaf nodes directly under one group node. See “Methods in opCollapseAppearances”. |
|
bool haveFlatten; |
Use short representations of surface normal data. See “Vertex Arrays”. |
|
bool haveShortNorms; |
Introduce complex lighting effects with reflection (or environment) maps. See Chapter 8, “Efficient High-Quality Lighting Effects: Reflection Mapping.” |
|
bool haveReflMap; |
Set a bias for level-of-detail calculations when the scene is moving. This feature of opViewer is discussed in “Viewing Class: opViewer”. |
| bool haveLODbias; |
Specify the hint for maximum deviations of a tessellation from the exact surface representation. See “Tessellating Parametric Surfaces”. |
|
bool haveChordalTol = -1; |
Specify the threshold distance between points below which they are considered identical when building topology. See “Summary of Scene Graph Topology: opTopo”. |
|
bool haveTopoTol; |
Command-Line Control Parameters (cont.) |
|
|
Specify the background color for the rendering window and the model orientation. These settings are controlled by opViewer options. See “Viewing Class: opViewer”. |
| bool haveBackgroundColor; |
Specify the number of vertices in the tessellation of surface boundaries. See “opTessParaSurfaceAction”. |
|
bool haveSamples; |
Specify the type of tessellator: a generic parametric surface tessellator or a NURBS surface tessellator. See “Tessellating Parametric Surfaces”. |
|
bool haveTessType = -1; |
Specify rendering features: occlusion culling (see “Occlusion Culling”) or interactive manipulation (see Chapter 7, “Interactive Highlighting and Manipulating”). |
| // --- Draw impl options |
Play back the scene. See “Rendering With View-Frustum and Occlusion Culling: opOccDrawImpl” |
| // Option to playback recordings |
Control OpenGL mode switching by clamping the first csAppearance encountered in the draw traversal to all subsequent csShapes. See “Avoiding OpenGL Mode Switching”. |
| bool haveOneAppearance; |
By default, build the best topology. See Chapter 10, “Creating and Maintaining Surface Topology.” |
| bool isOnePass = false; |
Get Command-Line Parameters |
|
|
You must supply a file with the scene graph. All other command-line control parameters are optional and were described with the argument declarations. See “Command-Line Parser: opArgParser”. |
| args.defRequired( “%s”,
args.defOption( “-width %d”, args.defOption( “-height %d”, args.defOption( “-size %d”, args.defOption( “-xpos %d”, args.defOption( “-ypos %d”, args.defOption( “-useDL”, args.defOption( “-frames %d”, args.defOption( “-print”, |
Get Command-Line Parameters (cont.) |
|
args.defOption( “-shortNorms”, args.defOption( “-reflmap %s”, args.defOption( “-ceilingmap %s”, args.defOption( “-cylindermap”, args.defOption( “-gaussianmap”, args.defOption( “-occ %d”, args.defOption( “-nopick”, args.defOption( “-lodBias %d”, args.defOption( “-noColors”, args.defOption( “-path %s”, |
Get Command-Line Parameters (cont.) |
| args.defOption( “-autoplay”, #ifdef OP_REAL_IS_DOUBLE args.defOption( “-ttol %l”, #else args.defOption( “-ctol %f”, args.defOption( “-ttol %f”, args.defOption( “-oneAppearance”, args.defOption( “-ceilingmap %s”, args.defOption( “-tess %s”, |
Get Command-Line Parameters (cont.) |
| // User defined background color |
Establish Status Information |
| // Print out version of Optimizer //set topoOption if (!haveTopoTol) numFiles = args.scanArgs(argc,argv); if (haveSize)h = w; |
Create the Appropriate Tessellator See Chapter 11, “Rendering Higher-Order Primitives: Tessellators.” |
| // Create a tessellator if ( tessType == NULL ) // Set the chordal tolerance // Set the sample count if the user set them |
Create the Topology Data StructuresSee Chapter 10, “Creating and Maintaining Surface Topology.” |
| //topology // Set the topology parameters topo->setDistanceTol( topoTol, meter ); |
Load the Scene Graph Data |
|
|
The loader manages topology in one of the following ways: It anticipates the development of connectivity information for all surfaces in the scene graph followed by tessellating the surface. Code for these steps appears later in the application. It develops connectivity information as surfaces load, and tessellates them. It ignores connectivity: it simply tessellates surfaces as they load without regard for adjacencies. See“Saving and Loading Scene-Graph Files”; Chapter 10, “Creating and Maintaining Surface Topology”; and “Base Class opTessellateAction”. |
| // Create a loader } // Load the file on the command line and get a
// scene graph back |
Load the Scene Graph Data (cont.)If there are several files making up the scene graph, place them under a csGroup node.
|
| if (numFiles) for (i=0;i<numFiles;i++) |
Build Topology and Tessellate |
|
|
The most accurate topology, which yields crack-free tessellations, is created by two traversals of the scene graph: one to establish adjacencies of surfaces, and the second to tessellate the surfaces (this is the default behavior). See “Building Topology: Computing and Using Connectivity Information”. |
| // Build topology if we haven't done it and the
// user asks for it fprintf(stderr, “Building topology starts ...
\n”); fprintf(stderr, “Tessellation starts ... \n”); delete tess; |
Set Parameters to Draw the Scene |
|
|
| // If the scene graph was loaded successfully,
draw it else end the program | |
| // Get stats on the scene graph | |
| if (haveOneAppearance) if (removeColors) | |
| // Optionally flatten the scene graph | |
See “Vertex Arrays”. |
| if (haveShortNorms) |
| // Note: viewer must be created before
// opDListScene. | |
Set the background color. See “Viewing Class: opViewer”. |
| if ( haveBackgroundColor ) |
Set the bias for LOD calculations color. See “Viewing Class: opViewer”. |
| // Set the LOD bias |
Set Parameters to Draw the Scene (cont.) |
|
|
See “Controlling Rendering: opKeyCallback and opDrawImpl”; “Rendering With View-Frustum and Occlusion Culling: opOccDrawImpl”; and “Interacting With a Rendered Object: opPickDrawImpl”. |
| // Make Occ draw object the default. if (havePath)
occDrawImpl->loadRecording(pathFile); opPickDrawImpl *pi = NULL; |
| if (havePrint) opPrintScene(obj); | |
See “Viewing Class: opViewer” on page 9.
|
|
viewer->addChild(obj); | ||
Set Parameters to Draw the Scene (cont.) |
|
|
See Chapter 8, “Efficient High-Quality Lighting Effects: Reflection Mapping.” |
| // A new reflection map
// --- picker needs refl map for highlighting // (could be passed into constructor also) if (pi != NULL) pi->setReflMap( rm ); |
See “Display Lists”. |
| // Build display lists |
Set Parameters to Draw the Scene (cont.) |
|
|
Set orientation of model, if specified. See “Viewing Class: opViewer”. |
| if ( haveRotation ) |
Draw the Scene |
| if (haveFrameCount) } |