I’m very new to OpenGL.
I have an object created from triangles. I draw shadow volumes from this object to infinity but, when compiled, they show up on side A or side B of the shadow volumes and I need them to show up on side C if that makes any sense.
The shapes of the volumes are correct in that they are tangent to the object and on the side opposite the light source.
Lastly, I don’t know if the problem is in the order I’m sending the vertexes to glVertex3f and glVertex4f or in the way I’m drawing the scene.
//------DRAW SCENE with lights off
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
//------DRAW SHADOW VOLUMES with backface culling
glStencilFunc(GL_ALWAYS, GL_FALSE, GL_FALSE); glEnable(GL_CULL_FACE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
//------DRAW SHADOW VOLUMES with frontface culling
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
//------DRAW SCENE with lights on
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 0, -1);
A picture of the problem might help us a bit here
Seems you’re trying to implement Z-Pass Stencil Shadows with shadowed areas indicated by a stencil value > 0.
So you want to configure stencil to achieve the following:
[ul][li] (Front-Face-Pass) render shadow volumes such that for every polygon that survives z-test with the solid geometry (Z_PASS) and faces towards the camera, increase the stencil value* render shadow volumes such that for every polygon that survives z-test with the solid geometry (Z_PASS) and faces away from the camera, decrease the stencil value[/ul][/li]Looking at your code: I guess that glStencilFunc(GL_ALWAYS, GL_FALSE, GL_FALSE)
does not make any sense when writing to the stencil buffer since you’re setting the mask (last parameter) to zero. In your case you want to write to all bits, so the mask should all be “111…1” or “~0”.
Again, when performing the lighting pass you want to restrict the drawing to areas with stencil value == 0 (no shadow) which is done by setting glStencilFunc( GL_EQUAL, 0, ~0 );
meaning pass if reference (zero in this case) is equal to the value in the stencil buffer. In other words this results in passing of stencil test if stencil value == 0.
Also, you may want to use GL_DECR_WRAP/GL_INCR_WRAP when specifying the stencil operation and check for an appropriate switching to Z-Fail shadows when the camera/front clipping plane is close to the shadow volumes.
That is much better. Thanks for your help and explanation.
Now it looks like I’m still not decrementing the stencil on pixels inside of the model on the second pass. Do I need to change glStencilFunc() for the back face pass? I still need to decrement all bits on zero. I tried altering the stencil function but I think I’m still getting the incremented bits from the whole shadow volume instead of just the incremented bits from the model.
Do I need to change glStencilFunc() for the back face pass?
No, you want to always draw the backfaces no matter what stencil value is in the stencil buffer.
Two things to check:
[ul][li]Are your extruded shadow volumes consistently wound? Culling solely depends on the order the vertices are provided and by default counter-clockwise order is associated with front facing polygons.[*]Hard to tell, but from looking at the last image, the shadowing has no more “streaks” as your first screenshots had. Could it be, that just the floor is not correctly shadowed? Remember, that without any modifications the vanilla shadow volume algorithm needs solid geometry to work as expected. Try to place the motorcycle object on a cube rather than on a single plane.[/ul] [/li]Do yourself a favour and add some debugging code to actually visualize the shadow volumes, preferably in wireframe mode. This makes error checking a lot easier.