pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
NAME
pfCullProgramResetPgm, pfCullProgramAddPgmOpcode,
pfCullProgramAddPgmInstruction, pfCullProgramNumPolytopes,
pfGetCullProgramNumPolytopes, pfCullProgramPolytope,
pfGetCullProgramPolytope, pfCullProgramFlags, pfGetCullProgramFlags,
pfCullProgramTestPolytope, pfCullProgramAddBinParent,
pfCullProgramIsSubbinOf, pfCullProgramResetBinParents - Specifies a set
of operations applied to each node and each pfGeoSet during cull
traversal.
FUNCTION SPECIFICATION
#include <Performer/pf.h>
void pfCullProgramResetPgm(pfCullProgram* cullprogram);
void pfCullProgramAddPgmOpcode(pfCullProgram* cullprogram,
int opcode, int data);
void pfCullProgramAddPgmInstruction(pfCullProgram* cullprogram,
_pfCullPgInstruction instruction, int data);
void pfCullProgramNumPolytopes(pfCullProgram* cullprogram,
int i);
int pfGetCullProgramNumPolytopes(pfCullProgram* cullprogram);
void pfCullProgramPolytope(pfCullProgram* cullprogram,
int index, pfPolytope *pol);
pfPolytope* pfGetCullProgramPolytope(pfCullProgram* cullprogram,
int index);
void pfCullProgramFlags(pfCullProgram* cullprogram, int which,
int value);
int pfGetCullProgramFlags(pfCullProgram* cullprogram,
int which);
int pfCullProgramTestPolytope(pfCullProgram* cullprogram,
int index);
void pfCullProgramAddBinParent(pfCullProgram* cullprogram,
int bin);
int pfCullProgramIsSubbinOf(pfCullProgram* cullprogram,
int bin);
void pfCullProgramResetBinParents(pfCullProgram* cullprogram);
Page 1
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
PARENT CLASS FUNCTIONS
The OpenGL Performer class pfCullProgram is derived from the parent class
pfObject, so each of these member functions of class pfObject are also
directly usable with objects of class pfCullProgram. Casting an object
of class pfCullProgram to an object of class pfObject is taken care of
automatically. This is also true for casts to objects of ancestor
classes of class pfObject.
void pfUserDataSlot(pfObject *obj, int slot, void *data);
void pfUserData(pfObject *obj, void *data);
void* pfGetUserDataSlot(pfObject *obj, int slot);
void* pfGetUserData(pfObject *obj);
int pfGetNumUserData(pfObject *obj);
int pfGetNamedUserDataSlot(const char *name);
const char* pfGetUserDataSlotName(int slot);
int pfGetNumNamedUserDataSlots(void);
int pfDeleteGLHandle(pfObject *obj);
Since the class pfObject is itself derived from the parent class
pfMemory, objects of class pfCullProgram can also be used with these
functions designed for objects of class pfMemory.
pfType * pfGetType(const void *ptr);
int pfIsOfType(const void *ptr, pfType *type);
int pfIsExactType(const void *ptr, pfType *type);
const char * pfGetTypeName(const void *ptr);
int pfRef(void *ptr);
int pfUnref(void *ptr);
int pfUnrefDelete(void *ptr);
int pfUnrefGetRef(void *ptr);
int pfGetRef(const void *ptr);
int pfCopy(void *dst, void *src);
int pfDelete(void *ptr);
int pfIsFluxed(void *ptr);
int pfCompare(const void *ptr1, const void *ptr2);
void pfPrint(const void *ptr, uint which, uint verbose,
FILE *file);
void * pfGetArena(void *ptr);
DESCRIPTION
A pfCullProgram is a class that is used to set up a cull program, a
sequence of instructions that are executed for each scene graph node and
each pfGeoSet during the cull traversal. There can be two separate cull
programs, one for nodes and one for pfGeoSets. The node cull program
uses a set of polytopes. Based on the position of the node with respect
to each polytope (inside, outside, intersects) it can determine whether
the node is culled out (good for occlusion culling or small feature
culling) or whether all pfGeoSets under this node are assigned to a
specific bin. The pfGeoSet cull program also uses a set of polytopes and
assigns each pfGeoSet to a different bin based on the position of the
pfGeoSet with respect to each polytope or it culls out the pfGeoSet. The
Page 2
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
best use of cull programs is for occlusion culling, small feature
culling, or in multi-pass rendering when in some passes only parts of the
scene have to be rendered and being able to assign these part to a bin
can reduce the rendering time.
There is always a default pfCullProgram present on pfChannel. To access
it, you can call LcpfGetChanCullProgram. Then you can set the program's
instructions, the polytopes, and enable the cull program by setting flag
PFCULL_PROGRAM using pfChanTravMode (see pfChannel for more details).
Example:
pfCullProgram *cullPgm = pfGetChanCullProgram(channel);
pfCullProgramResetPgm(cullPgm, PFCULLPG_GEOSET_PROGRAM);
pfCullProgramAddPgmOpcode(cullPgm, opcode1, data1);
...
pfCullProgramAddPgmOpcode(cullPgm, opcodeN, dataN);
pfCullProgramResetPgm(cullPgm, PFCULLPG_NODE_PROGRAM);
pfCullProgramAddPgmOpcode(cullPgm, opcode1, data1);
...
pfCullProgramAddPgmOpcode(cullPgm, opcodeM, dataM);
pfCullProgramNumPolytopes(cullPgm, 2);
pfCullProgramPolytope(cullPgm, ptope1);
pfCullProgramPolytope(cullPgm, ptope2);
You can define both node and pfGeoSet cull program at once by setting the
flag in pfCullProgramResetPgm to PFCULLPG_GEOSET_PROGRAM |
PFCULLPG_NODE_PROGRAM.
POLYTOPES
Cull program polytopes are standard pfPolytopes. They could be used to
defined various areas: it could be some subset of a view frustum in which
the geometry is drawn using different attributes, it could be a bounding
box around some area of interest and so on.
To initialize cull program polytopes, you set the number of polytopes
that are used by cull programs using pfCullProgramNumPolytopes. Then
create new pfPolytope in the shared arena and set it using
pfCullProgramPolytope. The polytopes are indexed from 0. Polytopes are
shared between the node and pfGeoSet cull program, even if they are
different.
To modify a polytope of certain index during the simulation, you get a
Page 3
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
pointer to the polytope using pfGetCullProgramPolytope, modify it, and
then call pfCullProgramPolytope.
PREDEFINED CULL PROGRAM INSTRUCTIONS
A cull program is a set of instructions that operate on bins and defined
polytopes. Instructions are defined in sequence. First, you reset the
default program (which consists of return instruction only) using
pfCullProgramResetPpgm and then specify each instruction by its opcode (-
pfCullProgramAddPgmOpcode) or directly by specifying a function (-
pfCullProgramAddPgmInstruction). Each instruction has associated an
integer value, used as a parameter for the instruction.
The cull program starts with the bin that is associated with the pfGeoSet
and as it is executed it modifies it. The output is the new bin
assignment.
The following instructions can be specified by an opcode.
PFCULLPG_TEST_POLYTOPE n
Test bounding box of the pfGeoSet or bounding sphere of a
pfNode against the polytope with index n. The result is one of
PFIS_FALSE (all out), PFIS_MAYBE (possible intersection),
PFIS_MAYBE | PFIS_TRUE (all in).
PFCULLPG_TEST_IS_SUBBIN_OF b
Test whether the bin that has been determined up to this point
is a subbin of bin b. The result is 1 or 0. Note that bin b is
considered a subbin of itself.
PFCULLPG_TEST_IS_TRANSPARENT
Test whether the pfGeoSet is transparent. The parameter is
ignored. The result is 1 or 0.
PFCULLPG_TEST_IS_LIGHT_POINT
Test whether the pfGeoSet belongs to a light point bin. The
parameter is ignored. The result is 1 or 0.
PFCULLPG_TEST_SMALLER_THAN
Test whether the screen size of a pfGeoSet or pfNode is below
the given number of pixels. The result is 1 or 0.
PFCULLPG_ASSIGN_BIN_MAYBE b
Assign bin b to the pfGeoSet if the result of the last polytope
test was PFIS_MAYBE.
Page 4
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
PFCULLPG_ASSIGN_BIN_TRUE b
Assign bin b to the pfGeoSet if the result of the last binary
test was 1.
PFCULLPG_ASSIGN_BIN_ALL_IN b
Assign bin b to the pfGeoSet if the result of the last polytope
test was PFIS_MAYBE | PFIS_TRUE.
PFCULLPG_ASSIGN_BIN_ALL_OUT b
Assign bin b to the pfGeoSet if the result of the last polytope
test was PFIS_FALSE.
PFCULLPG_ASSIGN_BIN_FALSE b
Assign bin b to the pfGeoSet if the result of the last polytope
test was 0.
PFCULLPG_ASSIGN_BIN b
Assign bin b to the pfGeoSet.
PFCULLPG_ADD_BIN_MAYBE b
Assign a subbin of bin b and the existing bin to the pfGeoSet
if the result of the last polytope test was PFIS_MAYBE. If the
existing bin is -1, the instruction operates as an assign
instruction. If the subbin does not exist it is dynamically
created.
PFCULLPG_ADD_BIN_TRUE b
Assign a subbin of bin b and the existing bin to the pfGeoSet
if the result of the last binary test was 1.
PFCULLPG_ADD_BIN_ALL_IN b
Assign a subbin of bin b and the existing bin to the pfGeoSet
if the result of the last polytope test was PFIS_MAYBE |
PFIS_TRUE.
PFCULLPG_ADD_BIN_ALL_OUT b
Assign a subbin of bin b and the existing bin to the pfGeoSet
if the result of the last polytope test was PFIS_FALSE.
Page 5
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
PFCULLPG_ADD_BIN_FALSE b
Assign a subbin of bin b and the existing bin to the pfGeoSet
if the result of the last polytope test was 0.
PFCULLPG_ADD_BIN b
Assign a subbin of bin b and the existing bin to the pfGeoSet.
PFCULLPG_JUMP_MAYBE c
Skip next c instructions if the result of the last polytope
test was PFIS_MAYBE. If c is negative, go back |c|-1
instructions.
PFCULLPG_JUMP_TRUE c
Skip next c instructions if the result of the last binary test
was 1.
PFCULLPG_JUMP_ALL_IN c
Skip next c instructions if the result of the last polytope
test was PFIS_MAYBE | PFIS_TRUE.
PFCULLPG_JUMP_ALL_OUT c
Skip next c instructions if the result of the last polytope
test was PFIS_FALSE.
PFCULLPG_JUMP_FALSE c
Skip next c instructions if the result of the last polytope
test was 0.
PFCULLPG_JUMP c
Skip next c instructions.
PFCULLPG_RETURN flags
Finish execution of the cull program. Each cull program has to
be terminated by a return instruction. The parameter is a
combination of the following binary flags:
PFCULLPG_CULL_ON_ALL_IN, PFCULLPG_CULL_ON_ALL_OUT,
PFCULLPG_CULL_ON_MAYBE, PFCULLPG_CULL_ON_TRUE,
PFCULLPG_CULL_ON_FALSE, PFCULLPG_CULL,
PFCULLPG_TEST_TRANSPARENCY, PFCULLPG_DONT_TEST_TRANSPARENCY,
Page 6
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
PFCULLPG_TEST_LPOINTS, and PFCULLPG_DONT_TEST_LPOINTS.
The first six flags determine whether the node or the pfGeoSet
is culled out, optionally based on the result of the last
polytope test. In that case any bin assignment made by the
cull program is ignored.
The last four flags control whether an additional test for the
pfGeoSet being transparent or being a light point is performed.
These flags have effect only on the pfGeoSet cull program. If
the pfGeoSet is transparent or is a light point, the pfGeoSet
is assigned a subbin of the transparent bin or the light point
bin and the bin resulting from the cull program.
If initially the pfGeoSet has no bin assigned to it, both the
transparency and light point tests are performed (to follow the
operation of a regular cull traversal). If those tests are not
needed the two DONT_TEST flags can be used. If the pfGeoSet
has initially assigned a bin, the tests are not performed
unless the binary flags specify so.
If you need to perform any of these two tests earlier, for
example, to differentiate bin assignment based on transparency,
you can use instructions PFCULLPG_TEST_IS_TRANSPARENT and
PFCULLPG_TEST_IS_LIGHT_POINT.
It is not recommended to use instructions that modify bin assignment in a
node cull program.
USER-DEFINED CULL PROGRAM INSTRUCTIONS
The user may provide his/her own instructions. The instruction has to be
a function, that takes two parameters, a pointer to pfCullProgram and and
an integer value (the instruction parameter). The instruction has to
return a value by which the instruction counter is increased - 1 for all
instructions except jump instructions. Actually, it is possible to write
whole cull programs as a single user-defined instruction.
There are two variables user-defined instruction can access during the
execution of a cull program and there are several useful methods they may
use. The variables are:
currentResult
stores the result of the last polytope test or a binary test.
bbox pfGeoSet's bounding box (not applicable in node cull programs).
Page 7
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
bsphere
nodes's bounding sphere (not applicable in geoset cull
programs).
There are four methods that can be used in instructions:
pfCullProgramTestPolytope(pgm,n)
Test polytope n using the pfGeoSet's bounding box bbox or
node's bounding sphere. It is recommended to use this function
rather than doing the test directly because the result is often
already known by testing the nodes above the current pfGeoSet
or node and the test can be avoided.
pfCullProgramAddBinParent(pgm,b)
The cull program keeps the list of parents that identify the
current bin (to avoid creating many subbins that may not be
needed). This function adds a new parent b, which could be also
a subbin.
pfCullProgramIsSubbinOf(pgm,b)
Tests whether the current bin is a subbin of bin b.
pfCullProgramResetBinParents(pgm)
This method resets the list of parents of the current bin.
For example, the predefined instruction PFCULLPG_ASSIGN_BIN_MAYBE can be
implemented as:
int MyAssignBinMaybe(pfCullProgram *pgm, int data)
{
if(pgm->currentResult & PFIS_MAYBE) {
pfCullProgramResetBinParents(pgm);
pfCullProgramAddBinParent(pgm, data);
}
return 1;
}
CULL TRAVERSAL
To reduce the amount of testing performed for each pfGeoSet, each node of
the tree is tested against all cull program polytopes (only when cull
programs are enabled). If the test is conclusive, that is the bounding
sphere of the node is inside or outside of a polytope, children of the
node are not tested against the given polytope. It is recommended to use
the node cull program only to determine culling and assign bins only at
Page 8
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
the pfGeoSet level using the pfGeoSet cull program.
If culling to the view frustum is enabled (flag PFCULL_VIEW set in
pfChanTravMode - see pfChannel for more details) it is done before the
cull program is executed. In this case pfGeoSets that are not
intersecting view frustum are culled out and cull program is not executed
for them.
A sample code illustrating the use of cull programs can be found in
/usr/share/Performer/src/pguide/libpf/C++: cullPgmSimple,
cullPgmMultipass.
OCCLUSION CULLING USING CULL PROGRAMS
In order to use cull programs for occlusion culling you have to choose
the occluders in the scene, for example walls in a room or the walls of
the nearest buildings in a city. Then you have to create a polytope
around the occluder. If it is a rectangle one face for the rectangle and
4 faces for edges - 4 planes each defined by the edge and the eye. You
have to update the polytope or polytopes every time the eye or the
occluder moves.
You can find and example of occlusion culling in
/usr/share/Performer/src/pguide/libpf/C++/occlusionCull.C. The sample
program also includes a function that for a polygon defined by 4 vertices
creates a polytope that can be used by a cull program to perform
occlusion culling.
At present the polytopes have to be convex. Consequently, in case two
occluders are touching but their common shape is concave they have to be
defined as two polytopes. In that case the geometry that is occluded by
both occluders and that spans their common boundary is not culled out. To
avoid that problem, you can define a convex polytope that contains both
shapes (a convex hull) and then define convex cut areas that are not part
of the occluders. This way you can also add holes in occluders. As long
as you start with a convex polytope, you can subtract as many convex
polytopes as you need.
The cull program then looks like:
PFCULLPG_TEST_POLYTOPE, 0 // convex hull
PFCULLPG_JUMP_ALL_IN, 1
PFCULLPG_RETURN, 0 // no cull
PFCULLPG_TEST_POLYTOPE, 1 // first cutout area
PFCULLPG_JUMP_ALL_OUT, 1
PFCULLPG_RETURN, 0 // no cull
PFCULLPG_TEST_POLYTOPE, N // n-th cutout area
PFCULLPG_JUMP_ALL_OUT, 1
Page 9
pfCullProgram(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages
PFCULLPG_RETURN, 0 // no cull
PFCULLPG_RETURN, PFCULLPG_CULL
See /usr/share/Performer/src/pguide/libpf/C++/occlusionCullConcave.C for
an example.
SMALL FEATURE CULLING USING CULL PROGRAMS
Since cull programs have access to bounding spheres of nodes and bounding
boxes of geosets they can be used for small feature culling. In small
feature culling geometry that is smaller (in screen space) than a given
number of pixels is culled out.
A cull program that performs a small feature culling looks as follows:
PFCULLPG_TEST_SMALLER_THAN, 1.5 // smaller than 1.5 pixels
PFCULLPG_RETURN, PFCULLPG_CULL_ON_TRUE
Do not forget to specify this program both for nodes and geosets. You
can find and example of small feature culling in
/usr/share/Performer/src/pguide/libpf/C++/cullSmallFeature.C.
SEE ALSO
pfObject, pfChannel
Page 10