Madhu Sethi (madhu++at++cae.ca)
Thu, 2 May 1996 10:10:45 -0400
I'm having trouble with enabling and then disabling shadows in multiple
channels.
My program opens 2 channels (from the same pipe and pipewindow) which share
most attributes (scene, view, drawcallback...). Initially, the pflightsource of
my scene has shadows enabled. Then, at some point during the simulation shadows
are
disabled. The problem is that I still see a shadow in the second channel after
disabling them. I believe shadows are really disabled because the light source
is moving, while no new shadow is generated. However, whatever shadow was there
previously has not been cleared.
The first channel works fine; there are no remnants of any shadow left.
I have tried disabling shadows in both the app process and in the culling
process - both results are the same.
-----------------------------------------------------------------
I am attaching a modified version of shadows.C to illustrate the
problem, and here are the main diffs b/n original and mine:
Using shadows.C as the template,
- I open another channel (on the same pipe, and pipewindow), which
share most attributes. This second channel should render the same
scene as the first one.
... after opening first channel chan ...
chan->setShare(PFCHAN_SCENE | PFCHAN_FOV | PFCHAN_VIEW | PFCHAN_NEARFAR |
PFCHAN_DRAWFUNC | PFCHAN_SWAPBUFFERS);
pfChannel *chan2 = new pfChannel(p);
chan->attach(chan2);
chan->setViewport(0, 0.5, 0, 1);
chan2->setViewport(0.5, 1, 0, 1);
- In the main loop, after some iterations, I disable shadows (and
projected texture mapping) for the pfLightSources (on both channels).
... within main sim loop ...
i++;
if (i==100) {
shad->setMode(PFLS_SHADOW_ENABLE, 0);
proj->setMode(PFLS_PROJTEX_ENABLE, 0);
}
Both shadows and projected texture mapping give the problem I
described above: they are not cleared in the second channel.
I have tried each, shadows and projected texture mapping in isolation,
and they both give the same problem in the second channel.
Thanks for your help!
-- Madhu Sethi CAE Electronics Ltd. Saint-Laurent, Quebec, Canada
/* * Copyright 1995, Silicon Graphics, Inc. * ALL RIGHTS RESERVED * * UNPUBLISHED -- Rights reserved under the copyright laws of the United * States. Use of a copyright notice is precautionary only and does not * imply publication or disclosure. * * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND: * Use, duplication or disclosure by the Government is subject to restrictions * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or * in similar or successor clauses in the FAR, or the DOD or NASA FAR * Supplement. Contractor/manufacturer is Silicon Graphics, Inc., * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311. * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without * fee, provided that (i) the above copyright notices and this * permission notice appear in all copies of the software and related * documentation, and (ii) the name of Silicon Graphics may not be * used in any advertising or publicity relating to the software * without the specific, prior written permission of Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY * THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE * OR PERFORMANCE OF THIS SOFTWARE. * * shadows.C: Performer program to demonstrate use of pfLightSource shadowing * and projected texturing. * Based on simple.C * * $Revision: 1.5 $ $Date: 1995/12/01 20:33:09 $ * */
#include <stdlib.h> #include <math.h> #include <Performer/pf.h> #include <Performer/pfdu.h> #include <Performer/pfutil.h> #include <Performer/pf/pfChannel.h> #include <Performer/pf/pfLightSource.h> #include <Performer/pf/pfNode.h> #include <Performer/pf/pfDCS.h> #include <Performer/pf/pfGeode.h> #include <Performer/pf/pfScene.h> #include <Performer/pf/pfMorph.h> #include <Performer/pr/pfLinMath.h> #include <Performer/pr/pfMaterial.h> #include <Performer/pr/pfGeoSet.h> #include <Performer/pr/pfGeoState.h> #include <Performer/pr/pfLight.h> #include <Performer/pr/pfTexture.h>
/*------------------------------------------------------------------*/
void OpenPipeWin (pfPipeWindow *pw) { pfLightModel *lm; int numSamples = 16;
pw->open();
#ifdef IRISGL // Shadows require a 32 bit non-multisampled zbuffer do { zbsize(32); stensize(1); mssize(numSamples, 32, 1); gconfig();
numSamples >>= 1;
} while (PF_ABS(getgconfig(GC_BITS_ZBUFFER)) < 32 && numSamples > 0);
if (numSamples > 0) multisample(1); else { RGBsize(12); mssize(0, 0, 0); zbsize(32); stensize(1); gconfig(); multisample(0); }
pfNotify(PFNFY_NOTICE, PFNFY_RESOURCE, "mssize(%d, %d, %d) zbsize(%d) Zrange 0x%x - 0x%x\n", getgconfig(GC_MS_SAMPLES), getgconfig(GC_BITS_MS_ZBUFFER), getgconfig(GC_BITS_MS_STENCIL), getgconfig(GC_BITS_ZBUFFER), getgconfig(GC_MS_ZMIN), getgconfig(GC_MS_ZMAX)); #endif
lm = new(NULL) pfLightModel; lm->setLocal(1); lm->apply();
pfCullFace(PFCF_BACK); }
void DrawChannel (pfChannel *, void *) { pfVec4 clr;
clr.set(.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_FATAL, PFNFY_USAGE, "Usage: shadows file.ext ...\n"); exit(1); }
// 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 ((pfMatrix*) dcs->getMatPtr())->getRow(3, pos); // v is direction vector from dcs to 'at' v = at - pos; v.normalize();
// Rotate y-axis onto v mat.makeVecRotVec(yaxis, v); mat.setRow(3, pos); // restore dcs origin dcs->setMat(mat); }
#define SPOT_SIZE 256 #define SPOT_RADIUS 64
// Create circular image for projected spotlight texture. static pfTexture* initSpotTex(void) { long i, j; pfTexture *tex; ushort *image;
image = (ushort*) pfMalloc(sizeof(unsigned short) * SPOT_SIZE * SPOT_SIZE, pfGetSharedArena());
for (i = 0; i < SPOT_SIZE / 2; i++) { for (j = 0; j < SPOT_SIZE / 2; j++) { unsigned long val;
val = 0;
// See if corners of texel are within circle. This antialiases // the edge of the circle somewhat. if ((i * i + j * j) <= SPOT_RADIUS * SPOT_RADIUS) val += 0xffff; if (((i + 1) * (i + 1) + j * j) <= SPOT_RADIUS * SPOT_RADIUS) val += 0xffff; if (((i + 1) * (i + 1) + (j + 1) * (j + 1)) <= SPOT_RADIUS * SPOT_RADIUS) val += 0xffff; if ((i * i + (j + 1) * (j + 1)) <= SPOT_RADIUS * SPOT_RADIUS) val += 0xffff;
val >>= 2;
// Set all 4 quadrants to val image[(SPOT_SIZE / 2 - i) * SPOT_SIZE + (SPOT_SIZE / 2 - j)] = image[(SPOT_SIZE / 2 - i) * SPOT_SIZE + (SPOT_SIZE / 2 + j)] = image[(SPOT_SIZE / 2 + i) * SPOT_SIZE + (SPOT_SIZE / 2 + j)] = image[(SPOT_SIZE / 2 + i) * SPOT_SIZE + (SPOT_SIZE / 2 - j)] = val; } }
tex = new(pfGetSharedArena()) pfTexture; tex->setImage((uint*) image, 2, SPOT_SIZE, SPOT_SIZE, 0); tex->setFormat(PFTEX_INTERNAL_FORMAT, PFTEX_IA_8); tex->setRepeat(PFTEX_WRAP, PFTEX_CLAMP);
return tex; }
#define FOV 60.0f #define NEAR 1.0f #define SQRT2INV .7071067811865475244
static pfDCS *shadDCS, *projDCS; pfLightSource *shad, *proj;
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 = new(arena) pfFrustum; shadFrust->makeSimple(FOV);
d = bsphere->radius / sinf(PF_DEG2RAD(FOV/2.0f)); d = PF_MAX2(d, NEAR + bsphere->radius);
shadFrust->setNearFar(NEAR, d + 1.1f * bsphere->radius);
// Create and configure white shadow casting light source shad = new pfLightSource; shad->setMode(PFLS_SHADOW_ENABLE, 1); shad->setAttr(PFLS_PROJ_FRUST, shadFrust); shad->setColor(PFLT_DIFFUSE, 1.0f, 1.0f, 1.0f); shad->setVal(PFLS_INTENSITY, .5f); shad->setPos(0.0f, 0.0f, 0.0f, 1.0f); // Make light local
// Create and configure blue spotlight proj = new pfLightSource; tex = initSpotTex(); // You can load your own spotlight texture if you wish // tex = new(arena) pfTexture; // tex->loadFile("spotlight.inta");
proj->setMode(PFLS_PROJTEX_ENABLE, 1); proj->setAttr(PFLS_PROJ_FRUST, shadFrust); proj->setAttr(PFLS_PROJ_TEX, tex); proj->setColor(PFLT_DIFFUSE, 0.0f, 0.0f, 1.0f); proj->setVal(PFLS_INTENSITY, .5f); proj->setPos(0.0f, 0.0f, 0.0f, 1.0f); // Make light local
group = new pfGroup;
// Make DCSes to move lights around shadDCS = new pfDCS;
mat.makeTrans(d*SQRT2INV, 0.0f, d*SQRT2INV); shadDCS->setMat(mat); lookAt(shadDCS, bsphere->center);
shadDCS->addChild(shad); group->addChild(shadDCS);
projDCS = new pfDCS;
mat.makeTrans(-d*SQRT2INV, 0.0f, d*SQRT2INV); projDCS->setMat(mat); lookAt(projDCS, bsphere->center);
projDCS->addChild(proj); group->addChild(projDCS);
return group; }
static pfGeode* initFloor(pfSphere *bsphere) { pfGeoSet *gset; pfGeoState *gstate; pfGeode *geode; pfVec3 *v; pfMaterial *mtl; float d; void *arena = pfGetSharedArena();
gset = new(arena) pfGeoSet; gstate = new(arena) pfGeoState; geode = new pfGeode;
v = (pfVec3*)pfMalloc(sizeof(pfVec3) * 4, arena); d = 3.0f * bsphere->radius; v[0].set(-d, -d, -d/3.0f); v[1].set( d, -d, -d/3.0f); v[2].set( d, d, -d/3.0f); v[3].set(-d, d, -d/3.0f); gset->setAttr(PFGS_COORD3, PFGS_PER_VERTEX, v, NULL);
v = (pfVec3*)pfMalloc(sizeof(pfVec3), arena); v[0].set(0.0f, 0.0f, 1.0f); gset->setAttr(PFGS_NORMAL3, PFGS_OVERALL, v, NULL);
gset->setPrimType(PFGS_QUADS); gset->setNumPrims(1);
mtl = new(arena) pfMaterial; mtl->setColorMode(PFMTL_BOTH, PFMTL_CMODE_OFF); gstate->setAttr(PFSTATE_FRONTMTL, mtl); gstate->setMode(PFSTATE_ENLIGHTING, 1);
gset->setGState(gstate); geode->addGSet(gset);
return geode; }
int main (int argc, char *argv[]) { double t = 0.; pfScene *scene; pfNode *root; pfDCS *dcs; pfPipe *p; pfPipeWindow *pw; pfChannel *chan; pfSphere bsphere; pfCoord view; pfMatrix mat, orbit; pfList *texList;
#ifndef IRISGL printf("Sorry, shadow only works in IRISGL.\n"); return 0; #endif
if (argc < 2) Usage();
// Initialize Performer pfInit();
// Use default multiprocessing mode based on number of // processors. pfMultiprocess(PFMP_DEFAULT);
// Load all loader DSO's before pfConfig() forks pfdInitConverter(argv[1]);
// Configure multiprocessing mode and start parallel // processes. pfConfig();
// Append to PFPATH additional standard directories where // geometry and textures exist pfFilePath(".:/usr/share/Performer/data");
// Do not use FLAT_ primitives because they look bad // with local lighting. pfdBldrMode(PFDBLDR_MESH_LOCAL_LIGHTING, 1);
// Read a single file, of any known type. if ((root = pfdLoadFile(argv[1])) == NULL) { pfExit(); exit(-1); }
// Create and attach loaded subgraph to a pfScene. scene = new pfScene; dcs = new pfDCS; mat.makeRot(30.0f, 1.0f, 0.0f, 0.0f); dcs->setMat(mat); dcs->addChild(root); scene->addChild(dcs);
// determine extent of scene's geometry scene->getBound(&bsphere);
// Create pfLightSources and add to scene scene->addChild(initLSources(&bsphere));
// Create "floor" for shadows dcs->addChild(initFloor(&bsphere));
// Configure and open GL window p = pfGetPipe(0); pw = new pfPipeWindow(p); pw->setName(argv[0]); pw->setOriginSize(0,0,800,800); pw->setConfigFunc(OpenPipeWin); pw->config(); // Create and configure a pfChannel. chan = new pfChannel(p);
// Set up frustum chan->setFOV(45.0f, 0.0f); chan->setNearFar(1.0f, 10.0f * bsphere.radius);
// Set up view view.xyz = bsphere.center; view.xyz[PF_Y] -= 3.0f * bsphere.radius; view.hpr.set(0.0f, 0.0f, 0.0f); chan->setView(view.xyz, view.hpr);
chan->setScene(scene); chan->setTravFunc(PFTRAV_DRAW,DrawChannel); chan->setShare(PFCHAN_SCENE | PFCHAN_FOV | PFCHAN_VIEW | PFCHAN_NEARFAR | PFCHAN_DRAWFUNC | PFCHAN_SWAPBUFFERS); pfChannel *chan2 = new pfChannel(p); chan->attach(chan2);
chan->setViewport(0, 0.5, 0, 1); chan2->setViewport(0.5, 1, 0, 1);
// If scene is non-textured then we can save an entire rendering pass texList = pfuMakeSceneTexList(scene); if (texList->getNum() == 0) { chan->setTravMode(PFTRAV_MULTIPASS, PFMPASS_NONTEX_SCENE); pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "Scene is non-textured! Using PFMPASS_NONTEX_SCENE " "optimization"); }
orbit.makeRot(1.0f, 0.0f, 0.0f, 1.0f);
int i=0; // Simulate for twenty seconds. while (t < 20.0f) { // Spin light sources around object mat = *projDCS->getMatPtr() * orbit; projDCS->setMat(mat); lookAt(projDCS, bsphere.center);
mat = *shadDCS->getMatPtr() * orbit; shadDCS->setMat(mat); lookAt(shadDCS, bsphere.center);
i++; if (i==100) { shad->setMode(PFLS_SHADOW_ENABLE, 0); proj->setMode(PFLS_PROJTEX_ENABLE, 0); } // Initiate cull/draw for this frame. pfFrame(); }
// Terminate parallel processes and exit. pfExit();
return 0; }
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:52:51 PDT