Hi everybody,
just registered here after beeing stuck for hours. I’m fairly new to OpenGL programming, though I wrote some simple programs and shaders before.
I’m sure somebody around here can tell me, what’s going wrong here.
What I’m trying to achieve here is a simple multi-pass shadowmapping rendering:
#1 Render the z-buffer of the light to a texture
#2 Render the shadows to another texture (viewport resolution)
(#3 Do something with this texture, that’s not implemented at the moment)
#4 Render the scene and apply the shadows from the previously rendered texture in step #2
For reference, that’s what the scene looks like without shadows:
When I display the result of step #2 in the viewport I get, what I expect - the calculated shadows, which are correctly occluded by the geometry:
Now when I simply display the texture rendered in step #2 in the fragment shader of step #4 I get this:
As you can see, this is basically the identical image, but the first and the third cylinder are suddenly missing, eventhough I didn’t change anything. So obviously there is something different rendered to the texture than, when I render the same thing to the viewport.
So I guess there must be either something wrong how I setup the FBO or the texture or some settings I set before drawing the scene.
Here I generate the texture used in step #2 and bind it to the FBO:
void CreateRawShadowFBO()
{
GLenum rawShadowsFBOstatus;
// generate and bind the rawShadowTexture
glGenTextures(1, &rawShadowTexture);
glBindTexture(GL_TEXTURE_2D, rawShadowTexture);
// set the parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
// texture size = viewport size
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, (int) observerWidth, (int) observerHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// generate and bind the rawShadowsFBO
glGenFramebuffers(1, &rawShadowsFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rawShadowsFBO);
// set the rawShadowTexture as render target
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rawShadowTexture, 0);
// check rawShadowsFBO status
rawShadowsFBOstatus = glCheckFramebufferStatusEXT(GL_DRAW_FRAMEBUFFER);
if(rawShadowsFBOstatus != GL_FRAMEBUFFER_COMPLETE_EXT)
printf("GL_FRAMEBUFFER_COMPLETE_EXT failed, CANNOT use rawShadowsFBO
");
// switch back to window-system-provided framebuffer
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, 0);
}
Here’s the shadow rendering part (step #2)
void ProcessShadowMap()
{
//set the viewport
glViewport(0, 0, (int) observerWidth, (int)observerHeight);
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//set the matrices
M3DMatrix44f shadowMat;
M3DMatrix44f viewMat;
M3DMatrix44f eyeToLightView;
UpdateMatrices(shadowMat, viewMat, eyeToLightView);
glColorMask(GL_TRUE,GL_TRUE, GL_TRUE, GL_FALSE);
glDepthMask(GL_TRUE);
glClear(GL_DEPTH_BUFFER_BIT);
// render the 'raw' shadows to the rawShadowsFBO
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rawShadowsFBO);
// set the process shadows shader
glUseProgram(procShadowsShader);
// bind the previously rendered depthmap
glBindTexture(GL_TEXTURE_2D, shadowMap);
// set the Model View Projection Matrix for the shader
glUniformMatrix4fv(glGetUniformLocation(procShadowsShader, "mvMatrix"), 1, GL_FALSE, transformPipeline.GetModelViewMatrix());
//Projektionsmatrix
glUniformMatrix4fv(glGetUniformLocation(procShadowsShader, "projMatrix"), 1, GL_FALSE, transformPipeline.GetProjectionMatrix());
// set the ShadowMatrix for the shader
glUniformMatrix4fv(glGetUniformLocation(procShadowsShader, "eyeToLightViewTexMatrix"), 1, GL_FALSE, shadowMat);
glUniformMatrix4fv(glGetUniformLocation(procShadowsShader, "eyeToLightViewMatrix"), 1, GL_FALSE, eyeToLightView);
//calc the light's position, at the origin of the light-view matrix
M3DMatrix44f invLight;
m3dInvertMatrix44(invLight,lightView);
M3DVector4f lp;
m3dLoadVector4(lp,0,0,0,0);
m3dTransformVector4(lightPos, lp, invLight);
// set the light's parameters
glUniform4fv(glGetUniformLocation(procShadowsShader,"lightPos"),1,lightPos);
glUniform1f(glGetUniformLocation(procShadowsShader,"lightNear"),lightNearClip);
glUniform1f(glGetUniformLocation(procShadowsShader,"lightFar"),lightFarClip);
float lightSizeX = (lightSize/lightFrustumWidth)/(float)shadowMapSize;
float lightSizeY = (lightSize/lightFrustumHeight)/(float)shadowMapSize;
glUniform2f(glGetUniformLocation(procShadowsShader,"wLight"),lightSizeX,lightSizeY);
glUniform1i(glGetUniformLocation(procShadowsShader,"shadowMap"),0);
//draw the model
modelBatch.Draw();
//(de)activate stuff
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
modelViewMatrix.PopMatrix();
glColorMask(GL_TRUE,GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
gltCheckErrors(procShadowsShader);
}
And here’s the final step #4, at the moment the shader used here just displays the rendered texture in step #2:
void RenderShadows()
{
//set the viewport
glViewport(0, 0, (int) observerWidth, (int)observerHeight);
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//set the projection matrix
viewFrustum.SetPerspective(45.0f,aspect,0.1f,100);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
//switch cameras
if(!toggleView)
modelViewMatrix.PushMatrix(observerFrame);
else
modelViewMatrix.PushMatrix(lightFrame);
//set the shader program
glUseProgram(displayShadows);
//bind the shadowtexture
glBindTexture(GL_TEXTURE_2D, rawShadowTexture);
// set the Model View Matrix
glUniformMatrix4fv(glGetUniformLocation(displayShadows, "mvMatrix"),
1, GL_FALSE, transformPipeline.GetModelViewMatrix());
//set the Projectionsmatrix
glUniformMatrix4fv(glGetUniformLocation(displayShadows, "projMatrix"),
1, GL_FALSE, transformPipeline.GetProjectionMatrix());
//set the Normalmatrix
glUniformMatrix3fv(glGetUniformLocation(displayShadows, "normalMatrix"),
1, GL_FALSE, transformPipeline.GetNormalMatrix());
//light position
M3DMatrix44f invLight;
m3dInvertMatrix44(invLight,lightView);
M3DVector4f lp;
m3dLoadVector4(lp,0,0,0,0);
m3dTransformVector4(lightPos, lp, invLight);
//light parameters
glUniform4fv(glGetUniformLocation(displayShadows,"lightPos"),1,lightPos);
glUniform4f(glGetUniformLocation(displayShadows,"lightAmbient"),1,1,1,1);
glUniform4f(glGetUniformLocation(displayShadows,"lightDiffuse"),1,1,1,1);
glUniform1f(glGetUniformLocation(displayShadows,"lightNear"),lightNearClip);
glUniform1f(glGetUniformLocation(displayShadows,"lightFar"),lightFarClip);
float lightSizeX = (lightSize/lightFrustumWidth)/(float)shadowMapSize;
float lightSizeY = (lightSize/lightFrustumHeight)/(float)shadowMapSize;
glUniform2f(glGetUniformLocation(displayShadows,"wLight"),lightSizeX,lightSizeY);
glUniform1i(glGetUniformLocation(displayShadows,"shadowMap"),0);
//draw the model
modelBatch.Draw();
glUseProgram(0);
glBindTexture(GL_TEXTURE_2D, 0);
modelViewMatrix.PopMatrix();
gltCheckErrors(displayShadows);
}
Anybode an idea what goes wrong, when rendering to the texture? I’d be really grateful for any hints