Hi,
I tried to applied the technique of the shadow volumes with stencil buffer to draw a shadowed scene. Unfortunately i don’t get a good result… in fact i get nothing. I guess i should have forgotten something in the parameters but i do not see it…
I Initiate the parameters as:
public void init(GLDrawable glDrawable)
{
GL myGL=glDrawable.getGL();//Get the GL object from glDrawable
GLU myGLU=glDrawable.getGLU();
myGL.glClearColor( 0, 0, 0, 0 ); // black clearing color
myGL.glClear(GL.GL_COLOR_BUFFER_BIT); // clear displaying buffer boolean currentCube
myGL.glGenTextures(14,textures);
for(int i=0;i<14;i++)
{
myGL.glBindTexture(GL.GL_TEXTURE_2D, textures[i]);
loadTexture(i);
myGL.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, tWidth, tHeight,0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, texture);
myGL.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR);
myGL.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR);
}
anim = new Animator(glDrawable);
wall = new HegeWall(textures,0,0,0,0,myGL,myGLU);
anim.start();
canvas.repaint();
}
Next here is the display method:
public void display(GLDrawable glDrawable)
{
GL myGL=glDrawable.getGL();
GLU glu = glDrawable.getGLU();
GLUT glut = new GLUT();
myGL.glClearColor( 0, 0, 0, 0 ); // Black clearing color
myGL.glClear( GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT |GL.GL_STENCIL_BUFFER_BIT); // clear all buffers myGL.glShadeModel(GL.GL_SMOOTH);
myGL.glEnable(GL.GL_DEPTH_TEST); // enable Z-buffer
myGL.glEnable(GL.GL_NORMALIZE); myGL.glEnable(GL.GL_CULL_FACE); myGL.glEnable(GL.GL_TEXTURE_2D);
myGL.glEnable(GL.GL_LIGHT0);
myGL.glEnable(GL.GL_LIGHT1);
myGL.glEnable(GL.GL_LIGHTING);
//Parameters of lights and activations of light (one only ambient light the other only diffuse light)
myGL.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, lightAmbient);
myGL.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, lightDiffuse);
myGL.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPosition);
myGL.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightPosition);
myGL.glMatrixMode(GL.GL_MODELVIEW);
myGL.glLoadIdentity();
glu.gluLookAt(eyex,eyey,eyez,lookx,looky,lookz,0,1.0,0);
// draw scene
scene(glDrawable);
//apply shadow volume algorithm
Shadow(glDrawable);
myGL.glFlush();
}
The scene consist of one piece of wall a large quad use for ground (grass) and a large spehere surrounding everything as the sky.
Here is the method for scene drawing
And the results can be seen on this screenshot http://ece.fsa.ucl.ac.be/fremacle/screen1.JPG
private void scene(GLDrawable glDrawable)
{
GL myGL=glDrawable.getGL();
GLU glu = glDrawable.getGLU();
//ground
myGL.glBindTexture(GL.GL_TEXTURE_2D, textures[1]);
myGL.glBegin(GL.GL_QUADS);
myGL.glNormal3f(0,1f,0);
myGL.glTexCoord2f(0,0);
myGL.glVertex3f(-20f,0,20f);
myGL.glTexCoord2f(80f,0);
myGL.glVertex3f(20f,0,20f);
myGL.glTexCoord2f(80f,80f);
myGL.glVertex3f(20f,0,-20f);
myGL.glTexCoord2f(0,80f);
myGL.glVertex3f(-20f,0,-20f);
myGL.glEnd();
//sky
myGL.glBindTexture(GL.GL_TEXTURE_2D, textures[4]);
GLUquadric quadric = glu.gluNewQuadric();
glu.gluQuadricTexture(quadric, true);
glu.gluQuadricDrawStyle(quadric,GLU.GLU_FILL);
glu.gluQuadricNormals(quadric, GLU.GLU_SMOOTH);
glu.gluQuadricOrientation(quadric, GLU.GLU_INSIDE);
myGL.glPushMatrix();
myGL.glRotatef(90f,1,0,0);
glu.gluSphere(quadric,35,200,200);
myGL.glPopMatrix();
//drawing wall
wall.Draw();
}
wall is an object that contains the methods to draw itself and to draw its shadow volume.
On the pictures here you can see (i did put a texture to make it more clear on the screen only) the shadow volume build for the wall (it is only a simple volume as i am beginning to try it)
http://ece.fsa.ucl.ac.be/fremacle/screen2.JPG
http://ece.fsa.ucl.ac.be/fremacle/screen3.JPG
As one can see I have closed the front of the shadow volume (which from the algorithm sounds normal to me)
From the last picture
http://ece.fsa.ucl.ac.be/fremacle/screen4.JPG
You can see that it match the wall correctly.
Now here is the method of the shadow volume algorithm, I have take the method sequence from Nehe productions tutorial 27 and followed the same scheme
private void Shadow(GLDrawable glDrawable)
{
GL gl=glDrawable.getGL();
gl.glDisable(GL.GL_LIGHT0);
gl.glDisable(GL.GL_TEXTURE_2D);
gl.glDepthMask(false);
gl.glDepthFunc(GL.GL_LEQUAL);
gl.glEnable(GL.GL_STENCIL_TEST);
gl.glColorMask(false, false, false, false);
gl.glStencilFunc(GL.GL_ALWAYS, 1, -1);
gl.glFrontFace(GL.GL_CCW);
gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_INCR);
wall.DrawShadow();
gl.glFrontFace(GL.GL_CW);
gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_DECR);
wall.DrawShadow();
gl.glFrontFace(GL.GL_CCW);
gl.glStencilFunc(GL.GL_NOTEQUAL, 0, 0xffffffff);
gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP);
gl.glColorMask(true,true,true,true);
scene(glDrawable);
gl.glDisable(GL.GL_STENCIL_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);
gl.glDepthMask(true);
gl.glEnable(GL.GL_LIGHT0);
gl.glEnable(GL.GL_TEXTURE_2D);
gl.glShadeModel(GL.GL_SMOOTH);
}
Now the problem is that if i actually use this method i have no crash but end with a completely gray screen… So i guess there might be something i have not completely understood… Can someone know what it can be?