Jump to content
  • Advertisement
Sign in to follow this  
polyfrag

OpenGL GLSL shadows not working

This topic is 2289 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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();
}

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!