From dbd90f7d607ae99c5eb5427dcf14cd5915952894 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 31 Jul 2009 17:17:49 -0700 Subject: Use shadow mapping instead of shadow texturing. --- ground.frag | 9 +++++---- ground.vert | 4 ++-- shadow_map.c | 40 +++++++++++++++++++++++++++++----------- 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); } -- cgit v1.2.3