diff options
author | Eric Anholt <eric@anholt.net> | 2009-07-30 16:10:18 -0700 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-07-30 17:14:17 -0700 |
commit | 72c1ef6b77eb6f4199e1fd34a452d279bce76bf4 (patch) | |
tree | 3d4f19ade125de77fda2d758724e1dfac96b46f6 | |
parent | 5db232853d035ddb307772b4299e51521114b55a (diff) |
Apply the shadow map to the ground plane.
-rw-r--r-- | glass.c | 3 | ||||
-rw-r--r-- | glass.h | 3 | ||||
-rw-r--r-- | ground.c | 22 | ||||
-rw-r--r-- | ground.frag | 4 | ||||
-rw-r--r-- | ground.vert | 4 | ||||
-rw-r--r-- | shadow_map.c | 14 |
6 files changed, 46 insertions, 4 deletions
@@ -77,6 +77,8 @@ struct uniform_desc ground_uniforms[GROUND_UNIFORM_MAX] = { [GROUND_UNIFORM_MV] = { "mv" }, [GROUND_UNIFORM_MVP] = { "mvp" }, [GROUND_UNIFORM_LIGHT_EYE] = { "light_eye" }, + [GROUND_UNIFORM_LIGHT_MVP] = { "light_mvp" }, + [GROUND_UNIFORM_SHADOW_SAMPLER] = { "shadow_sampler" }, }; struct uniform_desc shadow_uniforms[SHADOW_UNIFORM_MAX] = { @@ -810,6 +812,7 @@ load_ground_program(void) ground_prog = load_program("ground", ground_uniforms, ARRAY_SIZE(ground_uniforms)); + glUniform1i(ground_uniforms[GROUND_UNIFORM_SHADOW_SAMPLER].location, 0); } static void @@ -40,6 +40,8 @@ enum ground_uniform_list { GROUND_UNIFORM_MV, GROUND_UNIFORM_MVP, GROUND_UNIFORM_LIGHT_EYE, + GROUND_UNIFORM_LIGHT_MVP, + GROUND_UNIFORM_SHADOW_SAMPLER, GROUND_UNIFORM_MAX }; @@ -66,6 +68,7 @@ extern struct revolved_object ring; extern GLUvec4 ring_bounding_sphere_center_world; extern float ring_bounding_sphere_radius; extern GLuint shadow_tex; +extern GLUmat4 world_to_light_ndc; void do_ring_drawelements(void); @@ -53,13 +53,30 @@ static void install_ground_transform(void) { GLUmat4 mvp; + GLUmat4 world_to_shadow_texcoords; + GLUmat4 temp; gluMult4m_4m(&mvp, &projection, &world_to_eye); + /* Setup the viewport translation to map light NDC to texcoords. + */ + memcpy(&temp, &gluIdentityMatrix, sizeof(gluIdentityMatrix)); + temp.col[0].values[0] = (1.0 - 0.0) / 2.0; + temp.col[0].values[3] = temp.col[0].values[0] + 0.0; + temp.col[1].values[1] = (1.0 - 0.0) / 2.0; + temp.col[1].values[3] = temp.col[1].values[1] + 0.0; + temp.col[2].values[2] = (1.0 - 0.0) / 2.0; + temp.col[2].values[3] = (1.0 - 0.0) / 2.0; + + gluMult4m_4m(&world_to_shadow_texcoords, &temp, &world_to_light_ndc); + + /* Note that ground object coordinates are already in world space. */ glUniformMatrix4fv(ground_uniforms[GROUND_UNIFORM_MV].location, 1, 0, (float *)&world_to_eye); glUniformMatrix4fv(ground_uniforms[GROUND_UNIFORM_MVP].location, 1, 0, (float *)&mvp); + glUniformMatrix4fv(ground_uniforms[GROUND_UNIFORM_LIGHT_MVP].location, 1, 0, + (float *)&world_to_shadow_texcoords); } void @@ -75,6 +92,10 @@ draw_ground(void) glUseProgram(ground_prog); install_ground_transform(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, shadow_tex); + glEnable(GL_TEXTURE_2D); + glBindVertexArray(ground_obj); for (v = 0; v < ground_size - 1; v++) { @@ -99,6 +120,7 @@ draw_ground(void) indices[v]); } } + glDisable(GL_TEXTURE_2D); } void diff --git a/ground.frag b/ground.frag index a9cd20c..dca71f2 100644 --- a/ground.frag +++ b/ground.frag @@ -1,10 +1,12 @@ uniform vec3 light_eye; +varying vec2 shadow_coords; varying vec3 vertex_eye; +uniform sampler2D shadow_sampler; void main() { vec3 normal = vec3(0.0, 0.0, 1.0); - const vec4 material_color = vec4(1.0, 0.7, 0.3, 0.0); + vec4 material_color = texture2D(shadow_sampler, shadow_coords); vec3 l = normalize(light_eye - vertex_eye); vec3 v = normalize(-vertex_eye); vec3 h = normalize(l + v); diff --git a/ground.vert b/ground.vert index 549636b..f4d7713 100644 --- a/ground.vert +++ b/ground.vert @@ -5,7 +5,8 @@ varying vec3 eye_surf; varying vec3 tangent_surf; */ varying vec3 vertex_eye; -uniform mat4 mvp, mv; +varying vec2 shadow_coords; +uniform mat4 mvp, mv, light_mvp; void main() { @@ -14,6 +15,7 @@ void main() */ gl_Position = mvp * gl_Vertex; vertex_eye = vec3(mv * gl_Vertex); + shadow_coords = (light_mvp * gl_Vertex).xy; /* mat3 tbn = mat3(t, cross(n, t), diff --git a/shadow_map.c b/shadow_map.c index 290343a..59e7650 100644 --- a/shadow_map.c +++ b/shadow_map.c @@ -40,7 +40,8 @@ extern int no_multi_draw_arrays; extern GLUvec4 eye_world; -static GLUmat4 world_to_light_eye, world_to_light_ndc; +static GLUmat4 world_to_light_eye; +GLUmat4 world_to_light_ndc; GLuint shadow_tex = 0, shadow_fbo; static void @@ -55,6 +56,11 @@ calculate_light_projection(void) light_up.values[2] = 0.0; light_up.values[3] = 1.0; + /* + print_GLUvec4("light_world", &light_world); + print_GLUvec4("ring_center", &ring_bounding_sphere_center_world); + print_GLUvec4("light_up ", &light_up); + */ /* Transform for looking from they eye's point of view at the pile of * rings. */ @@ -62,7 +68,7 @@ calculate_light_projection(void) &light_world, &ring_bounding_sphere_center_world, &light_up); - gluPerspective4(&temp, 90, /*XXX: calculate me */ + gluPerspective4(&temp, 120, /*XXX: calculate me */ 1.0, /* we're using a bounding sphere, w == h */ 0.2, 40); gluMult4m_4m(&world_to_light_ndc, &temp, &world_to_light_eye); @@ -104,6 +110,10 @@ generate_rings_shadowmap(void) 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); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, shadow_width, shadow_height, 0, GL_RGBA, GL_FLOAT, NULL); |