[info-performer] z-buffer shadow

Date view Thread view Subject view Author view

From: faculaganymede (faculaganymede++at++yahoo.com)
Date: 01/25/2005 11:33:39


Hi All,

I am working on an OpenGL+Performer application on a
PC (XP, Radeon 9800 Pro) and trying to create shadows
using the z-buffering algorithm (very similar to
shadow-mapping; actually my first attempt was to use
the shadow-mapping method but failed after many
tries).

I am not very familiar with OpenGL but have some
experience with Performer. I've downloaded some
sample shadow programs that other people wrote using
OpenGL. I extracted the shadow creation code and
incorporated it into my Performer application, but I
just couldn't seem to get the shadows to work
properly. I think the main problem is with the
differences in how OpenGL and Performer handles the
view and projection matrices.

Could someone who is familiar with OpenGL+Performer
take a quick look at my code and tell me what I may be
doing wrong?

Below is my entire program, a modification of
Performer earthsky.cxx (I tried running it with
iris.flt):

--------------------------------------------------------------------------------------
#include <stdlib.h>
#include <Performer/pf/pfChannel.h>
#include <Performer/pf/pfEarthSky.h>
#include <Performer/pf/pfLightSource.h>
#include <Performer/pfdu.h>
#include <winbase.h>
#include <windows.h>

static void DrawChannel (pfChannel *chan, void *data);
void shadows();
void initialize();

//
// Usage() -- print usage advice and exit. This
// procedure is executed in the application
process.
//
static void
Usage (void)
{
    pfNotify(PFNFY_FATAL, PFNFY_USAGE, "Usage:
earthsky file.ext ...\n");
    exit(1);
}

static int FBAttrs[] = {
  PFFB_RGBA,
  PFFB_DOUBLEBUFFER,
  PFFB_BUFFER_SIZE, 24,
  PFFB_DEPTH_SIZE, 24,
  PFFB_RED_SIZE, 8,
  PFFB_GREEN_SIZE, 8,
  PFFB_BLUE_SIZE, 8,
  NULL,
};

#define SAFE_DELETE_ARRAY(x) { if( x ){ delete []
x; x = NULL; } }

// width and height of the window
GLsizei g_width = 480;
GLsizei g_height = 360;

// depth buffer
GLfloat * g_depth_light = NULL;
GLfloat * g_depth_view = NULL;

pfCoord view;

GLdouble eye_mat[16];
GLdouble light_mat[16];
GLdouble proj_mat[16];

int main (int argc, char *argv[])
{
    float t = 0.0f;
    pfSphere bsphere;
    
    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");
    
    // Read a single file, of any known type.
    pfNode *root = pfdLoadFile(argv[1]);
    if (root == NULL)
    {
                pfExit();
                exit(-1);
    }
    
    // Attach loaded file to a pfScene.
    pfScene *scene = new pfScene;
    scene->addChild(root);
    
    // determine extent of scene's geometry
    scene->getBound (&bsphere);
    
    // Create a pfLightSource and attach it to scene.
    scene->addChild(new pfLightSource);
    
    // Configure and open GL window
    pfPipe *p = pfGetPipe(0);
    pfPipeWindow *pw = new pfPipeWindow(p);
    pw->setWinType(PFPWIN_TYPE_X);
    pw->setName(argv[0]);
    pw->setOriginSize(100,100,g_width,g_height);
    pw->open();
    
    // Create and configure a pfChannel.
    pfChannel *chan = new pfChannel(p);
    chan->setScene(scene);
    chan->setNearFar(1.0f, 10.0f * bsphere.radius);
    chan->setFOV(45.0f, 0.0f);
    chan->setTravFunc(PFTRAV_DRAW, DrawChannel);
        view.hpr.set(0.0f, -90,0);
        view.xyz.set(0,0,5);
        chan->setView(view.xyz, view.hpr);
    

    pfEarthSky *esky = new pfEarthSky();
    esky->setMode(PFES_BUFFER_CLEAR, PFES_SKY_GRND);
    esky->setAttr(PFES_GRND_HT, -1.0f *
bsphere.radius);
    esky->setColor(PFES_GRND_FAR, 0.3f, 0.1f, 0.0f,
1.0f);
    esky->setColor(PFES_GRND_NEAR, 0.5f, 0.3f, 0.1f,
1.0f);
    chan->setESky(esky);
    

    SAFE_DELETE_ARRAY( g_depth_light );
    SAFE_DELETE_ARRAY( g_depth_view );

    g_depth_light = new GLfloat[g_width * g_height];
    g_depth_view = new GLfloat[g_width * g_height];

    // Simulate for twenty seconds.
    while (t < 20.0f)
    {
                
                // Go to sleep until next frame time.
                pfSync();
                                
                // Initiate cull/draw for this frame.
                pfFrame();
    }
    
    // Terminate parallel processes and exit.
    pfExit();
    
    return 0;
}

// Draw process callback
static void DrawChannel (pfChannel *chan, void *)
{
    GLint buffer = GL_NONE;
    glGetIntegerv( GL_DRAW_BUFFER, &buffer );

        view.hpr.set(0.0f, -65,0);
        view.xyz.set(0,-2,5);
        chan->setView(view.xyz, view.hpr);

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
);

        // disable drawing into color buffer
    glDrawBuffer( GL_NONE );

    pfDraw ();

    // save the depth buffer
    glReadPixels( 0, 0, g_width, g_height,
GL_DEPTH_COMPONENT, GL_FLOAT, g_depth_light );

    // enable drawing into color buffer
    glDrawBuffer( (GLenum)buffer );

//glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
);
//glDrawPixels( g_width, g_height, GL_LUMINANCE,
GL_FLOAT, g_depth_light);

pfMatrix light_view_mat;
chan->getViewMat(light_view_mat);
light_view_mat.invertAff(light_view_mat);
light_view_mat.postRot(light_view_mat, -90,1,0,0);

light_mat[0]=light_view_mat.mat[0][0];
light_mat[1]=light_view_mat.mat[0][1];
light_mat[2]=light_view_mat.mat[0][2];
light_mat[3]=light_view_mat.mat[0][3];
light_mat[4]=light_view_mat.mat[1][0];
light_mat[5]=light_view_mat.mat[1][1];
light_mat[6]=light_view_mat.mat[1][2];
light_mat[7]=light_view_mat.mat[1][3];
light_mat[8]=light_view_mat.mat[2][0];
light_mat[9]=light_view_mat.mat[2][1];
light_mat[10]=light_view_mat.mat[2][2];
light_mat[11]=light_view_mat.mat[2][3];
light_mat[12]=light_view_mat.mat[3][0];
light_mat[13]=light_view_mat.mat[3][1];
light_mat[14]=light_view_mat.mat[3][2];
light_mat[15]=light_view_mat.mat[3][3];

glGetDoublev( GL_PROJECTION_MATRIX, proj_mat );

        view.hpr.set(0.0f, -90,0);
        view.xyz.set(0,0,5);
        chan->setView(view.xyz, view.hpr);

    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
);
    pfDraw ();

pfMatrix eye_view_mat;
chan->getViewMat(eye_view_mat);
eye_view_mat.invertAff(eye_view_mat);
eye_view_mat.postRot(eye_view_mat, -90,1,0,0);

eye_mat[0]=eye_view_mat.mat[0][0];
eye_mat[1]=eye_view_mat.mat[0][1];
eye_mat[2]=eye_view_mat.mat[0][2];
eye_mat[3]=eye_view_mat.mat[0][3];
eye_mat[4]=eye_view_mat.mat[1][0];
eye_mat[5]=eye_view_mat.mat[1][1];
eye_mat[6]=eye_view_mat.mat[1][2];
eye_mat[7]=eye_view_mat.mat[1][3];
eye_mat[8]=eye_view_mat.mat[2][0];
eye_mat[9]=eye_view_mat.mat[2][1];
eye_mat[10]=eye_view_mat.mat[2][2];
eye_mat[11]=eye_view_mat.mat[2][3];
eye_mat[12]=eye_view_mat.mat[3][0];
eye_mat[13]=eye_view_mat.mat[3][1];
eye_mat[14]=eye_view_mat.mat[3][2];
eye_mat[15]=eye_view_mat.mat[3][3];

    // get the current depth buffer
    glReadPixels( 0, 0, g_width, g_height,
GL_DEPTH_COMPONENT, GL_FLOAT, g_depth_view );

//glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
);
//glDrawPixels( g_width, g_height, GL_LUMINANCE,
GL_FLOAT, g_depth_view);

        shadows();

}

//-----------------------------------------------------------------------------
// Name: shadows( )
// Desc: draws shadow
//-----------------------------------------------------------------------------
void shadows( )
{
    //GLdouble mv_mat[16], proj_mat[16];
    GLint viewport[4];
    GLdouble objx, objy, objz;
    GLfloat depth;
    
        //GLfloat * p = g_light_pos;
    GLfloat * depth_view, * depth_light;
    //GLdouble mv_light[16];
    GLdouble winx, winy, winz;
    GLint ix, iy;
    GLdouble depth_2;
    GLint x, y;
    

    glGetIntegerv( GL_VIEWPORT, viewport );

    // color of pixels in shadow
    GLuint pixel = { 0x7f7f7f7f };
    glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

    // get pointers to the depth buffers
    depth_view = g_depth_view;
    depth_light = g_depth_light;

        // set the project matrix to orthographic
        glMatrixMode(GL_PROJECTION);
                glPushMatrix();
                glLoadIdentity();
                gluOrtho2D( 0.0, (GLfloat)g_width, 0.0,
(GLfloat)g_height);

        // set the modelview matrix to identity
        glMatrixMode(GL_MODELVIEW);
                glPushMatrix();
                glLoadIdentity();

        int yk=0;
    // go through every pixel in frame buffer
    for( y = 0; y < g_height; y++ )
        {
        for( x = 0; x < g_width; x++ )
        {
            // depth at pixel
            depth = *depth_view++;

                        if(depth>1)
                        printf("depth=%f\n", depth);

            // on the far plane of frustum - don't
calculate
            if( depth > .99 )
                continue;

            // get world coordinate from x, y, depth
                        // map window coordinates to object coordinates
            gluUnProject( x, y, (GLdouble)depth,
eye_mat, proj_mat, viewport,
                          &objx, &objy, &objz );

            // get light view screen coordinate and
depth
                        // map object coordinates to window coordinates
            gluProject( objx, objy, objz, light_mat,
proj_mat,
                        viewport, &winx, &winy, &winz
);

            ix = (GLint)(winx + .5);
            iy = (GLint)(winy + .5);

            // make sure within the screen
            if( ix >= g_width || iy >= g_height || ix
< 0 || iy < 0 )
                continue;

            // get the depth value from the light
            depth_2 = (GLdouble)depth_light[ iy *
g_width + ix ];

            // is something between the light and the
pixel?
            if( (winz - depth_2) > .01 )
            {
                glRasterPos2i( x, y );
                glDrawPixels( 1, 1, GL_RGBA,
GL_UNSIGNED_BYTE, &pixel );
                                yk++;
            }
        }
        }

    // restore projection
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    // restore modelview transformation
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

        printf("yk=%d\n", yk);
}

=====
Thanks,
faculaganymede

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com


Date view Thread view Subject view Author view

This archive was generated by hypermail 2b29 : Tue Jan 25 2005 - 11:34:02 PST