pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
NAME
pfNewGArray, pfGetGArrayClassType, pfGArraySetAttr, pfGArraySetMultiAttr,
pfNumAttrsOfTypeGArray, pfRemoveAttrGArray, pfDisableAttrGArray,
pfEnableAttrGArray, pfGArrayIndexArray, pfGetGArrayIndexArray,
pfAllowCacheGArray, pfUpdateDataGArray, pfGetGArrayNumAttrs,
pfGetGArrayNthAttr, pfGArrayIsStandardArray, pfGetGArrayArrayMemSize,
pfGArrayDrawIndex, pfGArrayXformAttr, pfGArraySetupCoords,
pfGArrayCleanupCoords, pfNewVAttr, pfVAttrAll, pfVAttrName,
pfGetVAttrName, pfGetVAttrGLFunc, pfGetVAttrClientState, pfGetVAttrMask,
pfGetVAttrInstance, pfGetVAttrMaskOff, pfVAttrPtr, pfGetVAttrPtr,
pfVAttrStride, pfGetVAttrStride, pfVAttrDataType, pfGetVAttrDataType,
pfVAttrSize, pfGetVAttrSize, pfVAttrCopy, pfVAttrCompare - Create, modify
and query geometry set objects that use vertex arrays
FUNCTION SPECIFICATION
#include <Performer/pr.h>
pfGeoArray* pfNewGArray(void *arena);
pfType* pfGetGArrayClassType(void);
pfVertexAttr* pfGArraySetAttr(pfGeoArray* _garray, int attrType,
int size, GLenum type, GLenum stride, void *ptr);
pfVertexAttr* pfGArraySetMultiAttr(pfGeoArray* _garray, int attrType,
int stage, int size, GLenum type, GLenum stride,
void *ptr);
int pfNumAttrsOfTypeGArray(const pfGeoArray* _garray,
int attrType);
void pfRemoveAttrGArray(pfGeoArray* _garray,
pfVertexAttr *ai);
void pfDisableAttrGArray(pfGeoArray* _garray,
pfVertexAttr *ai);
void pfEnableAttrGArray(pfGeoArray* _garray,
pfVertexAttr *ai);
void pfGArrayIndexArray(pfGeoArray* _garray,
unsigned int *iarray);
unsigned int* pfGetGArrayIndexArray(const pfGeoArray* _garray);
void pfAllowCacheGArray(pfGeoArray* _garray, int x);
void pfUpdateDataGArray(pfGeoArray* _garray);
int pfGetGArrayNumAttrs(const pfGeoArray* _garray);
Page 1
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
pfVertexAttr* pfGetGArrayNthAttr(const pfGeoArray* _garray, int n);
int pfGArrayIsStandardArray(pfGeoArray* _garray,
pfVertexAttr *ai, int *gtype, int *gindex);
int pfGetGArrayArrayMemSize(pfGeoArray* _garray,
pfVertexAttr *ai, int *elemSize);
void pfGArrayDrawIndex(pfGeoArray* _garray);
int pfGArrayXformAttr(pfGeoArray* _garray, GLenum attrType,
int ptType, pfMatrix *xform);
void pfGArraySetupCoords(pfGeoArray *dis);
void pfGArrayCleanupCoords(pfGeoArray *dis);
pfVertexAttr* pfNewVAttr(pfGeoArray *parent, int attrType,
void *arena);
void pfVAttrAll(pfVertexAttr* _vattr, void *ptr,
GLsizei stride, GLenum type, short size);
void pfVAttrName(pfVertexAttr* _vattr, char *name);
char* pfGetVAttrName(const pfVertexAttr* _vattr);
pfFunc pfGetVAttrGLFunc(const pfVertexAttr* _vattr);
GLenum pfGetVAttrClientState(const pfVertexAttr* _vattr);
unsigned short pfGetVAttrMask(const pfVertexAttr* _vattr);
short pfGetVAttrInstance(const pfVertexAttr* _vattr);
short pfGetVAttrMaskOff(const pfVertexAttr* _vattr);
void pfVAttrPtr(pfVertexAttr* _vattr, void *data);
void* pfGetVAttrPtr(const pfVertexAttr* _vattr);
void pfVAttrStride(pfVertexAttr* _vattr, GLsizei stride);
GLsizei pfGetVAttrStride(const pfVertexAttr* _vattr);
void pfVAttrDataType(pfVertexAttr* _vattr, GLenum type);
GLenum pfGetVAttrDataType(const pfVertexAttr* _vattr);
void pfVAttrSize(pfVertexAttr* _vattr, short size);
Page 2
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
short pfGetVAttrSize(const pfVertexAttr* _vattr);
int pfVAttrCopy(pfVertexAttr* _vattr,
const pfVertexAttr *_src);
int pfVAttrCompare(const pfVertexAttr* _vattr,
const pfVertexAttr *_obj);
PARENT CLASS FUNCTIONS
The OpenGL Performer class pfGeoArray is derived from the parent class
pfGeoSet, so each of these member functions of class pfGeoSet are also
directly usable with objects of class pfGeoArray. Casting an object of
class pfGeoArray to an object of class pfGeoSet is taken care of
automatically. This is also true for casts to objects of ancestor
classes of class pfGeoSet.
void pfCompileGSet(pfGeoSet *gset);
void pfDrawGSet(pfGeoSet *gset);
void pfDrawHlightedGSet(pfGeoSet* gset);
void pfGSetNumPrims(pfGeoSet *gset, int num);
int pfGetGSetNumPrims(const pfGeoSet *gset);
void pfGSetPrimType(pfGeoSet *gset, int type);
int pfGetGSetPrimType(const pfGeoSet *gset);
void pfGSetPrimLengths(pfGeoSet* gset, int *lengths);
int * pfGetGSetPrimLengths(const pfGeoSet* gset);
int pfGetGSetPrimLength(const pfGeoSet* gset, int i);
void pfGSetAttr(pfGeoSet *gset, int attr, int bind,
void *alist, ushort *ilist);
int pfGetGSetAttrBind(const pfGeoSet *gset, int attr);
void pfGetGSetAttrLists(const pfGeoSet *gset, int attr,
void **alist, ushort **ilist);
int pfGetGSetAttrRange(const pfGeoSet *gset, int attr,
int *minIndex, int *maxIndex);
void pfGSetMultiAttr(pfGeoSet *gset, int attr, int index,
int bind, void *alist, ushort *ilist);
int pfGetGSetMultiAttrBind(const pfGeoSet *gset, int attr,
int index);
void pfGetGSetMultiAttrLists(const pfGeoSet *gset, int attr,
int index, void **alist, ushort **ilist);
int pfGetGSetMultiAttrRange(const pfGeoSet *gset, int attr,
int index, int *minIndex, int *maxIndex);
void pfGSetDecalPlane(pfGeoSet *gset, pfPlane *plane);
pfPlane * pfGetGSetDecalPlane(pfGeoSet *gset);
void pfGSetDrawMode(pfGeoSet *gset, int mode, int val);
int pfGetGSetDrawMode(const pfGeoSet *gset, int mode);
void pfGSetGState(pfGeoSet *gset, pfGeoState *gstate);
pfGeoState * pfGetGSetGState(const pfGeoSet *gset);
void pfGSetGStateIndex(pfGeoSet *gset, int id);
int pfGetGSetGStateIndex(const pfGeoSet *gset);
void pfGSetLineWidth(pfGeoSet *gset, float width);
Page 3
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
float pfGetGSetLineWidth(const pfGeoSet *gset);
void pfGSetPntSize(pfGeoSet *gset, float size);
float pfGetGSetPntSize(const pfGeoSet *gset);
void pfGSetHlight(pfGeoSet* gset, pfHighlight *hlight);
pfHighlight * pfGetGSetHlight(const pfGeoSet* gset);
void pfGSetDrawBin(pfGeoSet *gset, short bin);
int pfGetGSetDrawBin(const pfGeoSet *gset);
void pfGSetDrawOrder(pfGeoSet * gset, unsigned int order);
unsigned int pfGetGSetDrawOrder(const pfGeoSet *gset)
void pfGSetPassFilter(uint mask);
uint pfGetGSetPassFilter(void);
void pfHideGSetStripPrim(const pfGeoSet* gset, int i);
void pfUnhideGSetStripPrim(const pfGeoSet* gset, int i);
int pfIsGSetStripPrimHidden(const pfGeoSet* gset, int i);
int pfQueryGSet(const pfGeoSet* gset, uint which,
void* dst);
int pfMQueryGSet(const pfGeoSet* gset, uint* which,
void* dst);
void pfGSetBBox(pfGeoSet *gset, pfBox *box, int mode);
int pfGetGSetBBox(pfGeoSet *gset, pfBox *box);
void pfGSetBBoxFlux(pfGeoSet *gset, pfFlux *flux);
pfFlux* pfGetGSetBBoxFlux(pfGeoSet *gset);
void pfGSetIsectMask(pfGeoSet *gset, uint mask, int setMode,
int bitOp);
uint pfGetGSetIsectMask(pfGeoSet *gset);
int pfGSetIsectSegs(pfGeoSet *gset, pfSegSet *segSet,
pfHit **hits[]);
void pfGSetPassList(pfGeoSet *gset, pfPassList *passList);
pfPassList * pfGetGSetPassList(pfGeoSet *gset);
void pfGSetUpdateCteRefs(pfGeoSet *gset);
void pfGSetCalcTexBBox(pfGeoSet *gset);
void pfGSetTexBBox_i(pfGeoSet *gset, uint centerS,
uint centerT, uint halfwidth, uint halfheight);
void pfGSetTexBBox_f(pfGeoSet *gset, float minS, float maxS,
float minT, float maxT);
int pfGetGSetTexBBox_i(pfGeoSet *gset, uint* centerS,
uint* centerT, uint* halfwidth, uint* halfheight);
int pfGetGSetTexBBox_f(pfGeoSet *gset, float* minS,
float* maxS, float* minT, float* maxT);
void pfGSetCteAttr(pfGeoSet *gset, int which, void* val);
void* pfGetGSetCteAttr(pfGeoSet *gset, int which);
void pfGSetAppearance(pfGeoSet *gset,
islAppearance *appearance);
islAppearance* pfGetGSetAppearance(const pfGeoSet* gset);
int pfGSetIsShaded(pfGeoSet *gset);
void pfQuickCopyGSet(pfGeoSet *gset, pfGeoSet *src);
void pfGSetQuickAttr(pfGeoSet *gset, int _attr, void* _alist,
unsigned short* _ilist);
void pfGSetQuickMultiAttr(pfGeoSet *gset, int _attr,
int _index, void* _alist, unsigned short* _ilist);
Page 4
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
void pfGSetQuickPrimLengths(pfGeoSet *gset, int *_lengths);
void pfQuickResetGSet(pfGeoSet *gset, int extRefOnly);
void pfGSetOptimize(int _state);
int pfGetGSetOptimize(void);
int pfFluxedGSetInit(pfFluxMemory *fmem);
Since the class pfGeoSet is itself derived from the parent class
pfObject, objects of class pfGeoArray can also be used with these
functions designed for objects of class pfObject.
void pfUserDataSlot(pfObject *obj, int slot, void *data);
void pfUserData(pfObject *obj, void *data);
void* pfGetUserDataSlot(pfObject *obj, int slot);
void* pfGetUserData(pfObject *obj);
int pfGetNumUserData(pfObject *obj);
int pfGetNamedUserDataSlot(const char *name);
const char* pfGetUserDataSlotName(int slot);
int pfGetNumNamedUserDataSlots(void);
int pfGetGLHandle(pfObject *obj);
int pfDeleteGLHandle(pfObject *obj);
Since the class pfObject is itself derived from the parent class
pfMemory, objects of class pfGeoArray can also be used with these
functions designed for objects of class pfMemory.
pfType * pfGetType(const void *ptr);
int pfIsOfType(const void *ptr, pfType *type);
int pfIsExactType(const void *ptr, pfType *type);
const char * pfGetTypeName(const void *ptr);
int pfRef(void *ptr);
int pfUnref(void *ptr);
int pfUnrefDelete(void *ptr);
int pfUnrefGetRef(void *ptr);
int pfGetRef(const void *ptr);
int pfCopy(void *dst, void *src);
int pfDelete(void *ptr);
int pfIsFluxed(void *ptr);
int pfCompare(const void *ptr1, const void *ptr2);
void pfPrint(const void *ptr, uint which, uint verbose,
FILE *file);
void * pfGetArena(void *ptr);
PARAMETERS
garray identifies a pfGeoArray.
DESCRIPTION
The pfGeoArray (short for "Geometry Array") is a new OpenGL Performer
data structure aimed at replacing the existing pfGeoSet. Conceptually,
pfGeoArrays are very similar to pfGeoSets, but they allow the user to
Page 5
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
define new sets of attributes, in addition to the standard vertex
coordinates, normals, texture coordinates, or colors. These attributes
can be used by vertex or fragment programs applied to the primitives (see
pfVertexProgram and pfFragmentProgram). Also, pfGeoArrays are rendered
using vertex arrays and vertex objects making the rendering much more
efficient. pfGeoArrays can be up to 10 times faster than pfGeoSets on
Onyx4.
Each pfGeoArray is a collection of geometry with one primitive type, such
as points, lines, triangles. Vertex coordinates, normals, colors,
texture coordinates, and user defined attributes are used to specify the
primitives. There are two ways how the attributes are accessed. First,
each attribute is specified per vertex, there is no notion of attribute
per primitive or an overall attribute. Second, a single list of unsigned
integers is used to index all attributes of a pfGeoArray.
Indexing provides a more general mechanism for specifying geometry than
hardwired attribute lists and in many cases provide a substantial memory
savings due to shared attributes. Nonindexed pfGeoArrays's are sometimes
easier to construct and may exhibit better caching behavior. In our
experience, though, indexing is often desirable approach, especially when
your primitives share many vertices. Also, if you have a primitive with
many triangle strips it is better to create a single pfGeoArray contating
indexed triangles than to have a set of short pfGeoArrays, each
containing one triangle strip. The pfdOptimizeGraph functionality can be
extremely useful for converting from pfGeoSet data to very fast
pfGeoArray data.
pfNewGArray creates and returns a handle to a pfGeoArray. arena
specifies a malloc arena out of which the pfGeoArray is allocated or NULL
for allocation off the process heap. pfGeoArrays can be deleted with
pfDelete.
pfGeoArray Attributes
Attributes can be specified through the use of the pfGArraySetAttr and
pfGArraySetMultiAttr functions. These functions add or replace an
attribute if it already exists. These take one of the following tokens
for the attrType parameter:
PFGA_COORD_ARRAY
PFGA_NORMAL_ARRAY
PFGA_TEX_ARRAY
PFGA_COLOR_ARRAY
PFGA_COLOR2_ARRAY
PFGA_FOG_ARRAY
PFGA_WEIGHT_ARRAY
PFGA_GENERIC_ARRAY
Some of these attributes require specific OpenGL extensions for their
use. The PFGA_COLOR2_ARRAY attribute requires the GL_ARB_secondary_color
extension, the PFGA_FOG_ARRAY requires the GL_EXT_fog_coord extension,
Page 6
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
and the PFGA_WEIGHT_ARRAY attribute requires the GL_ARB_vertex_blend
extension. The PFGA_GENERIC_ARRAY token indicates the use of generic
attributes as described in the OpenGL GL_ARB_vertex_program extension.
The location of some generic attributes overlap the locations of
traditional attributes. If multiple attributes share the same location,
Performer does not attempt to fix this problem, and will simply use the
most recently specified attribute. The PFGA_TEX_COORD_ARRAY,
PFGA_GENERIC_ARRAY, and PFGA_WEIGHT_ARRAY attribute types may be
specified with a non-zero stage parameter, indicating the texture unit,
generic location, or weight unit to place the data.
The size for an attribute type must be one of 2, 3 or 4. The data type is
one of GL_DOUBLE, GL_FLOAT, GL_INT, GL_UNSIGNED_INT, GL_UNSIGNED_SHORT,
GL_SHORT, GL_UNSIGNED_BYTE, and GL_BYTE.
The setAttr functions return a pointer to a pfVertexAttr which contains
the related data to the newly created attribute. This data can be
updated through the use of the pfVertexAttr interface. The name, data
pointer, stride, data type and size of an attribute can be modified using
the following functions:
pfVAttrName
pfVAttrPtr
pfVAttrStride
pfVAttrDataType
pfVAttrSize
You can also remove an attribute using the function pfGArrayRemoveAttr.
Multitexturing is supported by adding multiple PFGA_TEX_ARRAY vertex
attributes and specifying different stages. For example:
pfGeoArray *gArray = pfNewGArray();
pfGArrayMultiAttr(gArray, PFGA_TEX_ARRAY, 0, 2, GL_FLOAT, 0, baseCoords);
pfGArrayMultiAttr(gArray, PFGA_TEX_ARRAY, 1, 2, GL_FLOAT, 0, bumpCoords);
/* set name for the two sets of tex coords we've just assigned */
pfVArrayName( pfGArrayQueryAttrTypeStage(gArray, PFGA_TEX_ARRAY, 0), "base texture coords");
pfVArrayName( pfGArrayQueryAttrTypeStage(gArray, PFGA_TEX_ARRAY, 1), "bump texture coords");
Additionally, a user can disable and enable attributes using the
pfDisableAttrGeoArray and pfEnableAttrGeoArray functions. These
functions do not remove the attributes from the pfGeoArray, but simply
disable and enable specific attributes for rendering.
For convenience, the function pfGetGArrayArrayMemSize is provided to
quickly calculate the size in client memory the array of a data a single
attribute consumes. This does not neccesarily equal the amount of
Page 7
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
graphics memory the attribute uses, but gives the number of bytes from
beginning to end that the pfGeoArray expects are used by the data array
of an attribute.
In OpenGL Performer 3.2, all of the methods used to set attributes such
as vertex coords, colors, etc, can be used via the existing pfGeoSet
interface. In that sense, replace a call from 'pfNewGSet' with a call to
new functionality. Note that indices will be copied if this happens
because although pfGeoSets use unsigned shorts to store indices,
pfGeoArrays use unsigned ints. Also, if more than one attribute for a
geoset is specified with different indices then the attributes will be
unrolled and the indices ignored.
Also note that when using get methods which require a token which specify
which attribute is requested, the token should be one of the pfGeoSet
(and not pfGeoArray) tokens. For example:
int min, max;
pfGeoArray *gArray = ...;
/* this is ok: */
pfGetGArrayAttrRange(gArray, PFGS_COORD3, &min, &max);
/* this is incorrect */
pfGetGArrayAttrRange(gArray, PFGA_COORD_ARRAY, &min, &max);
In future releases of OpenGL Performer this problem will be resolved but
with OpenGL Performer 3.2 a conflict exists between the tokens used for
pfGeoSets and pfGeoArrays. The underlying principle to keep in mind is
that when using methods which are defined in the pfGeoSet class use
pfGeoSet tokens and when using methods defined only in pfGeoArray then
use pfGeoArray tokens.
Note that since the pfGeoArray attributes are rendered in the order they
were added, it is possible to interleave the attributes with your own
callbacks, by creating special "callback" type with a function mask 0 (no
callback data), or function mask 0x1 (callback data are used).
It is possible to index the attributes, although unlike in a pfGeoSet, a
single index list is used for all attributes. The optional attribute
index list is a list of unsigned short integers. The index list is
specified using the function pfGArrayIndexArray.
If attribute and index lists are allocated from the pfMalloc routines,
pfGArraySetAttr and pfVAttrPtr will correctly update the reference counts
of the lists. Specifically, they will decrement the reference counts of
the old lists and increment the reference counts of the new lists. It
will also free any lists whose reference counts reach 0. When a
pfGeoArray is deleted with pfDelete, all pfMalloc'ed lists will have
Page 8
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
their reference counts decremented by one and will be freed if their
count reaches 0.
When pfGeoArrays are copied with pfCopy, all pfMalloc'ed lists of the
source pfGeoArray will have their reference counts incremented by one and
those pfMalloc'ed lists of the destination pfGeoArray will have their
reference counts decremented by one. pfCopy copies lists only by
reference (only the pointer is copied) and will not free any lists whose
reference counts reach 0.
Attribute data may be any of the following types of memory:
1. Data allocated with pfMalloc. This is the usual, and
recommended memory type for pfGeoArray index and attribute
arrays.
2. Static, malloc(), amalloc(), usmalloc() etc, data subsequently
referred to as non-pfMalloc'ed data. This type of memory is
not generally recommended since it does not support reference
counting or other features provided by pfMalloc. In
particular, the use of static data is highly discouraged and
may result in segmentation violations.
3. pfFlux memory. In a pipelined, multiprocessing environment, a
pfFlux provides multiple data buffers which allow frame-
accurate data modifications to pfGeoArray attribute arrays like
coordinates (facial animation), and texture coordinates (ocean
waves, surf). pfGArrayAddAttr and pfGArrayAttrPtr and will
accept a pfFlux* or pfFluxMemory* for the attribute list (index
lists do not support pfFlux) and the pfGeoArray will select the
appropriate buffer when rendered or intersected with. See
pfFlux for more details.
Since pfGeoArrays are chached using vertex array objects, if
you want to animate some attributes, you need to either disable
caching using function pfGArrayAllowCache or call the function
pfGArrayUpdateData each time you change any of the attribute
data.
4. pfCycleBuffer and pfCycleMemory. However pfCycleBuffer has
been obsoleted by pfFlux. See pfCycleBuffer for more details.
Performer allows mixing pfMalloc'ed, pfFlux and pfCycleBuffer attributes
on a single pfGeoArray.
pfGeoArray Primitive Types
Example 1:
Page 9
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
/* Set up a non-indexed, TRISTRIP pfGeoArray */
garray = pfNewGArray(NULL);
pfGSetPrimType(garray, PFGS_TRISTRIPS);
pfGSetNumPrims(garray, 1);
lengths[0] = 4;
pfGSetPrimLengths(gset, lengths);
coords = (pfVec3*) pfMalloc(sizeof(pfVec3) * 4, NULL);
colors = (pfVec4*) pfMalloc(sizeof(pfVec4) * 4, NULL);
pfGArraySetAttr(garray, PFGA_COORD_ARRAY, 3, GL_FLOAT, 0, coords);
pfGArraySetAttr(garray, PFGA_COLOR_ARRAY, 4, GL_FLOAT, 0, colors);
pfGetGSetClassType returns the pfType* for the class pfGeoArray. The
pfType* returned by pfGetGSetClassType is the same as the pfType*
returned by invoking pfGetType on any instance of class pfGeoArray.
Because OpenGL Performer allows subclassing of built-in types, when
decisions are made based on the type of an object, it is usually better
to use pfIsOfType to test if an object is of a type derived from a
Performer type rather than to test for strict equality of the pfType*'s.
NOTES
The following example shows one way to create a pfGeoArray defining a
hexahedron, which is also known as a cube.
static pfVec3 coords[] =
{
{-1.0, -1.0, 1.0}, /* front */
{ 1.0, -1.0, 1.0},
{ 1.0, 1.0, 1.0},
{-1.0, 1.0, 1.0},
{-1.0, -1.0, 1.0}, /* left */
{-1.0, 1.0, 1.0},
{-1.0, 1.0, -1.0},
{-1.0, -1.0, -1.0},
{-1.0, -1.0, -1.0}, /* back */
{-1.0, 1.0, -1.0},
{ 1.0, 1.0, -1.0},
{ 1.0, -1.0, -1.0},
{ 1.0, -1.0, 1.0}, /* right */
{ 1.0, -1.0, -1.0},
{ 1.0, 1.0, -1.0},
{ 1.0, 1.0, 1.0},
Page 10
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
{-1.0, 1.0, 1.0}, /* top */
{ 1.0, 1.0, 1.0},
{ 1.0, 1.0, -1.0},
{-1.0, 1.0, -1.0},
{-1.0, -1.0, 1.0}, /* bottom */
{-1.0, -1.0, -1.0},
{ 1.0, -1.0, -1.0},
{ 1.0, -1.0, 1.0}
};
static pfVec3 norms[] =
{
{ 0.0, 0.0, 1.0},
{ 0.0, 0.0, 1.0},
{ 0.0, 0.0, 1.0},
{ 0.0, 0.0, 1.0},
{-1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0},
{-1.0, 0.0, 0.0},
{ 0.0, 0.0, -1.0},
{ 0.0, 0.0, -1.0},
{ 0.0, 0.0, -1.0},
{ 0.0, 0.0, -1.0},
{ 1.0, 0.0, 0.0},
{ 1.0, 0.0, 0.0},
{ 1.0, 0.0, 0.0},
{ 1.0, 0.0, 0.0},
{ 0.0, 1.0, 0.0},
{ 0.0, 1.0, 0.0},
{ 0.0, 1.0, 0.0},
{ 0.0, 1.0, 0.0},
{ 0.0, -1.0, 0.0},
{ 0.0, -1.0, 0.0},
{ 0.0, -1.0, 0.0},
{ 0.0, -1.0, 0.0}
};
/* Convert static data to pfMalloc'ed data */
static void*
memdup(void *mem, size_t bytes, void *arena)
{
void *data = pfMalloc(bytes, arena);
memcpy(data, mem, bytes);
return data;
}
Page 11
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
/* Set up a PFGS_QUADS pfGeoArray */
garray = pfNewGArray(NULL);
pfGSetPrimType(garray, PFGS_QUADS);
pfGSetNumPrims(garray, 6);
pfGArraySetAttr(garray, PFGA_COORD_ARRAY, 3, GL_FLOAT, 0,
memdup(coords, sizeof(coords), NULL));
pfGArraySetAttr(garray, PFGA_NORMAL_ARRAY, 3, GL_FLOAT, 0,
memdup(norms, sizeof(norms), NULL));
Unlike pfGeoSets we cannot index vertex coordinates and normals
separately, resulting in a bigger memory requirements. The extra storage
is worth the reduced rendering times, though.
Another example of creating pfGeoArrays can be found in
libpfdu/pfdConvertToGeoArrays.C and src/pguide/libpr/C++/geoArray.C.
Converting pfGeoSets to pfGeoArrays
Since using pfGeoArrays can be much faster on some platforms, such us
Onyx4, you can convert your geometry from pfGeoSets to pfGeoArrays using
two functions: pfdConvertGeoSetToGeoArray and
pfdConvertNodeGeoSetsToGeoArrays. The first function converts an
individial pfGeoSet into a pfGeoArray. The second function traverses a
pfNode and replaces all its pfGeoSets to pfGeoArrays. The parameter
flags can be set to 0 or to PFD_CONVERT_TO_INDEXED_GEOARRAYS. In the
second case the loader tries to avoid the use of lengths array and it
converts strips to indexed lines or triangles.
Also, it is possible to use a pseudoloader .geoa to convert the geometry
from pfGeoSets to pfGeoArrays during loading. The pseudoloader is used as
follows: perfly file.ext.geoa. The pseudoloader calls
pfdConvertNodeGeoSetsToGeoArrays with the flag
PFD_CONVERT_TO_INDEXED_GEOARRAYS set. You can overwrite this default by
setting the environment variable PFD_CONVERT_TO_INDEXED_GEOARRAYS to 0.
NOTES
On some hardware, the implementation of hardware cached vertex arrays may
not be efficient. In these cases, you may want to try to disable vertex
buffer objects by setting environment variable
PF_USE_VERTEX_BUFFER_OBJECTS to 0. On hardware that doesn't have support
for the vertex_buffer_object or vertex_array_object extensions, while
pfGeoArrays will still render correctly, they may not be as fast as
rendering pfGeoSets, which are optimized for immediate mode rendering.
Additionally, the rules for obtaining maximum performance with scene
graphs involving pfGeoArrays can be different than those using pfGeoSets.
Page 12
pfGeoArray(3pf) OpenGL Performer 3.2.2 libpr C Reference Pages
For example, since unique pfGeoArrays will use different chunks of
grahics memory, it is preferable to use instancing as much as possible.
This implies that flattening scene graphs with instanced pfGeoArrays may
actually hurt performance.
SEE ALSO
pfGeoSet, pfApplyGState, pfColortable, pfCopy, pfCycleBuffer, pfDecal,
pfDelete, pfDisable, pfDispList, pfEnable, pfFlux, pfFluxMemory,
pfGeoState, pfHit, pfISL, pfLPointState, pfMalloc, pfMaterial,
pfNewHlight, pfObject, pfOptimizeGraph, pfGSetIsectSegs, pfShadeModel,
pfState, pfDispListOptimizer
Page 13