summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2009-07-31 17:17:49 -0700
committerEric Anholt <eric@anholt.net>2009-08-01 14:13:49 -0700
commitdbd90f7d607ae99c5eb5427dcf14cd5915952894 (patch)
tree56c0dc7602427e7a4215d82e8f24c8b265f5e8b1
parentafac7d4b1b156636e99676a2632a2a3e32442f79 (diff)
Use shadow mapping instead of shadow texturing.
-rw-r--r--ground.frag9
-rw-r--r--ground.vert4
-rw-r--r--shadow_map.c40
3 files changed, 36 insertions, 17 deletions
diff --git a/ground.frag b/ground.frag
index 8af0fb5..b5a733a 100644
--- a/ground.frag
+++ b/ground.frag
@@ -1,12 +1,13 @@
uniform vec3 light_eye;
-varying vec3 shadow_coords;
+varying vec4 shadow_coords;
varying vec3 vertex_eye;
-uniform sampler2D shadow_sampler;
+uniform sampler2DShadow shadow_sampler;
void main()
{
vec3 normal = vec3(0.0, 0.0, 1.0);
- vec4 material_color = texture2DProj(shadow_sampler, shadow_coords);
+ vec4 material_color = vec4(1.0, 0.7, 0.5, 1.0);
+ float shadow = shadow2DProj(shadow_sampler, shadow_coords).x;
vec3 l = normalize(light_eye - vertex_eye);
vec3 v = normalize(-vertex_eye);
vec3 h = normalize(l + v);
@@ -14,5 +15,5 @@ void main()
vec3 diffuse = material_color.xyz * n_dot_l;
float specular = pow(dot(normal, h), 16.0);
gl_FragColor = step(0.0, n_dot_l) *
- vec4(diffuse + vec3(specular), material_color.w);
+ vec4((diffuse + vec3(specular)) * shadow, material_color.w);
}
diff --git a/ground.vert b/ground.vert
index 4ed0a26..5403df1 100644
--- a/ground.vert
+++ b/ground.vert
@@ -5,7 +5,7 @@ varying vec3 eye_surf;
varying vec3 tangent_surf;
*/
varying vec3 vertex_eye;
-varying vec3 shadow_coords;
+varying vec4 shadow_coords;
uniform mat4 mvp, mv, light_mvp;
void main()
@@ -15,7 +15,7 @@ void main()
*/
gl_Position = mvp * gl_Vertex;
vertex_eye = vec3(mv * gl_Vertex);
- shadow_coords = (light_mvp * gl_Vertex).xyw;
+ shadow_coords = light_mvp * gl_Vertex;
/*
mat3 tbn = mat3(t,
cross(n, t),
diff --git a/shadow_map.c b/shadow_map.c
index 073ec6a..5fc8777 100644
--- a/shadow_map.c
+++ b/shadow_map.c
@@ -101,6 +101,7 @@ generate_rings_shadowmap(void)
{
int instance;
int shadow_width = 256, shadow_height = 256;
+ GLboolean first_time = GL_FALSE;
if (shadow_prog == 0)
return;
@@ -110,8 +111,6 @@ generate_rings_shadowmap(void)
calculate_light_projection();
if (shadow_tex == 0) {
- GLenum status;
-
glGenTextures(1, &shadow_tex);
glBindTexture(GL_TEXTURE_2D, shadow_tex);
glTexParameteri(GL_TEXTURE_2D,
@@ -122,30 +121,47 @@ generate_rings_shadowmap(void)
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,
+ glTexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_COMPARE_MODE,
+ GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D,
+ GL_TEXTURE_COMPARE_FUNC,
+ GL_LEQUAL);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
shadow_width, shadow_height, 0,
- GL_RGBA, GL_FLOAT, NULL);
+ GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glGenFramebuffersEXT(1, &shadow_fbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, shadow_fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
+ GL_DEPTH_ATTACHMENT_EXT,
GL_TEXTURE_2D,
shadow_tex,
0);
+
+ first_time = GL_TRUE;
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER_EXT, shadow_fbo);
+
+ glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+
+ if (first_time) {
+ GLenum status;
+
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
- fprintf(stderr, "shadow map FBO complete: 0x%08x\n",
+ fprintf(stderr, "shadow map FBO incomplete: 0x%08x\n",
status);
}
- glDisable(GL_DEPTH_TEST);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, shadow_fbo);
glViewport(0, 0, shadow_width, shadow_height);
/* Clear to the material color. */
- glClearColor(1.0, 0.7, 0.5, 1.0);
- glClear(GL_COLOR_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT);
/* Draw the rings in black. */
glBindVertexArray(ring.shadow_array_obj);
@@ -155,6 +171,8 @@ generate_rings_shadowmap(void)
do_ring_drawelements();
}
- glEnable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
+ glDrawBuffer(GL_BACK);
+ glReadBuffer(GL_BACK);
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
}