pfLPoint man page on IRIX

Man page or keyword search:  
man Server   31559 pages
apropos Keyword Search (all sections)
Output format
IRIX logo
[printable version]



pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

NAME
     pfChannel, pfApp, pfCull, pfDraw, pfLPoint, pfDrawBin, pfDrawScene,
     pfNodePickSetup - Set and get pfChannel definition parameters.

FUNCTION SPECIFICATION
     #include <Performer/pf/pfChannel.h>

		       pfChannel::pfChannel(pfPipe *pipe);

     static pfType *   pfChannel::getClassType(void);

     pfPipe *	       pfChannel::getPipe(void);

     void	       pfChannel::setViewport(float l, float r, float b,
			 float t);

     void	       pfChannel::getViewport(float* l, float* r, float* b,
			 float* t);

     void	       pfChannel::getOrigin(int *xo, int *yo);

     void	       pfChannel::getSize(int *xs, int *ys);

     void	       pfChannel::setLODState(const pfLODState *ls);

     void	       pfChannel::getLODState(pfLODState *ls);

     void	       pfChannel::setLODStateList(pfList *lsList);

     pfList *	       pfChannel::getLODStateList(void);

     int	       pfChannel::getPWinIndex(void);

     pfPipeWindow *    pfChannel::getPWin(void);

     void	       pfChannel::setTravFunc(int trav, pfChanFuncType func);

     pfChanFuncType    pfChannel::getTravFunc(int trav);

     void *	       pfChannel::allocChanData(int size);

     void	       pfChannel::setChanData(void *data, size_t size);

     void *	       pfChannel::getChanData(void);

     size_t	       pfChannel::getChanDataSize(void);

     void	       pfChannel::passChanData(void);

     void	       pfChannel::clear(void);

									Page 1

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     int	       pfChannel::attach(pfChannel* chan1);

     int	       pfChannel::detach(pfChannel* chan1);

     int	       pfChannel::ASDattach(pfChannel* chan1);

     int	       pfChannel::ASDdetach(pfChannel* chan1);

     void	       pfChannel::setShare(uint mask);

     uint	       pfChannel::getShare(void);

     void	       pfChannel::setFOV(float horiz, float vert);

     void	       pfChannel::getFOV(float* horiz, float* vert);

     void	       pfChannel::setNearFar(float near, float far);

     void	       pfChannel::getNearFar(float* near, float* far);

     void	       pfChannel::setAutoAspect(int which);

     int	       pfChannel::getAutoAspect(void);

     void	       pfChannel::getBaseFrust(pfFrustum *frust);

     void	       pfChannel::getPtope(pfPolytope *ptope);

     void	       pfChannel::makePersp(float left, float right,
			 float bottom, float top);

     void	       pfChannel::makeInfPersp(float left, float right,
			 float bottom, float top);

     void	       pfChannel::makeOrtho(float left, float right,
			 float bottom, float top);

     void	       pfChannel::makeSimple(float fov);

     int	       pfChannel::getFrustType(void);

     void	       pfChannel::setAspect(int which,
			 float widthHeightRatio);

     float	       pfChannel::getAspect(void);

     void	       pfChannel::orthoXform(pfChannel* src,
			 const pfMatrix &mat);

     void	       pfChannel::getNear(pfVec3 &ll, pfVec3 &lr, pfVec3 &ul,
			 pfVec3 &ur);

									Page 2

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     void	       pfChannel::getFar(pfVec3 &ll, pfVec3 &lr, pfVec3 &ul,
			 pfVec3 &ur);

     int	       pfChannel::getEye(pfVec3 &eye);

     void	       pfChannel::apply(void);

     int	       pfChannel::contains(const pfVec3 &pt, pfChannel* chan);

     int	       pfChannel::contains(const pfSphere* sph);

     int	       pfChannel::contains(const pfCylinder* cyl);

     int	       pfChannel::contains(const pfBox* box);

     void	       pfChannel::setCullPtope(const pfPolytope *ptope);

     void	       pfChannel::getCullPtope(pfPolytope *ptope, int space);

     int	       pfChannel::pick(int mode, float px, float py,
			 float radius, pfHit **picklist[]);

     int	       pfChannel::isect(pfNode *node, pfSegSet *segSet,
			 pfHit **hits[], pfMatrix *mat);

     void	       pfChannel::setScene(pfScene *scene);

     pfScene *	       pfChannel::getScene(void);

     void	       pfChannel::setESky(pfEarthSky *sky);

     pfEarthSky *      pfChannel::getESky(void);

     void	       pfChannel::setGState(pfGeoState *gstate);

     pfGeoState *      pfChannel::getGState(void);

     void	       pfChannel::setGStateTable(pfList *gstable);

     pfList*	       pfChannel::getGStateTable(void);

     void	       pfChannel::setStressFilter(float frac, float low,
			 float high, float scale, float max);

     void	       pfChannel::getStressFilter(float *frac, float *low,
			 float *high, float *scale, float *max);

     void	       pfChannel::setStress(float stress);

     float	       pfChannel::getStress(void);

									Page 3

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     float	       pfChannel::getLoad(void);

     void	       pfChannel::setTravMode(int trav, int mode);

     int	       pfChannel::getTravMode(int trav);

     void	       pfChannel::setTravMask(int trav, uint mask);

     uint	       pfChannel::getTravMask(int trav);

     void	       pfChannel::setBinSort(int bin, int sortType,
			 uint64_t *sortOrders);

     int	       pfChannel::getBinSort(int bin, uint64_t *sortOrders);

     void	       pfChannel::setBinOrder(int bin, int order);

     int	       pfChannel::getBinOrder(int bin);

     int	       pfChannel::getFreeBin(void);

     void	       pfChannel::setBinSortPriority(int bin, int priority);

     int	       pfChannel::getBinSortPriority(int bin);

     void	       pfChannel::setBinChildOrderMask(int bin,
			 uint64_t orderMask);

     uint64_t	       pfChannel::getBinChildOrderMask(int bin);

     void	       pfChannel::setBinFlags(int bin, int flags);

     int	       pfChannel::getBinFlags(int bin);

     void	       pfChannel::setBinCallBack(int bin, int type,
			 pfDListFuncType func);

     pfDListFuncType   pfChannel::getBinCallBack(int bin, int type);

     void	       pfChannel::setBinUserData(int bin, void *userData,
			 int size);

     void *	       pfChannel::getBinUserData(int bin, int *size);

     int	       pfChannel::findSubBin(int bin1, int bin2, int create);

     int	       pfChannel::findBinParent(int bin, int lastKnownParent);

     pfCullProgram *   pfChannel::getCullProgram(void);

									Page 4

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     void	       pfChannel::setView(pfVec3 &xyz, pfVec3 &hpr);

     void	       pfChannel::getView(pfVec3 &xyz, pfVec3 &hpr);

     void	       pfChannel::setViewMat(pfMatrix &mat);

     void	       pfChannel::getViewMat(pfMatrix &mat);

     void	       pfChannel::setViewOffsets(pfVec3 &xyz, pfVec3 &hpr);

     void	       pfChannel::getViewOffsets(pfVec3 &xyz, pfVec3 &hpr);

     void	       pfChannel::getOffsetViewMat(pfMatrix &mat);

     pfFrameStats *    pfChannel::getFStats(void);

     int	       pfChannel::setStatsMode(uint mode, uint val);

     void	       pfChannel::drawStats(void);

     void	       pfChannel::setLODAttr(int attr, float val);

     float	       pfChannel::getLODAttr(int attr);

     void	       pfChannel::setProjMode(int mode);

     int	       pfChannel::getProjMode(void);

     pfPipeVideoChannel *
		       pfChannel::getPVChan(void);

     void	       pfChannel::setPWinPVChanIndex(int num);

     int	       pfChannel::getPWinPVChanIndex(void);

     void	       pfChannel::setOutputViewport(float l, float r, float b,
			 float t);

     void	       pfChannel::getOutputViewport(float *l, float *r,
			 float *b, float *t);

     void	       pfChannel::getOutputOrigin(int *xo, int *yo);

     void	       pfChannel::getOutputSize(int *xs, int *ys);

     void	       pfChannel::setPixScale(float s);

     float	       pfChannel::getPixScale(void);

     void	       pfChannel::setMinPixScale(float min);

									Page 5

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     float	       pfChannel::getMinPixScale(void);

     void	       pfChannel::setMaxPixScale(float max);

     float	       pfChannel::getMaxPixScale(void);

     int	       pfChannel::getUserFrustType(void);

     void	       pfChannel::getBaseUserFrust(pfFrustum *frust);

     float	       pfChannel::getUserAspect(void);

     void	       pfChannel::getUserFOV(float *fovH, float *fovV);

     void	       pfChannel::getUserNearFar(float *n, float *f);

     void	       pfChannel::getUserNear(pfVec3 &ll, pfVec3 &lr,
			 pfVec3 &ul, pfVec3 &ur);

     void	       pfChannel::getUserFar(pfVec3 &ll, pfVec3 &lr,
			 pfVec3 &ul, pfVec3 &ur);

     void	       pfChannel::getUserPtope(pfPolytope *dst);

     int	       pfChannel::getUserEye(pfVec3& eye);

     void	       pfChannel::getUserLeftRightBottomTop(float *l,
			 float *r, float *b, float *t);

     int	       pfChannel::userContains(const pfVec3& pt);

     int	       pfChannel::userContains(const pfSphere *sphere);

     int	       pfChannel::userContains(const pfBox *box);

     int	       pfChannel::userContains(const pfCylinder *cyl);

     void	       pfChannel::setCallig(pfCalligraphic* callig);

     pfCalligraphic*   pfChannel::getCallig(void);

     pfCalligraphic*   pfChannel::getCurCallig(void);

     void	       pfChannel::setCalligEnable(int enable)

     int	       pfChannel::getCalligEnable(void);

     void	       pfApp(void);

     void	       pfCull(void);

									Page 6

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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.  This is also true for
     ancestor classes of class pfObject.

     void*   pfObject::operator new(size_t);
     void*   pfObject::operator new(size_t, pfFluxMemory *fmem);
     void    pfObject::setUserData(void *data);
     void    pfObject::setUserData(int slot, void *data);
     void*   pfObject::getUserData(pfObject *obj);
     void*   pfObject::getUserData(pfObject *obj, int slot);
     int     pfObject::getNumUserData();

     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.

     void*	    pfMemory::getData(const void *ptr);
     pfType *	    pfMemory::getType();
     int	    pfMemory::isOfType(pfType *type);
     int	    pfMemory::isExactType(pfType *type);
     const char *   pfMemory::getTypeName();
     int	    pfMemory::copy(pfMemory *src);
     int	    pfMemory::compare(const pfMemory *mem);
     void	    pfMemory::print(uint which, uint verbose, char *prefix,
		      FILE *file);
     int	    pfMemory::getArena(void *ptr);
     void*	    pfMemory::getArena();
     int	    pfMemory::ref();
     int	    pfMemory::unref();
     int	    pfMemory::unrefDelete();
     int	    pfMemory::unrefGetRef();
     int	    pfMemory::getRef();
     int	    pfMemory::checkDelete();
     int	    pfMemory::isFluxed();
     void *	    pfMemory::getArena();
     int	    pfMemory::getSize();

									Page 7

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

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.  new pfChannel 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 pfPipeWindow::config).  new pfChannel creates and returns a handle
     to a pfChannel.  pfChannels are always allocated from shared memory and
     cannot be created statically, on the stack or in arrays.

     pfChannel::getClassType returns the pfType* for the class pfChannel.  The
     pfType* returned by pfChannel::getClassType is the same as the pfType*
     returned by invoking the virtual function getType 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  the member function isOfType 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
     pfChannel::getPipe returns the parent pfPipe of the pfChannel.
     pfChannel::getPWin returns the pfPipeWindow of the pfChannel.

     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 new
     pfChannel 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.	 pfChannel::getPWin will return the
     pfPipeWindow of the pfChannel.

     Channels of a pfPipeWindow are drawn in the order in which they are
     assigned to the pfPipeWindow.  pfChannel::getPWinIndex 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 pfPipeWindow
     man page for more information.

									Page 8

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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 pfChannel::setTravMode.  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.

     pfChannel::setViewport specifies the fractional viewport used by the
     pfChannel.	 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.

     pfChannel::getViewport copies the fractional viewport of the pfChannel
     into l, r, b, t.

     pfChannel::setOutputViewport 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 pfChannel::setViewportLn.  However, a
     separate output viewport is interesting for some advanced multichannel
     rendering operations and is used internally by OpenGL Performer for
     dynamic video resizing (DVR).

     pfChannel::setProjMode 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.

	  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.

									Page 9

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     Use pfChannel::getProjMode to get the current setting of a channel's
     projection mode.

     pfChannel::getOrigin copies the window coordinates of the origin of
     chan's viewport into xo and yo.

     pfChannel::getSize copies the X and Y pixel sizes of the pfChannel'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.

     pfChannel::setTravFunc sets the application, cull, draw or light points
     process callback functions for the pfChannel.  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
     pfChannel::allocChanData.	pfChannel::allocChanData returns a pointer to
     a word-aligned buffer of shared memory of size bytes.  Alternately,
     applications can provide passthrough data with pfChannel::setChanData.
     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).

     pfChannel::getChanDataSize returns the size of the pfChannel's
     passthrough data block.  pfChannel::getChanData returns a pointer to a
     buffer that was set by pfChannel::setChanData or allocated by
     pfChannel::allocChanData or NULL if no buffer has been allocated or set.
     pfChannel::getTravFunc 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, pfChannel::passChanData should be called whenever the user
     data is 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

								       Page 10

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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 (pfChannel::allocChanData) 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 pfChannel::setTravFunc,
     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
     pfChannel::setTravFunc.  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
     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

								       Page 11

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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.
     pfChannel::clear called from the draw callback will clear the channel
     viewport.	If the pfChannel has a pfEarthSky (see pfChannel::setESky),
     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 = new pfChannel(pfGetPipe(0));
	       :

	      /* Setup channel passthrough data */
	      pd = (PassData*)chan->allocChanData(sizeof(PassData));

	      /* Bind cull and draw callback functions to channel */
	      chan->setTravFunc(PFTRAV_CULL, cullFunc);
	      chan->setTravFunc(PFTRAV_DRAW, drawFunc);

	      pd->val = 0;
	      chan->passChanData();
	      pfFrame();

								       Page 12

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	       :
	  }

	  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);
	      chan->clear();
	      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 pfChannel::attach.
     If the pfChannel or chan1 are themselves members of a channel group, then
     all channels that are grouped with either the pfChannel 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 pfChannel::detach.

     The attributes shared by the members of a channel group are specified by
     the mask argument to pfChannel::setShare.	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:

	  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.

								       Page 13

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	  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.

	  PFCHAN_LPOINTFUNC
	       All channels invoke the same channel light points callback.

	  PFCHAN_VIEWPORT
	       All channels use the same viewport specification.

     pfChannel::getShare returns the share mask of the pfChannel.  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

								       Page 14

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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	 = new pfChannel(pfGetPipe(0));
	  middle = new pfChannel(pfGetPipe(0));
	  right	 = new pfChannel(pfGetPipe(0));

	  /* Form channel group with middle as the "master" */
	  middle->attach(left);
	  middle->attach(right);

	  /* Set FOV of all channels */
	  middle->makeSimple(45.0f);
	  middle->setAutoAspect(PFFRUST_CALC_VERT);

	  /* Set clipping planes of all channels */
	  middle->setNearFar(1.0f, 2000.0f);

	  hprOffsets->set(0.0f, 0.0f, 0.0f);
	  xyzOffsets->set(0.0f, 0.0f, 0.0f);

	  /*
	   * Set up viewport and viewing offsets.
	   * Note that these are not shared by default.
	   */
	  left->setViewport(0.0f, 1.0f/3.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = 45.0f;
	  left->setViewOffsets(xyzOffsets, hprOffsets);

	  middle->setViewport(1.0f/3.0f, 2.0f/3.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = 0.0f;
	  middle->setViewOffsets(xyzOffsets, hprOffsets);

	  right->setViewport(2.0f/3.0f, 1.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = -45.0f;
	  right->setViewOffsets(xyzOffsets, hprOffsets);

   VIEWING FRUSTUM
     Many pfChannel frustum routines are borrowed from pfFrustum (but not
     inherited).  These routines have the identical prototype as the pfFrustum
     routines but operate on the pfChannel's internal viewing frustum:
     makeSimple, makePersp, makeInfPersp, makeOrtho, setNearFar, getNearFar,
     getFOV, setAspect, getAspect, getFrustType, orthoXform, getNear, getFar,
     getEye, apply, and contains.  The reader is referred to the pfFrustum man
     page for details on the function descriptions.

								       Page 15

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     In addition to the pfFrustum routines, OpenGL Performer provides the
     pfChannel::setFOV and pfChannel::setAutoAspect convenience routines.

     The horiz and vert arguments to pfChannel::setFOV 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.

     pfChannel::setFOV 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.  pfChannel::makeSimple also creates an on-axis
     frustum but both horizontal and vertical fields of view are specified
     with fov.

     pfChannel::getFOV 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 pfChannel::setAutoAspect specifies which FOV extent
     to automatically match to the aspect ratio of the pfChannel'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. pfChannel::makePersp and pfChannel::makeOrtho disable
     automatic aspect ratio matching since it is assumed that the viewing
     frustum aspect ratio is completely specified by these commands.

     pfChannel::setNearFar 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.
     pfChannel::getNearFar 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.

								       Page 16

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     pfChannel::getBaseFrust copies the base viewing frustum of the pfChannel
     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
     pfChannel::setView).  pfChannel::orthoXform transforms the base frustum
     of src by mat and copies the result into the base frustum of the dst
     pfChannel. pfChannel::getPtope 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 = new pfChannel(pipe0);

	  /*
	   * Set horizontal FOV to 45 degrees and automatically match
	   * vertical FOV to channel viewport.
	   */
	  chan->setFOV(45.0f, -1.0f);

     Here's how to do the same thing using the basic primitives.

	  /* Set up a simple viewing frustum */
	  chan = new pfChannel(pipe0);

	  /*
	   * Set horizontal FOV to 45 degrees and automatically match
	   * vertical FOV to channel viewport.
	   */
	  chan->makeSimple(45.0f);
	  chan->setAutoAspect(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 = new pfChannel(pfGetPipe(0));
	  lrChan = new pfChannel(pfGetPipe(1));
	  urChan = new pfChannel(pfGetPipe(2));
	  ulChan = new pfChannel(pfGetPipe(3));

	  /* Form channel group with urChan as the "master" */
	  urChan->attach(llChan);

								       Page 17

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	  urChan->attach(lrChan);
	  urChan->attach(ulChan);

	  /*
	   * Share viewport but not field of view
	   * in addition to the default shared attributes.
	   */
	  share = urChan->getShare();
	  urChan->setShare((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.
	   */
	  llChan->makePersp(-1.0f, 0.0f, -1.0f, 0.0f);
	  lrChan->makePersp( 0.0f, 1.0f, -1.0f, 0.0f);
	  urChan->makePersp( 0.0f, 1.0f,  0.0f, 1.0f);
	  ulChan->makePersp(-1.0f, 0.0f,  0.0f, 1.0f);

	  urChan->setNearFar(1.0f, 2000.0f);

     Example 3: Set up a single pipe, 3-channel simulation.

	  left	 = new pfChannel(pfGetPipe(0));
	  middle = new pfChannel(pfGetPipe(0));
	  right	 = new pfChannel(pfGetPipe(0));

	  /* Form channel group with middle as the "master" */
	  middle->attach(left);
	  middle->attach(right);

	  /* Set FOV of all channels */
	  middle->makeSimple(45.0f);
	  middle->setAutoAspect(PFFRUST_CALC_VERT);

	  /* Set clipping planes of all channels */
	  middle->setNearFar(1.0f, 2000.0f);

	  hprOffsets[PF_P] = 0.0f;
	  hprOffsets[PF_R] = 0.0f;
	  xyzOffsets->set(0.0f, 0.0f, 0.0f);

	  /*
	   * Set up viewport and viewing offsets.
	   * Note that these are not shared by default.
	   */
	  left->setViewport(0.0f, 1.0f/3.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = 45.0f;
	  left->setViewOffsets(hprOffsets, xyzOffsets);

								       Page 18

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	  middle->setViewport(1.0f/3.0f, 2.0f/3.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = 0.0f;
	  middle->setViewOffsets(hprOffsets, xyzOffsets);

	  right->setViewport(2.0f/3.0f, 1.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = -45.0f;
	  right->setViewOffsets(hprOffsets, xyzOffsets);

     Example 4: Custom culling to pfChannel viewing frustum.

	  /*
	   * User-supplied cull callback (see pfChannel::setTravFunc)
	   */
	  extern void
	  myCullFunc(pfChannel *chan, void *data)
	  {
	      pfBox *boundingBox = (pfBox*)data;

	      if (chan->contains(boundingBox))
		  drawGSetsWithinBoundingBox();
	  }

     pfChannel::ASDattach 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);

								       Page 19

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     pfChannel::ASDdettach detaches the channel from sharing the active mesh
     from another channel.

     pfChannel::getAutoAspect returns the aspect ratio matching mode of the
     pfChannel.

     A pfChannel normally uses its viewing frustum for culling its pfScene (-
     pfChannel::setScene).  However, a custom culling volume may be specified
     by pfChannel::setCullPtope.  If non-NULL, ptope identifies a pfPolytope
     which is used for scene culling. A copy of ptope, internal to the
     pfChannel, is transformed by chan's viewing matrix before culling. If
     ptope is NULL, the pfChannel 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.	pfChannel::getCullPtope copies the culling polytope of the
     pfChannel 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
     pfChannel::getPVChan. In the indexed case, the pfPipeVideoChannel index
     is set to num using pfChannel::setPWinPVChanIndex and returned by
     pfChannel::getPWinPVChanIndex.

     With Dynamic Video Resolution, the actual rendering area (known as the
     output viewport) may be smaller than the nominal channel viewport. The
     size of the actual viewport area is available from
     pfChannel::getOutputViewport 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
     pfChannel::getOutputOrigin 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
     pfChannel::getOutputSize 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.  pfChannel::setPixScale sets the
     indicated channel's pixel scale factor to s.  pfChannel::getPixScale
     returns this value for the channel.

								       Page 20

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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.  pfChannel::setMinPixScale sets the minimum
     allowable pixel scale value for the channel, and
     pfChannel::getMinPixScale gets the value.	pfChannel::setMaxPixScale sets
     the maximum allowable pixel scale value for the channel, and
     pfChannel::getMaxPixScale 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 pfChannel::setCompositorShareMask.
     pfChannel::getCompositorShareMask 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
     pfChannel::setShare.

     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

								       Page 21

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     the pairs below should yield the same result.

		 actual frustum			     nominal frustum
      _______________________________________________________________________
      getUserFrustType			     getFrustType
      getBaseUserFrust			     getBaseFrust
      getUserAspect			     getAspect
      getUserFOV			     getFOV
      getUserNearFar			     getNearFar
      getUserNear			     getNear
      getUserFar			     getFar
      getUserPtope			     getPtope
      getUserEye			     getEye
      getUserLeftRightBottomTop		     getLeftRightBottomTop
      userContains(const pfVec3& pt)	     contains(const pfVec3& pt)
      userContains(const pfSphere *sphere)   contains(const pfSphere *sphere)
      userContains(const pfBox *box)	     contains(const pfBox *box)
      userContains(const pfCylinder *cyl)    contains(const pfCylinder *cyl)

					   |

   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
     pfPipeVideoChannel::setCallig).

     It is also possible to specify a pfCalligraphic per channel using
     pfChannel::setCallig and pfChannel::getCallig get the value that has been
     set.  pfChannel::getCurCallig 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
     pfChannel::setCalligEnable with 1 as enable. pfChannel::getCalligEnable
     returns this value. By default calligraphic light points are not enabled,
     the returned value is therefore 0.

								       Page 22

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

   PICKING
     pfChannel::pick 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
     return value of pfChannel::pick 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
     pfChannel::pick in the current process.  They should not be deleted by
     the application.

     The contents of the pfHit object are queried using pfHit::query and
     pfHit::mQuery.  See the man pages for pfHit and pfNode 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 pfNode::isect 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 pfNode 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

								       Page 23

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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
     scene graph.  This effectively calls pfNode::setTravMask with
     PFIS_SET_PICK.  Selective picking can be done by calling
     pfNode::setTravMask, 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
     pfNode::setTravMask manual page for more information on intersection
     setup.

     pfChannel::isect is identical to pfNode::isect 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
     pfChannel::setScene and pfChannel::setESky set the pfScene and pfEarthSky
     that the pfChannel will cull and draw.  pfChannel::setScene increments
     the reference count of scene so that scene must first be removed from the
     pfChannel by pfChannel::setScene(NULL) before scene can be deleted with
     pfDelete.

     pfChannel::getScene and pfChannel::getESky return the current pfScene and
     pfEarthSky for the pfChannel.

     Example 1: Setting a pfChannel's pfScene.

	  void
	  cullFunc(pfChannel *chan, void *data)
	  {
	      pfCull();
	  }

	  void
	  drawFunc(pfChannel *chan, void *data)
	  {
	      chan->clear();
	      pfDraw();
	  }

	  /* somewhere in application setup phase */
	   :
	  /* set channel's scene */
	  chan->setScene(scene);

								       Page 24

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	  /* bind cull and draw process callbacks */
	  chan->setTravFunc(PFTRAV_CULL, cullFunc);
	  chan->setTravFunc(PFTRAV_DRAW, drawFunc);

   GEOSTATES
     pfChannel::setGState sets the pfChannel's pfGeoState to gstate. If non-
     NULL, gstate is loaded before the pfChannel's DRAW callback is invoked.
     Specifically, gstate is loaded with pfGeoState::load 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.  pfChannel::getGState returns the pfGeoState of the
     pfChannel.

     pfChannel::setGStateTable sets the pfChannel's pfGeoState table to
     gstable.  If non-NULL, gstable is made the global pfGeoState table with
     pfGeoState::applyTable before the pfChannel's DRAW callback is invoked.
     Any indexed pfGeoStates, either referenced by a pfScene (-
     pfScene::setGStateIndex) or by scene pfGeoSets (pfGeoSet::setGStateIndex)
     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.

     pfChannel::setLODState specifies a global pfLODState to be used for this
     channel.

     pfChannel::setLODStateList specifies a pfList of pfLODStates to be
     indexed into by pfLODs that have specified indexes via
     pfLOD::setLODStateIndex.  (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.

								       Page 25

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     pfChannel::setStressFilter sets the stress filter used by the pfChannel.
     frac is the fraction of a frame period the pfChannel 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.	pfChannel::getStressFilter
     returns the stress filter parameters for the pfChannel.

     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 pfChannel::attach).  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.

     pfChannel::getLoad will return the last computed load for the pfChannel.
     The load value is defined as time * frameRate / frac.

     The application may choose to not use the default OpenGL Performer stress
     filter by calling pfChannel::setStress to explicitly set the stress
     value.  Stress values set by pfChannel::setStress will override the
     default stress values computed by the stress filter shown above.

     pfChannel::getStress returns the last computed stress value for the
     pfChannel.	 The individual stress value is returned regardless of
     pfChannel attribute sharing (pfChannel::setShare).

								       Page 26

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

   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 pfChannel::setScene.  A
     pfScene is a hierarchy of pfNodes that defines the visual database.

     pfChannel::setTravMode sets the traversal mode of the pfChannel.  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 pfChannel::setTravFunc).
	       If it is set, any pfLightSources in the pfScene will be
	       ignored.

								       Page 27

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	       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
	       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.

     pfChannel::getTravMode 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.

     pfChannel::setTravMask sets the pfChannel's drawing mask and is used in
     conjunction with pfNode::setTravMask 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 pfNode::setTravMask.  The default pfNode
     and pfChannel masks are 0xffffffff so that a pfChannel culls and draws
     all pfNodes.

     pfChannel::getTravMask returns the drawing traversal mask for the

								       Page 28

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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:

	  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 pfGeoSet::setDrawBin.
     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 pfChannel::setBinOrder) - 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.

								       Page 29

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	  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
     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.

     pfChannel::getFreeBin 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 pfChannel::setBinOrder 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
     pfChannel::findSubbin. 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 pfChannel::findSubbin with parameters 5 and 6.	 Let us assume
     that subbin of bin 5 and 6 is bin 8. Then you call pfChannel::findSubbin
     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 pfChannel::findBinParent 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 pfChannel::setBinOrder.
     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 pfChannel:setBinChildOrderMask.
     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

								       Page 30

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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
     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 pfChannel::setBinFlags.

     Individual bins, including subbins, may be rendered with pfDrawBin when
     called in the pfChannel's draw callback (see pfChannel::setTravFunc).  -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.

     pfChannel::setBinSort 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

								       Page 31

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	       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.

	  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;

	  chan->setBinSort(PFSORT_OPAQUE_BIN, PFSORT_BY_STATE, sortOrders);
	  chan->setBinSort(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
     pfChannel::setBinSortPriority.  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

								       Page 32

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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
     pfChannel::setBinFlags.  The transparent bin is by default non-exclusive.

     Root bins can have draw callbacks associated with them. Draw callbacks
     are set by calling function pfChannel::setBinCallBack. The parameters
     are: the 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
     pfChannel::setBinUserData.	 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
     pfChannel::setView 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.

     pfChannel::setViewMat 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 pfChannel::setViewOffsets.  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 pfChannel::setView and pfChannel::setViewMat.	 Although this
     has similar functionality to pfChannel::setView, it is specifically

								       Page 33

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     useful for applications which render the same scene into adjacent
     displays using multiple pfChannels.  Two examples where one would use
     pfChannel::setViewOffsets as well as pfChannel::setView are offset-eye
     stereo image viewing applications, and for video wall applications.

     Example 1: Set up a single pipe, 3-channel simulation using
     pfChanViewOffsets.

	  left	 = new pfChannel(pfGetPipe(0));
	  middle = new pfChannel(pfGetPipe(0));
	  right	 = new pfChannel(pfGetPipe(0));

	  /* Form channel group with middle as the "master" */
	  middle->attach(left);
	  middle->attach(right);

	  /* Set FOV of all channels */
	  middle->makeSimple(45.0f, 45.0f);
	  middle->setAutoAspect(PFFRUST_CALC_VERT);

	  /* Set clipping planes of all channels */
	  middle->setNearFar(1.0f, 2000.0f);

	  hprOffsets[PF_P] = 0.0f;
	  hprOffsets[PF_R] = 0.0f;
	  xyzOffsets->set(0.0f, 0.0f, 0.0f);

	  /*
	   * Set up viewport and viewing offsets.
	   * Note that these are not shared by default.
	   */
	  left->setViewport(0.0f, 1.0f/3.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = 45.0f;
	  left->setViewOffsets(hprOffsets, xyzOffsets);

	  middle->setViewport(1.0f/3.0f, 2.0f/3.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = 0.0f;
	  middle->setViewOffsets(hprOffsets, xyzOffsets);

	  right->setViewport(2.0f/3.0f, 1.0f, 0.0f, 1.0f);
	  hprOffsets[PF_H] = -45.0f;
	  right->setViewOffsets(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.

								       Page 34

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     Example 2: Local viewer lighting model

	  pfLightModel	 *lm;

	  lm = new pfLightModel;
	  lm->setLocal(1);
	  lm->apply();

     pfChannel::getView copies the view point/direction into xyz and hpr.

     pfChannel::getViewMat copies the viewing matrix (without viewing offsets)
     into mat.

     pfChannel::getViewOffsets copies the view positional and rotational
     offsets into the indicated arrays (xyz and hpr).

     pfChannel::getOffsetViewMat 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 pfChannel::setViewOffsets and nominal is specified by either
     pfChannel::setViewMat or pfChannel::setView.

   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.	pfChannel::getFStats
     is used to get this pfFrameStats structure from the indicated channel.
     pfChannel::setStatsMode of the PFCSTATS_DRAW mode selects which of the
     enabled statistics classes should be displayed in that channel by
     pfChannel::drawStats or pfFrameStats::draw.  The statistics are enabled
     by pfFrameStats::setClass and the PFCSTATS_DRAW mode is only controlling
     the display of statistics that are already enabled.

     pfChannel::drawStats or pfFrameStats::draw 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.

     pfChannel::setStatsMode selects which of the currently already enabled
     statistics through pfFrameStats::setClass, should be drawn.  It takes
     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 pfChannel::drawStats or pfFrameStats::draw are those
     statistics classes that have been enabled by pfChannel::setStatsMode for
     display, and are also enabled for collection. By default, all enabled

								       Page 35

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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 pfStats::setClass manual page for more
     information on enabling statistics classes.

     For the Process Frame Times Statistics class, pfChannel::drawStats
     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

								       Page 36

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	       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
	       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.

								       Page 37

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	  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 pfFrameStats::setClass,
	       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.

	  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
     pfFrameStats::setClass (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

								       Page 38

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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.

     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

								       Page 39

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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
     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 pfChannel::setTravMode 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 pfChannel::setStress) 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 pfChannel::drawStats 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 pfChannel::setLODAttr.

								       Page 40

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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 the pfChannel.  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.

	  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 pfLOD::setTransition.  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 (pfChannel::setStress) 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 the pfChannel'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	       ^	   |

								       Page 41

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

	     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
     (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.

     pfChannel::getLODAttr returns the value of the LOD modification parameter
     specified by attr.

     OpenGL Performer computes a stress value based on graphics load (-
     pfChannel::setStress) 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

								       Page 42

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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
     pfChannel::allocChanData should be as small as possible and
     pfChannel::passChanData 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
     pfList::get 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 pfPipe::setSwapFunc 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.

     pfChannel::drawStats and pfFrameStats::draw 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.

								       Page 43

pfChannel(3pf)		      OpenGL Performer 3.2.2 libpf C++ Reference Pages

     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
     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
     pfPipeWindow, pfPipe, pfNode, pfGeoState, pfStats, pfCompositor,
     pfConfig, pfCullFace, pfCullProgram, pfDispList, pfEarthSky, pfESkyFog,
     pfObject, pfFrame, pfFrameRate, pfFrustum, pfGetSemaArena, pfLightSource,
     pfLOD, pfMultipipe, pfMultiprocess, pfPolytope, pfPhase, pfScene,
     pfGetSemaArena, pfTransparency, pfuLockCPU

								       Page 44

[top]

List of man pages available for IRIX

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net