Sign in to follow this  
adawg1414

game shadows?

Recommended Posts

Can someone please give me some really good resources for creating shadows in games? Mainly real-time shadowing with moving lights/objects.

Share this post


Link to post
Share on other sites
Thanks, the FBO shadows is just what I was looking for ... it just seems as though no one has created a GREAT shadow tutorial for games. Unfortunately the NVidia stuff is just for NVidia graphics cards and they over complicate with no comments!!

If anyone has some more resources please post, all resources will help in the long run.

Share this post


Link to post
Share on other sites
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
Aren't framebuffer objects supposed to be "easier" and a lot better with resources? I really just need someone who works with framebuffer objects to explain to me where I'm not understanding the "simple" concept of:
1. create the fbo
2. create the texture
3. attach the texture to the fbo
4. render the scene to the fbo
5. use the fbo as a texture

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