diff options
author | Ian Romanick <[email protected]> | 2007-06-07 12:09:44 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2007-06-07 12:09:44 -0700 |
commit | 2260c245fd5798a6b3661c3a529654d9f577821d (patch) | |
tree | 6ad4abe0147d3658e64d4e55e6a18de2a50356ab | |
parent | f575d4fa7f69a5de87c52002ffaf3e745634aff5 (diff) |
Refactor shadow map modelview and projection code
Explicitly store the modelview matrix and projection matrix used when the
shadow map is created. These matrices only need be updated when
RenderShadowMap is called. Previously, slightly different code was used to
draw and project the shadow map.
-rw-r--r-- | progs/demos/shadowtex.c | 72 |
1 files changed, 50 insertions, 22 deletions
diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c index 634d0b65720..e87edcf071d 100644 --- a/progs/demos/shadowtex.c +++ b/progs/demos/shadowtex.c @@ -67,6 +67,9 @@ static GLboolean NeedNewShadowMap = GL_FALSE; static GLuint ShadowTexture, GrayTexture; static GLuint ShadowFBO; +static GLfloat lightModelview[16]; +static GLfloat lightProjection[16]; + static GLboolean HaveFBO = GL_FALSE; static GLboolean UseFBO = GL_FALSE; static GLboolean HavePackedDepthStencil = GL_FALSE; @@ -134,27 +137,56 @@ DrawScene(void) } -/* - * Load the GL_TEXTURE matrix with the projection from the light - * source's point of view. +/** + * Calculate modelview and project matrices for the light + * + * Stores the results in \c lightProjection (projection matrix) and + * \c lightModelview (modelview matrix). */ static void MakeShadowMatrix(const GLfloat lightPos[4], const GLfloat spotDir[3], GLfloat spotAngle, GLfloat shadowNear, GLfloat shadowFar) { - GLfloat d; - - glMatrixMode(GL_TEXTURE); + /* compute frustum to enclose spot light cone */ + const GLfloat d = shadowNear * tan(spotAngle); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); glLoadIdentity(); - glTranslatef(0.5, 0.5, 0.5 + Bias); - glScalef(0.5, 0.5, 0.5); - d = shadowNear * tan(spotAngle); glFrustum(-d, d, -d, d, shadowNear, shadowFar); + glGetFloatv(GL_PROJECTION_MATRIX, lightProjection); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); gluLookAt(lightPos[0], lightPos[1], lightPos[2], lightPos[0] + spotDir[0], lightPos[1] + spotDir[1], lightPos[2] + spotDir[2], - 0, 1, 0); + 0.0, 1.0, 0.0); + glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview); + glPopMatrix(); +} + + +/** + * Load \c GL_TEXTURE matrix with light's MVP matrix. + */ +static void SetShadowTextureMatrix(void) +{ + static const GLfloat biasMatrix[16] = { + 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(biasMatrix); + glTranslatef(0.0, 0.0, Bias); + glMultMatrixf(lightProjection); + glMultMatrixf(lightModelview); glMatrixMode(GL_MODELVIEW); } @@ -258,7 +290,6 @@ RenderShadowMap(void) { GLenum depthFormat; /* GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT */ GLenum depthType; /* GL_UNSIGNED_INT_24_8_EXT or GL_UNSIGNED_INT */ - float d; if (WindowWidth >= 1024 && WindowHeight >= 1024) { ShadowTexWidth = ShadowTexHeight = 1024; @@ -283,17 +314,11 @@ RenderShadowMap(void) depthType = GL_UNSIGNED_INT; } - /* compute frustum to enclose spot light cone */ - d = ShadowNear * tan(SpotAngle); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(-d, d, -d, d, ShadowNear, ShadowFar); + glLoadMatrixf(lightProjection); + glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(LightPos[0], LightPos[1], LightPos[2], /* from */ - 0, 0, 0, /* target */ - 0, 1, 0); /* up */ + glLoadMatrixf(lightModelview); if (UseFBO) { GLenum fbo_status; @@ -418,6 +443,7 @@ Display(void) LightPos, SpotDir); if (NeedNewShadowMap) { + MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar); RenderShadowMap(); NeedNewShadowMap = GL_FALSE; } @@ -458,7 +484,8 @@ Display(void) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); - MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar); + + SetShadowTextureMatrix(); EnableIdentityTexgen(); } else if (DisplayMode == SHOW_DISTANCE) { @@ -476,7 +503,8 @@ Display(void) GL_COMPARE_R_TO_TEXTURE_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_2D); - MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar); + + SetShadowTextureMatrix(); EnableIdentityTexgen(); } |