Athanasios Gaitatzes (gaitat++at++fhw.gr)
Thu, 18 Nov 1999 15:23:52 +0200
Since couple of people have asked here is the modified shadows.c. No
local lights and no spotlights or projected textures unless there is something
I really don't understand. I use it as 'shadows -s iris.flt' on a Onyx2
8 processors latest Iris and Performer code.
I have been unable though to make the same thing work in a CAVE and
that's what I am interested in so if someone has any suggestions they would
be most welcome.
Thank you
/*
* shadows.c: Performer program to demonstrate use of pfLightSource
shadowing
*
* cc -s -O2 -n32 -o shadows shadows.c -L/usr/lib32 -lpfdu -lpfutil
-lpf \
*
-lGL -lGLU -lX11 -lm -lC -limage
*
*/
static int Shadow = 0;
static int enable_shadows = 1; /* disable shadows if HW does not handle
it */
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <Performer/pf.h>
#include <Performer/pfdu.h>
#include <Performer/pfutil.h>
static int FBAttrs[] = {
PFFB_RGBA,
PFFB_DOUBLEBUFFER,
PFFB_DEPTH_SIZE, 1,
None,
};
void
OpenPipeWin (pfPipeWindow *pw)
{
pfOpenPWin(pw);
}
/* ARGSUSED */
void
DrawChannel (pfChannel *chan, void *data)
{
pfVec4 clr;
pfSetVec4(clr, .2f, .2f, .2f, 1.0f);
pfClear(PFCL_COLOR|PFCL_DEPTH, clr);
pfDraw();
}
/*
* Usage() -- print usage advice
and exit. This
* procedure is executed in the
application process.
*/
static void
Usage (void)
{
pfNotify(PFNFY_NOTICE, PFNFY_USAGE, "Usage: shadows
[-s] file.ext ...\n");
pfNotify(PFNFY_NOTICE, PFNFY_USAGE, "
-s : enable shadow \n");
exit(1);
}
/*
* docmdline() -- use getopt to
get command-line arguments,
* executed at the start of the
application process.
*/
static int
docmdline(int argc, char *argv[])
{
int opt;
/* process command-line arguments */
while ((opt = getopt(argc, argv, "sh")) != -1)
{
switch (opt)
{
case 's':
Shadow = 1;
break;
case 'h':
Usage();
}
}
return optind;
}
/* Compute matrix so +Y axis of DCS is pointing at 'at' */
static void
lookAt(pfDCS *dcs, pfVec3 at)
{
pfVec3
v, pos;
pfMatrix
mat;
static pfVec3
yaxis = {0.0f, 1.0f, 0.0f};
/* v is origin of dcs */
pfGetMatRowVec3(*pfGetDCSMatPtr(dcs), 3, pos);
/* v is direction vector from dcs to 'at' */
pfSubVec3(v, at, pos);
pfNormalizeVec3(v);
/* Rotate y-axis onto v */
pfMakeVecRotVecMat(mat, yaxis, v);
pfSetMatRowVec3(mat, 3, pos); /* restore dcs origin
*/
pfDCSMat(dcs, mat);
}
#define FOV
45.0f
#define NEAR
1.0f
#define SQRT2INV .7071067811865475244
static pfDCS
*shadDCS;
static pfLightSource *shad;
static pfGroup*
initLSources(pfSphere *bsphere)
{
pfFrustum *shadFrust;
pfTexture *tex;
pfGroup *group;
float
d;
pfMatrix mat;
void *arena
= pfGetSharedArena();
/* Create and configure shadow frustum. Fit frustum
tightly to scene. */
shadFrust = pfNewFrust(arena);
pfMakeSimpleFrust(shadFrust, FOV);
d = bsphere->radius / sinf(PF_DEG2RAD(FOV/2.0f));
d = PF_MAX2(d, NEAR + bsphere->radius);
pfFrustNearFar(shadFrust, NEAR, d + 1.1f * bsphere->radius);
if (enable_shadows)
{
/* Create and configure
white shadow casting light source */
shad = pfNewLSource();
pfLSourceMode(shad, PFLS_SHADOW_ENABLE,
1);
pfLSourceAttr(shad, PFLS_PROJ_FRUST,
shadFrust);
pfLSourceColor(shad, PFLT_DIFFUSE,
1.0f, 1.0f, 1.0f);
pfLSourceVal(shad, PFLS_INTENSITY,
.2f); /* shadow not complety dark *//*
pfLSourcePos(shad, 0.0f, 0.0f, 0.0f, 1.0f); */ /* Make
light local */ pfLSourceVal(shad,
PFLS_SHADOW_SIZE, 256);
}
group = pfNewGroup();
/* Make DCSes to move lights around */
if (enable_shadows)
{
shadDCS = pfNewDCS();
pfMakeTransMat(mat, d*SQRT2INV,
0.0f, d*SQRT2INV);
pfDCSMat(shadDCS, mat);
lookAt(shadDCS, bsphere->center);
pfAddChild(shadDCS, shad);
if (Shadow)
pfAddChild(group, shadDCS);
}
return group;
}
int
main (int argc, char *argv[])
{
pfScene *scene;
pfNode *root;
pfDCS *dcs;
pfPipe *p;
pfPipeWindow *pw;
pfChannel *chan;
pfSphere bsphere;
pfCoord view;
pfMatrix mat, orbit;
int
ret;
int
arg = 1;
int
found;
arg = docmdline(argc,argv);
/* Initialize Performer */
pfInit();
if (Shadow)
{
pfQueryFeature(PFQFTR_TEXTURE_SHADOW,
&ret);
if (!(ret == PFQFTR_FAST))
{
printf("Sorry, Shadows are not supported !\n");
enable_shadows = 0;
}
}
else
enable_shadows = 0;
/* Use default multiprocessing mode based on number
of
* processors.
*/
pfMultiprocess(PFMP_DEFAULT);
/* Load all loader DSO's before pfConfig() forks
*/
for (found = arg; found < argc; found++)
pfdInitConverter(argv[found]);
/* Configure multiprocessing mode and start parallel
* processes.
*/
pfConfig();
/* Append to PFPATH additional standard directories
where
* geometry and textures exist
*/
pfFilePath(".:/usr/share/Performer/data");
/* load files named by command line arguments */
scene = pfNewScene();
dcs = pfNewDCS();
pfMakeRotMat(mat, 30.0f, 1.0f, 0.0f, 0.0f);
pfDCSMat(dcs, mat);
pfAddChild(scene, dcs);
for (found = 0; arg < argc; arg++)
{
if ((root = pfdLoadFile(argv[arg]))
!= NULL)
{
pfAddChild(dcs, root);
found++;
}
}
if (!found)
{
pfNotify(PFNFY_FATAL,PFNFY_USAGE,"Error
loading database files");
exit(-1);
}
/* determine extent of scene's geometry */
pfGetNodeBSphere (scene, &bsphere);
/* Create pfLightSources and add to scene */
pfAddChild(scene, initLSources(&bsphere));
/* Configure and open GL window */
p = pfGetPipe(0);
pw = pfNewPWin(p);
pfPWinName(pw, argv[0]);
pfPWinConfigFunc(pw, OpenPipeWin);
pfPWinOriginSize(pw, 0, 0, 500, 500);
pfPWinType(pw, PFPWIN_TYPE_X);
pfPWinFBConfigAttrs(pw, FBAttrs);
pfConfigPWin(pw);
/* Create and configure a pfChannel. */
chan = pfNewChan(p);
pfChanScene(chan, scene);
pfChanNearFar(chan, NEAR, 5.0f * bsphere.radius);
pfChanFOV(chan, FOV, 0.0f);
pfCopyVec3(view.xyz, bsphere.center);
view.xyz[PF_Y] -= 3.0f * bsphere.radius;
pfSetVec3(view.hpr, 0.0f, 0.0f, 0.0f);
pfChanView(chan, view.xyz, view.hpr);
pfChanTravFunc(chan, PFTRAV_DRAW, DrawChannel);
pfMakeRotMat(orbit, -1.2f, 0.f, 0.0f, 1.0f);
/* Simulate for ever ! */
while (1)
{
/* Spin light sources around
object */
if (enable_shadows)
{
pfMultMat(mat, *pfGetDCSMatPtr(shadDCS), orbit);
pfDCSMat(shadDCS, mat);
lookAt(shadDCS, bsphere.center);
}
/* Initiate cull/draw for
this frame. */
pfFrame();
}
}
--
Athanasios Gaitatzes (gaitat++at++fhw.gr)
Virtual Reality Department
Foundation of the Hellenic World
38 Poulopoulou St., Athens 11851, Greece
Tel: +30 1 3422292 Fax: +30 1 3422272
This archive was generated by hypermail 2.0b2 on Thu Nov 18 1999 - 05:31:20 PST