pfShadow(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfShadow(3pf)NAME
pfNewShadow, pfShadowNumCasters, pfGetShadowNumCasters,
pfShadowShadowCaster, pfShadowAdjustCasterCenter,
pfGetShadowShadowCaster, pfGetShadowShadowCasterMatrix,
pfShadowNumSources, pfGetShadowNumSources, pfShadowSourcePos,
pfGetShadowSourcePos, pfShadowLight, pfGetShadowLight,
pfShadowAmbientFactor, pfGetShadowAmbientFactor,
pfShadowTextureBlendFunc, pfShadowAddChannel, pfShadowUpdateView,
pfShadowUpdateCaster, pfShadowApply, pfShadowDraw, pfShadowFlags,
pfGetShadowFlags, pfShadowVal, pfGetShadowVal, pfGetShadowDirData -
Controls rendering of shadows under selected objects.
FUNCTION SPECIFICATION
#include <Performer/pf.h>
pfShadow* pfNewShadow(void);
void pfShadowNumCasters(pfShadow* _shadow, int index);
int pfGetShadowNumCasters(pfShadow* _shadow);
void pfShadowShadowCaster(pfShadow* _shadow, int index,
pfNode *caster, PFMATRIX mat);
void pfShadowAdjustCasterCenter(pfShadow* _shadow, int index,
pfVec3 *trans);
pfNode* pfGetShadowShadowCaster(pfShadow* _shadow, int index);
pfMatrix* pfGetShadowShadowCasterMatrix(pfShadow* _shadow, int index);
void pfShadowNumSources(pfShadow* _shadow, int num);
int pfGetShadowNumSources(pfShadow* _shadow);
void pfShadowSourcePos(pfShadow* _shadow, int index, float x,
float y, float z, float w);
void pfGetShadowSourcePos(pfShadow* _shadow, int index, float *x,
float *y, float *z, float *w);
void pfShadowLight(pfShadow* _shadow, int index, pfLight *light);
pfLight* pfGetShadowLight(pfShadow* _shadow, int index);
void pfShadowAmbientFactor(pfShadow* _shadow, int light,
float factor);
float pfGetShadowAmbientFactor(pfShadow* _shadow, int light);
Page 1
pfShadow(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfShadow(3pf)
void pfShadowTextureBlendFunc(pfShadow* _shadow,
_pfBlendFunc blendFunc);
void pfShadowAddChannel(pfShadow* _shadow, pfChannel *channel);
void pfShadowUpdateView(pfShadow* _shadow);
void pfShadowUpdateCaster(pfShadow* _shadow, int index,
PFMATRIX mat);
void pfShadowApply(pfShadow* _shadow);
void pfShadowDraw(pfShadow* _shadow, pfChannel *chan);
void pfShadowFlags(pfShadow* _shadow, int which, int value);
int pfGetShadowFlags(const pfShadow* _shadow, int which);
void pfShadowVal(pfShadow* _shadow, int caster, int light,
int which, float val);
float pfGetShadowVal(pfShadow* _shadow, int caster, int light,
int which);
pfDirData* pfGetShadowDirData(pfShadow* _shadow, int caster,
int light);
PARENT CLASS FUNCTIONS
The OpenGL Performer class pfShadow is derived from the parent class
pfObject, so each of these member functions of class pfObject are also
directly usable with objects of class pfShadow. Casting an object of
class pfShadow to an object of class pfObject is taken care of
automatically. This is also true for casts to objects of ancestor
classes of class pfObject.
void pfUserDataSlot(pfObject *obj, int slot, void *data);
void pfUserData(pfObject *obj, void *data);
void* pfGetUserDataSlot(pfObject *obj, int slot);
void* pfGetUserData(pfObject *obj);
int pfGetNumUserData(pfObject *obj);
int pfGetNamedUserDataSlot(const char *name);
const char* pfGetUserDataSlotName(int slot);
int pfGetNumNamedUserDataSlots(void);
int pfDeleteGLHandle(pfObject *obj);
Since the class pfObject is itself derived from the parent class
pfMemory, objects of class pfShadow can also be used with these functions
designed for objects of class pfMemory.
Page 2
pfShadow(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfShadow(3pf)
pfType * pfGetType(const void *ptr);
int pfIsOfType(const void *ptr, pfType *type);
int pfIsExactType(const void *ptr, pfType *type);
const char * pfGetTypeName(const void *ptr);
int pfRef(void *ptr);
int pfUnref(void *ptr);
int pfUnrefDelete(void *ptr);
int pfUnrefGetRef(void *ptr);
int pfGetRef(const void *ptr);
int pfCopy(void *dst, void *src);
int pfDelete(void *ptr);
int pfIsFluxed(void *ptr);
int pfCompare(const void *ptr1, const void *ptr2);
void pfPrint(const void *ptr, uint which, uint verbose,
FILE *file);
void * pfGetArena(void *ptr);
DESCRIPTION
A pfShadow is used to control rendering of shadows under selected
objects. The user can specify a set of objects and a set of light
sources. The class takes over the drawing and renders shadows for each
combination of a shadow caster and a light source. Shadows are rendered
by projecting the objects as seen from the light source into a texture
and projecting the texture onto a scene. To avoid computing the texture
for each frame, a set of textures is precomputed at the first frame, then
for each frame the best representative is chosen and warped to
approximate the correct shadow.
A pfShadow is not part of the scene graph, it is created separately by
the application process. Once created the user can specify the number of
shadow casters by calling pfShadowNumCasters and then set each caster
using pfShadowShadowCasters. Each shadow caster is specified by a scene
graph node and a matrix that contains the transformation of the node with
respect to the scene graph root. Shadow casters are indexed from 0 to
the number of casters minus 1. Similarly, the number of light sources is
set by function pfShadowNumSources. A light source is defined by its
position or direction, set by pfShadowSourcePos or pfShadowLight. The
class initialization is completed by calling pfShadowApply.
A pfShadow needs information about the current eye position and view
direction. Since this information is not directly accessible in a draw
process it is necessary to call pfShadowAddChannel for each channel (at
the beginning of the application). Whenever the view changes the
application process has to call pfShadowUpdateView. Even if the view
does not change, this function has to be called at least once in a single
process mode or as many times as the number of buffers in a pfFlux in MP
mode. Without updating the view the shadow is not rendered correctly.
Example:
Page 3
pfShadow(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfShadow(3pf)
pfShadow *shd = pfNewShadow();
pfShadowNumCasters(shd, 2);
pfShadowShadowCaster(shd, 0, node1, matrix1);
pfShadowShadowCaster(shd, 1, node2, matrix2);
pfShadowNumSources(shd, 1);
pfShadowSourcePos(shd, 0, x1, y1, z1, w1);
pfShadowAddChannel(channel);
pfShadowApply(shd);
See a sample implementation of shadows in
perf/samples/pguide/libpf/C++/shadowsNew.
ADDITIONAL PARAMETERS
As the caster is projected into a shadow texture the center of the
projection corresponds with the center of the bounding box of the
caster's node. When the shadow texture is skewed to approximate shadows
from slightly different direction its is best if the center of the
projection corresponds with the center of the object. The bounding box
center may not coincide with the center of the object (in case of some
long protruding parts) and function pfShadowAdjustCasterCenter can be
used to shift the bounding box center towards the object center.
The shadow texture is used to darken the scene pixels when the texture
texel is set to 1. The amount by which the scene pixel is darkened can be
set by pfShadowAmbientFactor. The default value is 0.6
For each combination shadow caster-light source it is possible to specify
how many shadow textures are used, what their sizes are, and the set of
directions, for which the textures are precomputed. The number of
textures and their size can be set by pfShadowVal, where the first
parameter is PFSHD_PARAM_TEXTURE_SIZE or PFSHD_PARAM_NUM_TEXTURES. The
set of directions can be controlled by getting the pointer to the
corresponding pfDirData (a class that stores data associated with a set
of directions), using pfGetShadowDirData. Then you can either select the
default mode (see below) or specify the directions directly. See class
pfDirData for more details. By default there is one texture of size
512x512 and the direction corresponds to the light direction (or a vector
from a point light source to the object center). If there are more
textures, the original light direction is rotated around a horizontal
direction, assuming that the object will mostly keep its horizontal
position (for example a helicopter or a plane).
RENDERING
Page 4
pfShadow(3pf) OpenGL Performer 3.2.2 libpf C Reference Pages pfShadow(3pf)
The user has to call the draw function provided by the class pfShadowDraw
otherwise shadows are not rendered. Before the first frame is rendered
all required shadow textures are precomputed. A warning is printed if the
window size is smaller than the texture dimensions. Make sure that the
window is not obscured, otherwise the textures would not be correct.
By default only the closest shadow texture is selected for any direction
and it is skewed so that it approximates the correct shadow. Optionally,
a flag PFSHD_BLEND_TEXTURES can be set using pfShadowFlags. In this case
two closest textures are selected and blended together, resulting in
smoother transitions. Also, instead of a linear blend between the
textures, the user can define a blend function, mapping values 0-1 to
interval 0-1. The blend function can be set using
pfShadowTextureBlendFunc.
Every time the caster changes its position or orientation with respect to
the light source, it is necessary to update its matrix using
pfShadowUpdateCaster (the caster is identified by its index). When the
caster's matrix changes the shadow of the caster changes as well. In
this case, the set of precomputed shadow textures is searched to find one
or two closest representatives.
A visual with an alpha channel has to be selected for the rendering to
work. See sample code in perf/samples/pguide/libpf/C++/shadowsNew.C for
an example of how to get a visual with an alpha channel.
LIMITATIONS
Since pfShadow is using its own draw function you cannot use it together
with pfVolFog.
pfShadow is using cull programs to cull out geometry that is not affected
by the shadow to make the multi-pass drawing more efficient. At present,
though, the cull program used by pfShadow class overwrites any other cull
program specified by the user. Note: make sure that you do not overwrite
TravMode in your application by setting it to PFCULL_ALL, the mode is set
by pfShadow when pfShadowApply is called.
When projecting a caster into a shadow texture, pfSwitch children are
selected according to switch value. In case of pfLOD the finest level is
chosen. Also, pfSequences are ignored, which can be useful in case of
helicopter rotors, for example.
SEE ALSO
pfObject, pfDirData, pfTexture, pfCullProgram
Page 5