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
This archive was generated by hypermail 2b29 : Tue Jan 25 2005 - 11:34:02 PST