IRIX 6.5 » Books » Developer »
OpenGL Optimizer Programmer's Guide: An Open API for Large-Model Visualization
(document number: 007-2852-002 / published: 1998-06-09)
table of contents | additional info | download find in page
Chapter 11. Rendering Higher-Order Primitives: Tessellators
To render a shape, you must develop an approximation of it constructed of a collection of like primitives, typically csTriFans or csTriStrips. The tool that translates a shape into a mesh of contiguous triangles is called a tessellator.
Tessellation is interpretive; there is necessarily a difference between the original surface and the tessellated mesh. You can control how closely you want the mesh to resemble the surface.
Close resemblance, requiring many triangles, produces a realistic shape but incurs slow graphic processing.
A gross approximation of the original surface results in fast processing.
Applications often create a series of tessellated representations of a shape, each one called a level of detail (LOD). High resolution LODs are used when shapes are close to the viewer and low resolution LODs are used when shapes are far from the viewer. Because distance obscures detail, high resolution LODs are not necessary to represent distant shapes.
This chapter describes how to control the tessellation of shapes in the following sections:
Tessellators generate a sequence of straight-line segments to approximate an edge curve of a surface, then cover the surface with triangular tiles. With each triangle vertex it creates, a tessellator also stores the normal vector at the point from original surface. The normal vectors are necessary for lighting and shading calculations.
Tessellations necessarily burden the entire graphics pipeline; they provide a first definition of the rendering task by specifying a maximal set of vertices to be sent to the graphics hardware. You can redefine and simplify the rendering task by using the tools discussed in Part II, “High-Level Strategic Tools for Fast Rendering.”
Tessellators for Varying Levels of Detail
Ideally you would quickly generate the simplest tessellation that adequately represents surfaces of interest. What is adequate depends on your particular rendering task. You may want to generate several tessellations with varying degrees of complexity and accuracy for one opRep and place them in level-of-detail nodes, as discussed in Chapter 4, “Rendering Appropriate Levels of Detail.” The tessellators include accessor functions to help you assess the load they create for the graphics hardware.
The control parameter for tessellations specifies the maximum deviation from the exact surface. Figure 11-2 illustrates the effects of varying the deviation. The upper left image is appropriate for accurate representation of the surface, the lower right image would be appropriate if the object were in the distant background of a scene.
The surface shown in Figure 11-2 was made with the repTest application using an opFrenetSweptSurface as follows (see “opFrenetSweptSurface” and “Rendering Higher Order Reps—repTest”):
opReal profile( opReal t ) { return 0.5*cos(t*6.0) + 1.25; };
opSuperQuadCurve3d *cross =
new opSuperQuadCurve3d( 0.75, new opVec3(0.0, 0.0, 0.0), 3.0 );
opCircle3d *path = new opCircle3d( 1.75, new opVec3(0.0, 0.0, 0.0) );
opFrenetSweptSurface *fswept =
new opFrenetSweptSurface( cross, path, profile );
fswept->setHandednessHint( true );
|
The number of triangles in Figure 11-2 decreases as the maximum-deviation parameter chordalDevTol varies from .001 to .01 to .1 to .5 (see “Tessellating Parametric Surfaces”). These numbers should be compared to the scale of the object, which has a maximum diameter of 6.125 = 2(1.75 + 1.75 × .75), a minimum diameter of .875 = 2(1.75 - 1.75 × .75), a maximum height of 2.625 = 2(1.75 × .75), and a minimum height of 1.125 = 2(.75 × .75).
Tessellators Act on a Whole Graph or Single Node
You can apply a tessellator either to a scene graph or to just one node. The tessellators produce a csGeoSet from an opRep and place that csGeoSet in the csShape that holds the opRep.
Tessellators and Topology: Managing Cracks
A tessellation begins with a discrete set of vertices at surface edges. To prevent cracks from appearing between adjacent surfaces, the same set of vertices should be used to tessellate both surfaces.
To address the crack problem, you have several options, which are discussed in “Building Topology: Computing and Using Connectivity Information”. Table 10-1 lists the different approaches to topology building, and the methods to use for each.
Base Class opTessellateAction
The important methods of opTessellateAction are apply() and mpApply(), which tessellate all opReps below the csNode that is their only argument. They perform single-process (apply()) or multiple-process (mpApply()) traversal of the scene graph. If the csNode is a csShape holding an opRep, then only that opRep is tessellated. If you supply a csNode argument that is inappropriate for a particular opTessellateAction subclass, nothing happens.
Subclasses of opTessellateAction, which are described in the subsequent sections of this chapter, provide tessellators for specific opReps. Each subclass has a pair of public functions, tessellate() and tessellator(), which implement a tessellation for a specific opRep. Although these functions are public, you should not need them if you use any OpenGL Optimizer opTessellateAction; call one of the apply functions, apply() or mpApply(), to tessellate.
Tessellating a Scene Graph With Several Tessellators
If you create several subclasses of opTessellateAction and call opTessellateAction::apply(), then for each surface encountered during the tessellation traversal, the algorithm used to perform the tessellation is that of the most derived instance of opTessellateAction that is appropriate for the surface. Thus, a call to the base class method will do the right thing for each opParaSurface, if you create instances of subclasses that provide the algorithms for doing so.
Retessellating a Scene Graph
A tessellator won't tessellate an opRep if getGeometryCount is not zero. If you want to retessellate an opRep, you must call clearTessellation() for opParaSurface and call removeGeometry() for opCurve2d or opCurve3d. See the example in /Optimizer/src/apps/removetess/main.cxx for details.
Class Declaration for opTessellateAction
The class has the following main methods:
class opTessellateAction : public csDispatch
{
public:
// Creating and destroying
opTessellateAction( void );
~opTessellateAction( void );
// Accessor functions
void setExtSize( int s );
int getExtSize( )
int getTriangleCount()
int getTriStripCount()
int getTriFanCount()
void setReverseTrimLoop( opBool enable )
opBool getReverseTrimLoop()
void setBuildTopoWhileTess(opBool _buildTopoWhileTess)
opBool getBuildTopoWhileTess()
void setTopo(opTopo * _topo)
opTopo *getTopo( void )
// Recursive action application
void apply ( csNode *node );
void mpApply( csNode *node );
};
|
Methods in opTessellateAction
| apply() and mpApply() | |
Tessellate all opReps in a scene graph using a single-process or multi-process traversal, respectively. Subclasses of opTessellateAction define specific tessellation algorithms.
| | getTriangleCount() | |
Returns the number of all triangles generated by this instance of the tessellator.
| | getTriStripCount() and getTriFanCount() | |
Return the number of tristrips or trifans in the tessellation.
| | setBuildTopoWhileTess() and getBuildTopoWhileTess() | |
Sets a flag whether surface connectivity is computed during the tessellation traversal. Set the topology data structure to use with setTopo().
If TRUE, before tessellating each surface, the connectivity of all previously tessellated surfaces is used to avoid cracks when tessellating. Notice that the final tessellations of the surfaces in the scene graph may still have cracks because of unforeseen junctions between surfaces.
If FALSE, no topology is constructed while tessellating. This leads to two very different possible results:
If topology information for the surfaces to be tessellated was developed before the tessellation, by calling opTopo::buildTopologyTraverse() or opTopo::buildTopology() or by constructing topology by hand, the tessellator uses the information and avoids cracks between surfaces. This option provides the most crack-free tessellations possible.
If topology information was not developed before the tessellation traversal, then surfaces are tessellated without regard to connectivity and cracks appear between all adjacent surfaces. This option provides the least crack-free tessellations possible.
| | setExtSize() and getExtSize() | |
Set and return an estimate of how many surfaces you expect to tessellate and thus allocate contiguous space in memory for opDvectors that hold the tessellation csGeoSet, a list of vertices, and a list of normals.
| | setReverseTrimLoop() and getReverseTrimLoop() | |
Set and recover the orientation of trim loops. Recall that the side of the surface to the left of the trim loop is rendered (see the section “Parametric Surfaces”).
| | setTopo() and getTopo() | |
Set and get the opTopo that holds the topology information used by the tessellator (see “Summary of Scene Graph Topology: opTopo”).
|
Tessellating Curves in Space
The class opTessCurve3dAction provides methods to develop a discrete approximation to an opCurve3d.
Class Declaration for opTessCurve3dAction
The class has the following main methods:
class OP_DLLEXPORT opTessCurve3dAction : public opTessellateAction
{
public:
// Creating and destroying
opTessCurve3dAction( );
opTessCurve3dAction( opReal chordalDevTol,
opBool scaleTolByCurvature,
int samples );
~opTessCurve3dAction();
// Accessor functions
void setChordalDevTol( const opReal chordalDevTol );
opReal getChordalDevTol( );
void setScaleTolByCurvature( const opReal scaleTolByCurvature );
opBool getScaleTolByCurvature( );
void setSampling( const int samples );
int getSampling( );
};
|
Methods in opTessCurve3dAction
| apply() and mpApply() | |
Are inherited from opTessellateAction. They tessellate individual opCurve3ds or all opCurve3ds in a scene graph using a single-process or multi-process traversal, respectively.
| | setChordalDevTol() and getChordalDevTol() | |
Set and get the maximum distance from the original surface to the edges produced by the tessellation.
| | setSampling() and getSampling() | |
Set and get the hint for the number of vertices in the tessellation.
| | setScaleTolByCurvature() and getScaleTolByCurvature() | |
Set and get a flag to control whether the chordal deviation parameter should be scaled by curvature. If non zero, the tessellation of highly curved portions of a curve improves.
|
Tessellating a Cuboid: opTessCuboidAction
The opTessCuboidAction class tessellates an opCuboid. opTessCuboidAction is a minimal example of a tessellator.
Class Declaration for opTessCuboidAction
The class has the following main methods:
class opTessCuboidAction : public opTessellateAction
{
public:
opTessCuboidAction( );
~opTessCuboidAction( );
// Tessellate action
static void tessellate( csDispatch *action, csObject *object);
// The actual cuboid tessellator
void tessellator( opCuboid &c);
};
|
Methods in opTessCuboidAction
| apply() and mpApply() | |
Are inherited from opTessellateAction. Tessellate individual opCuboids or all opCuboids in a scene graph using single-process or multi-process traversal.
|
The methods tessellate() and tessellator() occur for all subclasses of opTessellateAction; you will rarely need to use them (see “Base Class opTessellateAction” for more details about these functions).
Tessellating Parametric Surfaces
This section discusses the two classes OpenGL Optimizer provides for tessellating parametric surfaces. The class opTessParaSurfaceAction has methods for any parametric surface. The class opTessNurbSurfaceAction takes advantage of OpenGL NURBS routines.
The opTessParaSurfaceAction class develops tessellations of any opParaSurface. If a surface has boundary curves, the tessellator starts there and specifies vertices at the edges of the surface. The tessellator then covers the surface with csTriStripSets or csTriFanSets, using the boundary vertices to “pin” the edges of the tessellation. If necessary, the tessellator creates edge vertices by constructing a discrete version of the boundary curve associated with each of the surface's opEdges. An advantage of starting all tessellations at boundaries is easy coordination of tessellations by several processors.
As part of the tessellation process, you can generate the u-v coordinates for each vertex created by the tessellator.
To control the accuracy of a tessellation, you specify a chordal deviation parameter which constrains the distance of edges in the tessellation from the original surface.
Class Declaration for opTessParaSurfaceAction
The class has the following main methods:
class opTessParaSurfaceAction : public opTessellateAction
{
public:
opTessParaSurfaceAction();
opTessParaSurfaceAction( opReal chordalDevTol,
opBool scaleTolByCurvature, int samples);
~opTessParaSurfaceAction();
// Accessor functions
void setChordalDevTol( const opReal chordalDevTol );
opReal getChordalDevTol( );
void setScaleTolByCurvature( const opReal scaleTolByCurvature )
opBool getScaleTolByCurvature()
void setSampling( const int samples )
int getSampling( )
void setNonUniformSampling(const opBool samples);
opBool getNonUniformSampline();
void setGenUVCoordinates( const opBool genUVCoordinates );
opBool getGenUVCoordinates( );
opBool capUbegin;
opBool capUend;
opBool capVbegin;
opBool capVend;
};
|
Methods in opTessParaSurface
| apply() and mpApply() | |
Are inherited from opTessellateAction. Tessellate individual opParaSurfaces or all opParaSurfaces in a scene graph using single-process or multi-process traversal.
| | opTessParaSurface() | |
Creates the class and provides a hint for the maximum deviation of the tessellation from the original surface, indicates whether the tolerance should be scaled by curvature, and provides a hint for how many vertices to include in the tessellation.
| | setChordalDevTol() and getChordalDevTol() | |
Set and get the maximum distance from the original surface to the edges produced by the tessellation.
| | setGenUVCoordinates() and getGenUVCoordinates() | |
Set and get a flag that indicates whether to generate u-v coordinates for the vertices produced in the tessellation. The coordinates for each vertex are stored as the vertex's texture coordinates.
| | setSampling() and getSampling() | |
Set and get the hint for the number of triangle vertices in the tessellation along each boundary of the surface. If the surface has no trim curves defining its “outer” edges, then the sampling is along the edges of the u-v rectangle that parameterizes the surface.
| | setScaleTolByCurvature() and getScaleTolByCurvature() | |
Set and get a flag to control whether the chordal deviation parameter should be scaled by curvature. If non zero, the tessellation of highly curved areas improves.
| | capUbegin, capUend, capVbegin, capVend | |
Define a rectangular region in coordinate space and thus provide a simple method to restrict tessellation to a portion of the surface.
|
The methods tessellate() and tessellator(), which are not shown in the declaration above, occur for all subclasses of opTessellateAction; you will rarely need to use them (see “Base Class opTessellateAction” for more details about these functions).
Sample From repTest: Tessellating and Rendering a Sphere
The sample code in this section not only illustrates the main code elements for tessellating an opParaSurface but describes the steps in the rendering process. The lines of code perform the following procedures:
Submitting the scene graph to an opViewer. This is part of the main program loop.
Creating an instance of an opTessParaSurfaceAction.
Creating and tessellating an opSphere.
Developing the Cosmo3D scene-graph nodes.
The code in this section comes mainly from the functions main(), in the file /usr/share/Optimizer/src/apps/repTest/main.cxx, and makeShape() and makeObjects() in the file /usr/share/Optimizer/apps/repTest/repTest.cxx.
The opTessNurbSurfaceAction class tesselates surfaces using OpenGL NURBS utilities. As a result, the tessellation developed by opTessNurbSurfaceAction is well tuned for rendering. For more details about the OpenGL utilities, see the section “The GLU NURBS Interface” in Chapter 12 of the OpenGL Programming Guide, Second Edition.
The only member function of note is the constructor, which takes a chordal deviation parameter that has the same effect as that for opTessParaSurfaceAction.
Tessellating a Regular Mesh
To facilitate visualization of discrete data sets, OpenGL Optimizer provides four tessellators for various types of the template class opRegMesh. The tessellators accept opRegMeshType opConstant and opVariable. These are brief descriptions of the tessellation classes discussed in this section:
Visualizing Scalar-Valued Functions
| opTessIsoAction | |
Acts on a surface determined by a constant value of an opReal-valued function defined on a three-dimensional lattice. An opTessIsoAction takes an opRegMesh<opReal> and a value for the mesh function and returns a tessellation of the corresponding level surface, or iso-surface.
| | opTessSliceAction | |
Acts on planes that slice through a three-dimensional opRegMesh<opReal> and, according to a simple “rainbow” scheme, colors the values of the function at points that lie on the plane: red corresponds to the minimum value of the mesh function, and blue corresponds to the maximum value. The slicing planes are perpendicular to the x, y, or z axes.
|
Visualizing Vector-Valued Functions
The last two mesh tessellators return what are known as “hedgehog” plots of the vector fields. They are both trivial derivations of the base class opTessVecAction:
| opTessVec2dAction | |
Acts on a two-dimensional vector field defined on a two-dimensional grid. An opTessVec2d takes an opRegMesh<opVec2> and returns a set of arrows on the x-y plane.
| | opTessVec3dAction | |
Acts on a three-dimensional vector field defined on a three-dimensional grid. An opTessVec3d takes an opRegMesh<opVec3> and returns a set of arrows distributed in space.
|
The opTessIsoAction class interprets discrete versions of opReal-valued functions defined on three-dimensional space. That is, opTessIsoAction acts on an opRegMesh<opReal> and tessellates the mesh function's iso-surfaces.
Class Declaration for opTessIsoAction
The class has the following main methods:
class opTessIsoAction : public opTessellateAction
{
public:
// Creating and destroying
opTessIsoAction ();
opTessIsoAction (opReal threshold, int stride = 1);
~opTessIsoAction ();
// Accessor functions
void setThreshold (opReal thresh)
opReal getThreshold ()
void setStride (int _stride)
int getStride ()
};
|
Methods in opTessIsoAction
| apply() and mpApply() | |
Are inherited from opTessellateAction. They tessellate all opRegMesh<opReal>s in a scene graph using single-process or multi-process traversal.
| | opTessIsoAction() | |
The variable threshold specifies the value of the mesh function on the iso-surface. The variable stride specifies the sampling of the mesh by specifying how to increment the mesh indices. For example, a stride value of two takes every other point along the axes. The default value of threshold is 0 and of stride is 1.
|
The opTessSliceAction class interprets discrete versions of opReal-valued functions defined on three-dimensional space. That is, opTessSliceAction acts on an opRegMesh<opReal> and shows, by a simple rainbow map, values of the functions that lie on a plane. opTessSliceAction uses one of three possible planes perpendicular to the coordinate axes.
Class Declaration for opTessSliceAction
The class has the following main methods:
class opTessSliceAction : public opTessellateAction
{
public:
opTessSliceAction();
opTessSliceAction (opReal position, char axis);
~opTessSliceAction();
// Accessor functions
void setPosition (opReal _position)
opReal getPosition ()
void setAxis (int _axis)
char getAxis ()
};
|
Methods in opTessSliceAction
| apply() and mpApply() | |
Are inherited from opTessellateAction. They tessellate all opRegMesh<opReal>s in a scene graph using single-process or multi-process traversal.
| | opTessSliceAction(position, axis) | |
Sets the slice plane perpendicular to axis. Values for axis are x, y, or z. The position argument specifies the location of the slice plane: the point where axis intersects the plane. The default position is 0.0, and the default axis is the x axis.
| | setAxis() and getAxis() | |
Set and get the current slice axis.
| | setPosition() and getPosition() | |
Set and get the current slice position along the currently defined axis. The argument for setPosition() should be between zero and the mesh resolution in the direction of axis.
|
opTessVecAction is the base class for the tessellators that act on an opRegMesh<opVec2> or an opRegMesh<opVec3>. The latter are trivial derivations from an opTessVecAction.
Class Declaration for opTessVecAction
The class has the following main methods:
class opTessVecAction : public opTessellateAction
{
public:
opTessVecAction( );
~opTessVecAction( );
// --- Accessors
void setMagScale (opReal _scale)
void setInitialColor (csVec4f _iColor)
void setTerminalColor (csVec4f _tColor)
opReal getMagScale()
csVec4f getInitialColor()
csVec4f getTerminalColor()
};
|
Methods in opTessVecAction
| setMagScale() and getMagScale() | |
Set and get the vector magnitude scale factor. This allows you to adjust the length of the rendered vectors. The default value is 1.0.
| | setInitialColor() and getInitialColor() | |
Set and get the color to be used at the base of the vectors. The default value is opaque white: (1.0, 1.0, 1.0, 1.0).
| | setTerminalColor() and getTerminalColor() | |
Set and get the color to be used at the tip of the vectors. The default value is opaque white: (1.0, 1.0, 1.0, 1.0).
|
opTessVec2dAction and opTessVec3dAction
The opTessVec2dAction and opTessVec3dAction classes provide tessellators for the two mesh classes opRegMesh<opVec2> and opRegMesh<opVec3>. They are derived from opTessVecAction, and each contains no public member functions other than a constructor, a destructor, and the necessary tessellate() and tessellator() functions. If the opRep passed to one of the tessellators is not of the correct type, the tesselator returns NULL.
| apply() and mpApply() | |
Are inherited from opTessellateAction. They tessellate all opRegMesh<opVec2>s or opRegMesh<opVec3>s in a scene graph using single-process or multi-process traversal.
|
Sample Mesh Tessellation: opviz and opVizViewer
The following discussion highlights the basic structure of the opviz sample application, to orient you when you look at the source files.
The application opviz uses calls to OpenGL Optimizer's three-dimensional opRegMesh tessellators, and uses the opVizViewer class, which is derived from opViewer, to control scene graph interactions and rendering. The application opviz can read Plot3D data files, (three samples are included in the OpenGL Optimizer library to illustrate mesh tessellation). For more information on Plot3D data format, see, for example, http://www.nas.nasa.gov/NAS/FAST/RND-93-010.walatka-clucas/htmldocs/
chp_21.formats.html.
The application opviz runs tessellators on an opThreadManager, which uses an opFunctionAction to distribute tessellation tasks. For more information on opThreadManager and opFunctionAction, see “Overview of the Thread Manager”.
The following sections first present controls added to opViewer by the class opVizViewer, and then cover these components of opviz:
The main rendering routine and data loading
Creating a tessellator and a csShape to hold the tessellation
Applying the tessellator to an opRegMesh using an opThreadMgr
The opVizViewer class extends the functionality of opViewer by defining the function opVizViewer::keyHandler() to manipulate three tessellators.
Key Bindings for opVizViewer
The class opVizViewer allows you to perform these actions from the keyboard, in addition to those provided by opViewer:
| i
| | Runs an opTessIso.
UP increases the function value used as a threshold and tessellates the new isosurface.
DOWN decreases the function value and tessellates the new isosurface.
| | c | | Runs an opTessSlice.
RIGHT moves the slice plane, which is perpendicular to the x, y, or z axis, in the positive direction along the appropriate axis, and tessellates the new slice.
LEFT moves slice in the negative direction along the appropriate axis and tessellates the new slice.
x sets the slice plane perpendicular to the x axis.
y sets the slice plane perpendicular to the y axis.
z sets the slice plane perpendicular to the y axis.
| | g
| | Runs an opTessVec3d.
+ increases the size of plotted vectors.
- decreases the size of the plotted vectors.
| | 0,1...
| | Selects the mesh to act on.
|
The opviz main loop parses command-line arguments, calls a data loader, and then calls eventLoop(), which is inherited from opViewer, to handle interaction with the data.
The data loader can read the three sample meshes (two scalar meshes and a vector mesh) that are included in the library. These meshes are discussed in Chapter 9 in these sections:
The data loader calls the opVizViewer methods addScalarMesh() and addVectorMesh(), which bring in the mesh data and modify the scene graph for convenient viewing. The add functions use the methods of the classes ScalarVizPacket and VectorVizPacket to control the tessellators.
Using a Tessellator—Code Example
Initializing a Tessellator
The function ScalarVizPacket::init_isosurface(), from which the following lines are taken, is an example of how to begin using a tessellator. Tessellating slices of a vector field or a scalar mesh requires similar lines of code.
Create the tessellator
iso = new opTessIsoAction ();
|
Create a csShape node to hold the tessellation.
For this application the node is placed under the root node group.
material-> setShininess (.0078125f * 116.0f);
material->setTransparency (0.5);
material-> setDiffuseColor (0.08, 0.0, 1.0);
material-> setSpecularColor (0.75, 0.75, 1.0);
appear->setMaterial (material);
appear->setLightEnable (1);
appear->setTranspEnable (1);
appear->setTranspMode( csContext::BLEND_TRANSP);
iso_shape->setAppearance (appear);
group->addChild (iso_shape);
|
opviz Tessellation and Thread Manager Calls
When you enter i after starting opviz, the application calls ScalarVizPacket::run_isosurface(), which tessellates the sample data set. The application opviz, via subsequent calls in eventLoop(), then renders the isosurface. run_isosurface() uses the tessellator created by init_isosurface() and obtains tessellation parameters from the data management structure developed by addScalarMesh().
Although run_isosurface() creates a multi-thread framework, opviz uses only one thread. The application provides a framework that is easily extended to a multiprocess tessellation controlled by an opMPFunListAction (see “opMPFunListAction: Many Tasks, Many Processes”). For opviz, tessellations are performed by instances of an opFunctionAction called IsoAction. See the section “opFunctionAction: One Task, One Process”.
Creating a Multi-Threaded Environment
The function run_isosurface(), from which this code is taken, provides a multi-threaded environment.
The function checks the number of available processors and creates an opThreadManager, which runs only one thread; see “Overview of the Thread Manager”.
int numThreads = opGetProcessorCount();
// ...error checking code deleted
tm = new opThreadMgr(numThreads);
// --- Create action array. Currently the action array only
// contains one action: isosurface generation
// create array
int numActions = 1;
opFunctionAction **actions =
(opFunctionAction **) new
opFunctionAction [ numActions ];
// insert action(s) in the array
for (int i=0; i < numActions; i++)
|
IsoAction is an opFunAction. Its method function() performs the tessellation. See “opFunctionAction: One Task, One Process”.
// the action objects take a mesh and tessellator
actions[i] = new IsoAction (mesh, iso, iso_shape);
// --- the thread manager runs the
// action(s) on separate threads
tm-> SchedMPFunList (new opMPFunListAction( numActions, actions)
);
|
Because this procedure may occur while another process is in a rendering traversal, the code from IsoAction::function() first removes the iso_shape node from the scene graph by submitting an opTransaction::removeChild() to the transaction manager. Then function() tessellates iso_shape, and submits an opTransaction::addChild() to the transaction manager, placing the newly tessellated shape back in the scene graph. (See “opTransaction” in Chapter 14).
Here shape is the member of IsoAction that corresponds to iso_shape in the lines of code above from ScalarVizPacket::init_isosurface() and scalarMesh is the member that corresponds to mesh.
int pc = shape->getParentCount();
for ( int i = 0; i < pc; i++ )
{
csGroup *parent =
(csGroup *)shape->getParent(i);
int place = parent->findChild (shape);
// --- extract existing geometry,
// delete and replace old one
opTransaction *trans1 =
new opTransaction;
trans1->removeChild(parent, shape);
opBlockingCommit(trans1);
isosurface->
tessellator(*scalarMesh, shape);
opTransaction *trans2 =
new opTransaction;
trans2->addChild(parent, shape);
opCommit(trans2);
}
|
To recover memory, function() has the IsoAction deleted.
OpenGL Optimizer Programmer's Guide: An Open API for Large-Model Visualization
(document number: 007-2852-002 / published: 1998-06-09)
table of contents | additional info | download
Front Matter
About This Guide
Part I. Getting Started
Part II. High-Level Strategic Tools for Fast Rendering
Part III. Specific Tools for Fast Rendering
Part IV. Managing and Rendering Higher-Order Geometric Primitives
Part V. Traversers, Low-Level Geometry Processing, and Multiprocessing
Part VI. Utilities and Troubleshooting
Part VII. Appendices
Glossary
Index
home/search |
what's new |
help
|