pfLayer(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfLayer(3pf)NAME
pfNewLayer, pfGetLayerClassType, pfLayerMode, pfGetLayerMode,
pfLayerPlane, pfGetLayerPlane, pfLayerBase, pfGetLayerBase, pfLayerDecal,
pfGetLayerDecal - Create, modify, and query layer nodes for decals and
coplanar polygons.
FUNCTION SPECIFICATION
#include <Performer/pf.h>
pfLayer * pfNewLayer(void);
pfType * pfGetLayerClassType(void);
void pfLayerMode(pfLayer *layer, int mode);
int pfGetLayerMode(const pfLayer *layer);
void pfLayerPlane(pfLayer *layer, pfPlane *plane);
pfPlane * pfGetLayerPlane(const pfLayer *layer);
void pfLayerBase(pfLayer *layer, pfNode *base);
pfNode * pfGetLayerBase(const pfLayer *layer);
void pfLayerDecal(pfLayer *layer, pfNode *decal);
pfNode * pfGetLayerDecal(const pfLayer *layer);
PARENT CLASS FUNCTIONS
The OpenGL Performer class pfLayer is derived from the parent class
pfGroup, so each of these member functions of class pfGroup are also
directly usable with objects of class pfLayer. Casting an object of
class pfLayer to an object of class pfGroup is taken care of
automatically. This is also true for casts to objects of ancestor
classes of class pfGroup.
int pfAddChild(pfGroup *group, pfNode *child);
int pfInsertChild(pfGroup *group, int index, pfNode *child);
int pfReplaceChild(pfGroup *group, pfNode *old, pfNode *new);
int pfRemoveChild(pfGroup *group, pfNode* child);
int pfSearchChild(pfGroup *group, pfNode* child);
pfNode * pfGetChild(const pfGroup *group, int index);
int pfGetNumChildren(const pfGroup *group);
int pfBufferAddChild(pfGroup *group, pfNode *child);
int pfBufferRemoveChild(pfGroup *group, pfNode *child);
Since the class pfGroup is itself derived from the parent class pfNode,
objects of class pfLayer can also be used with these functions designed
for objects of class pfNode.
Page 1
pfLayer(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfLayer(3pf)
pfGroup * pfGetParent(const pfNode *node, int i);
int pfGetNumParents(const pfNode *node);
void pfNodeBSphere(pfNode *node, pfSphere *bsph, int mode);
int pfGetNodeBSphere(pfNode *node, pfSphere *bsph);
pfNode* pfClone(pfNode *node, int mode);
pfNode* pfBufferClone(pfNode *node, int mode, pfBuffer *buf);
int pfFlatten(pfNode *node, int mode);
int pfNodeName(pfNode *node, const char *name);
const char * pfGetNodeName(const pfNode *node);
pfNode* pfFindNode(pfNode *node, const char *pathName,
pfType *type);
pfNode* pfLookupNode(const char *name, pfType* type);
int pfNodeIsectSegs(pfNode *node, pfSegSet *segSet,
pfHit **hits[]);
void pfNodeTravMask(pfNode *node, int which, uint mask,
int setMode, int bitOp);
uint pfGetNodeTravMask(const pfNode *node, int which);
void pfNodeTravFuncs(pfNode* node, int which,
pfNodeTravFuncType pre, pfNodeTravFuncType post);
void pfGetNodeTravFuncs(const pfNode* node, int which,
pfNodeTravFuncType *pre, pfNodeTravFuncType *post);
void pfNodeTravData(pfNode *node, int which, void *data);
void * pfGetNodeTravData(const pfNode *node, int which);
void pfNodeTravMode(pfNode* node, int which, int mode,
int val);
int pfGetNodeTravMode(const pfNode* node, int which,
int mode);
Since the class pfNode is itself derived from the parent class pfObject,
objects of class pfLayer can also be used with these functions designed
for objects 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 pfLayer 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);
Page 2
pfLayer(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfLayer(3pf)
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);
PARAMETERS
layer identifies a pfLayer.
DESCRIPTION
On Z-buffer based machines, numerical precision can cause distracting
artifacts when rendering coplanar geometry. A pfLayer is a node derived
from pfGroup that supports proper drawing of coplanar geometry on OpenGL
platforms.
A pfLayer can be thought of as a stack of geometry where each layer has
visual priority over the geometry beneath it in the stack. An example of
a 3 layer stack consists of stripes which are layered over a runway which
is layered over the ground. The bottommost layer is called the "base"
while the other layers are called "decals". When using certain hardware
mechanisms (PFDECAL_BASE_STENCIL) to implement pfLayers, the "base" is
special because it defines the depth values which are used to determine
pfLayer visibility with respect to other scene geometry and which are
written to the depth buffer.
pfNewLayer creates and returns a handle to a pfLayer. Like other
pfNodes, pfLayers are always allocated from shared memory and can be
deleted using pfDelete.
pfGetLayerClassType returns the pfType* for the class pfLayer. The
pfType* returned by pfGetLayerClassType is the same as the pfType*
returned by invoking pfGetType on any instance of class pfLayer. Because
OpenGL Performer allows subclassing of built-in types, when decisions are
made based on the type of an object, it is usually better to use
pfIsOfType to test if an object is of a type derived from a Performer
type rather than to test for strict equality of the pfType*'s.
Since pfLayer is derived from pfGroup, pfGroup API may be used to
manipulate its child list. OpenGL Performer considers child 0 to be the
base geometry and children 1 through N-1 to be decals. Decals are
rendered in order such that decal[i+1] is drawn atop decal[i]. In other
words, decal[i+1] has visual priority over decal[i] even though they are
coplanar. pfLayerBase and pfLayerDecal are convenience routines for
Page 3
pfLayer(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfLayer(3pf)
setting the base and decal children of layer in the common case where
there is only one decal child. pfGetLayerBase and pfGetLayerDecal return
the base and first child of layer.
The mode argument to pfLayerMode specifies which hardware mechanism to
use and is one of:
PFDECAL_BASE_DISPLACE
Use slope-based polygon displacement to slightly displace the
depth values of decal geometry closer to the eye so they have
visual priority. Each decal is displaced more than its
predecessor to properly resolve priority between decals. The
maximum number of decals is 8.
PFDECAL_BASE_DISPLACE | PFDECAL_LAYER_OFFSET
Use slope-based polygon displacement to slightly displace the
depth values of decal geometry closer to the eye so they have
visual priority. In addition, decal geometry is offset a
constant amount to eliminate anomalies caused by geometry which
is nearly perpendicular to the view. Each decal is displaced
and offset more than its predecessor to properly resolve
priority between decals. The maximum number of decals is 8.
PFDECAL_BASE_STENCIL
Use the stencil-buffer logic to determine visibility of decal
geometry. There is no limit to the number of decals.
PFDECAL_BASE_FAST
Use a decaling mechanism appropriate to the hardware that
produces the fastest, but not necessarily the highest quality,
decaling.
PFDECAL_BASE_HIGH_QUALITY
Use a decaling mechanism appropriate to the hardware that
produces the highest quality, but not necessarily the fastest,
decaling.
The decal mode may also include the PFDECAL_PLANE token OR-ed with one of
the above tokens which will enable the use of the decal reference plane
(set with pfLayerPlane). This can offer much higher quality of
PFDECAL_BASE_DISPLACE type layers.
The default layer mode is PFDECAL_BASE_FAST. pfGetLayerMode returns the
mode of layer.
The different pfLayer modes offer quality-feature tradeoffs listed in the
table below:
DISPLACE STENCIL (DISPLACE | OFFSET)
___________________________________________________________
|
|
|
Page 4
pfLayer(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfLayer(3pf)
Quality medium high high
Sorting enabled disabled enabled
Coplanarity not required required not required
Multipass ok not ok ok
Containment not required required not required
|
|
|
The STENCIL mechanism offers the best image quality but at a performance
cost since the base and layer geometry must be rendered in order,
obviating any benefits of sorting by graphics state offered by
pfChanBinSort. When multisampling on RealityEngine, this mechanism also
significantly reduces pixel fill performance. The performance impact is
not as severe in InfiniteReality systems. An additional constraint is
that STENCILed layers must be coplanar or decal geometry may incorrectly
show through base geometry. A subtle but important issue with STENCILed
layers is that they are unsuitable for multipass renderings (projected
textures) since multiple surfaces are visible at a given pixel. For
proper results, each layer in the "stack" must be completely contained
within the boundaries of the base geometry.
The DISPLACE mechanism offers the best performance since layers can be
sorted by graphics state, because the displace call itself is usually
faster than other mode changes, and because there is no pixel fill rate
penalty when it is in use. The OFFSET mechanism adds a constant offset to
the decal geometry. This mode can be very expensive (RealityEngine) so
when using it the database should be sorted with PFSTATE_DECAL as the
first sorting key (see pfChanBinSort). Both DISPLACE mechanisms do not
require that geometry within a single layer be coplanar and also produce
a single visible surface at each pixel for multipass renderings. The main
disadvantage is that decal geometry may incorrectly poke through other
geometry due to the displacement of the decal geometry. Another
disadvantage is that the maximum number of decals is 8.
The performance differences between STENCIL and DISPLACE modes are
hardware-dependent so some experimentation and benchmarking is required
to determine the most suitable method for your application.
pfLayerPlane sets a reference plane to be used for all geometry under the
pfLayer node. pfGetLayerPlane returns the reference plane, or NULL if no
such plane is set on the pfLayer.
NOTES
Using PFDECAL_BASE_STENCIL for pfLayer nodes requires several steps for
proper operation. First, the graphics hardware must support stencil plane
rendering. Secondly, the graphics context must be configured with at
least one stencil plane, and the lowest order bit of the allocated
stencil planes be reserved for OpenGL Performer use. pfInitGfx
configures the graphics context in just this way.
The use of displacements for rendering coplanar geometry can cause visual
artifacts such as decals "Z fighting" or "flimmering" when viewed
perpendicularly, and the "punching through" of decals that should mask
Page 5
pfLayer(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfLayer(3pf)
base geometry when both are viewed obliquely. The former artifact can be
eliminated by specifying PFDECAL_BASE_DISPLACE | PFDECAL_LAYER_OFFSET as
the layer mode. Subtle details of this rendering mode are described in
the pfDecal man page. If unacceptable artifacts still persist, the
database should be modified to eliminate the need for coplanar rendering
or PFDECAL_BASE_HIGH_QUALITY should be used.
When using PFDECAL_LAYER_OFFSET, the minimum depth buffer range set with
lsetdepth must be incremented an extra 1024 * max layers so the negative
displacement of the layers does not wrap. pfInitGfx does this
automatically.
BUGS
OpenGL Performer properly renders coplanar geometry only on machines that
have a hardware stencil buffer allocated or which support displaced
polygon rendering.
SEE ALSO
pfChanBinSort, pfDecal, pfGroup, pfInitGfx, pfLookupNode, pfNode,
pfDelete
Page 6