]> git.tdb.fi Git - libs/gl.git/blobdiff - source/effects/shadowmap.cpp
Suppoer per-light shadow casters in ShadowMap
[libs/gl.git] / source / effects / shadowmap.cpp
index 1b5f531b913c2d339f8e1aee3830775d576aed58..74dad5e78b74fb6d32505008ca2ecf15d262600b 100644 (file)
@@ -11,17 +11,12 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
-ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting *l, Renderable &c):
+ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting *l):
        Effect(r),
        width(w),
        height(h),
        lighting(l),
-       shadow_caster(c),
-       sampler(Resources::get_global().get<Sampler>("_linear_clamp_shadow.samp")),
-       radius(1),
-       depth_bias(4),
-       darkness(1.0f),
-       rendered(false)
+       sampler(Resources::get_global().get<Sampler>("_linear_clamp_shadow.samp"))
 {
        depth_buf.storage(DEPTH_COMPONENT32F, width, height, 1);
        fbo.set_format((DEPTH_ATTACHMENT,DEPTH_COMPONENT32F));
@@ -39,16 +34,16 @@ ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting *l, R
 }
 
 ShadowMap::ShadowMap(unsigned s, Renderable &r, const DirectionalLight &l, Renderable &c):
-       ShadowMap(s, s, r, 0, c)
+       ShadowMap(s, s, r, 0)
 {
-       add_light(l, s);
+       add_light(l, s, c);
 }
 
-ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting &l, Renderable &c):
-       ShadowMap(w, h, r, &l, c)
+ShadowMap::ShadowMap(unsigned w, unsigned h, Renderable &r, const Lighting &l):
+       ShadowMap(w, h, r, &l)
 { }
 
-void ShadowMap::add_light(const DirectionalLight &light, unsigned s)
+void ShadowMap::add_light(const DirectionalLight &light, unsigned s, Renderable &c)
 {
        if(!lighting && !lights.empty())
                throw invalid_operation("ShadowMap::add_light");
@@ -94,6 +89,7 @@ void ShadowMap::add_light(const DirectionalLight &light, unsigned s)
        sl.light = &light;
        sl.index = index;
        sl.region = region;
+       sl.shadow_caster = &c;
 
        string base = format("shadows[%d]", index);
        shdata.uniform(base+".enabled", 1);
@@ -142,7 +138,8 @@ void ShadowMap::setup_frame(Renderer &renderer)
 
        rendered = true;
        renderable.setup_frame(renderer);
-       shadow_caster.setup_frame(renderer);
+       for(const ShadowedLight &l: lights)
+               l.shadow_caster->setup_frame(renderer);
 
        for(ShadowedLight &l: lights)
        {
@@ -153,10 +150,8 @@ void ShadowMap::setup_frame(Renderer &renderer)
                l.shadow_camera.set_orthographic(radius*2, radius*2);
                l.shadow_camera.set_depth_clip(-radius, radius);
 
-               Matrix shadow_matrix = l.shadow_camera.get_object_matrix();
-               shadow_matrix.scale(radius*2, radius*2, -radius*2);
-               shadow_matrix.translate(-0.5, -0.5, depth_bias/l.region.width-0.5);
-               shadow_matrix.invert();
+               Matrix to_texcoord = Matrix().translate(Vector3(0.5f, 0.5f, 0.5f-depth_bias/l.region.width)).scale(0.5f);
+               Matrix shadow_matrix = to_texcoord*l.shadow_camera.get_projection_matrix()*l.shadow_camera.get_view_matrix();
 
                shdata.uniform(format("shadows[%d].shd_world_matrix", l.index), shadow_matrix);
        }
@@ -169,7 +164,7 @@ void ShadowMap::setup_frame(Renderer &renderer)
                renderer.set_scissor(&l.region);
                renderer.set_camera(l.shadow_camera);
 
-               renderer.render(shadow_caster);
+               renderer.render(*light.shadow_caster);
        }
 }
 
@@ -200,7 +195,7 @@ void ShadowMap::set_debug_name(const string &name)
        fbo.set_debug_name(name+" [FBO]");
        for(unsigned i=0; i<lights.size(); ++i)
                lights[i].shadow_camera.set_debug_name(format("%s/light%d.camera", name, i));
-       depth_buf.set_debug_name(name+"/depth.tex2d");
+       depth_buf.set_debug_name(name+"/depth.tex");
        shdata.set_debug_name(name+" [UBO]");
 #else
        (void)name;