PDA

View Full Version : Rendering to texture/FBO issue



nattfoedd
06-07-2012, 10:26 AM
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:
http://bildupload.sro.at/a/thumbs/1-no_shadows.jpg (http://bildupload.sro.at/a/images/1-no_shadows.png)

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:
http://bildupload.sro.at/a/thumbs/shadows_viewport.jpg (http://bildupload.sro.at/a/images/shadows_viewport.png)

Now when I simply display the texture rendered in step #2 in the fragment shader of step #4 I get this:
http://bildupload.sro.at/a/thumbs/shadows_texture.jpg (http://bildupload.sro.at/a/images/shadows_texture.png)

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\n");

// 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(procShadow sShader, "mvMatrix"), 1, GL_FALSE, transformPipeline.GetModelViewMatrix());
//Projektionsmatrix
glUniformMatrix4fv(glGetUniformLocation(procShadow sShader, "projMatrix"), 1, GL_FALSE, transformPipeline.GetProjectionMatrix());

// set the ShadowMatrix for the shader
glUniformMatrix4fv(glGetUniformLocation(procShadow sShader, "eyeToLightViewTexMatrix"), 1, GL_FALSE, shadowMat);
glUniformMatrix4fv(glGetUniformLocation(procShadow sShader, "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(procShadowsShade r,"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.GetProject ionMatrix());


//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(displaySha dows, "mvMatrix"),
1, GL_FALSE, transformPipeline.GetModelViewMatrix());
//set the Projectionsmatrix
glUniformMatrix4fv(glGetUniformLocation(displaySha dows, "projMatrix"),
1, GL_FALSE, transformPipeline.GetProjectionMatrix());

//set the Normalmatrix
glUniformMatrix3fv(glGetUniformLocation(displaySha dows, "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 :)