Shadow Mapping without shaders

From OpenGL Wiki
Jump to navigation Jump to search

Since there are websites that already discuss this well, and they are old, they don't use shaders, they don't use VBOs, they don't use FBOs, they use GL_ARB_depth_texture and GL_ARB_shadow, we won't discuss the concept here. Rather, we will point out corrections. Here is one such website.
http://www.paulsprojects.net/tutorials/smt/smt.html

This uses GLUT.
It uses GLU for gluPerspective, gluOrtho2D.

It uses glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP).
That's not a good idea. Please use
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) and also look at
http://www.opengl.org/wiki/Common_Mistakes#Texture_edge_color_problem

It uses glShadeModel(GL_FLAT) in order to improve speed. That's not necessary. Just leave it as GL_SMOOTH

It uses glutSolidTorus, glutSolidCube, glutSolidSphere and makes a display list.

It uses GL_ALPHA_TEST. Careful, this reduces performances since it disable hierarchal z-buffer optimization on GPUs. Also, really old GPUs aren't effected such as Radeon 7500 and Geforce 256. The bad news, modern GPUs are effected and most people are using modern GPUs. People have Geforce GTX 295 these days.

It calls glFinish()
http://www.opengl.org/wiki/Common_Mistakes#glFinish_and_glFlush

The texture is created like this

  // Create the shadow map texture
  glGenTextures(1, &shadowMapTexture);
  glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapSize, shadowMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);

This is a little better

  // Create the shadow map texture
  glGenTextures(1, &shadowMapTexture);
  glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  // Enable shadow comparison
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, 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, GL_LEQUAL);
  // Shadow comparison should generate an INTENSITY result
  glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, shadowMapSize, shadowMapSize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);

and the texture is updated like so (which is actually good, he uses glCopyTexSubImage2D instead of glCopyTexImage2D. glCopyTexImage2D would causes a delete and reallocation of the texture which would cause a slow down.)

  glBindTexture(GL_TEXTURE_2D, shadowMapTexture);
  glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize);

He calls

  glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(lightPosition));

and in the introduction he says he will use a point light. The only problem is, he isn't doing omnidirectional lighting.


And finally the website http://www.paulsprojects.net/tutorials/smt/smt.html