David Plew (kishore++at++aimnet.com)
Mon, 10 Mar 1997 09:39:23 -0800 (PST)
>How do I achieve some multipass rendering tecxhniques (motion blur, depth
>of field
>effect) on Performer 1.2 or 2.0?
>------------------------------------------------------
>$BEOJU!!?7 Arata Watanabe
Here are the sample codes to do both. The original code was given to me by
Ran Yakir of BVR Technologies Ltd. I have made a few changes to his idea
to produce the following code.
/**************************** Depth of Field *******************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <Performer/pf.h>
#include <Performer/pr.h>
#include <gl.h>
#include "jitter.h"
#define PI 3.14
#ifndef IRISGL
#define ACSIZE 16
#define GLXSIZE 8
static int attribList[] = {
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 24,
GLX_RED_SIZE, GLXSIZE,
GLX_GREEN_SIZE, GLXSIZE,
GLX_BLUE_SIZE, GLXSIZE,
GLX_STENCIL_SIZE, 1,
GLX_ACCUM_RED_SIZE, ACSIZE,
GLX_ACCUM_GREEN_SIZE, ACSIZE,
GLX_ACCUM_BLUE_SIZE, ACSIZE,
GLX_ACCUM_ALPHA_SIZE, ACSIZE,
None};
#endif
int xsize = 720, ysize = 486;
void *arena;
pfPipe *p;
pfPipeWindow **pw;
float vx = 0.5f, vy = 0.0f, vz = 1.0f;
void channelDraw(pfChannel *chan, void *data);
void OpenPipeWin(pfPipeWindow *pw);
void bufferSwap(pfPipe *, pfPipeWindow *);
int main(int argc, char *argv[])
{
pfScene *scene;
pfGroup *root;
pfChannel *chan;
pfMatrix mat, mat1, mat2;
float x, z;
pfInit();
arena = pfGetSharedArena();
pw = (pfPipeWindow **) pfMalloc(sizeof(pfPipeWindow **), arena);
pfConfig();
scene = pfNewScene();
if ((root = (pfGroup *) pfdLoadFile("/disk4/people/kishore/performer/data/manyGlobes.iv")) == NULL)
{
printf("Unable to create scene data base....\n");
pfExit();
exit(-1);
}
pfAddChild(scene, root);
p = pfGetPipe(0);
*pw = pfNewPWin(p);
//pfPWinType(*pw, PFWIN_TYPE_X);
pfPWinName(*pw, "Depth of Field");
pfPWinOriginSize(*pw, 100, 100, xsize, ysize);
pfOpenPWin(*pw);
pfPWinConfigFunc(*pw, OpenPipeWin);
pfConfigPWin(*pw);
chan = pfNewChan(p);
x = pfTan(45.0f/2.0f);
z = pfTan(31.241362f/2.0f); // choose z such that aspect = xsize/ysize
// else image will distort
pfMakePerspChan(chan, -x, x, -z, z);
pfMakeEulerMat(mat1, 0.0f, 0.0f, 0.0f);
pfMakeTransMat(mat2, vx, vy, vz); // dof doesn't work if vx and
// vz are non-zero
pfMultMat(mat,mat1,mat2);
pfChanViewMat(chan,mat);
pfChanScene(chan, scene);
pfChanTravFunc(chan, PFTRAV_DRAW, channelDraw );
while (1)
{
pfSync();
pfFrame();
}
pfExit();
exit(0);
}
void OpenPipeWin(pfPipeWindow *pw)
{
#ifdef IRISGL
printf("OpenPipeWin \n");
pfOpenPWin(pw);
RGBmode();
RGBsize(12);
doublebuffer();
mssize(8, 32, 1);
acsize (12);
zbsize(32);
gconfig();
#else
XVisualInfo * acc_vis = NULL;
if ( acc_vis = pfChoosePWinFBConfig(pw, attribList) ) {
printf("Got the required visual\n");
pfPWinFBConfig ( pw, acc_vis );
}
pfOpenPWin(pw);
#endif
pfSwapPWinBuffers(pw);
}
void accPerspective( pfChannel *chan, float eyedx, float eyedy, float focus )
{
float left, right, bottom, top;
float near, far;
float dx, dy;
float fovh, fovv;
float fov2;
float xeye = eyedx * 1;
float yeye = eyedy * 1;
pfGetChanNearFar(chan, &near, &far );
pfGetChanFOV(chan, &fovh, &fovv );
fov2 = ( ( fovv * M_PI ) / 180.0f ) / 2.0f;
top = near / ( cos( fov2 ) / sin( fov2 ) );
bottom = -top;
right = near * pfGetChanAspect(chan) / ( cos( fov2 ) / sin( fov2 ) );
left = -right;
dx = -xeye * near / focus;
dy = -yeye * near / focus;
// pfMakePerspChan(chan, left + dx, right + dx, bottom + dy, top + dy );
// pfApplyChan(chan);
#ifdef IRISGL
mmode(MPROJECTION);
window(left+dx, right+dx, bottom+dy, top+dy, near, far);
mmode(MVIEWING);
#else
glMatrixMode ( GL_PROJECTION );
glLoadIdentity();
glFrustum(left+dx, right+dx, bottom+dy, top+dy, near, far);
glMatrixMode ( GL_MODELVIEW );
#endif
pfTranslate( -xeye, vy, -yeye );
}
void channelDraw(pfChannel *chan, void *data)
{
int i;
static float scale = 0.43;
#ifdef IRISGL
acbuf( AC_CLEAR, 0.0f );
#else
glClearAccum ( 0.0,0.0,0.0,0.0);
glClear(GL_ACCUM_BUFFER_BIT);
#endif
for (i=0; i<8; i++)
{
// pfPushMatrix();
#ifndef IRISGL
glMatrixMode ( GL_PROJECTION );
glPushMatrix();
glMatrixMode ( GL_MODELVIEW );
glPushMatrix();
#else
mmode(MVIEWING);
pushmatrix();
#endif
// Change perspective for defocusing.
accPerspective( chan, scale*j8[i].x, scale*j8[i].y, 15);
pfClearChan(chan);
pfDraw();
#ifndef IRISGL
glMatrixMode ( GL_PROJECTION );
glPopMatrix();
glMatrixMode ( GL_MODELVIEW );
glPopMatrix();
#else
mmode(MVIEWING);
popmatrix();
#endif
// pfPopMatrix();
#ifdef IRISGL
acbuf( AC_ACCUMULATE, 1.0/8.0);
#else
glAccum(GL_ACCUM, 1.0/8.0);
/*
// Do the following if you want to see the accum. each loop
glAccum(GL_RETURN, 8.0/(float)i);
pfSwapPWinBuffers(*pw);
*/
#endif
}
#ifdef IRISGL
acbuf( AC_RETURN, 1.0f );
#else
glAccum(GL_RETURN, 1.0f );
#endif
}
/**************************** Motion blur ***********************************/
#include <stdio.h>
#include <stdlib.h>
#include <Performer/pf.h>
#include <Performer/pfutil.h>
#include <Performer/pr.h>
#ifndef IRISGL
#define ACSIZE 16
#define GLXSIZE 8
static int attribList[] = { // used with OpenGL
GLX_RGBA,
GLX_DOUBLEBUFFER,
GLX_DEPTH_SIZE, 24,
GLX_RED_SIZE, GLXSIZE,
GLX_GREEN_SIZE, GLXSIZE,
GLX_BLUE_SIZE, GLXSIZE,
GLX_STENCIL_SIZE, 1,
GLX_ACCUM_RED_SIZE, ACSIZE,
GLX_ACCUM_GREEN_SIZE, ACSIZE,
GLX_ACCUM_BLUE_SIZE, ACSIZE,
GLX_ACCUM_ALPHA_SIZE, ACSIZE,
GLX_SAMPLES_SGIS, 4,
None};
#endif
int xsize = 720, ysize = 486, *FBconfigured;
void *arena;
pfTexture **tex;
pfPipe *p;
pfGroup *MkScene();
pfGeoSet *MakeTexCube(void);
void channelDraw(pfChannel *chan, void *data);
void OpenPipeWin(pfPipeWindow *pw);
int main(int argc, char *argv[])
{
pfChannel *chan;
pfScene *scene;
pfGroup *root, *pass1;
pfCoord view;
pfDCS *dcs;
pfPipeWindow *pw;
float i = 0.0, step = 0.04;
pfInit();
arena = pfGetSharedArena();
tex = (pfTexture **) pfMalloc(sizeof(pfTexture *), arena);
FBconfigured = (int *) pfMalloc(sizeof(int *), arena);
*FBconfigured = 1;
pfConfig();
scene = pfNewScene();
pass1 = pfNewGroup();
dcs = pfNewDCS();
if ((root = MkScene()) == NULL)
{
printf("Unable to create scene data base....\n");
pfExit();
exit(1);
}
pfAddChild(scene, dcs);
pfAddChild(dcs, pass1);
pfAddChild(pass1, root);
p = pfGetPipe(0);
pw = pfNewPWin(p);
//pfPWinType(pw, PFWIN_TYPE_X); // motion blur not working with X in igl
pfPWinName(pw, "Motion Blur");
pfPWinOriginSize(pw, 100, 100, xsize, ysize);
pfPWinConfigFunc(pw, OpenPipeWin);
pfConfigPWin(pw);
chan = pfNewChan(p);
pfChanScene(chan, scene);
pfChanNearFar(chan, 1.0f, 10000.0f);
pfChanFOV(chan, 10.0f, -1.0f);
pfSetVec3(view.hpr, 0, 0, 0);
pfSetVec3(view.xyz, 0, -50, 0);
pfChanView(chan, view.xyz, view.hpr);
pfChanTravFunc(chan, PFTRAV_DRAW, channelDraw );
while (1)
{
pfSync();
pfFrame();
/* translate the geo back and forth */
if (i >= 5.0)
step = -0.04;
if (i <= 0.0)
step = 0.04;
pfDCSTrans(dcs, i, 0, 0);
i = i + step;
}
}
void OpenPipeWin(pfPipeWindow *pw)
{
#ifdef IRISGL
pfOpenPWin(pw);
acsize (16);
gconfig (); // call this if using GL window, else remove it
acbuf (AC_CLEAR, 0.0);
#else
XVisualInfo * acc_vis = NULL;
if (acc_vis = pfChoosePWinFBConfig(pw, attribList))
{
printf("OpenPipeWin : Got the required visual\n");
pfPWinFBConfig ( pw, acc_vis );
}
else
{
printf("OpenPipeWin : Unable to get any visual\n");
*FBconfigured = 0;
}
pfOpenPWin(pw);
if (acc_vis)
{
glClearAccum ( 0.0,0.0,0.0,0.0);
glClear(GL_ACCUM_BUFFER_BIT);
}
#endif
}
void channelDraw(pfChannel *chan, void *data)
{
static float af = 0.88;
#ifdef IRISGL
static float f = 0.0;
#else
static float f = 0.001;
static float mf = 0.0;
#endif
pfClearChan(chan);
pfDraw();
#ifdef IRISGL
acbuf ( AC_MULT, af ); // af controls the length of the trail
acbuf ( AC_ACCUMULATE, 1.0);
f = f * af + 1.0;
acbuf (AC_RETURN, 1.0/f);
#else
if (*FBconfigured)
{
glAccum(GL_MULT, af);
mf = af*mf;
glAccum(GL_ACCUM, f);
mf = f + mf;
glAccum(GL_RETURN, 1.0/mf);
}
#endif
}
pfGroup *MkScene()
{
pfGroup *group;
pfGeode *cube;
pfGeoSet *coloredCube;
group = pfNewGroup();
cube = pfNewGeode();
coloredCube = MakeTexCube();
pfAddGSet(cube, coloredCube);
pfAddChild(group,cube);
return group;
}
/******************************** End *******************************************/
Please read your own geometry file in depth of field program. I haven't been
able to get this to work on IR, but both work on RE2.
Hope this helps
-anita
kishore++at++aimnet.com
=======================================================================
List Archives, FAQ, FTP: http://www.sgi.com/Technology/Performer/
Submissions: info-performer++at++sgi.com
Admin. requests: info-performer-request++at++sgi.com
This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:54:52 PDT