Sign in to follow this  
Enalis

OpenGL simple z-fail shadow volume trouble.

Recommended Posts

I'm trying to set up a simple shadow volume rendering method from which I can expand on. I have implemented shadow mapping but am unpleased with the general results, mainly, I wanted omnidirectional lights. So I did a bunch of reading and found some code but all I'm getting is the scene drawn in grayscale, with no shadows. Here is the code used, it's not very large:
// store current OpenGL state
glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_LIGHTING_BIT | GL_STENCIL_BUFFER_BIT);

// draw the model with the light disabled
glDisable(GL_LIGHTING);
RenderObjects();
glEnable(GL_LIGHTING);

// store current OpenGL state
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT);

glColorMask(0, 0, 0, 0); // do not write to the color buffer
glDepthMask(0); // do not write to the depth (Z) buffer
glEnable(GL_CULL_FACE); // cull faces (back or front)
glEnable(GL_STENCIL_TEST); // enable stencil testing

// set the reference stencil value to 0
glStencilFunc(GL_ALWAYS, 0, ~0);

// increment the stencil value on Z fail
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);

// draw only the back faces of the shadow volume
glCullFace(GL_FRONT);
// pass in variable
GLOBAL->shadowVolume_extrude->TurnOn();
GLOBAL->shadowVolume_extrude->SetFloat4("lightPosition", GLSL_UNIFORM, lights[0]->position.x, lights[0]->position.y, lights[0]->position.z, 1.0f);
RenderObjects();	// NOT QUITE RIGHT

// decrement the stencil value on Z fail
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);

// draw only the front faces of the shadow volume
glCullFace(GL_BACK);
RenderObjects();	// NOT QUITE RIGHT
GLOBAL->shadowVolume_extrude->TurnOff();

// restore OpenGL state
glPopAttrib();

// re-draw the model with the light enabled only where
// it has previously been drawn
glDepthFunc(GL_EQUAL);

// update the color only where the stencil value is 0
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 0, ~0);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

RenderObjects();

// restore OpenGL state
glPopAttrib();

And here is RenderObjects():

void RenderingInterface::RenderObjects(void){
	gPHYSICS->DrawShapes(false);

	// draw objects, replace this with different rendering techniques switch and call separate functions.
	for (unsigned int objectIndex = 0; objectIndex < objectCount; objectIndex++){
		Object *current = objects[objectIndex];
		for (unsigned int bodyIndex = 0; bodyIndex < current->GetBodyCount(); bodyIndex++){
			gGRAPHICS->PushMatrix();
			btCollisionObject* colObj = gPHYSICS->GetWorldPtr()->getCollisionObjectArray()[current->GetBody(bodyIndex)->GetBulletCollisionObejctIndex()];
			btRigidBody* body = btRigidBody::upcast(colObj);
			float m[16];
			if (body && body->getMotionState()){
				btDefaultMotionState* motionState = (btDefaultMotionState*)body->getMotionState();
				motionState->m_graphicsWorldTrans.getOpenGLMatrix(m);
			}else{
				colObj->getWorldTransform().getOpenGLMatrix(m);
			}
			gGRAPHICS->MultMatrix(m);
			gGRAPHICS->Rotate(90.0f, 1.0f, 0.0f, 0.0f);
			gGRAPHICS->Primitive(current->GetBody(bodyIndex)->GetMesh());
			gGRAPHICS->PopMatrix();
		}
	}
}

Just a note, anything using gGRAPHICS-> basically translates directly into opengl

Share this post


Link to post
Share on other sites
It seems I've made a lot of errors. I was thinking about it wrong, I need to generate edge lists and quad lists to do this without geometry shaders. So, does anyone know of a good site to learn a common algorithm to do these things? I was thinking about it and it seems this would get really taxing to do every frame, but it seems you would have to for dynamic shadowing?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this