Skip to main content
GameDev.net gamedev.net
🔒 Locked

Deferred Lighting Optimizations and problems

Started by Enalis Jan 5, 2007 at 10:44 AM 1 replies 1.6k views
Original Post
Enalis
Enalis
This is my code to test our a deferred lighting system. There are a few problems, the bloom pass is not drawing at all to the attached frame buffer object color attachment 4. That is the main problem. I test the framebuffer for errors and it's not reporting anything. The other problem is this thing is just way too slow. I've tested the RenderTestModels() separately and it functions fine so I'm wondering if some better trained eyes can glance this code over and let me know of any thing I could do to increase efficiency or tell my why I can't render to the 4th color attachment?

	// setup our aux buffers
	GLint currentDrawBuf;
	glGetIntegerv(GL_DRAW_BUFFER, &currentDrawBuf); // Save the current Draw buffer

	// do initial info gathering pass
	// bind our frame buffer object textures, this needs fixed up.
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, renderer.FBO);
	glReadBuffer(GL_NONE);
	glDrawBuffer(GL_NONE);
	deferredShader.TurnOn();

	// set our draw buffers into the Multiple Rendering Targets gl_FragData; where 0 < 1 < 3;
	GLenum buffers[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
	glDrawBuffers(3, buffers);

	// push our initial rendering matrix on the stack
	glPushMatrix();
	// and initialize the viewport for a rendering context
	glViewport(0, 0, width, height);

	// clear our three frame buffers used in the info gathering phase
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	// set our shader variables
	deferredShader.SetFloat("parallax", GLSL_UNIFORM, 1.0f);	// set the parallax mapping off
	deferredShader.SetFloat("bumpMagnitude", GLSL_UNIFORM, 0.01f);	// bump maximum
	deferredShader.SetFloat("specular", GLSL_UNIFORM, 1.0f);	// get from object material
	deferredShader.SetFloat3("cameraPosition", GLSL_UNIFORM, renderer.camera->xPos, renderer.camera->yPos, renderer.camera->zPos);
	deferredShader.SetFloat3("cameraView", GLSL_UNIFORM, renderer.camera->xView, renderer.camera->yView, renderer.camera->zView);
	deferredShader.SetInt("decalMap", 0);						// object material
	deferredShader.SetInt("normalMap", 1);						// object material
	deferredShader.SetInt("heightMap", 2);						// object material

	// apply our textures to our mesh rendering
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, parallaxTestTextures[DECAL_TEXTURE]);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, parallaxTestTextures[NORMAL_TEXTURE]);
	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, parallaxTestTextures[HEIGHT_TEXTURE]);

	// render our mesh data :: need to change this to Vertex Buffer Objects
	RenderTestModel(cVector3f(0.0f, 0.0f, 0.0f));

	// pull off our rendering matrix
	glPopMatrix();

	deferredShader.TurnOff();
	// end initial info gathering pass

	//now do all shadow passes

	// end shadow passes

	// do all lighting passes on accumulation buffer
	// set our draw and read buffer to our fourth color attachment index 3 for blending the light maps onto
	// turn on the shader
	lightAccumShader.TurnOn();
	glDrawBuffer(GL_COLOR_ATTACHMENT3_EXT);
	glReadBuffer(GL_COLOR_ATTACHMENT3_EXT);
//	GLenum buffers2[] = {GL_COLOR_ATTACHMENT3_EXT, GL_COLOR_ATTACHMENT4_EXT};
//	glDrawBuffers(2, buffers2);
	// push a rendering context matrix on the stack
	glPushMatrix();
	// reset the viewport for a new rendering context
	glViewport(0, 0, width, height);
	// clear them out
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	// switch to a 2d mode <- may be causing a serious slowdown.
	orthoMode(0, 16, 0, 12);
	// enable blending for blending the light maps
	glEnable(GL_BLEND);
	// take the source alpha of the pixel that was set and blend with one
	glBlendFunc(GL_SRC_ALPHA, GL_ONE);

	// for each light in the scene
	for (int i = 0; i < renderer.numOfLights; i++){
		// bind our data storage frame buffer textures
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D,renderer.FBOTextures[0]);			// Bind the Decals and specular
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D,renderer.FBOTextures[1]);			// Bind the normals and depth
		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D,renderer.FBOTextures[2]);			// Bind the Position and free

		// give our textures to our shaders
		lightAccumShader.SetInt("input0", 0);
		lightAccumShader.SetInt("input1", 1);
		lightAccumShader.SetInt("input2", 2);

		// give all the crazy variables for lights
		lightAccumShader.SetInt("lightType", renderer.lights->type);
		lightAccumShader.SetFloat3("cameraPosition", GLSL_UNIFORM, renderer.camera->xPos, renderer.camera->yPos, renderer.camera->zPos);
		lightAccumShader.SetFloat3("cameraView", GLSL_UNIFORM, renderer.camera->xView, renderer.camera->yView, renderer.camera->zView);
		lightAccumShader.SetFloat3("lightPosition", GLSL_UNIFORM, renderer.lights->position.x, renderer.lights->position.y, renderer.lights->position.z);
		lightAccumShader.SetFloat3("lightDirection", GLSL_UNIFORM, renderer.lights->direction.x, renderer.lights->direction.y, renderer.lights->direction.z);
		lightAccumShader.SetFloat3("lightDiffuse", GLSL_UNIFORM, renderer.lights->diffuse.x, renderer.lights->diffuse.y, renderer.lights->diffuse.z);
		lightAccumShader.SetFloat3("lightSpecular", GLSL_UNIFORM, renderer.lights->specular.x, renderer.lights->specular.y, renderer.lights->specular.z);
		lightAccumShader.SetFloat("lightConstantAttenuation", GLSL_UNIFORM, renderer.lights->constantAttenuation);
		lightAccumShader.SetFloat("lightLinearAttenuation", GLSL_UNIFORM, renderer.lights->linearAttenuation);
		lightAccumShader.SetFloat("lightQuadraticAttenuation", GLSL_UNIFORM, renderer.lights->quadraticAttenuation);

		// draw a quad :: optimize this!
		glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f);	glVertex2i(0, 0);
		glTexCoord2f(1.0f, 0.0f);	glVertex2i(16, 0);
		glTexCoord2f(1.0f, 1.0f);	glVertex2i(16, 12);
		glTexCoord2f(0.0f, 1.0f);	glVertex2i(0, 12);
//		glTexCoord2f(0.0f, 0.0f);	glVertex3f(0.0f, 0.0f, 0.0f);
//		glTexCoord2f(1.0f, 0.0f);	glVertex3f(1.0f, 0.0f, 0.0f);
//		glTexCoord2f(1.0f, 1.0f);	glVertex3f(1.0f, 1.0f, 0.0f);
//		glTexCoord2f(0.0f, 1.0f);	glVertex3f(0.0f, 1.0f, 0.0f);
		glEnd();
	}
	// reset the current texture
	glActiveTexture(GL_TEXTURE0);
	// go back to 3d mode // might remove because we will continue to be in ortho mode for a while
	perspectiveMode();
	// pop our rendering context off the stack
	glPopMatrix();
	// turn off the shader
	lightAccumShader.TurnOff();
	// no more need for blending
	glDisable(GL_BLEND);
	// end lighting passes

	// do bloom pass
	// set to our 
	glDrawBuffer(GL_COLOR_ATTACHMENT4_EXT);
	glReadBuffer(GL_COLOR_ATTACHMENT4_EXT);
	renderer.CheckFBOStatus();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	// reset the viewport to our texture size
//	glViewport(0, 0, width / 2, height / 2);
	glViewport(0, 0, width, height);
	// set the active texture
	glActiveTexture(GL_TEXTURE0);
	// set the light map as the input
	glBindTexture(GL_TEXTURE_2D, renderer.FBOTextures[3]);
	// turn on the bloom shader
	bloomMap.TurnOn();
	// input the map sizes for bloom map creation
	blendHDRShader.SetFloat("mapSizeX", GLSL_UNIFORM, 800.0f);
	blendHDRShader.SetFloat("mapSizeY", GLSL_UNIFORM, 600.0f);
	// give our light texture to our shader
	bloomMap.SetInt("lightMap", 0);
	// push a view matrix
	glPushMatrix();
	// set into ortho mode
	orthoMode(0, 0, 12, 16);

	// draw our quad
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 0.0f);	glVertex2i(0, 0);
	glTexCoord2f(1.0f, 0.0f);	glVertex2i(16, 0);
	glTexCoord2f(1.0f, 1.0f);	glVertex2i(16, 12);
	glTexCoord2f(0.0f, 1.0f);	glVertex2i(0, 12);
	glEnd();

	// put back in 3d mode
	perspectiveMode();
	// pop a view matrix
	glPopMatrix();

	// turn off the shader
	bloomMap.TurnOff();
	// end bloom pass

	// do final blending pass
	// go back to rendering on our screen
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	// reset the draww buffer
	glDrawBuffer(currentDrawBuf);
	// start a new rendering context
	glViewport(0, 0, width, height);

	// bind our data textures for debugging modes and our light and decal maps
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D,renderer.FBOTextures[0]);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, renderer.FBOTextures[3]);
	glActiveTexture(GL_TEXTURE2);
	glBindTexture(GL_TEXTURE_2D, renderer.FBOTextures[2]);
	glActiveTexture(GL_TEXTURE3);
	glBindTexture(GL_TEXTURE_2D, renderer.FBOTextures[1]);
	glActiveTexture(GL_TEXTURE4);
	glBindTexture(GL_TEXTURE_2D, renderer.FBOTextures[4]);

	// turn on the shader
	blendHDRShader.TurnOn();
	// input our textures into the shader
	blendHDRShader.SetInt("decalMap", 0);
	blendHDRShader.SetInt("lightMap", 1);
	blendHDRShader.SetInt("posSpecMap", 2);
	blendHDRShader.SetInt("normalMap", 3);
	blendHDRShader.SetInt("bloomMap", 4);
	// is hdr on?
	blendHDRShader.SetInt("HDR", HDR);

	// push our rendering context on the stack
	glPushMatrix();
	// set to ortho mode
	orthoMode(0, 16, 0, 12);
	// draw our quad
	glBegin(GL_QUADS);
	glTexCoord2f(0.0f, 0.0f);	glVertex2i(0, 0);
	glTexCoord2f(1.0f, 0.0f);	glVertex2i(16, 0);
	glTexCoord2f(1.0f, 1.0f);	glVertex2i(16, 12);
	glTexCoord2f(0.0f, 1.0f);	glVertex2i(0, 12);
	glEnd();
	// reset the current texture
	glActiveTexture(GL_TEXTURE0);
	// go back to 3d mode
	perspectiveMode();
	// take our rendering context off the stack
	glPopMatrix();
	// turn off the shader
	blendHDRShader.TurnOff();
	// end final blending pass

Douglas Eugene Reisinger II
Projects/Profile Site
Enalis
Enalis
I checked the gl errors at color attachment 4 and it said invalid enumerant which I'm assuming it means it can't attach that buffer for some reason?
Douglas Eugene Reisinger II
Projects/Profile Site
Enalis
Enalis
ok, one more update, through searching forums I found that there is a max on color attachments so the question of performance still remains but I can find a solution for the other problem.
Douglas Eugene Reisinger II
Projects/Profile Site

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.