PDA

View Full Version : shadows



Dalhia
01-27-2001, 02:50 PM
OK, i'm having some serious problems trying to implement shadows. Maybe I am not quite understanding how the stencil buffer works. I am trying to find the shadow a quadrilateral would cast. I first calculate the geometric projection of the quadrilateral out into a value called infinity (which puts the shadow past everything that I have drawn). Once I get the shadow coordinates on the infinity plane I turn on the stencil buffer and draw a quadrilateral inbetween each corresponding edge of the shadow and the quadrilateral that casts it. This forms some sort of specified volume inside of the stencil buffer. Every place that a non-culled front facing quadrilateral exists the stencil bit is increased. Then I redraw all of the quadrilaterals into the stencil buffer, except this time all front facing quadrilaterals are culled. This time, for every place that a non-culled back-facing quadrilateral exists the stencil bit is decreased. These two passes should cancel the space inbetween the shadow and the quadrilateral casting it, leaving only the shadow (where there is no overlap). Once this is set into the stencil buffer, I can then blend a darker alpha value into the area that have non-zero values in the stencil buffer. I take advantage of the fact that the graphics hardware clips the the shadow quadrilaterals where another quadrilateral is drawn. I believe the clipping happens after all of the drawing and before the casting of any shadows (my shadows are cast after my quadrilaterals are drawn). So if any other quadrilaterals are in the volume created by the shadow quadrilaterals then the clipping that they cause should result in a shadow on their surface. Is there anything wrong with that, or am i not writing the code correctly? Here's a snippet of the code that does the shadows:



glPushAttrib (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT);

glDisable (GL_LIGHTING);
glDepthMask (GL_FALSE);
glDepthFunc (GL_LEQUAL);

glEnable (GL_STENCIL_TEST);
glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilFunc (GL_ALWAYS, 1, 0xFFFFFFFFL);

//do all front facing parts and increment
glFrontFace (GL_CCW);
glStencilOp (GL_KEEP, GL_KEEP, GL_INCR);
//draws each quadrilateral designated by geometric projection of the light source and the quadrilateral
ShadowPass(...);

//do all back facing parts and decrement
glFrontFace (GL_CW);
glStencilOp (GL_KEEP, GL_KEEP, GL_DECR);
ShadowPass (...);

glFrontFace (GL_CCW);
glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glColor4f (0.0f, 0.0f, 0.0f, 0.4f);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glStencilFunc (GL_NOTEQUAL, 0, 0xFFFFFFFFL);
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
glPushMatrix();
glLoadIdentity();
glBegin (GL_TRIANGLE_STRIP);
glVertex3f(-0.1f, 0.1f,-0.10f);
glVertex3f(-0.1f,-0.1f,-0.10f);
glVertex3f( 0.1f, 0.1f,-0.10f);
glVertex3f( 0.1f,-0.1f,-0.10f);
glEnd();
glPopMatrix();
glPopAttrib();