summaryrefslogtreecommitdiff
path: root/lighting.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lighting.cpp')
-rw-r--r--lighting.cpp76
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);
}