Sign in to follow this  
adawg1414

OpenGL fbo game shadows?

Recommended Posts

I've posted this in the Game Programming forum and since I'm using OpenGL I figured this might also be a good place to post. Is it too hard to post good shadowing code on the internet these days? I've followed links and instructions but I can't seem to find any really good shadowing code. I'm trying to set up a framebuffer object and render to texture for creating shadows in game. Here's what I've done: 1. I've set up a framebuffer object and a texture for rendering my scene to.
	// set up the framebuffer and renderbuffer objects
	glEnable(GL_TEXTURE_2D);
	bFBOSupported = glewIsExtensionSupported("GL_EXT_framebuffer_object");
	if(bFBOSupported)
	{
		cout << "frame buffers are supported!\n";

		// NOTE:	getting the function address is necessary for using extensions if you don't do glewInit()
		//			wglGetProcAddress() will return a pointer to a procedure so that we can use that extensions functionality
		//			glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)wglGetProcAddress("glGenFramebuffersEXT");

		// generate frame buffers
		glGenFramebuffersEXT(1, &fbos);

		// generate textures
		glGenTextures(eNUM_TEXTURES, textures);

		// initalize the texture
		glBindTexture(GL_TEXTURE_2D, textures[eFramebuffer]);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, SHADOWBUFFER_WIDTH, SHADOWBUFFER_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

		// attach texture to the fbo
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbos);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, textures[eFramebuffer], 0);
		glDrawBuffer(GL_FALSE);
		glReadBuffer(GL_FALSE);

		// Check for errors...
		CheckFramebufferStatus();

		// unbind stuff
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
		glBindTexture(GL_TEXTURE_2D, 0);
	}
	else
		cout << "frame buffers are not supported!\n";


this prints a "incomplete attachment" error to the console window 2. I've tried to render my scene to the frame buffer.
void DrawToFrameBuffer(void)
{
	// Bind the frame-buffer object and attach to it a render-buffer object 
	// set up as a depth-buffer.
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbos);
	{
		glPushAttrib(GL_VIEWPORT_BIT); // save the viewport
		{
			// Set up the frame-buffer object just like you would set up a window.
			glViewport(0, 0, SHADOWBUFFER_WIDTH, SHADOWBUFFER_HEIGHT);

			// look from the light's point of view
			gluLookAt(	fLightPos[0], fLightPos[1], fLightPos[2],		// Look from the light's position
						0.0f, 0.0f, 0.0f,								// Towards the teapot's position
						0.0f, 1.0f, 0.0f );								// the up vector 

			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glCullFace(GL_FRONT);	// cull the front face to get the back faces drawn
			glShadeModel(GL_FLAT);	// change to flat shading for speed
			glColorMask(0, 0, 0, 0);// disable the color drawing
				
			glPushMatrix();
				// Now, render anything to the frame-buffer object just like you we would
				// have done with a regular window.
				// draw the teapot
				glTranslatef( moveX, moveY, 0.0f );
				
				glFrontFace(GL_CW);		// the teapot is clockwise drawing
				glutSolidTeapot(0.5f);
			glPopMatrix();

                        // draw a "floor"
			glPushMatrix();
				glFrontFace(GL_CCW);
				glBegin(GL_QUADS);
					glVertex3f(	-3.0f,	-1.0f,	-3.0f);
					glVertex3f(	3.0f,	-1.0f,	-3.0f);
					glVertex3f(	3.0f,	-1.0f,	3.0f);
					glVertex3f(	-3.0f,	-1.0f,	3.0f);
				glEnd();
			glPopMatrix();
		}
		glPopAttrib(); // restore the viewport
	}
	// Unbind the frame-buffer and render-buffer objects.
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

	//restore states
	glFrontFace(GL_CCW);
    glCullFace(GL_BACK);
    glShadeModel(GL_SMOOTH);
    glColorMask(1, 1, 1, 1); 
}


I'm not sure if I should be clearing the color and depth bits here, but I do. 3. I then render the scene (a teapot and floor) where I bind the fbo texture to the floor.
void Render(void)
{
	if(GetAsyncKeyState(VK_ESCAPE))
	{
		ShutdownGL();	
		PostQuitMessage(0);
	}
	
	DrawToFrameBuffer();

	//--------------------------------------------------------------------------
	// Now, set up the regular window for rendering...
	//--------------------------------------------------------------------------

	MoveCamera();
	MoveObject();

	//glViewport( 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT );
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	//glMatrixMode( GL_MODELVIEW );
    //glLoadIdentity();
	camera.ApplyCameraTransform();

	// set the light position
	// i'm keeping this after the camera transform to keep the light seperate from the camera
	glLightfv(GL_LIGHT0, GL_POSITION, fLightPos);
	// draw a sphere at the light's position so we can see where it is
	glDisable(GL_LIGHTING);
	glPushMatrix();
		glTranslatef(fLightPos[0], fLightPos[1], fLightPos[2]);
		glutSolidSphere(0.3f, 8, 6);
	glPopMatrix();
	glEnable(GL_LIGHTING);

	// draw the teapot
	glPushMatrix();
		glTranslatef( moveX, moveY, 0.0f );
		glFrontFace(GL_CW);
		glutSolidTeapot(0.5f);
	glPopMatrix();

	// Finally, we could use the dynamic framebuffer texture like a regular static texture.
	// i'm going to bind the texture and use it on the "ground" to make a shadow
	glBindTexture(GL_TEXTURE_2D, textures[eFramebuffer]);

	//Enable shadow comparison
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE);

    //Shadow comparison should be true (ie not in shadow) if r<=texture
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);

    //Shadow comparison should generate an INTENSITY result
    glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY); 

	//Set alpha test to discard false comparisons
    glAlphaFunc(GL_GEQUAL, 0.99f);
    glEnable(GL_ALPHA_TEST); 

	glPushMatrix();
		glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
		glFrontFace(GL_CCW);

		glNormal3f(	0.0f,	1.0f,	0.0f);
		glBegin(GL_QUADS);
			glVertex3f(	-3.0f,	-1.0f,	-3.0f);
			glVertex3f(	3.0f,	-1.0f,	-3.0f);
			glVertex3f(	3.0f,	-1.0f,	3.0f);
			glVertex3f(	-3.0f,	-1.0f,	3.0f);
		glEnd();
	glPopMatrix();
	glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_ALPHA_TEST); 

	glutSwapBuffers();
	glutPostRedisplay();
}


Where am I going wrong in this long ass quest for real time shadows?

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