Rendering to texture/FBO issue

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 :slight_smile: