diff options
Diffstat (limited to 'lighting.cpp')
-rw-r--r-- | lighting.cpp | 76 |
1 files changed, 64 insertions, 12 deletions
diff --git a/lighting.cpp b/lighting.cpp index 75ae7c2..0e41ddd 100644 --- a/lighting.cpp +++ b/lighting.cpp @@ -1,5 +1,6 @@ #include "lighting.hpp" #include "model.hpp" +#include "renderer.hpp" #include "world.hpp" extern "C" { @@ -12,17 +13,28 @@ struct GPU_Light { v3f dir; float brightness; v3f colour; - float pad; + int caster_id; +}; + +struct GPU_Caster { + m4f projection; }; void Lighting::init(Device* dev) { int i; + Sampler_State ss{}; lights.init( dev, "Light buffer", max_lights * sizeof(GPU_Light), Buffer_Flags::storage_buffer ); + casters.init( + dev, + "Caster buffer", + max_shadows * sizeof(GPU_Caster), + Buffer_Flags::storage_buffer + ); shadows = dev->create_texture( "Shadowmap Array", texture_format_d16, @@ -35,6 +47,7 @@ void Lighting::init(Device* dev) { 0 ); for (i = 0; i < max_shadows; i++) { + cameras[i] = 0; shadow_slices[i] = dev->alias_texture( shadows, "Shadowmap Slice", @@ -49,18 +62,40 @@ void Lighting::init(Device* dev) { i ); } + ss.min = Filter_Mode::linear; + ss.mag = Filter_Mode::linear; + ss.mip = Filter_Mode::linear; + ss.address_u = Address_Mode::border; + ss.address_v = Address_Mode::border; + ss.border[0] = 1.0f; + ss.border[1] = 1.0f; + ss.border[2] = 1.0f; + ss.border[3] = 1.0f; + ss.compare = Depth_Mode::less; + shadow_sampler = dev->create_sampler("shadow sampler", ss); } -void Lighting::destroy(Device* dev) { +void Lighting::destroy(Device* dev, Renderer& r) { int i; lights.destroy(dev); - for (i = 0; i < max_shadows; i++) + casters.destroy(dev); + dev->destroy_sampler(shadow_sampler); + for (i = 0; i < max_shadows; i++) { dev->destroy_texture(shadow_slices[i]); + r.destroy_camera(cameras[i]); + } dev->destroy_texture(shadows); } -void Lighting::write_buf(void* ptr, World& w) { - GPU_Light* dst = (GPU_Light*)ptr; +void Lighting::write_bufs( + void* lptr, + void* cptr, + World& w, + Renderer& r, + Model_Scene& s +) { + GPU_Light* ldst = (GPU_Light*)lptr; + GPU_Caster* cdst = (GPU_Caster*)cptr; int count = 0, ccount = 0; for (auto v : w.view<Sun_Light>()) { GPU_Light gl; @@ -72,20 +107,37 @@ void Lighting::write_buf(void* ptr, World& w) { gl.brightness = l.brightness; gl.colour = l.colour; gl.dir = l.dir; - dst[count++] = gl; - if (l.caster) { - Caster& c = casters[ccount++]; - c.vp = m4f::identity(); - } + if (l.caster && ccount < max_shadows) { + int cid = ccount++; + GPU_Caster& c = cdst[cid]; + Camera_Id camid = cameras[cid]; + if (!camid) + camid = r.create_camera(); + Camera& cam = r.get_camera(camid); + cam.init_shadow(l.dir, s.bound.min, s.bound.max); + c.projection = cam.get_proj() * cam.get_view(); + cameras[cid] = camid; + gl.caster_id = cid; + } else + gl.caster_id = -1; + ldst[count++] = gl; } light_count = count; caster_count = ccount; } -void Lighting::update(Device* dev, Context& ctx, World& w) { +void Lighting::update( + Device* dev, + Context& ctx, + World& w, + Renderer& r, + Model_Scene& s +) { light_count = 0; - write_buf(lights.map(dev), w); + write_bufs(lights.map(dev), casters.map(dev), w, r, s); + casters.unmap(dev); lights.unmap(dev); lights.update(ctx); + casters.update(ctx); } |