GLSL shadows not working

Started by
0 comments, last by polyfrag 11 years, 7 months ago
I copied this code from the tutorial at gametutorials.com and this is what I see in my game:

noshadows.jpg

Here is the code:

corpstates.cpp

void RenderWorld()
{
DrawHeightMap();
DrawEntities();
}

inline void RenderPlayScene()
{
// Set the current viewport to our texture size
glViewport(0, 0, (int)SHADOW_WIDTH, (int)SHADOW_HEIGHT);
// Now we just need to set the matrices for the light before we render
glMatrixMode(GL_PROJECTION);

// Push on a matrix to make sure we can restore to the old matrix easily
glPushMatrix();
// Set the current projection matrix to our light's projection matrix
glLoadMatrixf(g_mProjection);
// Load modelview mode to set our light's modelview matrix
glMatrixMode(GL_MODELVIEW);
// Load the light's modelview matrix before we render to a texture
glLoadMatrixf(g_mModelView);
// Since we don't care about color when rendering the depth values to
// the shadow-map texture, we disable color writing to increase speed.
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// Eliminate artifacts caused by shadow mapping
glPolygonOffset(8.0f, 4.0f);

// This turns of the polygon offset functionality to fix artifacts.
// Comment this out and run the program to see what artifacts I mean.
glEnable(GL_POLYGON_OFFSET_FILL);
// Render the world according to the light's view
RenderWorld();
// Now that the world is rendered, save the depth values to a texture
glBindTexture(GL_TEXTURE_2D, g_renderTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, (int)SHADOW_WIDTH, (int)SHADOW_HEIGHT);
// We can turn color writing back on since we already stored the depth values
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
// Turn off polygon offsetting
glDisable(GL_POLYGON_OFFSET_FILL);
// Restore our normal viewport size to our screen width and height
glViewport(0, 0, (int)g_width, (int)g_height);
// Go back to the projection mode and restore the original matrix
glMatrixMode(GL_PROJECTION);
// Restore the original projection matrix
glPopMatrix();
// Go back to modelview model to start drawing like normal
glMatrixMode(GL_MODELVIEW);
// Clear the color and depth bits and start over from the camera's view
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
g_camera.Look();
// After we have switched backed to our camera's view, we need to
// grab the inverse of the modelview's matrix. If you are unfamiliar
// with what an inverse of a matrix does, let's review. If you
// multiply a matrix by it's inverse, it basically zeros it out.
// We need the inverse because in the vertex shader we will have a
// vertex that is multiplied by the camera's view matrix (modelview),
// and we need to bring that back down to world space and project
// it into the light's clip space. Since we are working in the light's
// clip space and not the camera's clip space this needs to happen.
// For this to work, we need to make sure we have called the Look()
// function from the camera object before calling GetInverseMatrix().
// Pass in the global matrix that will store our modelview inverse matrix.
// This function grabs the current modelview matrix and returns the inverse.
g_camera.GetInverseMatrix(g_mCameraInverse);
// Render the world and apply the shadow map texture to it
ApplyShadowMap();
glLightfv( GL_LIGHT0, GL_POSITION, g_LightPosition );
}

void RenderScene()
{
if(g_mode == PLAY)
StoreLightMatrices();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
if(g_mode == PLAY)
RenderPlayScene();
g_GUI.draw();
SwapBuffers(g_hDC);
}


shadow.h

void StoreLightMatrices()
{
// Reset our current light matrices
memset(g_mModelView, 0, sizeof(float)*16);
memset(g_mProjection, 0, sizeof(float)*16);
// Let's push on a new matrix so we don't change the rest of the world
glPushMatrix();
// Push on a new matrix to keep our view changes isolated
glPushMatrix();
// Reset the current modelview matrix
glLoadIdentity();
// This is where we set the light's position and view.
gluLookAt(g_LightPosition[0], g_LightPosition[1], g_LightPosition[2],
g_LightView[0], g_LightView[1], g_LightView[2], 0, 1, 0);
// Now that we have the light's view, let's save the current modelview matrix.
glGetFloatv(GL_MODELVIEW_MATRIX, g_mModelView);
// Now pop off the current light view's matrix
glPopMatrix();
// Reset the current matrix
glLoadIdentity();
// Set our FOV, aspect ratio, then near and far planes for the light's view
gluPerspective(60.0f, 1.0f, 0.5f, 25.0f);
// Grab the current matrix that will be used for the light's projection matrix
glGetFloatv(GL_MODELVIEW_MATRIX, g_mProjection);
// Go back to the original matrix
glPopMatrix();
}
void CreateRenderTexture(int sizeX, int sizeY, int channels, int type)
{
// Create a pointer to store the blank image data
unsigned int *pTexture = NULL;
// Store the current channels to be allocated by default
int channelsTrue = channels;
// If the channels are greater than 4 there must be a special flag like
// GL_DEPTH_COMPONENT, so make sure we only allocate 1 bit per pixel.
if(channels > 4)
channelsTrue = 1;
// Allocate and init memory for the image array and point to it from pTexture
pTexture = new unsigned int [sizeX * sizeY * channelsTrue];
memset(pTexture, 0, sizeX * sizeY * channelsTrue * sizeof(unsigned int));
// Register the texture with OpenGL and bind it to the texture ID
glGenTextures(1, &g_renderTexture);
glBindTexture(GL_TEXTURE_2D, g_renderTexture);

// Create the texture and store it on the video card
glTexImage2D(GL_TEXTURE_2D, 0, channels, sizeX, sizeY, 0, type, GL_UNSIGNED_INT, pTexture);

// Set the texture quality
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
// Since we stored the texture space with OpenGL, we can delete the image data
delete [] pTexture;
}
void RenderWorld();
void ApplyShadowMap()
{

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

// This function is the main function that needs to be changed from the
// previous tutorial. We needed to take out the texture generation code
// so a couple things will change. This means we will need to turn our
// shadow on, as well as multiply the inverse of our camera matrix by
// the light's projection and modelview matrix. We still include the
// bias matrix to convert the clip space to a 0 to 1 ratio instead of
// a -1 to 1 ratio.
// Let's turn our shaders on for doing shadow mapping on our world
g_Shader.TurnOn();
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

// Turn on our texture unit for shadow mapping and bind our depth texture
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, g_renderTexture);

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// In order for the shader to have access to our light's texture of depth
// values, we need to tell our fragment shader the texture unit that our
// texture is being bound to. Since we use GL_TEXTURE0_ARB we pass in 0.
GLuint uniform = glGetUniformLocationARB(g_Shader.GetProgram(), "shadowMap");
glUniform1iARB(uniform, 0);
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

// Here is where we set the mode and function for shadow mapping with shadow2DProj().
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
// Create our bias matrix to have a 0 to 1 ratio after clip space
const float mBias[] = {0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};
glMatrixMode(GL_TEXTURE);
glLoadMatrixf(mBias); // The bias matrix to convert to a 0 to 1 ratio
glMultMatrixf(g_mProjection); // The light's projection matrix
glMultMatrixf(g_mModelView); // The light's modelview matrix

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// Instead of using texture generation functions that handle the inverse
// camera matrix for us, we calculated this ourselves and need to multiply
// it by the preceding matrices. Remember the equation for projection:
//
// mProjectedTexture = mLightProjection * mLightModelview * mCameraInverse;
//
// We need to use this because we are projecting the shadow map onto the
// world from the light's position. A bit tricky to wrap your head around?
// Keep in mind, the camera's inverse matrix is really the modelview matrix
// inverted with the camera already applied to it.
// Following the above equation, multiply our camera's inverse by the matrices.
glMultMatrixf(g_mCameraInverse);
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

glMatrixMode(GL_MODELVIEW); // Switch back to normal modelview mode
RenderWorld(); // Render the world that needs to be shadowed
// Now that the world is shadowed and we are done with the texture generation,
// let's set everything back to normal by resetting the texture matrix.
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
// Turn the first multi-texture pass off
glActiveTextureARB(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_2D);

/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// Light expected, we need to turn our shader off since we are done
g_Shader.TurnOff();
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
}


ShadowMapping.frag

uniform sampler2DShadow shadowMap;
varying vec4 projCoord;
void main ()
{
const float kTransparency = 0.3;
vec4 color = gl_Color;
float rValue = shadow2DProj(shadowMap, projCoord).r + kTransparency;
rValue = clamp(rValue, 0.0, 1.0);
vec3 coordPos = projCoord.xyz / projCoord.w;
if(coordPos.x >= 0.0 && coordPos.y >= 0.0 && coordPos.x <= 1.0 && coordPos.y <= 1.0 )
{
gl_FragColor = color * rValue;
}
else
{
gl_FragColor = color;
}
}


ShadowMapping.vert

varying vec4 projCoord;
void main()
{
vec4 realPos = gl_ModelViewMatrix * gl_Vertex;

projCoord = gl_TextureMatrix[0] * realPos;
gl_FrontColor = gl_Color;
gl_Position = ftransform();
}
Advertisement
I rendered the shadow map in the top-left corner and it doesn't show the yellow people for some reason.

rendertexture.jpg

This topic is closed to new replies.

Advertisement