How do I achieve some multipass renderings (motion blur, depth of

New Message Reply Date view Thread view Subject view Author view

David Plew (kishore++at++aimnet.com)
Mon, 10 Mar 1997 09:39:23 -0800 (PST)


 field effect) on Performer1.2 or 2.0 ?

>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


New Message Reply Date view Thread view Subject view Author view

This archive was generated by hypermail 2.0b2 on Mon Aug 10 1998 - 17:54:52 PDT

This message has been cleansed for anti-spam protection. Replace '++at++' in any mail addresses with the '@' symbol.