Jump to content

  • Log In with Google      Sign In   
  • Create Account


GLSL shadows not working


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 polyfrag   Crossbones+   -  Reputation: 1825

Like
0Likes
Like

Posted 10 September 2012 - 01:03 AM

I copied this code from the tutorial at gametutorials.com and this is what I see in my game:

Posted Image

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


Sponsor:

#2 polyfrag   Crossbones+   -  Reputation: 1825

Like
0Likes
Like

Posted 10 September 2012 - 02:05 AM

I rendered the shadow map in the top-left corner and it doesn't show the yellow people for some reason.

Posted Image




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS