pfdOptimizeGraph(3pf) OpenGL Performer 3.2.2 libpfdu Reference Pages
NAME
pfdMergeGraph, pfdStripGraph, pfdSpatializeGraph - Optimize Performer
scene graph structures for rendering
FUNCTION SPECIFICATION
#include <Performer/pfdu.h>
pfNode * pfdMergeGraph(pfNode *node, unsigned int flags);
pfNode * pfdStripGraph(pfNode *node, unsigned int cacheLength,
unsigned int flags);
pfNode * pfdSpatializeGraph(pfNode *node, unsigned int octreeLevels,
unsigned int maxStripLength, unsigned int flags);
DESCRIPTION
pfdMergeGraph gathers all pfGeoSets referenced in the each static
subgraph rooted at node. It then creates a new subgraph for each which
has a minimum number of pfGeoSets by grouping together pfGeoSets which
share state and attribute data. By default, the function only operates
on static subgraphs, and thus will not destroy pfLOD, pfSequence, or
other dynamic structures in a hierarchy. The new graph, which is not
spatialized, is returned to the caller. Controlling the behavior of this
operation can be done by passing in the OR result of the following flags:
PFD_MERGE_GEOSETS
This token tells the function to merge the geoSets - if this
token is not present, then no operations will be performed.
The next set of flags control the behavior for certain types of pfGroup
nodes. Nodes which typically are used as dynamic in scene graphs can be
forced as static, which will allow for greater optimization. In most
cases, the currently selected child (or children) will be used as the
subtree of the node. These flags can be ORed into the flags parameter:
PFD_STATIC_SWITCHES
PFD_STATIC_LODS
PFD_STATIC_SEQUENCES
PFD_STATIC_MORPHS
These functions currently treat all SCS and DCS nodes as dynamic. If it
is desired to optimize through these nodes, convert all possible DCS
nodes to SCS nodes, and then flatten the graph.
All methods described in this page can output geometry as either
pfGeoSets or pfGeoArrays, and as either indexed or non-indexed. The
default behavior is to output non-indexed pfGeoArrays if any are present,
and non-indexed pfGeoSets otherwise. This can be controlled by ORing in
the following tokens into the flags parameter:
PFD_OUTPUT_GEOSETS
Page 1
pfdOptimizeGraph(3pf) OpenGL Performer 3.2.2 libpfdu Reference Pages
PFD_OUTPUT_GEOARRAYS
PFD_OUTPUT_INDEXED
These flags force the output format to be of the type and
format indicated.
pfdMergeGraph returns the root to a new scene graph, and does not modify
the graph which is rooted at node. It is up to the calling application
to delete the previous graph if it is no longer needed. If no operations
to the graph are required, the function may return the same node as
input, in which case the node should not be deleted.
It is important to note that there is no default behavior for this
function - that is, if flags is set to 0, then it is assumed as meaning
that the above options are disabled. In this case, the result will be no
change to the input geometry, including no conversion to an output format
different than what is given. This means a given set of flags can be
sent to all three functions in the pfdOptimizeGraph pipeline, and
undesired actions can be skipped by leaving them out of the flags.
pfdStripGraph collects all pfGeoSets in the graph rooted by node and
modifies each in several possible ways in order to increase performance.
This can include stripping (converting from separate primitives, such as
triangles, to their stripped form, triangle strips) or unstripping
geometry, merging stripped geometry, and reordering primitives. On
certain hardware, such as Onyx4, reordering primitives can improve
performance by taking advantage of hardware vertex caches to decrease the
number of transformed vertices. Specifying an integer length for
cacheLength will use the given value as the length of the cache on the
target hardware. If this is unknown or may vary on several targets,
using a value of 0 will use a more generic algorithm providing better
results on machines of varying cache lengths. Controlling the behavior
of the operation can be done by passing in the OR result of the following
tokens as the flags parameter:
PFD_STRIP_UNSTRIPPED_PRIMITIVES
This token indicates that any primitives which are not stripped
should be stripped.
PFD_STRIP_STRIPPED_PRIMITIVES
This token indicates that any primitives which are already
stripped should be restripped.
PFD_UNSTRIP_STRIPPED_PRIMITIVES
This token indicates that any primitives which are already
stripped should be unstripped, or converted back to a separated
form. If this token and PFD_STRIP_STRIPPED_PRIMITIVES are both
passed, the input geometry is first unstripped, and then
restripped.
PFD_MERGE_TRISTRIPS
This token indicates that triangle strips should be joined with
degenerate triangles to construct longer strips. This will
Page 2
pfdOptimizeGraph(3pf) OpenGL Performer 3.2.2 libpfdu Reference Pages
reduce the number of primitives in a pfGeoSet, and may improve
performance by reducing the number of draw calls needed to
render the geometry.
PFD_REORDER_CACHE_REUSE
This token indicates that the primitives should be reordered to
improve cache reuse. On systems with a hardware vertex cache,
this may improve performance, and is typically the most
effective reordering strategy.
PFD_REORDER_REDUCE_DEGENERATES
This token indicates that the reordering of primitives should
seek to reduce the number of degenerate merging triangles.
This is not typically as effective as reordering to improve
cache reuse.
As in pfdMergeGraph, the function has no default behavior, and will
perform no graph modification if no flags are passed in. The same output
flags can be passed to pfdStripGraph as pfdMergeGraph.
pfdSpatializeGraph operates similarily to pfdSpatialize and pfdBreakup.
It takes the graph rooted at node, and first breaks up the geometry into
smaller chunks, which may improve spatialization, and thus culling. This
breakup turns each geode into a subgraph rooted by a pfGroup node with
several pfGeode children. Next, each static subgraph is spatialized via
pfSpatialize. Similarily to pfdMergeGraph, this operation does not
change the dynamic aspects of a scene graph. Graphs rooted by nodes such
as pfSwitch and pfSequence will not be changed by the operation. The
maxStripLength parameter controls how long of strips breakup will allow.
If this value is set to 0, then no maximum will be used. The
octreeLevels parameter controls the target number of octree levels for
the breakup and spatialization operations. However, depending upon the
number of pfGeoSets in the graph, there may be slightly more or less
levels in the actual output graph. Like pfdStripGraph, the flags
parameter is used to pass in the OR result of the following tokens to
control the behavior of the operation.
PFD_BREAKUP_GEOSETS
This token indicates that the breakup operation should be
performed.
PFD_SPATIALIZE_GRAPH
This token indicates that the spatialization operation should
be performed.
As in pfdMergeGraph, the function has no default behavior, and will
perform no graph modification if no flags are passed in. Like both above
functions, the output can be controlled by the same tokens passed through
the flags parameter, and returns the root to a new scene graph.
Collectively, the three above functions can be run as a pipeline on an
input scene graph to reformat and optimize the graph for best performance
Page 3
pfdOptimizeGraph(3pf) OpenGL Performer 3.2.2 libpfdu Reference Pages
on a given hardware. Additionally, some compund tokens are available for
setting the flags which can be passed to all three functions to modify
behavior. These tokens are:
PFD_OPTIMIZE_AGGRESSIVE
This token indicates that the operations should perform their
most aggressive optimizations. This includes restripping all
primitives, reordering to improve cache reuse, merging strips,
and performing all spatialization steps. While this may not
always be the best set of operations, it should provide an
excellent starting point, especially for optimizing on newer
hardware, such as Onyx4.
PFD_OPTIMIZE_CONSERVATIVE
This token is used for performing only the safest
optimizations. These optimizations are unlikely to decrease
performance, and may be useful for optimizing across several
different platforms and generations of hardware.
PFD_OPTIMIZE_INDEXED_TRIS
On some hardware, indexed triangles may be the fastest geometry
format. For these systems, the above token will use aggressive
methods, but output to an indexed, unstripped, but reordered
format.
These tokens are combinations of the previous tokens, and may be used in
compound with any of the previously mention tokens (most notably, the
output tokens). All three compound tokens include PFD_OUTPUT_INDEXED, so
if that mode is not desired an application could remove it by performing
an AND of token and the negation of PFD_OUTPUT_INDEXED.
The following code sample illustrates using the optimization functions in
a pipeline on an input graph and saving to a file.
root = pfdLoadFile(inputFile);
if (root == NULL)
{
pfNotify(PFNFY_FATAL, PFNFY_USAGE,
"Input graph was not found. Quitting.");
}
// First, call merge graph
root = pfdMergeGraph(root, PFD_OPTIMIZE_AGGRESSIVE);
// Now strip each of the merged geoSets
// length of the cache is 12 vertices
root = pfdStripGraph(root, 12, PFD_OPTIMIZE_AGGRESSIVE);
// Finally, spatialize the graph
// Have 3 octree levels, and no maximum strip length
root = pfdSpatializeGraph(root, 3, 0, PFD_OPTIMIZE_AGGRESSIVE);
Page 4
pfdOptimizeGraph(3pf) OpenGL Performer 3.2.2 libpfdu Reference Pages
// Save new scene graph
pfdStoreFile(root, outputFile);
NOTES
The libpfdu source code, object code and documentation are provided as
unsupported software. Routines are subject to change in future releases.
SEE ALSO
pfGeoSet, pfGeoArray
Page 5