summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-07-30 16:10:18 -0700
committerEric Anholt <eric@anholt.net>2009-07-30 17:14:17 -0700
commit72c1ef6b77eb6f4199e1fd34a452d279bce76bf4 (patch)
tree3d4f19ade125de77fda2d758724e1dfac96b46f6
parent5db232853d035ddb307772b4299e51521114b55a (diff)
Apply the shadow map to the ground plane.
-rw-r--r--glass.c3
-rw-r--r--glass.h3
-rw-r--r--ground.c22
-rw-r--r--ground.frag4
-rw-r--r--ground.vert4
-rw-r--r--shadow_map.c14
6 files changed, 46 insertions, 4 deletions
diff --git a/glass.c b/glass.c
index 091b32f..36bb3fe 100644
--- a/glass.c
+++ b/glass.c
@@ -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
diff --git a/glass.h b/glass.h
index 93628f9..4db5395 100644
--- a/glass.h
+++ b/glass.h
@@ -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);
diff --git a/ground.c b/ground.c
index 69e7453..59f4dd9 100644
--- a/ground.c
+++ b/ground.c
@@ -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);