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

FBOs and Shadow Mapping

Started by TheFallenKing Apr 7, 2006 at 7:28 PM 0 replies 650+ views
Original Post
TheFallenKing
TheFallenKing
I've been trying to implement shadow mapping using Cg shaders for a while now, but I can't seem to get it right. I've been hung up on actually capturing the depth buffer to use as my shadow map. I figured the complexity of my original program was causing too much trouble with debugging, so I set out to create a simple test bed program (why I didn't do this from the start, I don't know). All this program _should_ do, is alternate between rendering the scene normally, and rendering the scene to a FBO with a depth attachment (toggle by pressing F1). When using the FBO, the depth attachment is then rendered to the screen...only problem is this last part comes out as a black screen. I've been looking at this code for too long now to figure out what's wrong with it - I don't understand FBOs well enough to begin with, was hoping I could figure them out while working on this. Could someone please look through my code below and tell me what exactly it is that I'm doing wrong?

void initFBO(void)
{
	glGenTextures(1, &shadow_tx);
	glBindTexture(GL_TEXTURE_2D, shadow_tx);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16,
		shadow_sz, shadow_sz, 0, GL_DEPTH_COMPONENT,
		GL_UNSIGNED_BYTE, NULL);
	glTexParameteri(GL_TEXTURE_2D,
		GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	// create fbo and attach texture to ti
	glGenFramebuffersEXT(1, &shadow_fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fb);
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
		GL_DEPTH_ATTACHMENT_EXT,
		GL_TEXTURE_2D, shadow_tx, 0);
	glDrawBuffer(GL_FALSE);
	glReadBuffer(GL_FALSE);

	// verify all is well and restore state
	GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	switch (status)
	{
	case GL_FRAMEBUFFER_COMPLETE_EXT:
		break;
	case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
		cerr << "FBO configuration unsupported" << endl;
		exit(-1);
	default:
		cerr << "FBO programmer error" << endl;
		exit(-1);
	}
	glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);
}// end initFBO()


void renderShadowMap(void)
{
	glDisable(GL_LIGHTING);

	glPushAttrib(GL_VIEWPORT);
	glViewport(0, 0, shadow_sz, shadow_sz);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(-1, 1, -1, 1);

	glMatrixMode(GL_TEXTURE);
	glPushMatrix();
	glLoadIdentity();

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, shadow_tx);
    glBegin( GL_QUADS );
    {
        glTexCoord2f( 0.0f, 0.0f );
        glVertex3f( -1.0f, -1.0f, 0.0f );
    
        glTexCoord2f( 0.0f, 1.0f );
        glVertex3f( -1.0f, 1.0f, 0.0f );

        glTexCoord2f( 1.0f, 1.0f );
        glVertex3f( 1.0f, 1.0f, 0.0f );

        glTexCoord2f( 1.0f, 0.0f );
        glVertex3f( 1.0f, -1.0f, 0.0f );
    }
    glEnd();
	glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);

	glPopMatrix();

	glMatrixMode(GL_TEXTURE);
	glPopMatrix();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glMatrixMode(GL_MODELVIEW);

	glPopAttrib();
    glEnable(GL_LIGHTING);
}// end renderShadowMap()


void renderScene(void)
{
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	{
		glTranslatef( 0.0f, 2.5f, 0.0f );
		glRotatef(-g_fSpinY_R, 1.0f, 0.0f, 0.0f);
		glRotatef(g_fSpinX_R, 0.0f, 1.0f, 0.0f);

		glColor3f( 1.0f, 1.0f ,1.0f );
		glutSolidTeapot(1.0);
	}
	glPopMatrix();

	glPushMatrix();
	{
		glRotatef(-g_fSpinX_R, 0.0f, 1.0f, 0.0f);
		glBegin( GL_QUADS );
		{
			glNormal3f( 0.0f, 1.0f,  0.0f );
			glVertex3f(-5.0f, 0.0f, -5.0f );
			glVertex3f(-5.0f, 0.0f,  5.0f );
			glVertex3f( 5.0f, 0.0f,  5.0f );
			glVertex3f( 5.0f, 0.0f, -5.0f );
		}
		glEnd();
	}
	glPopMatrix();
}// end renderScene()


void render(void)
{
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();

    gluLookAt(g_lightPosition[0],
		g_lightPosition[1],
		g_lightPosition[2],
        0.0f, 2.5f, 0.0f,
        0.0f, 1.0f, 0.0f);

    // Get the model-view matrix
    glGetFloatv(GL_MODELVIEW_MATRIX, g_lightsLookAtMatrix);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0f, -2.0f, -15.0f);
    glRotatef(-g_fSpinY_L, 1.0f, 0.0f, 0.0f);
    glRotatef(-g_fSpinX_L, 0.0f, 1.0f, 0.0f);

    // Render the light's position as a sphere...
    glDisable(GL_LIGHTING);
    glPushMatrix();
    {
        glLightfv(GL_LIGHT0, GL_POSITION, g_lightPosition);
        glTranslatef(g_lightPosition[0], g_lightPosition[1], g_lightPosition[2]);

        glColor3f(1.0f, 1.0f, 0.5f);
		glutSolidSphere(0.1, 8, 8);
    }
    glPopMatrix();
    glEnable(GL_LIGHTING);

	if(g_bRenderDepthTexture)
	{
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, shadow_tx);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fb);
	}

    renderScene();

	if(g_bRenderDepthTexture)
	{
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
		glBindTexture(GL_TEXTURE_2D, 0);
		glDisable(GL_TEXTURE_2D);
	}

    if(g_bRenderDepthTexture)
		renderShadowMap();

	glutSwapBuffers();
}// end render()

EDIT: Tagged the source code the wrong way.
Enrico
Enrico
I have a small applications that just does Shadow Mapping (via ARB_shadow) with FBOs. I can send you the C++ code, if you are interested?

About your source: The only thing I see is that you bind "shadow_tx", when you render to the FBO. You should try to disable the texture while rendering to the depth FBO. Maybe it works ;)
--

Topic Locked

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

Sign in to reply to this topic.