pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)NAME
pfNewChan, pfGetChanClassType, pfGetChanPipe, pfChanViewport,
pfGetChanViewport, pfGetChanOrigin, pfGetChanSize, pfChanLODState,
pfGetChanLODState, pfChanLODStateList, pfGetChanLODStateList,
pfGetChanPWinIndex, pfGetChanPWin, pfChanTravFunc, pfGetChanTravFunc,
pfAllocChanData, pfChanData, pfGetChanData, pfGetChanDataSize,
pfPassChanData, pfClearChan, pfAttachChan, pfDetachChan, pfASDattachChan,
pfASDdetachChan, pfChanShare, pfGetChanShare, pfChanFOV, pfGetChanFOV,
pfChanNearFar, pfGetChanNearFar, pfChanAutoAspect, pfGetChanAutoAspect,
pfGetChanBaseFrust, pfGetChanPtope, pfMakePerspChan, pfMakeInfPerspChan,
pfMakeOrthoChan, pfMakeSimpleChan, pfGetChanFrustType, pfChanAspect,
pfGetChanAspect, pfOrthoXformChan, pfGetChanNear, pfGetChanFar,
pfGetChanEye, pfApplyChan, pfChanContainsPt, pfChanContainsSphere,
pfChanContainsCyl, pfChanContainsBox, pfChanCullPtope,
pfGetChanCullPtope, pfChanPick, pfChanNodeIsectSegs, pfChanScene,
pfGetChanScene, pfChanESky, pfGetChanESky, pfChanGState, pfGetChanGState,
pfChanGStateTable, pfGetChanGStateTable, pfChanStressFilter,
pfGetChanStressFilter, pfChanStress, pfGetChanStress, pfGetChanLoad,
pfChanTravMode, pfGetChanTravMode, pfChanTravMask, pfGetChanTravMask,
pfChanBinSort, pfGetChanBinSort, pfChanBinOrder, pfGetChanBinOrder,
pfGetChanFreeBin, pfChanBinSortPriority, pfGetChanBinSortPriority,
pfChanBinChildOrderMask, pfGetChanBinChildOrderMask, pfChanBinFlags,
pfGetChanBinFlags, pfChanBinCallBack, pfGetChanBinCallBack,
pfChanBinUserData, pfGetChanBinUserData, pfChanFindSubBin,
pfChanFindBinParent, pfGetChanCullProgram, pfChanView, pfGetChanView,
pfChanViewMat, pfGetChanViewMat, pfChanViewOffsets, pfGetChanViewOffsets,
pfGetChanOffsetViewMat, pfGetChanFStats, pfChanStatsMode,
pfDrawChanStats, pfChanLODAttr, pfGetChanLODAttr, pfChanProjMode,
pfGetChanProjMode, pfGetChanPVChan, pfChanPWinPVChanIndex,
pfGetChanPWinPVChanIndex, pfChanOutputViewport, pfGetChanOutputViewport,
pfGetChanOutputOrigin, pfGetChanOutputSize, pfChanPixScale,
pfGetChanPixScale, pfChanMinPixScale, pfGetChanMinPixScale,
pfChanMaxPixScale, pfGetChanMaxPixScale, pfGetChanUserFrustType,
pfGetChanBaseUserFrust, pfGetChanUserAspect, pfGetChanUserFOV,
pfGetChanUserNearFar, pfGetChanUserNear, pfGetChanUserFar,
pfGetChanUserPtope, pfGetChanUserEye, pfUserLeftRightBottomTopChan,
pfChanUserContainsPt, pfChanUserContainsSphere, pfChanUserContainsBox,
pfChanUserContainsCyl, pfChanCallig, pfGetChanCallig, pfGetChanCurCallig,
pfChanCalligEnable, pfGetChanCalligEnable, pfApp, pfCull, pfDraw,
pfLPoint, pfDrawBin, pfDrawScene, pfNodePickSetup - Set and get pfChannel
definition parameters.
FUNCTION SPECIFICATION
#include <Performer/pf.h>
pfChannel * pfNewChan(pfPipe *pipe);
pfType * pfGetChanClassType(void);
pfPipe * pfGetChanPipe(const pfChannel *chan);
Page 1
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
void pfChanViewport(pfChannel* chan, float l, float r,
float b, float t);
void pfGetChanViewport(const pfChannel* chan, float* l,
float* r, float* b, float* t);
void pfGetChanOrigin(const pfChannel* chan, int *xo,
int *yo);
void pfGetChanSize(const pfChannel* chan, int *xs, int *ys);
void pfChanLODState(pfChannel* chan, const pfLODState *ls);
void pfGetChanLODState(const pfChannel* chan,
pfLODState *ls);
void pfChanLODStateList(const pfChannel* chan,
pfList *lsList);
pfList* pfGetChanLODStateList(const pfChannel* chan);
int pfGetChanPWinIndex(pfChannel *chan);
pfPipeWindow * pfGetChanPWin(pfChannel *chan);
void pfChanTravFunc(pfChannel* chan, int trav,
pfChanFuncType func);
pfChanFuncType pfGetChanTravFunc(pfChannel* chan, int trav);
void * pfAllocChanData(pfChannel* chan, int size);
void pfChanData(pfChannel *chan, void *data, size_t size);
void * pfGetChanData(pfChannel* chan);
size_t pfGetChanDataSize(const pfChannel *chan);
void pfPassChanData(pfChannel* chan);
void pfClearChan(pfChannel* chan);
int pfAttachChan(pfChannel* chan0, pfChannel* chan1);
int pfDetachChan(pfChannel* chan0, pfChannel* chan1);
int pfASDattachChan(pfChannel* chan0, pfChannel* chan1);
int pfASDdetachChan(pfChannel* chan0, pfChannel* chan1);
Page 2
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
void pfChanShare(pfChannel* chan, uint mask);
uint pfGetChanShare(pfChannel* chan);
void pfChanFOV(pfChannel* chan, float horiz, float vert);
void pfGetChanFOV(const pfChannel* chan, float* horiz,
float* vert);
void pfChanNearFar(pfChannel* chan, float near, float far);
void pfGetChanNearFar(const pfChannel* chan, float* near,
float* far);
void pfChanAutoAspect(pfChannel* chan, int which);
int pfGetChanAutoAspect(const pfChannel* chan);
void pfGetChanBaseFrust(const pfChannel* chan,
pfFrustum *frust);
void pfGetChanPtope(const pfChannel *chan,
pfPolytope *ptope);
void pfMakePerspChan(pfChannel* chan, float left,
float right, float bottom, float top);
void pfMakeInfPerspChan(pfChannel* chan, float left,
float right, float bottom, float top);
void pfMakeOrthoChan(pfChannel* chan, float left,
float right, float bottom, float top);
void pfMakeSimpleChan(pfChannel* chan, float fov);
int pfGetChanFrustType(const pfChannel* chan);
void pfChanAspect(pfChannel* chan, int which,
float widthHeightRatio);
float pfGetChanAspect(const pfChannel* chan);
void pfOrthoXformChan(pfChannel* dst, pfChannel* src,
const pfMatrix mat);
void pfGetChanNear(const pfChannel* chan, pfVec3 ll,
pfVec3 lr, pfVec3 ul, pfVec3 ur);
void pfGetChanFar(const pfChannel* chan, pfVec3 ll,
pfVec3 lr, pfVec3 ul, pfVec3 ur);
Page 3
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
int pfGetChanEye(const pfChannel* chan, pfVec3 eye);
void pfApplyChan(pfChannel *chan);
int pfChanContainsPt(const pfVec3 pt, pfChannel* chan);
int pfChanContainsSphere(const pfChannel* chan,
const pfSphere* sph);
int pfChanContainsCyl(const pfChannel* chan,
const pfCylinder* cyl);
int pfChanContainsBox(const pfChannel* chan,
const pfBox* box);
void pfChanCullPtope(pfChannel *chan,
const pfPolytope *ptope);
void pfGetChanCullPtope(const pfChannel *chan,
pfPolytope *ptope, int space);
int pfChanPick(pfChannel *chan, int mode, float px,
float py, float radius, pfHit **picklist[]);
int pfChanNodeIsectSegs(pfChannel *chan, pfNode *node,
pfSegSet *segSet, pfHit **hits[], pfMatrix *mat);
void pfChanScene(pfChannel* chan, pfScene *scene);
pfScene * pfGetChanScene(const pfChannel* chan);
void pfChanESky(pfChannel* chan, pfEarthSky *sky);
pfEarthSky * pfGetChanESky(const pfChannel* chan);
void pfChanGState(pfChannel *chan, pfGeoState *gstate);
pfGeoState * pfGetChanGState(const pfChannel *chan);
void pfChanGStateTable(pfChannel *chan, pfList *gstable);
pfList * pfGetChanGStateTable(const pfChannel *chan);
void pfChanStressFilter(pfChannel *chan, float frac,
float low, float high, float scale, float max);
void pfGetChanStressFilter(const pfChannel *chan,
float *frac, float *low, float *high, float *scale,
float *max);
Page 4
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
void pfChanStress(pfChannel *chan, float stress);
float pfGetChanStress(const pfChannel *chan);
float pfGetChanLoad(const pfChannel *chan);
void pfChanTravMode(pfChannel *chan, int trav, int mode);
int pfGetChanTravMode(const pfChannel *chan, int trav);
void pfChanTravMask(pfChannel* chan, int trav, uint mask);
uint pfGetChanTravMask(const pfChannel* chan, int trav);
void pfChanBinSort(pfChannel *chan, int bin, int sortType,
uint64_t *sortOrders);
int pfGetChanBinSort(const pfChannel *chan, int bin,
uint64_t *sortOrders);
void pfChanBinOrder(pfChannel *chan, int bin, int order);
int pfGetChanBinOrder(const pfChannel *chan, int bin);
int pfGetChanFreeBin(pfChannel* chan);
void pfChanBinSortPriority(pfChannel* _chan, int bin,
int priority);
int pfGetChanBinSortPriority(const pfChannel* _chan,
int bin);
void pfChanBinChildOrderMask(pfChannel* _chan, int bin,
uint64_t orderMask);
uint64_t pfGetChanBinChildOrderMask(const pfChannel* _chan,
int bin);
void pfChanBinFlags(pfChannel* _chan, int bin, int flags);
int pfGetChanBinFlags(const pfChannel* _chan, int bin);
void pfChanBinCallBack(pfChannel* _chan, int bin, int type,
pfDListFuncType func);
pfDListFuncType pfGetChanBinCallBack(pfChannel* _chan, int bin,
int type);
void pfChanBinUserData(pfChannel* _chan, int bin,
void *userData, int size);
Page 5
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
void* pfGetChanBinUserData(pfChannel* _chan, int bin,
int *size);
int pfChanFindSubBin(pfChannel* _chan, int bin1, int bin2,
int create);
int pfChanFindBinParent(pfChannel* _chan, int bin,
int lastKnownParent);
pfCullProgram* pfGetChanCullProgram(pfChannel* _chan);
void pfChanView(pfChannel* chan, pfVec3 xyz, pfVec3 hpr);
void pfGetChanView(pfChannel* chan, pfVec3 xyz, pfVec3 hpr);
void pfChanViewMat(pfChannel* chan, pfMatrix mat);
void pfGetChanViewMat(const pfChannel* chan, pfMatrix mat);
void pfChanViewOffsets(pfChannel* chan, pfVec3 xyz,
pfVec3 hpr);
void pfGetChanViewOffsets(const pfChannel* chan, pfVec3 xyz,
pfVec3 hpr);
void pfGetChanOffsetViewMat(const pfChannel *chan,
pfMatrix mat);
pfFrameStats * pfGetChanFStats(pfChannel* chan);
int pfChanStatsMode(pfChannel* chan, uint mode, uint val);
void pfDrawChanStats(pfChannel* chan);
void pfChanLODAttr(pfChannel* chan, int attr, float val);
float pfGetChanLODAttr(pfChannel* chan, int attr);
void pfChanProjMode(pfChannel* chan, int mode);
int pfGetChanProjMode(const pfChannel* chan);
pfPipeVideoChannel *
pfGetChanPVChan(const pfChannel* chan);
void pfChanPWinPVChanIndex(pfChannel* chan, int num);
int pfGetChanPWinPVChanIndex(const pfChannel* chan);
void pfChanOutputViewport(const pfChannel* chan, float l,
float r, float b, float t);
Page 6
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
void pfGetChanOutputViewport(const pfChannel* chan,
float *l, float *r, float *b, float *t);
void pfGetChanOutputOrigin(const pfChannel* chan, int *xo,
int *yo);
void pfGetChanOutputSize(const pfChannel* chan, int *xs,
int *ys);
void pfChanPixScale(pfChannel* chan, float s);
float pfGetChanPixScale(const pfChannel* chan);
void pfChanMinPixScale(pfChannel* chan, float min);
float pfGetChanMinPixScale(const pfChannel* chan);
void pfChanMaxPixScale(pfChannel* chan, float max);
float pfGetChanMaxPixScale(const pfChannel* chan);
int pfGetChanUserFrustType(const pfChannel* _chan);
void pfGetChanBaseUserFrust(const pfChannel* _chan,
pfFrustum *frust);
float pfGetChanUserAspect(pfChannel* _chan);
void pfGetChanUserFOV(const pfChannel* _chan, float *fovH,
float *fovV);
void pfGetChanUserNearFar(const pfChannel* _chan, float *n,
float *f);
void pfGetChanUserNear(const pfChannel* chan, pfVec3 ll,
pfVec3 lr, pfVec3 ul, pfVec3 ur);
void pfGetChanUserFar(const pfChannel* chan, pfVec3 ll,
pfVec3 lr, pfVec3 ul, pfVec3 ur);
void pfGetChanUserPtope(const pfChannel* _chan,
pfPolytope *dst);
int pfGetChanUserEye(const pfChannel* _chan, pfVec3 eye);
void pfUserLeftRightBottomTopChan(pfChannel* _chan,
float *l, float *r, float *b, float *t);
int pfChanUserContainsPt(const pfChannel* _chan,
const pfVec3 pt);
Page 7
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
int pfChanUserContainsSphere(const pfChannel* _chan,
const pfSphere *sphere);
int pfChanUserContainsBox(const pfChannel* _chan,
const pfBox *box);
int pfChanUserContainsCyl(const pfChannel* _chan,
const pfCylinder *cyl);
void pfChanCallig(pfChannel* chan, pfCalligraphic* callig);
pfCalligraphic* pfGetChanCallig(const pfChannel* chan);
pfCalligraphic* pfGetChanCurCallig(pfChannel* chan);
void pfChanCalligEnable(pfChannel* chan, int enable)
int pfGetChanCalligEnable(const pfChannel* chan);
void pfApp(void);
void pfCull(void);
void pfDraw(void);
void pfLPoint(void);
void pfDrawBin(int bin);
void pfDrawScene(void);
void pfNodePickSetup(pfNode *node);
PARENT CLASS FUNCTIONS
The OpenGL Performer class pfChannel is derived from the parent class
pfObject, so each of these member functions of class pfObject are also
directly usable with objects of class pfChannel. Casting an object of
class pfChannel 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);
Page 8
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
Since the class pfObject is itself derived from the parent class
pfMemory, objects of class pfChannel 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);
PARAMETERS
chan identifies a pfChannel.
node identifies a pfNode.
trav is a symbolic token identifying a traversal:
PFTRAV_CULL
PFTRAV_DRAW
DESCRIPTION
A pfChannel is essentially a view onto a scene. pfNewChan creates a new
pfChannel on the pfPipe identified by pipe. The new pfChannel will be
rendered by the pipe into a pfPipeWindow window associated with pipe (See
pfConfigPWin). pfNewChan creates and returns a handle to a pfChannel.
pfChannels are always allocated from shared memory.
pfGetChanClassType returns the pfType* for the class pfChannel. The
pfType* returned by pfGetChanClassType is the same as the pfType*
returned by invoking pfGetType on any instance of class pfChannel.
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.
PIPE WINDOWS, PIPES, AND CHANNELS
pfGetChanPipe returns the parent pfPipe of chan. pfGetChanPWin returns
the pfPipeWindow of chan.
Page 9
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
Multiple pfChannels may be rendered by a single pfPipe into a single
pfPipeWindow. It is recommended that multiple pfChannels rather than
multiple pfPipes be used to render multiple views on a single hardware
pipeline. If necessary, multiple pfPipeWindows can be rendered by a
single pfPipe on a single hardware pipeline. The handle returned by
pfNewChan should be used to identify the pfChannel in OpenGL Performer
routines.
Upon creation, pfChannels are automatically assigned to the first
pfPipeWindow of its parent pfPipe. pfGetChanPWin will return the
pfPipeWindow of chan.
Channels of a pfPipeWindow are drawn in the order in which they are
assigned to the pfPipeWindow. pfGetChanPWinIndex can be used to get the
position of a channel in its pfPipeWindow list. A return value of (-1)
indicates that the channel is not assigned to a pfPipeWindow. Channels
can be re-ordered in their pfPipeWindow, or moved to other pfPipeWindows
via list style API on pfPipeWindows. See the pfAddChan, pfInsertChan,
pfMoveChan, and pfRemoveChan man pages for more information.
All active pfChannels are culled and drawn by pfFrame. A pfChannel is by
default active but can be selectively turned on and off by PFDRAW_ON and
PFDRAW_OFF arguments to pfChanTravMode. Multiple pfChannels on a pfPipe
will be drawn only if they are assigned to a pfPipeWindow and will be
drawn in the order they were assigned to that pfPipeWindow.
pfChanViewport specifies the fractional viewport used by chan. l, r, b,
t specify the left, right, bottom, and top extents of a viewport in the
range 0.0 to 1.0. The fractional viewport is relative to the parent
pfPipe's graphics window. Channel viewports on a single pfPipe may
overlap. Viewport extents are clamped to the range 0.0 to 1.0.
pfGetChanViewport copies the fractional viewport of chan into l, r, b, t.
pfChanOutputViewport sets the area of the pfChannel viewport that is to
be output to display. Typically this does not need to be set and is by
default equal to that set by pfChanViewportpfChanProjMode is used to set
the projection mode, which is important when using the Dynamic Video
Resizing (DVR) feature of InfiniteReality graphics systems. In operation,
the two modes are nearly indistinguishable and are mostly important in
the case where a pfChannel has a draw callback function that expects the
viewport to be set to the default (PFCHAN_PROJ_OUTPUT_VIEWPORT) value.
The mode argument is one of these values:
PFCHAN_PROJ_OUTPUT_VIEWPORT
This is the default mode of operation. it sets the graphics
library viewport and scissor mask (see glScissor(3g)) to the
output viewport of the pfChannel, which typically is also the
full viewport.
Page 10
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
PFCHAN_PROJ_VIEWPORT
The viewport will be set to the full pfChannel viewport but the
screen scissor mask will be set to the pfChannel output
viewport.
PFCHAN_PROJ_WINDOW
This mode sets the graphics library viewport for the pfChannel
to be the full extent of the pfPipeWindow, then uses the
projection matrix and GL scissor mask to scale down the
displayed area to the output viewport. This can be important
when using the DVR facility since it reduces any jitter that
might otherwise occur between adjacent channels caused by
clamping viewport boundaries to integer pixel values.
Use pfGetChanProjMode to get the current setting of a channel's
projection mode.
pfGetChanOrigin copies the window coordinates of the origin of chan's
viewport into xo and yo.
pfGetChanSize copies the X and Y pixel sizes of chan's viewport into xs
and ys.
APPLICATION-DEFINED CALLBACKS AND DATA
Although OpenGL Performer normally handles all culling and drawing,
invocation of user written and registered extension functions (callback
functions) is supported to allow custom culling and drawing by the
application. Furthermore, OpenGL Performer manages callback data such
that when configured for multiprocessing, data contention and
synchronization issues are handled transparently.
pfChanTravFunc sets the application, cull, draw or light points process
callback functions for chan. The trav argument specifies which traversal
is to be set and is one of: PFTRAV_APP, PFTRAV_CULL, PFTRAV_DRAW or
PFTRAV_LPOINT. User-data that is passed to these functions is allocated
on a per-channel basis by pfAllocChanData. pfAllocChanData returns a
pointer to a word-aligned buffer of shared memory of size bytes.
Alternately, applications can provide passthrough data with pfChanData.
data is a memory block of size bytes which should be allocated from a
shared malloc arena visible to all OpenGL Performer processes when
multiprocessing (see pfMultiprocess).
pfGetChanDataSize returns the size of chan's passthrough data block.
pfGetChanData returns a pointer to a buffer that was set by pfChanData or
allocated by pfAllocChanData or NULL if no buffer has been allocated or
set. pfGetChanTravFunc returns the app, cull or draw callback functions
for chan or NULL if the callback has not been set.
In order to propagate user data downstream to the cull and draw
callbacks, pfPassChanData should be called whenever the user data is
Page 11
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
changed to indicate that the data should be "passed through" the OpenGL
Performer rendering pipeline. The next call to pfFrame will copy the
channel buffer into internal OpenGL Performer memory so that the
application will then be free to modify data in the buffer without fear
of corruption.
In the cull phase of the rendering pipeline, OpenGL Performer invokes the
cull callback with a pointer to the pfChannel being culled and a pointer
to the pfChannel's data buffer. The cull callback may modify data in the
buffer. The potentially modified buffer is then copied and passed to the
user's draw callback. Modifications to the data buffer are not visible
upstream. For example, changes made by the cull or draw process are not
seen by the application process.
When OpenGL Performer is configured for multiprocessing (see
pfMultiprocess), it is important to realize that the cull and draw
callbacks may be invoked from different processes and thus may run in
parallel with each other as well as with the main application process.
OpenGL Performer provides both shared arenas (see pfGetSemaArena and
pfGetSharedArena) and channel data (pfAllocChanData) for interprocess
communication.
With user callbacks, it is possible to extend or even completely replace
OpenGL Performer actions with custom traversal, culling and drawing.
pfApp, pfCull, pfDraw and pfLPoint trigger the default OpenGL Performer
processing. This default processing is invoked automatically in the
absence of any user callbacks specified by pfChanTravFunc , otherwise the
user callback usually invokes them directly.
pfApp carries out the application traversal for the channel and should
only be invoked in the application callback specified by pfChanTravFunc.
The application callback is invoked once for each channel group that is
sharing PFCHAN_APPFUNC.
pfLPoint runs in parallel with draw. It opens a ring display list and
preprocess the light points in the bin that has been provided by the
culling. The display list stays opened after the call to pfLPoint() so
every command issued after that call will be sent over to the draw
process. Note that every command issued before pfLPoint() will be
immediately executed, such as pfCalligraphic parametrisation for the
current frame. Note also that the light point process does not have any
graphic context and therefore it is forbidden to do some direct graphic
calls here.
pfCull should only be called in the cull callback and causes OpenGL
Performer to cull the current channel and generate an OpenGL Performer
display list (see pfDispList) suitable for rendering if the
PFMP_CULL_DL_DRAW multiprocessing mode is enabled (see pfMultiprocess).
Then, in the draw callback only, pfDraw will traverse the pfDispList and
send rendering commands to the graphics hardware, thus drawing the scene.
If the PFMP_CULL_DL_DRAW multiprocessing mode is not set then all
Page 12
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
display-listable operations will be applied directly to the graphics
pipeline rather than accumulated in a pfDispList for subsequent drawing.
In essence, the draw process does the work of both pfCull and pfDraw
without the intermediate step of building a pfDispList. This mode avoids
the overhead of building and traversing a pfDispList but consequently is
not suitable for multipass renderings which require multiple invocations
of pfDraw.
When the draw callback is invoked, the graphics context will already have
been properly configured for drawing the pfChannel. Specifically, the
viewport, perspective and viewing matrices are set to the correct values.
In addition, graphics library light sources corresponding to the active
pfLightSources in the scene will be enabled so that geometry rendered in
the draw callback will be properly lit. User modifications of this
initial state are not reset by pfDraw.
If a draw callback is specified, OpenGL Performer will not automatically
clear the viewport, leaving control of this to the application.
pfClearChan called from the draw callback will clear the channel
viewport. If chan has a pfEarthSky (see pfChanESky), then the pfEarthSky
will be drawn. Otherwise, the viewport will be cleared to black and the
z-buffer cleared to its maximum value.
By default, pfFrame causes pfCull and pfDraw to be invoked for each
active pfChannel. It is legal for the draw callback to call pfDraw more
than once for multipass renderings. Note that pfDraw will render the
internal multipass pfLightSource projected texture lights and shadows
every time it is called. pfDrawScene may be more convenient as it will
draw the scene without the internal multipass.
Example 1: Set up channel callbacks and passthrough data
typedef struct
{
int val;
} PassData;
void cullFunc(pfChannel *chan, void *data);
void drawFunc(pfChannel *chan, void *data);
int
main()
{
PassData *pd;
/* Initialize OpenGL Performer */
pfInit();
pfConfig();
/* Create and initialize pfChannel 'chan' */
chan = pfNewChan(pfGetPipe(0));
Page 13
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
:
/* Setup channel passthrough data */
pd = (PassData*)pfAllocChanData(chan, sizeof(PassData));
/* Bind cull and draw callback functions to channel */
pfChanTravFunc(chan, PFTRAV_CULL, cullFunc);
pfChanTravFunc(chan, PFTRAV_DRAW, drawFunc);
pd->val = 0;
pfPassChanData(chan);
pfFrame();
:
}
void
cullFunc(pfChannel *chan, void *data)
{
PassData *pd = (PassData*)data;
pd->val++;
pfCull();
}
void
drawFunc(pfChannel *chan, void *data)
{
PassData *pd = (PassData*)data;
fprintf(stderr, "%ld\n", pd->val);
pfClearChan(chan);
pfDraw();
}
SHARING ATTRIBUTES THROUGH CHANNEL GROUPS
OpenGL Performer supports the notion of a 'channel group' which is a
collection of pfChannels that share certain attributes. A channel group
is created by attaching a pfChannel to another with pfAttachChan. If
chan0 or chan1 are themselves members of a channel group, then all
channels that are grouped with either chan0 or chan1 are combined into a
single channel group. All attached channels acquire the share mask and
shared attributes of the channel group. A channel is removed from a
channel group by pfDetachChan.
The attributes shared by the members of a channel group are specified by
the mask argument to pfChanShare. By definition, all channels in a group
have the same share mask. A pfChannel that is attached to a channel
group inherits the share mask of the group. mask is a bitwise OR of the
following tokens which enumerate the attributes that can be shared:
Page 14
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
PFCHAN_FOV
Horizontal and vertical fields of view are shared.
PFCHAN_VIEW
The view position and orientation are shared.
PFCHAN_VIEW_OFFSETS
The XYZ and HPR offsets from the view direction are shared.
PFCHAN_NEARFAR
The near and far clip planes are shared.
PFCHAN_SCENE
All channels display the same scene.
PFCHAN_EARTHSKY
All channels display the same earth-sky model.
PFCHAN_STRESS
All channels use the same stress filter parameters.
PFCHAN_LOD
All channels use the same LOD modifiers.
PFCHAN_SWAPBUFFERS
All channels swap buffers at the same time, even when the
channels are on multiple pfPipes.
PFCHAN_SWAPBUFFERS_HW
All channels swap buffers at the same time. Under IrisGL the
GANGDRAW feature of the mswapbuffers function, under OpenGL the
glxSwapBarrier extension, is used to synchronize buffer
swapping through hardware interlocking. When channels are
distributed across more than one pipe, the SwapReady signal is
to be connected between the pipes. This signal can also be
used to synchronize graphics pipelines across multiple
machines.
PFCHAN_STATS_DRAWMODE
All channels draw the same statistics graph.
PFCHAN_APPFUNC
The application callback is invoked once for all channels
sharing PFCHAN_APPFUNC.
PFCHAN_CULLFUNC
All channels invoke the same channel cull callback.
PFCHAN_DRAWFUNC
All channels invoke the same channel draw callback.
Page 15
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
PFCHAN_LPOINTFUNC
All channels invoke the same channel light points callback.
PFCHAN_VIEWPORT
All channels use the same viewport specification.
pfGetChanShare returns the share mask of chan. The default attributes
cause channels within a share group to share all attributes except
PFCHAN_VIEW_OFFSETS, PFCHAN_VIEWPORT and PFCHAN_SWAPBUFFERS_HW.
Channel groups are useful for multichannel simulations where many of the
viewing parameters are the same across pfChannels. For example, a 3-
channel simulation consisting of left, middle, and right views typically
shares the near and far clipping planes. With a channel group, the
clipping planes need only be set on a single pfChannel, say the middle
one, and all other pfChannels in the group will acquire the same
settings.
Example 1: Set up a single pipe, 3-channel simulation
left = pfNewChan(pfGetPipe(0));
middle = pfNewChan(pfGetPipe(0));
right = pfNewChan(pfGetPipe(0));
/* Form channel group with middle as the "master" */
pfAttachChan(middle, left);
pfAttachChan(middle, right);
/* Set FOV of all channels */
pfMakeSimpleFrust(middle, 45.0f);
pfChanAutoAspect(middle, PFFRUST_CALC_VERT);
/* Set clipping planes of all channels */
pfChanNearFar(middle, 1.0f, 2000.0f);
pfSetVec3(hprOffsets, 0.0f, 0.0f, 0.0f);
pfSetVec3(xyzOffsets, 0.0f, 0.0f, 0.0f);
/*
* Set up viewport and viewing offsets.
* Note that these are not shared by default.
*/
pfChanViewport(left, 0.0f, 1.0f/3.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = 45.0f;
pfChanViewOffsets(left, xyzOffsets, hprOffsets);
pfChanViewport(middle, 1.0f/3.0f, 2.0f/3.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = 0.0f;
pfChanViewOffsets(middle, xyzOffsets, hprOffsets);
pfChanViewport(right, 2.0f/3.0f, 1.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = -45.0f;
Page 16
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
pfChanViewOffsets(right, xyzOffsets, hprOffsets);
VIEWING FRUSTUM
Many pfChannel frustum routines are borrowed from pfFrustum. These
routines have the identical function as the pfFrustum routines but
operate on the pfChannel's internal viewing frustum. The routine
correspondence is listed in the following table.
pfChannel routine pfFrustum routine
____________________________________________
pfMakeSimpleChan pfMakeSimpleFrust
pfMakePerspChan pfMakePerspFrust
pfMakeInfPerspChan pfMakeInfPerspFrust
pfMakeOrthoChan pfMakeOrthoFrust
pfChanNearFar pfFrustNearFar
pfGetChanNearFar pfGetFrustNearFar
pfGetChanFOV pfGetFrustFOV
pfChanAspect pfFrustAspect
pfGetChanAspect pfGetFrustAspect
pfGetChanFrustType pfGetFrustType
pfOrthoXformChan pfOrthoXformFrust
pfGetChanNear pfGetFrustNear
pfGetChanFar pfGetFrustFar
pfGetChanEye pfGetFrustEye
pfApplyChan pfApplyFrust
pfChanContainsPt pfFrustContainsPt
pfChanContainsSphere pfFrustContainsSphere
pfChanContainsBox pfFrustContainsBox
pfChanContainsCyl pfFrustContainsCyl
|
The reader is referred to the pfFrustum man page for details on the
function descriptions.
In addition to the pfFrustum routines, OpenGL Performer provides the
pfChanFOV and pfChanAutoAspect convenience routines.
The horiz and vert arguments to pfChanFOV specify total horizontal and
vertical fields of view (FOV) in degrees. If either angle is <= 0.0 or
>= 180.0, OpenGL Performer will automatically compute that field of view
based on the other specified field of view and the aspect ratio of the
pfChannel viewport. If both angles are defaulted in this way, OpenGL
Performer will use its default of horiz=45.0 with vert matched to the
aspect ratio of the pfChannel. Note that the aspect ratio of a pfChannel
is defined by its fractional viewport as well as the pixel size of its
physical display window.
pfChanFOV constructs a on-axis frustum, one where the line from the
eyepoint passing through the center of the image is perpendicular to the
projection plane. pfMakeSimpleChan also creates an on-axis frustum but
both horizontal and vertical fields of view are specified with fov.
Page 17
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
pfGetChanFOV copies the total horizontal and vertical fields of view into
horiz and vert respectively. If an angle is matched to the aspect ratio
of the pfChannel, then the computed angle is returned.
The which argument to pfChanAutoAspect specifies which FOV extent to
automatically match to the aspect ratio of chan's viewport. which is a
symbolic token and is one of:
PFFRUST_CALC_NONE
Do not automatically modify field of view.
PFFRUST_CALC_HORIZ
Automatically modify horizontal FOV to match channel aspect.
PFFRUST_CALC_VERT
Automatically modify vertical FOV to match channel aspect.
Automatic aspect ratio matching is useful for situations where the
initial size of the display window is not known or where the display
window may change size during runtime. Aspect ratio matching guarantees
that the image will not be distorted in either horizontal or vertical
dimensions. pfMakePerspChan and pfMakeOrthoChan disable automatic aspect
ratio matching since it is assumed that the viewing frustum aspect ratio
is completely specified by these commands.
pfChanNearFar specifies the near and far clip distances of the viewing
frustum. near and far are the positive, world-coordinate distances along
the viewing ray from the eye point to the near and far clipping planes
which are parallel to the viewing plane. pfGetChanNearFar copies the
near and far clipping distances into near and far. The default values
are 1.0 for the near plane and 1000.0 for the far plane.
pfGetChanBaseFrust copies the base viewing frustum of chan into frust.
The base viewing frustum has its eyepoint at the origin and its viewing
direction as the +Y axis. The base frustum of a pfChannel is transformed
into world coordinates by the viewing transformation (see pfChanView).
pfOrthoXformChan transforms the base frustum of src by mat and copies the
result into the base frustum of the dst pfChannel. pfGetChanPtope copies
the transformed base frustum into dst.
Example 1: Two equivalent ways of defining a typical viewing channel.
This method is the easiest and most common.
/* Set up a simple viewing frustum */
chan = pfNewChan(pipe0);
/*
* Set horizontal FOV to 45 degrees and automatically match
* vertical FOV to channel viewport.
*/
pfChanFOV(chan, 45.0f, -1.0f);
Page 18
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
Here's how to do the same thing using the basic primitives.
/* Set up a simple viewing frustum */
chan = pfNewChan(pipe0);
/*
* Set horizontal FOV to 45 degrees and automatically match
* vertical FOV to channel viewport.
*/
pfMakeSimpleChan(chan, 45.0f);
pfChanAutoAspect(chan, PFFRUST_CALC_VERT);
Example 2: Set up a 4 channel, 4 pipe video wall with total horizontal
and vertical FOVs of 90 degrees.
/*
* ul == upper left ur == upper right
* ll == lower left lr == lower right
*/
llChan = pfNewChan(pfGetPipe(0));
lrChan = pfNewChan(pfGetPipe(1));
urChan = pfNewChan(pfGetPipe(2));
ulChan = pfNewChan(pfGetPipe(3));
/* Form channel group with urChan as the "master" */
pfAttachChan(urChan, llChan);
pfAttachChan(urChan, lrChan);
pfAttachChan(urChan, ulChan);
/*
* Share viewport but not field of view
* in addition to the default shared attributes.
*/
share = pfGetChanShare(urChan);
pfChanShare(urChan, (share & ~PFCHAN_FOV) | PFCHAN_VIEWPORT );
/*
* Set up off-axis viewing frusta which "tile" video wall.
* pfChannel viewport aspect ratio must be 1:1 or image will
* be distorted.
*/
pfMakePerspChan(llChan, -1.0f, 0.0f, -1.0f, 0.0f);
pfMakePerspChan(lrChan, 0.0f, 1.0f, -1.0f, 0.0f);
pfMakePerspChan(urChan, 0.0f, 1.0f, 0.0f, 1.0f);
pfMakePerspChan(ulChan, -1.0f, 0.0f, 0.0f, 1.0f);
pfChanNearFar(urChan, 1.0f, 2000.0f);
Page 19
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
Example 3: Set up a single pipe, 3-channel simulation.
left = pfNewChan(pfGetPipe(0));
middle = pfNewChan(pfGetPipe(0));
right = pfNewChan(pfGetPipe(0));
/* Form channel group with middle as the "master" */
pfAttachChan(middle, left);
pfAttachChan(middle, right);
/* Set FOV of all channels */
pfMakeSimpleChan(middle, 45.0f);
pfChanAutoAspect(middle, PFFRUST_CALC_VERT);
/* Set clipping planes of all channels */
pfChanNearFar(middle, 1.0f, 2000.0f);
hprOffsets[PF_P] = 0.0f;
hprOffsets[PF_R] = 0.0f;
pfSetVec3(xyzOffsets, 0.0f, 0.0f, 0.0f);
/*
* Set up viewport and viewing offsets.
* Note that these are not shared by default.
*/
pfChanViewport(left, 0.0f, 1.0f/3.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = 45.0f;
pfChanViewOffsets(left, hprOffsets, xyzOffsets);
pfChanViewport(middle, 1.0f/3.0f, 2.0f/3.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = 0.0f;
pfChanViewOffsets(middle, hprOffsets, xyzOffsets);
pfChanViewport(right, 2.0f/3.0f, 1.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = -45.0f;
pfChanViewOffsets(right, hprOffsets, xyzOffsets);
Example 4: Custom culling to pfChannel viewing frustum.
/*
* User-supplied cull callback (see pfChanTravFunc)
*/
extern void
myCullFunc(pfChannel *chan, void *data)
{
pfBox *boundingBox = (pfBox*)data;
if (pfChanContainsBox(chan, boundingBox))
drawGSetsWithinBoundingBox();
}
Page 20
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
pfASDattachChan lets one channel shares the active geometry evaluated by
pfASD nodes from another channel. Normally, pfASD evaluates separate
active meshes based on each channel that traverses the node. It
automatically ensures that the meshes are consistantly connected between
channels. This is very useful for multiple channels that panel a wall
like shown above. If channels have very different view points, such as in
a multi-player game, then the application should define one pfASD node
for each channel, since the active mesh is going to be very different
from one channel to the other. This is especially important if one
channel is going to have a different evaluation function or a different
LODRange from another, e.g. infra-rad channel and regular channel. pfASD
nodes can share the same raw attribute data, such as pfASDFaces, and
pfASDVerts.
In some applications, one channel would like to display the same geometry
as another channel, e.g. a bird's eye view of the terrain, then this API
should be used to define it. chan0 is the current channel, and chan1 is
the channel that supplies the orginal active mesh. The API can be called
multiple times to define that channel0 shares active meshes from multiple
channels. Example: Define an inset window that looks at the active
geometry generated by master channel traversal.
/* top down view of the active geometry in master Channel */
pfASDattachChan(ViewState->insetChannel, masterChan);
pfASDdettachChan detaches the channel from sharing the active mesh from
another channel.
pfGetChanAutoAspect returns the aspect ratio matching mode of chan.
A pfChannel normally uses its viewing frustum for culling its pfScene (-
pfChanScene). However, a custom culling volume may be specified by
pfChanCullPtope. If non-NULL, ptope identifies a pfPolytope which is
used for scene culling. A copy of ptope, internal to chan, is transformed
by chan's viewing matrix before culling. If ptope is NULL, chan will use
its view frustum for culling. A pfPolytope is a set of half spaces whose
intersection defines a convex volume. Culling performance will be
proportional to the number of facets in ptope. pfGetChanCullPtope copies
the culling polytope of chan into ptope. The space argument must be one
of the constants PF_WORLDSPACE or PF_EYESPACE; the culling polytope will
be expressed in the respective coordinate space.
VIDEO CHANNELS
The pfPipeVideoChannel associated with a channel is returned by
pfGetChanPVChan. In the indexed case, the pfPipeVideoChannel index is set
to num using pfChanPWinPVChanIndex and returned by
pfGetChanPWinPVChanIndex.
With Dynamic Video Resolution, the actual rendering area (known as the
Page 21
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
output viewport) may be smaller than the nominal channel viewport. The
size of the actual viewport area is available from
pfGetChanOutputViewport where the l, r, b, and t arguments are pointers
to float values that will be updated by the call.
The origin and size of a channel are dynamic under the effect of video
resizing in the same sense. As an example, a viewport whose lower-left
corner is at the center of the pfPipe (with coordinates 0.5, 0.5) would
be changed to an origin of (0.25, 0.25) with respect to the full pfPipe
window if the DVR settings were for scale factors of 0.5 in both X and Y.
The actual rendering origin of a pfChannel is available from
pfGetChanOutputOrigin with the returned values in the integers pointed to
by xo and yo. The size of a viewport also changes when DVR scaling is in
use, and the actual values are returned by pfGetChanOutputSize in the
integers pointed to by xs and ys.
When Dynamic Video Resolution is used to alter the rendered size of a
pfChannel, a corresponding change should be made to the width of points
and lines, the two geometry types that support a specific pixel width.
For example, when a channel is scaled in size by on half, lines and
points must be drawn half as wide as well so that when the final image is
enlarged by the inverse scale factor, in this case two, the lines and
points will have the same screen size. pfChanPixScale sets the indicated
channel's pixel scale factor to s. pfGetChanPixScale returns this value
for the channel.
Channels also have minimum and maximum pixel scale values, that can be
used to define an acceptable range of pixel scale values. This can be
used to keep lines and points from getting too thin under the effects of
extreme DVR scaling. pfChanMinPixScale sets the minimum allowable pixel
scale value for the channel, and pfGetChanMinPixScale gets the value.
pfChanMaxPixScale sets the maximum allowable pixel scale value for the
channel, and pfGetChanMaxPixScale gets the value.
COMPOSITOR
When developing multi-pipe applications through the use of the
pfCompositor class and related API, the user must not create pfChannels
on compositor-slave-pipes, ie pfPipes which are managed by a pfCompositor
but which are not compositor master pipes.
Each time a pfChannel is created on a master compositor pipe, OpenGL
Performer will automatically create an associated compositor- slave
pfChannel on all slave-pipes of the pfCompositor.
Additionally, most pfChannel methods called on a master-compositor
pfChannel will automatically be propagated to all associated compositor
slaves.
Compositor-related method propagation can be enabled and disabled for
individual pfChannel methods through pfChanCompositorShareMask.
Page 22
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
pfGetChanCompositorShareMask can be used to query which pfChannel methods
will be propagated according to current settings. In both methods,
different PFCOMP_SHARE_* tokens are 'OR-ed' together to express share
mask as a single integer value. See man pfCompositor for a full list of
the PFCOMP_SHARE_* tokens. Note that most of these tokens have a one-
to-one correspondance with PFCHAN_* share tokens used by pfChanShare.
pfChannels managed by pfCompositor objects will generally render to only
a portion of the viewport specified by the application on master
compositor chennel. Consequently, also the frustum atually used for
culling and drawing a composited channel will differ from the (nominal)
frustum specified by application on master compositor channel.
A number of pfChannel methods have a compositor-related counterpart
(another pfChannel method) allowing user to retrieve both 'nominal' and
'actual' pfChannel parameters.
Below is a list of compositor-related method-pairs. For composited
pfChannels, the 'User' versions of these methods will refer to the
pfChannel's frustum as set by the user on compositor's master channel.
The non-User methods instead refer to the actual frustum used for culling
and rendering the pfChannel, as computed the by pfCompositor.
Note that for regular (non-composited) pfChannels, both methods in any of
the pairs below should yield the same result.
Page 23
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
actual frustum nominal frustum
_______________________________________________________
pfGetChanUserFrustType pfGetChanFrustType
pfGetChanBaseUserFrust pfGetChanBaseFrust
pfGetChanUserAspect pfGetChanAspect
pfGetChanUserFOV pfGetChanFOV
pfGetChanUserNearFar pfGetChanNearFar
pfGetChanUserNear pfGetChanNear
pfGetChanUserFar pfGetChanFar
pfGetChanUserPtope pfGetChanPtope
pfGetChanUserEye pfGetChanEye
pfUserLeftRightBottomTopChan pfLeftRightBottomTopChan
pfChanUserContainsPt pfChanContainsPt
pfChanUserContainsSphere pfChanContainsSphere
pfChanUserContainsBox pfChanContainsBox
pfChanUserContainsCyl pfChanContainsCyl
|
CALLIGRAPHIC LIGHT POINTS
If a LightPointBoard has been found and initialized before pfConfig, each
pfPipeVideoChannel is automatically setup with a pfCalligraphic
initialized with the pfPipeVideoChannel screen as the Light Point Board
number, and the Video Channel Id as the output to use for calligraphic
light points. You may change this automatic behavior by setting you own
pfCalligraphic on the pfPipeVideoChannel (see pfPVChanCallig).
It is also possible to specify a pfCalligraphic per channel using
pfChanCallig and pfGetChanCallig get the value that has been set.
pfGetChanCurCallig get the pfCalligraphic that is used for this
pfChannel. If a pfCalligraphic has been set then this value is returned,
otherwise the pfCalligraphic set in the pfPipeVideoChannel is returned.
The lightpoint board is connected to the SwapReady signal to be
synchronized with the swapBuffer of the graphic pipe. Usually, the
SwapReady signal is enabled only when more than one pipe is used by an
application, in order to synchronize the swapBuffer of channels
distributed across more than one pipe. However, the signal SwapReady has
to be enabled even in single pipe configuration. Enabling calligraphic
light points on a pfChannel will take care of that by attaching the
pfWindow to a swapBarrier. To enable calligraphic call
pfChanCalligEnable with 1 as enable. pfGetChanCalligEnable returns this
value. By default calligraphic light points are not enabled, the returned
value is therefore 0.
PICKING
pfChanPick is used for screen to world-space ray intersections on a
pfChannel's scene. This operation is often referred to as picking.
Intersections will only occur with parts of the database that are within
the viewing frustum, and that are enabled for picking intersections. The
Page 24
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
return value of pfChanPick is the number of successful intersections with
the channel scene according to mode.
picklist is a user-supplied pointer. Upon return, the address of an
array of pointers to pfHit objects is stored there. The pfHit objects
come from an internally maintained pool and are reused on subsequent
calls. Hence, the contents are only valid until the next invocation of
pfChanPick in the current process. They should not be deleted by the
application.
The contents of the pfHit object are queried using pfQueryHit and
pfMQueryHit. See the man pages for pfHit and pfNodeIsectSegs for a
description of the queries.
mode specifies the behavior of the traversal and type of information that
will be returned from the picking process.
mode is a bitwise OR of tokens. In addition to those tokens that can be
specified to pfNodeIsectSegs in the mode field of the pfSegSet, the
following values are also allowed:
PFPK_M_NEAREST
Return the picking intersection closest to the viewpoint.
PFPK_M_ALL
Return all picking intersections.
PFTRAV_LOD_CUR
When traversing pfLODs, select the child to traverse based on
range in the specified channel.
When PFPK_M_ALL is set, picklist will contain all of the successful
picking intersections in order of increasing distance from the viewer
eyepoint. See the pfNodeIsectSegs manual page for information on the
PFIS_ intersection tokens.
px, py identify a 2-dimensional point in normalized channel screen
coordinates in the range 0.0 to 1.0 (with the lower left corner being
(0.0, 0.0)), that corresponds to the channel location to be used for
picking. This 2-dimensional point is used to create a ray from the
viewer eyepoint through the near clipping plane to intersect with the
channel scene.
radius is the radius of the picking region in normalized channel
coordinates used for the picking of lines. This argument is provided for
coarse picking, and possibly for eventual picking of lines and points
which is currently not implemented. If radius is non-zero, then the mode
argument must not specify the PFTRAV_IS_PRIM mode.
pfNodePickSetup enables the entire database tree under node for picking
intersections and should be called with a pointer to the pfChannel's
Page 25
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
scene graph. This effectively calls pfNodeTravMask with PFIS_SET_PICK.
Selective picking can be done by calling pfNodeTravMask, setting the
traversal to PFTRAV_ISECT and including PFIS_SET_PICK in the intersection
mask for nodes that are to be enabled for picking intersections. The
picking traversal will not continue past any node that has not been
enabled for picking intersections. See the pfNodeTravMask manual page
for more information on intersection setup.
pfChanNodeIsectSegs is identical to pfNodeIsectSegs except a pfChannel is
provided for evaluating pfLODs during the intersection traversal. In
addition, mat specifies an initial transform, allowing intersection
traversals to begin at non-root nodes. All line segments in segSet will
be transformed by mat. mat may be NULL if no initial transform is
needed.
EARTH AND SKY
pfChanScene and pfChanESky set the pfScene and pfEarthSky that chan will
cull and draw. pfChanScene increments the reference count of scene so
that scene must first be removed from chan by pfChanScene(chan, NULL)
before scene can be deleted with pfDelete.
pfGetChanScene and pfGetChanESky return the current pfScene and
pfEarthSky for chan.
Example 1: Setting a pfChannel's pfScene.
void
cullFunc(pfChannel *chan, void *data)
{
pfCull();
}
void
drawFunc(pfChannel *chan, void *data)
{
pfClearChan(chan);
pfDraw();
}
/* somewhere in application setup phase */
:
/* set channel's scene */
pfChanScene(chan, scene);
/* bind cull and draw process callbacks */
pfChanTravFunc(chan, PFTRAV_CULL, cullFunc);
pfChanTravFunc(chan, PFTRAV_DRAW, drawFunc);
Page 26
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
GEOSTATES
pfChanGState sets chan's pfGeoState to gstate. If non-NULL, gstate is
loaded before chan's DRAW callback is invoked. Specifically, gstate is
loaded with pfLoadGState so that the state encapsulated by gstate becomes
the global state that may be inherited by other pfGeoStates within the
scene graph. The pfGeoState state inheritance mechanism is described in
detail in the pfGeoState man page. Note that the channel pfGeoState is
loaded before any scene pfGeoState so that state elements in the scene
pfGeoState override those in the channel's pfGeoState. pfGetChanGState
returns the pfGeoState of chan.
pfChanGStateTable sets chan's pfGeoState table to gstable. If non-NULL,
gstable is made the global pfGeoState table with pfApplyGStateTable
before chan's DRAW callback is invoked. Any indexed pfGeoStates, either
referenced by a pfScene (pfSceneGStateIndex) or by scene pfGeoSets (-
pfGSetGStateIndex) will be accessed through gstable. Indexed pfGeoStates
are useful for efficiently managing a single database with multiple
appearances, e.g., a normal vs. an infrared view of a scene would
utilize 2 pfGeoState tables, each referencing a different set of
pfGeoStates.
STRESS PROCESSING AND LEVEL-OF-DETAIL
OpenGL Performer attempts to maintain the fixed frame rate set with
pfFrameRate by manipulating levels-of-detail (LODs) to reduce graphics
load when rendering time approaches a frame period. At the end of each
frame, OpenGL Performer computes a load metric for each pfChannel based
on the length of time it took to render the pfChannel. Load is simply
the actual rendering time divided by the desired frame interval.
pfChanLODState specifies a global pfLODState to be used for this channel.
pfChanLODStateList specifies a pfList of pfLODStates to be indexed into
by pfLODs that have specified indexes via pfLODLODStateIndex. (See pfLOD
and pfLODState).
If stress processing is enabled, OpenGL Performer uses the load metric
and a user-defined stress filter to compute a stress value which
multiplies effective LOD ranges (see pfLOD) for the next frame. Stress >
1.0 'pushes out' LOD ranges so that coarser models are drawn and graphics
load is reduced. Stress == 1.0 means the system is not in stress and
LODs are not modified.
pfChanStressFilter sets the stress filter used by chan. frac is the
fraction of a frame period chan is expected to take to render. frac
should be 1.0 if only a single pfChannel is drawn on a pfPipe and should
be > 0.0 and < 1.0 for multichannel simulations. frac allows the
application to apportion rendering time amongst multiple channels so that
a channel drawing a complex scene may be allocated more time than a
channel drawing a simple one. pfGetChanStressFilter returns the stress
filter parameters for chan.
Page 27
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
low and high define a hysteresis band for system load. When load is >=
low and <= high, stress is held constant. When load is < low or > high,
OpenGL Performer will reduce or increase stress respectively until load
stabilizes within the hysteresis band. low should be <= high and they
both should be positive. Stress is computed using the following
algorithm:
/* increase stress when above high load level */
if (load > high)
S[i] = minimum(S[i-1] + scale*load, max);
else
/* decrease stress when below low load level */
if (load < low)
S[i] = maximum(S[i-1] - scale*load, 0.0f);
else
/* stress unchanged when between low and high load levels */
S[i] = S[i-1];
where S[i] == stress for frame i and load = time[i] * frameRate / frac.
By default, scale = 0.0 and max = 1.0 so that stress is disabled. Stress
is clamped to the range [1.0, max].
pfChannels in a channel group may share a stress filter (PFCHAN_STRESS),
and LOD behavior (PFCHAN_LOD) (see pfAttachChan). It is useful for
pfChannels which draw into adjacent displays to share LOD behavior. In
this case, the LOD multiplier used by all pfChannels in the channel group
is the maximum of each individual pfChannel. This ensures that LOD's
which straddle displays will always be drawn at the same LOD on each
display.
pfGetChanLoad will return the last computed load for chan. The load
value is defined as time * frameRate / frac.
The application may choose to not use the default OpenGL Performer stress
filter by calling pfChanStress to explicitly set the stress value.
Stress values set by pfChanStress will override the default stress values
computed by the stress filter shown above.
pfGetChanStress returns the last computed stress value for chan. The
individual stress value is returned regardless of pfChannel attribute
sharing (pfChanShare).
CUSTOMIZING SCENE GRAPH TRAVERSAL
A pfChannel directs two important traversals: cull and draw. In the cull
traversal, the pfChannel defines the viewing frustum that the database is
culled to and also defines other parameters that modify level-of-detail
behavior. When drawing, the pfChannel defines the parameters of the
"camera" which views the scene. In both cases, a pfChannel traverses a
pfScene which is attached to the pfChannel via pfChanScene. A pfScene is
Page 28
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
a hierarchy of pfNodes that defines the visual database.
pfChanTravMode sets the traversal mode of chan. trav specifies a
traversal type and is either PFTRAV_CULL, PFTRAV_DRAW or PFTRAV_LPOINT,
for the culling, drawing and light points traversal respectively. mode
specifies the corresponding traversal mode. The culling mode is a
bitwise OR of:
PFCULL_VIEW
When set, PFCULL_VIEW enables culling to the viewing frustum.
If not set, the entire database will be rendered every frame.
For best drawing performance it is recommended that PFCULL_VIEW
be set. Unless PFCULL_GSET is also set, OpenGL Performer culls
the database only down to the pfGeode level.
PFCULL_SORT
When PFCULL_SORT is set, OpenGL Performer sorts the database
into "bins" which are rendered in a user-specified order. In
addition, geometry within a bin may be sorted by graphics state
like texture or by range for front-to-back or back-to-front
rendering. Unless the cull stage of the OpenGL Performer
pipeline becomes the bottleneck or PFMP_CULLoDRAW mode is used,
PFCULL_SORT should be set for optimal drawing performance.
Further sorting details are described below.
PFCULL_GSET
When PFCULL_GSET is set, OpenGL Performer culls individual
pfGeoSets within pfGeodes. At the expense of some extra
culling time, this can provide a significantly tighter cull
both because of the finer granularity and because pfGeoSet
culling uses bounding boxes rather than bounding spheres.
However, when traversing portions of the scene graph under a
transformation (pfSCS or pfDCS), OpenGL Performer reverts back
to a cull which stops at the pfGeode level.
PFCULL_IGNORE_LSOURCES
When PFCULL_IGNORE_LSOURCES is not set, OpenGL Performer will
traverse all paths in the scene hierarchy which end at a
pfLightSource node before proceeding with the normal cull
traversal (see pfLightSource). This is required for
pfLightSources to illuminate the scene and will ensure that
graphics hardware lighting is properly configured before the
user's draw callback is invoked (see pfChanTravFunc). If it is
set, any pfLightSources in the pfScene will be ignored.
The pfLightSource cull traversal obeys all traversal rules such
as node callbacks, traversal masks, transformations (pfSCS and
pfDCS nodes), and selectors (pfSwitch and pfLOD).
PFCULL_PROGRAM
When PFCULL_PROGRAM is set a cull program attached to the
channel is executed for each pfGeoSet during the cull
Page 29
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
traversal. See pfCullProgram for more details.
For drawing, mode is either PFDRAW_OFF or PFDRAW_ON. PFDRAW_OFF
essentially turns off chan. No culling or drawing traversal will take
place. Drawing is enabled by default.
When the optional light points process is used, light points
preprocessing and drawing can be disable for a particular channel giving
PFDRAW_OFF for mode. Creating a light points process enable the the
preprocessing for every channel by default.
pfGetChanTravMode returns the mode corresponding to trav or -1 if trav is
an illegal or unknown traversal type.
The PFTRAV_MULTIPASS traversal mode is only active when the pfChannel's
scene has one or more pfLightSources which use projected texture-type
lighting. See the pfLightSource man page for more details.
By default, culling to the viewing frustum, culling to pfGeoSet bounding
boxes, pfLightSource culling, and sorting is enabled: (PFCULL_VIEW |
PFCULL_GSET | PFCULL_SORT) For convenience, this default bitmask is
provided by the PFCULL_ALL token.
pfChanTravMask sets chan's drawing mask and is used in conjunction with
pfNodeTravMask for selective culling and drawing of scene graphs on a
per-pfChannel basis. During the traversal, the bitwise AND of the
traversal mask and the node mask is computed. If the result is non-zero,
the node is culled or drawn as usual. If off (zero), the behavior is as
follows depending on trav:
PFTRAV_CULL
Node is not culled and is considered to be entirely within the
viewing frustum. The cull traversal traverses the node and its
children without any view culling.
PFTRAV_DRAW
Node is completely ignored. Both cull and draw traversals skip
the node and its children. It is therefore ignored by the light
points process.
Node traversal masks are set by pfNodeTravMask. The default pfNode and
pfChannel masks are 0xffffffff so that a pfChannel culls and draws all
pfNodes.
pfGetChanTravMask returns the drawing traversal mask for the specified
pfChannel. trav is either PFTRAV_CULL or PFTRAV_DRAW.
USING BINS
As mentioned above, pfChannels can sort the database for improved image
quality and improved rendering performance. Database sorting consists of
two steps:
Page 30
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
1. Partition database into "bins" which are rendered in a
particular order.
2. Sort database within each bin by:
2a. Graphics state, in which case there is no particular rendering
order or,
2b. Range from the eyepoint in which case the database is rendered
either front-to-back or back-to-front.
During the cull traversal, pfGeoSets are placed into the appropriate bin
according to their bin identifier that was set by pfGSetDrawBin. If the
bin identifier is >= 0, the cull traversal will place that pfGeoSet into
the bin with that identifier. If the bin identifier is < 0, then the cull
traversal will decide in which default bin the pfGeoSet belongs.
Note that a pfGeoSet will not go in a bin if: - PFCULL_SORT is not set -
the bin has no drawing order set (see pfChanBinOrder) - the pfGeoSet has
no directly attached pfGeoState.
OpenGL Performer provides the following default bins:
PFSORT_OPAQUE_BIN -
Used for opaque geometry.
PFSORT_TRANSP_BIN -
Used for transparent geometry. Transparent geometry is that
which uses PFTR_BLEND_ALPHA type of pfTransparency.
PFTR_MS_ALPHA-type transparency is considered to be opaque for
purposes of binning.
PFSORT_SHADER_BIN -
Used for all shaded geometry: pfGeoSets with an islAppearance.
See man pfGeoSet::setAppearance for more information about
shaders.
PFSORT_PATCHYFOG_BIN -
Used internally by pfVolFog.
PFSORT_DEFAULT_BIN - Used for unsorted opaque geometry.
In addition, if the light points process is enabled, a special bin
PFSORT_LPSTATE_BIN is created to sort out all pfGeoSets that have a
pfLPointState attached to their pfGeoState. This bin will not be given
Page 31
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
directly to the draw process but instead will be preprocessed by
pfLPoint(). The result of the preprocessing is sent to the draw process
through an internal ring display list.
pfGetChanFreeBin returns the next available bin identifier and should be
used to avoid collisions with previously selected bins and bins that are
used internally by OpenGL Performer. Note that a bin is considered
unsused if no call to pfChanBinOrder has been made.
Bins are often used to group geometry with certain characteristics.
Sometimes it may be desirable for a pfGeoSet to be in several bins. For
this purpose you can create a subbin of two existing bins using function
pfChanFindSubBin. The parameters are the two parent bins and an integer
value indicating whether the subbin should be created if it does not
exist. The function returns -1 if the bin does not exists (and it was
not supposed to be created) or if any of the parent bins do not exist.
If you need to create a subbin of more than two bins call this function
several times. For example, to create a subbin of bin 5, 6, and 7, you
call pfChanFindSubBin with parameters 5 and 6. Let us assume that subbin
of bin 5 and 6 is bin 8. Then you call pfChanFindSubBin again, with
parameters 8 and 7 to obtain subbin of bins 5, 6, and 7. It does not
matter in what order you call it because all subbins are directly linked
to their parent root bins (and vice versa), there is no tree hierarchy.
See pfCullProgram for an example of using subbins.
The method pfChanFindBinParent returns the first parent of bin bin that
is bigger than the value specified as the second parameter. Thus by
calling this method several times (until it returns -1) you can determine
all parents of a bin.
Each root draw bin has a rendering order set by pfChanBinOrder. If order
is < 0, then bin is not ordered at all - pfGeoSets which belong to bin
are not stored in the bin but are rendered immediately. If order is >=0,
it defines the order in which the bin is rendered, 0 == first, 1 ==
second etc. The order of subbins is determined by the ChildOrderMask of
their parents. This mask can be set by pfChanBinChildOrderMask. When a
subbin is created the mask or all its parents is combined (using binary
OR) as set as a rendering order of the subbin.
By default, the opaque bin rendering order is PFSORT_OPAQUE_BIN_ORDER (0)
and the transparent bin is PFSORT_TRANSP_BIN_ORDER (1) so that
transparent surfaces are rendered after opaque surfaces. It is legal to
change the rendering order of the default bins and for different bins to
have the same rendering order although the relative order of these bins
is undefined. The order of subbins cannot be changed.
The light point bin has a huge PFSORT_LPSTATE_BIN_ORDER which is an
indicative value telling that the result of the preprocessing will be
drawn after every other geometry. Modifying the order of this bin has no
effect on that behavior.
Normally, pfDraw renders all root bins in the appropriate order. If a
Page 32
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
bin has subbins, objects that are not in any subbin of the bin are
rendered first, followed by objects of each subbin.
To avoid drawing subbins multiple times (for each of its parents) it is
recommended to set a flag PFBIN_DONT_DRAW_BY_DEFAULT for those root bins
that share subbins with the default opaque or transparent bin. The bin
flags can be set using pfChanBinFlags.
Individual bins, including subbins, may be rendered with pfDrawBin when
called in the pfChannel's draw callback (see pfChanTravFunc). -1 is a
special argument to pfDrawBin that lets you render the default
sceneDisplayList that contains all the objects that did not fall in any
defined bin. Note that this default sceneDisplayList exists only in
PFMP_CULL_DL_DRAW multiprocessing mode. In case of drawing a subbin, all
subbins that have the same parents as a given subbin will be drawn. For
example, consider root bins 5, 6, and 7 and subbins 8 (child of 5 and 6)
and 9 (child of 5, 6, and 7). When pfDrawBin is called with bin 8, bin 9
will be rendered as well.
pfChanBinSort defines how pfGeoSets are sorted within a bin. sortType is
a symbolic token which identifies the sorting method for bin:
PFSORT_NO_SORT
Do not sort the bin. sortOrders is ignored.
PFSORT_FRONT_TO_BACK
Sort the pfGeoSets in the bin in increasing range from the
eyepoint. Range is computed as the distance from the pfChannel
eyepoint to the center of the pfGeoSet's bounding box.
sortOrders is ignored.
PFSORT_BACK_TO_FRONT
Sort the pfGeoSets in the bin in decreasing range from the
eyepoint. Range is computed as the distance from the pfChannel
eyepoint to the center of the pfGeoSet's bounding box.
sortOrders is ignored.
PFSORT_BY_STATE
Sort the pfGeoSets in the bin by graphics state. The pfGeoSets
in bin are first sorted by pfGeoState. Then if sortOrders is
not NULL, the pfGeoSets will be further sorted by the ordered
list of PFSTATE_* elements in sortOrders. In this case,
sortOrders should consist of a PFSORT_STATE_BGN token followed
by 0 or more PFSTATE_* tokens followed by a PFSORT_STATE_END
token followed by a PFSORT_END token to end the list. The
PFSTATE_* tokens define a sorting hierarchy. The elements in
sortOrders are copied into the pfChannel data structure, so in
this case it is acceptable to pass static or automatic data not
allocated through pfMalloc.
Page 33
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
PFSORT_DRAW_ORDER
Sort the pfGeoSets in the bin directly by their draw order, in
ascending number.
By default, a new bin as a PFSORT_NO_SORT sort order.
Example 1: Sorting configuration example
int sortOrders[PFSORT_MAX_KEYS], i = 0;
sortOrders[i++] = PFSORT_STATE_BGN;
sortOrders[i++] = PFSTATE_FOG;
sortOrders[i++] = PFSTATE_MATERIAL;
sortOrders[i++] = PFSTATE_TEXTURE;
sortOrders[i++] = PFSORT_STATE_END;
sortOrders[i++] = PFSORT_END;
pfChanBinSort(chan, PFSORT_OPAQUE_BIN, PFSORT_BY_STATE, sortOrders);
pfChanBinSort(chan, PFSORT_TRANSP_BIN, PFSORT_BACK_TO_FRONT, NULL);
The default sorting order for the PFSORT_OPAQUE_BIN bin is by pfGeoState
only and the default sorting order for the PFSORT_TRANSP_BIN bin is
PFSORT_BACK_TO_FRONT.
The light points bins sorting is PFSORT_DRAW_ORDER.
Sorting by state is limited to the scope of a transformation (pfDCS or
pfSCS) or a node with draw callbacks, i.e. - pfGeoSets affected by
different transformations or draw callbacks are not sorted together.
However, range sorting spans both transformation and draw callback
boundaries. Thus a range-sorted scene graph with many transformations
and expensive draw callbacks may suffer reduced performance due to an
increased number of transformation and draw callback changes.
If a bin has subbins pfGeoSets are ordered in each subbin separately as
are pfGeoSets that do not belong to any subbin of the bin. A subbin
inherits ordering from a parent with highest sort priority, set by
pfChanBinSortPriority. In case of the transparent bin, the order in
which pfGeoSets are drawn (back-to-front) is important to avoid visible
artifacts and subbins, even if their pfGeoSets were ordered back-to-
front, may break that order. For this purpose, you can mark selected
bins as non-exclusive. If a pfGeoSet belongs to a subbin of a non-
exclusive bin it is added both to the subbin and directly to the list of
pfGeoSets of the non-exclusive bin. Thus when pfGeoSets of the non-
exclusive bin are sorted they are all in one list. Any root bin can be
marked non-exclusive by setting flag PFBIN_NONEXCLUSIVE_BIN using
pfChanBinFlags. The transparent bin is by default non-exclusive.
Root bins can have draw callbacks associated with them. Draw callbacks
are set by calling function pfChanBinCallBack. The parameters are: the
Page 34
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
bin number, the type of a callback (PFBIN_CALLBACK_PRE_DRAW or
PFBIN_CALLBACK_POST_DRAW), and the callback itself. The callback is a
function that has only one parameter, a void pointer that points to the
user data. Each bin has one user data pointer, shared between pre-draw
and post-draw callbacks. This pointer can be set using pfChanBinUserData.
If the callbacks are costly it makes sense to group subbins of a bin with
costly callbacks together. To achieve this make sure that you set a high
child order mask (see above) for the bin.
Subbins are heavily used by cull programs. A cull program allows the user
to specify a sequence of tests, performed during cull traversal, to
decide what bin a pfGeoSet belongs to. More information can be found in
man page for pfCullProgram.
VIEWPOINT AND CAMERA SPECIFICATION
pfChanView specifies both the origin and direction of view for a
pfChannel. xyz specifies the x,y,z position of the viewpoint in world
coordinates and hpr specifies the Euler angles (heading, pitch, and roll)
in degrees of the viewing direction relative to the nominal view (as
defined below). The order of application of these angles is ROTy(roll) *
ROTx(pitch) * ROTz(heading) where ROTa(angle) is a rotation matrix about
world axis a of angle degrees. In all cases a positive rotation is
counterclockwise by the right hand rule. The nominal viewing coordinate
system is +Y = forward, +Z = up, +X = right. For example, a roll of 90
degrees and a heading of -90 degrees would align the view direction with
the +X world axis and the up direction with the -Y world axis.
pfChanViewMat provides another means of specifying view point and
direction. mat is a 4x4 homogeneous matrix which defines the view
coordinate system such that the upper 3x3 submatrix defines the
coordinate system axes and the bottom vector defines the coordinate
system origin. OpenGL Performer defines the view direction to be along
the positive Y axis and the up direction to be the positive Z direction,
e.g., the second row of mat defines the viewing direction and the third
row defines the up direction in world coordinates. mat must be
orthonormal or results are undefined.
The actual viewing direction used for culling and drawing is modified by
the offsets specified by pfChanViewOffsets. The argument xyz defines a
translation from the nominal eyepoint. The Euler angles given in hpr
define an additional rotation of the viewing direction from that
specified by pfChanView and pfChanViewMat. Although this has similar
functionality to pfChanView, it is specifically useful for applications
which render the same scene into adjacent displays using multiple
pfChannels. Two examples where one would use pfChanViewOffsets as well
as pfChanView are offset-eye stereo image viewing applications, and for
video wall applications.
Example 1: Set up a single pipe, 3-channel simulation using
pfChanViewOffsets.
Page 35
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
left = pfNewChan(pfGetPipe(0));
middle = pfNewChan(pfGetPipe(0));
right = pfNewChan(pfGetPipe(0));
/* Form channel group with middle as the "master" */
pfAttachChan(middle, left);
pfAttachChan(middle, right);
/* Set FOV of all channels */
pfMakeSimpleChan(middle, 45.0f, 45.0f);
pfChanAutoAspect(middle, PFFRUST_CALC_VERT);
/* Set clipping planes of all channels */
pfChanNearFar(middle, 1.0f, 2000.0f);
hprOffsets[PF_P] = 0.0f;
hprOffsets[PF_R] = 0.0f;
pfSetVec3(xyzOffsets, 0.0f, 0.0f, 0.0f);
/*
* Set up viewport and viewing offsets.
* Note that these are not shared by default.
*/
pfChanViewport(left, 0.0f, 1.0f/3.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = 45.0f;
pfChanViewOffsets(left, hprOffsets, xyzOffsets);
pfChanViewport(middle, 1.0f/3.0f, 2.0f/3.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = 0.0f;
pfChanViewOffsets(middle, hprOffsets, xyzOffsets);
pfChanViewport(right, 2.0f/3.0f, 1.0f, 0.0f, 1.0f);
hprOffsets[PF_H] = -45.0f;
pfChanViewOffsets(right, hprOffsets, xyzOffsets);
Both translation and rotational offsets are encoded in the graphics
library's ModelView matrix. This ensures that fogging is consistent
across multiple, adjacent pfChannels. However, proper lighting requires
a lighting model which specifies a local viewer. Otherwise, geometry
which spans multiple pfChannels will be lit differently on each
pfChannel.
Example 2: Local viewer lighting model
pfLightModel *lm;
lm = pfNewLModel(arena);
pfLModelLocal(lm, 1);
pfApplyLModel(lm);
Page 36
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
pfGetChanView copies the view point/direction into xyz and hpr.
pfGetChanViewMat copies the viewing matrix (without viewing offsets) into
mat.
pfGetChanViewOffsets copies the view positional and rotational offsets
into the indicated arrays (xyz and hpr).
pfGetChanOffsetViewMat copies the combined nominal and offset viewing
matrices into mat. This combined viewing matrix is that used for culling
and for configuring the graphics library with the appropriate
transformation. It is defined as offset * nominal where offset is
specified by pfChanViewOffsets and nominal is specified by either
pfChanViewMat or pfChanView.
DRAWING FRAME STATISTICS
OpenGL Performer keeps track of times spent, and operations done, in the
application, cull, and draw stages of the rendering pipeline and
accumulates the data in a pfFrameStats structure. pfGetChanFStats is
used to get this pfFrameStats structure from the indicated channel.
pfChanStatsMode of the PFCSTATS_DRAW mode selects which of the enabled
statistics classes should be displayed in that channel by pfDrawChanStats
or pfDrawFStats. The statistics are enabled by pfFStatsClass and the
PFCSTATS_DRAW mode is only controlling the display of statistics that are
already enabled.
pfDrawChanStats or pfDrawFStats must be called during each frame that a
statistics display is desired and may be called from any of OpenGL
Performer's application, cull, or draw processes. This manual page give
some pointers on how to interpret the statistics to help in tuning your
database. Refer to the OpenGL Performer Programming Guide for more
detailed information.
pfChanStatsMode selects which of the currently already enabled statistics
through pfFStatsClass, should be drawn. It takes a pointer to a
pfChannel, chan, and mode, which is currently just PFCSTATS_DRAW, and the
corresponding value for val, which is a statistics class enabling
bitmask. The statistics classes displayed by pfDrawChanStats or
pfDrawFStats are those statistics classes that have been enabled by
pfChanStatsMode for display, and are also enabled for collection. By
default, all enabled statistics are displayed.
At the top of the display is the actual frame rate being achieved and the
frame rate set by pfFrameRate and the phase set by pfPhase. If
statistics collection of process frame times has been disabled, then the
actual frame rate will not be known and "???" will be shown. When the
graphics statistics class is enabled for collection, the average number
of pfGeoSets and triangles being displayed is also shown on the top of
the statistics display. See the pfStatsClass manual page for more
information on enabling statistics classes.
Page 37
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
For the Process Frame Times Statistics class, pfDrawChanStats displays
the amount of time, on average, spent by each process on a single frame,
as well as the number of frames that missed the goal, or extended beyond
the time for the specified goal frame rate. When the
PFFSTATS_PFTIMES_HIST mode is enabled (on by default), a timing diagram
of previous frames is displayed.
Red vertical lines indicate video retrace intervals and green ones
indicate frame boundaries. Horizontal bars indicate the time taken by
pipeline stages. The three different stages: APP, CULL, AND draw are
separated vertically and stages belonging to the same frame are the same
color. Each stage of each frame is labeled with the name of the stage
and its offset from the current frame. For example, the current
application stage is labeled app0 and draw-3 is the draw stage of three
frames back. Stages that are in the same process are connected by thin
vertical lines while stages that are a single process by themselves are
not.
The bar for the application stage is split into a total of six pieces.
The frame starts where the colors change right after a frame boundary
line. Pick up where a new color starts. This will be inside pfFrame and
is where control is given back to the application.
o Post-pfFrame()
The time spent in the application's main loop between the
pfFrame() call and the pfSync() call (highest segment in
application line, drawn as a thick, bright line).
o pfSync() clean and pfApp()
The time spent cleaning the scene graph from application
changes during pfSync(); drawn as mid-hight thick, bright line.
This will also include the time for pfAppFrame() which is
called from pfSync() if not already called for the current
frame by the user. pfSequences are also evaluated as part of
pfAppFrame().
o pfSync() sleep
The time spent sleeping in pfSync() while waiting for the next
field or frame boundary (depending on pfPhase and process
model); the lowest point in the application line, drawn as a
thin pale dotted line. Typically this wait is for when pfPhase
is PFPHASE_LOCK or PFPHASE_FLOAT. However, note that in
single process with pfPhase of PFPHASE_FREE_RUN, there will be
a sleep period to wait for the swapbuffer of the draw to
complete before continuing with the application since any other
graphics call would effective force such a sleep anyway and in
a place where its timing effect could not be measured.
o Critical Section
The time spent in the application code between calling pfSync()
and calling pfFrame(); drawn as bright raised line. This is the
Page 38
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
critical path section and this line should be as small as
possible or non-existent.
o pfFrame() clean
The time spent in pfFrame() cleaning the scene graph after any
changes that might have been made in the previous subsegment,
and then checking intersections; drawn as mid-hight thick
bright line. This line should typically be very small or non-
existent as it is part of the critical path and implies
database changes between pfSync() and pfFrame() which would be
an expensive place to do such changes.
o pfFrame() update
The time spent waiting while the cull and other downstream
process copy updated information from the application and then
starting the downstream stages on the the now-finished frame
(drawn as a low thin line). The end of this line is where
pfFrame() returns and the user main application section (or
post frame section) starts again.
The cull bar is divided into two pieces: first the time spent getting
updates from the application process (slightly raised), and the time
spent culling the scene graph.
The draw timing bar is divided into potentially six pieces:
o Pre-pfDraw()
The time spent in the channel draw callback before the call to
pfDraw() (a very short thick dark raised segment. This will
include the time for your call to pfClearChan(). However, under
normal circumstances, this segment should barely be visible at
all). Operations taking place during this time should only be
latency-critical since they are holding off the draw for the
current frame..
o pfDraw()
The time spent by OpenGL Performer traversing the scene graph
in pfDraw() (drawn as lowered bright thick segment). This
should typically be the largest segment as in the draw line.
o Post-pfDraw()
The time spent in the channel draw callback after pfDraw()
(another short thick dark raised segment;). On InfiniteReality,
if graphics pipeline timing statistics have been enabled by
specifying PFFSTATS_ENGFXPFTIMES to pfFStatsClass, this line
will include the time to finish the fill for this channel.
Otherwise, it only includes the time for the CPU to execute and
send graphics commands and graphics pipeline processing from
this channel could impact the timing of other channels.
Page 39
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
o Raster LPoint Draw
The time to rendering raster light points computed by a forked
lpoint process. This is drawn as a very raised bright line and
if it exists will be the highest point in the draw line. The
last channel drawn on the pipe will include the time for the
graphics pipeline to finish its drawing. Even if you have no
operations after pfDraw() in you draw callback, this line for
the last channel might look quite long, particularly if you are
very fill-limited and do not have InfiniteReailty graphics
pipeline statistics enabled. It is possible for rendering
calls issued in the previous section to fill up the graphics
FIFO and have calls issued on this section have to wait while
the graphics pipeline processes the commands and FIFO drains,
making the time look longer than expected. If there is no
forked lpoint process, this line will be combined with the
post-draw line of the last pfChannel.
o Draw Stats and Call Swapbuffers
The time spent waiting for the graphics pipeline to finish
drawing the current frame, draw the channel statistics (for all
channels), and make the call to swap color buffers. This is
drawn as apale dotted line. The hardware will complete the
swapbuffers upon the following vertical field or frame line.
The draw timing bar is somewhat inaccurate because the time stamps are
taken from the host and do not reflect when the graphics pipeline
actually finished rendering. Therefore, time for graphics work done in
one part of the draw might be counted in a following part when the
graphics pipeline FIFO filled up and caused the host to wait. This means
that some pfDraw() time could be counted in the following user callback
time, or in the time to draw the statistics. If graphics pipeline timing
statistics are enabled by specifying PFFSTATS_ENGFXPFTIMES to
pfFStatsClass (available on InfiniteReality graphics platforms), the draw
timing line will not have the above inaccuracy as the end time will be
generated by the graphics pipeline when the channel is done drawing.
If the light process is used its timing bar is added. Like the draw
timing line, the lowest part represent the time actually spent in
pfLPoint() preprocessing the light points; time spend in the user's call
back routine is in the darkened parts bedore and after. The rendering
time to draw the preprocessed light points is included in the draw timing
bar.
When fill statistics are enabled, the main channel will be painted in
colors ranging from blue to pink that indicate per-pixel depth-
complexity. The brightest (pinkest) areas are those pixels that have
been written many times. The statistics displayed, in green, include
average total depth complexity (total number of pixel writes), as well as
the average, minimum, and maximum number of times a given pixel is
written.
Page 40
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
When the Graphics Statistics class is enabled for collection and display,
detailed statistics on numbers of primitives, attributes, state changes,
and matrix transformations are all displayed. These statistics show what
is being drawn by the graphics pipeline. When the
PFSTATS_GFX_TSTRIP_LENGTHS mode is enabled, a histogram of triangle strip
lengths showing the percentage of triangles in the scene in strips of
given lengths is also displayed. For the strip length statistics, quads
are counted as strips of length two and independent triangles are counted
as strips of length one. For graphics performance, it is good to have
much of the database as possible in triangle strips, and making those
triangle strips as long as possible. On a system with RealityEngine
graphics, pay special attention to the numbers for texture loads and
number of bytes loaded. If these numbers are non-zero, then it means
that hardware texture memory is being overflowed and swapped regularly
and this will degrade graphics performance. Both InfiniteReality and
Impact graphics systems are designed to page textures during simulation
and have FIFOS in strategic locations within the hardware pipeline to
support this operation.
The CPU statistics display will show some of the statistics seen in
osview(1). Graphics context switches occur when there are multiple
active graphics windows on the same screen. An application needing high
fixed frame rates should not be encurring graphics context switches.
Another useful indicator of graphics overload is the fifonowait and
fifowait numbers. An excessive number of times seen waiting on the
graphics FIFO could indicate a graphics bottleneck and fill statistics
should be examined. If there are an excessive number of process context
switches, then it might help performance to restrict the draw process to
a single processor and then isolate that processor. OpenGL Performer
will not do this automatically; however, there are utilities in the
OpenGL Performer utility library, libpfutil (see pfuLockCPU), that enable
you to do this. These utilities are demonstrated in the OpenGL Performer
Perfly sample application. These utilities use the IRIX REACT extensions
via sysmp(2).
When the Database Statistics class is enabled for collection and display,
the number of displayed and evaluated nodes for each node type is shown.
When the cull statistics are displayed, a table showing the total number
of nodes and pfGeoSets traversed by the cull process, the number of node
bounding sphere and pfGeoSet bounding boxes tested, and the total number
of nodes, and pfGeoSets, (of those traversed) that were trivially
rejected as being outside the viewing frustum, the number that were fully
inside the viewing frustum, and the number that intersected the viewing
frustum. The database and culling statistics together can show the
efficiency of the database hierarchy. If many of the nodes in the
database are being traversed by the cull process when only a small
percentage are actually visible, then this indicates that the database
hierarchy is not spatially coherent. If there are many pfGeoSets in each
pfGeode, and many pfGeoSets are being rejected by the cull, then adding
more database hierarchy above current nodes may actually speed up the
culling traversal because cull tests on nodes would be able to accept or
reject large pieces of the database without traversing lower nodes. If
Page 41
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
the number of pfLOD nodes evaluated is much more then the number that are
actually drawn, then adding LOD hierarchy might help to reduce the total
number of LOD range calculations, which are fairly expensive.
If there are few nodes in the database relative to the number of
pfGeoSets and the cull is taking a small amount of time but the draw is
taking longer than desired, then adding more nodes and using a database
hierarchy that is spatially coherent should improve the accuracy of the
cull and speed up the draw traversal. If there are only a few pfGeoSets
per pfGeode and the cull is taking longer than the draw in multiprocess
mode, or is taking a significant amount of time in a process shared with
the draw, then it might benefit to not cull down to the pfGeoSet level.
Refer to the pfChanTravMode reference page for information on setting
cull traversal modes.
Graphics load is displayed in the lower portion of the statistics window.
The load hysteresis band (see pfChanStress) is drawn in white and the
previous 3 seconds of graphics load is drawn in red. Load is not scaled
and ranges from 0.0 to 1.0 within the lower portion of the statistics
window.
If stress is active, the display shows a graph of the previous 3 seconds
of stress which is drawn in white. Stress is drawn into the upper
portion and is scaled to fit.
The pfDrawChanStats display is very useful for debugging and profiling a
particular application and also for visualizing the behavior of differing
multiprocessing modes and pfPipe phases.
OpenGL Performer level-of-detail behavior is primarily dependent on
pfChannel viewing parameters such as view position, field-of-view, and
viewport pixel size. OpenGL Performer assumes that LODs are modeled for
a canonical FOV of 45 degrees and a viewport size of 1024 pixels. OpenGL
Performer computes an internal scale value for pfChannels whose FOV or
viewport size differ from these defaults. This scale value is used to
modify LOD ranges so that correct LOD behavior is maintained. If your
LODs were not modeled with the above defaults you may use PFLOD_SCALE
(see below) to adjust the LOD ranges.
Other LOD modification parameters are set with pfChanLODAttr. attr is a
symbolic token that specifies which LOD parameter to set and is one of
the following:
PFLOD_SCALE
val multiplies the range computed between chan's eyepoint and
all pfLOD's drawn by chan. This is used to globally increase
or decrease level of detail on a per-pfChannel basis. The
default LOD scale is 1.0. See the pfLODState and pfLOD man page
for more details.
Page 42
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
PFLOD_FADE
val specifies the global fade scale used to fade between levels
of detail. Fade is enabled when val > 0, and is disabled when
val <= 0. Fade is disabled by default. Note that when
computing the actual "fade" or transition distances, this scale
is multiplied by individual fade distance values that are
specified via pfLODTransition. Default pfLOD transition ranges
are 1.0. See the pfLODState and pfLOD man page for more
details.
Performer's LOD fading implementation requires hardware support
for blending using a method other than alpha blending. On
platforms with multisample support, Performer will use
multisample blending for the fading. If there is no multisample
support, Performer will use stipple patterns to do screen door
blending. On platforms where multisample is not present and
stipple patterns are expensive, Performer can not smoothly fade
LOD's.
PFLOD_STRESS_PIX_LIMIT
System stress (pfChanStress) will not affect LOD's whose
projected pixel size exceeds val pixels. This feature is
disabled by default.
PFLOD_FRUST_SCALE
The range multiplier based on chan's viewport and FOV is
multipled by val. Typically, this feature is enabled with a
value of 1.0 and disabled with a value of 0.0.
LOD fade is useful for avoiding distracting LOD switches. When within
the fade range, LODs are drawn semi-transparent so that adjacent LODs
smoothly blend together. Fade determines the transparency of an two
independent levels of detail. Here is an example for a pfLOD with 3
levels-of-detail and fade range of 30 database units:
Switch Range
0 100 250 350
| | | |
|------------|====|====|-------------|====|====|-----|====|====|
| ^ | ^ | | ^
| | |
| 20/80 LOD0/LOD1 ^ |
100% LOD0 | 40% LOD2
50/50 LOD1/LOD2
=== indicates where fading is active.
Fade transparency is complementary so that fading the same LOD child with
(fade) and (1.0 - fade) will generate a fully opaque image. As an
example, a fade of 0.7 will cover 70% of the screen area while a fade of
Page 43
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
(1.0 - fade) = (1.0 - 0.7) = 0.3 will cover the remaining 30% of the
screen area.
OpenGL Performer ensures that LODs whose switch range is <= 0.0 do not
fade in and also clamps the user-specified fade range to half the
distance between LOD switches. For example, if a pfLOD is specified with
switch ranges 0.0, 100.0, 400.0 and the fade range is 80.0, the result
will be:
Example 2: Fade clamping
Range LOD(s) drawn
---------------------------------------------
0 -> 50 100% LOD0
50 -> 100 100% -> 50% LOD0 + 0% -> 50% LOD1
100 -> 180 50% -> 0% LOD0 + 50% -> 100% LOD1
180 -> 320 100% LOD1
320 -> 400 100% -> 50% LOD1
400 -> 480 50% -> 0% LOD1
Use fade with discretion since it increases rendering time because two
LODs instead of one are drawn when range is within the fade interval.
pfGetChanLODAttr returns the value of the LOD modification parameter
specified by attr.
OpenGL Performer computes a stress value based on graphics load (-
pfChanStress) to modify LODs. Specifically, when the system approaches
overload, simpler LODs are drawn in order to reduce graphics load.
However, in some situations image fidelity considerations make it
undesirable to draw low levels-of-detail of objects which are close to
the viewer and thus occupy considerable screen space.
PFLOD_STRESS_PIX_LIMIT limits the effects of stress to LODs whose
projected pixel size is less than val. Projected pixel size is based on
the bounding volume of the LOD and is approximate. When val < 0.0, the
stress pixel limit is disabled.
PFLOD_SCALE is a global scale that is useful for debugging and for
adapting LODs modeled at one FOV and viewport size to the canonical FOV
and viewport size used by OpenGL Performer. A val of 0.0 will cause only
the highest LODs are displayed, since the effective distance will be
uniformly scaled to 0.0.
NOTES
All pfChannels on a pfPipe are rendered into a single graphics window so
that they can share hardware resources such as textures. Additionally,
each channel is rendered in succession rather than in parallel to avoid
costly graphics context switching.
For best performance, channel buffers allocated by pfAllocChanData should
Page 44
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
be as small as possible and pfPassChanData should be called only when
necessary to reduce copying overhead.
When configured as a process separate from the draw, the cull callback
should not invoke OpenGL graphics calls since only the draw process is
attached to a graphics context. However, the display listable libpr
commands invoked in the cull callback will be correctly added to the
current OpenGL Performer libpr display list being built for later
processing by the draw process. Light points process should never invoke
graphics calls as it is separate from the draw process.
Callbacks should not modify the OpenGL Performer database but may use
pfGet routines to inquire information as desired.
Draw callbacks should not attempt to perform framebuffer swapping
operations directly since OpenGL Performer must control this to handle
frame and channel synchronization. If user control of buffer swapping is
required, register a pfPipeSwapFunc callback to cause the named user
written function to be used by OpenGL Performer for swapping buffers.
Sorting back-to-front is required for accurate rendering of
PFTR_BLEND_ALPHA surfaces. The ordering mechanism described above
provides range sorting on a per-pfGeoSet, not a per-triangle basis so
some anomalies may be apparent when rendering transparent surfaces.
These anomalies may be reduced by rejecting back-facing polygons (see
pfCullFace and PFSTATE_CULLFACE).
The OpenGL Performer world coordinate system is +X = East, +Y = North, +Z
= Up and viewing coordinate system is +X = Right, +Y = Forward, +Z = Up.
Note that this is not the same as the OpenGL default coordinate system
which uses +X = Right, +Y = Up, +Z = Out of the screen. OpenGL Performer
internally manages the transformation required to go from a 'Z-up' world
to a 'Y-up' world.
pfDrawChanStats and pfDrawFStats do not actually draw the diagram but set
a flag so that the diagram is drawn just before OpenGL Performer swaps
image buffers.
Drawing the timing diagram does take a small amount of time in the draw
process, so it will perturb the frame rate and timing data to some
degree.
Fade-based level of detail transition is supported only on RealityEngine
systems and then only when multisampling is enabled.
Octane2 VPro provides a way to improve precision of parameter
interpolation across primitives (especially those primitives which are
large in screen space). For this purpose, Performer running on an Octane2
uses a special purpose cull program which is applied in cull traversal to
detect such primitives (see pfCullProgram for more information about cull
programs). If your application is cull limited, you can disable this
default behavior by setting environment variable GL_VERTEX_PRECLIP. Your
Page 45
pfChannel(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfChannel(3pf)
cull will be faster, but your draw will be slower (unless you disable the
detection). The possible values of the environment variable are NICEST
(detects all primitives), FASTEST (faster detection), or DISABLED (no
detection).
BUGS
Intersections, and thus picking, with lines and points is not yet
implemented.
SEE ALSO
pfConfigPWin, pfAddChan, pfInsertChan, pfMoveChan, pfRemoveChan,
pfPipeSwapFunc, pfNodeIsectSegs, pfLoadGState, pfNodeBSphere,
pfNodeTravMask, pfStatsClass, pfStatsClassMode, pfCompositor, pfConfig,
pfCullFace, pfCullProgram, pfDispList, pfEarthSky, pfESkyFog, pfObject,
pfFrame, pfFrameRate, pfFrustum, pfGetSemaArena, pfLightSource, pfLOD,
pfMultipipe, pfMultiprocess, pfPolytope, pfPhase, pfScene,
pfGetSemaArena, pfTransparency, pfuLockCPU
Page 46