diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-06-17 09:54:12 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-06-17 10:02:17 +0200 |
commit | 6c33746542f91abc300319cd057839299d17dea5 (patch) | |
tree | a1109100959c500e812d58905d8abc5882d94320 | |
parent | 0c9383d5944a53b9b6fcc60fc56450a5418f0963 (diff) |
wip
-rw-r--r-- | editor/imgui.cpp | 7 | ||||
-rw-r--r-- | main/draw.cpp | 51 | ||||
-rw-r--r-- | main/main-impl.hpp | 4 | ||||
-rw-r--r-- | shaders/lightmap.cpp | 61 | ||||
-rw-r--r-- | shaders/lightmap.frag | 4 | ||||
-rw-r--r-- | shaders/lightmap.hpp | 18 |
6 files changed, 93 insertions, 52 deletions
diff --git a/editor/imgui.cpp b/editor/imgui.cpp index d8377033..b8ba4a57 100644 --- a/editor/imgui.cpp +++ b/editor/imgui.cpp @@ -227,12 +227,15 @@ void app::draw_lightmap_test() .falloff = li.falloff, }; auto& shader = M->lightmap_shader(); + shader.bind(); shader.begin_accum(); shader.begin_light({ 0, 0 }, L); shader.add_chunk({}, e_->chunk()); - shader.finish_light_only(); - ImGui::Image(&shader.scratch_texture(), {1024, 1024}); + shader.finish_and_blend_light(); + //shader.finish_light_only(); shader.end_accum(); + //ImGui::Image(&shader.scratch_texture(), {1024, 1024}); + ImGui::Image(&shader.accum_texture(), {1024, 1024}); M->bind(); } ImGui::End(); diff --git a/main/draw.cpp b/main/draw.cpp index 4628eaf8..67e92e91 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -4,6 +4,7 @@ #include "src/camera-offset.hpp" #include "src/anim-atlas.hpp" #include "main/clickable.hpp" +#include "src/light.hpp" #include <Corrade/Containers/ArrayView.h> #include <Magnum/GL/DefaultFramebuffer.h> #include <Magnum/GL/Renderer.h> @@ -114,27 +115,48 @@ auto main_impl::get_draw_bounds() const noexcept -> draw_bounds return {x0, x1, y0, y1}; } -void main_impl::draw_lights_for_chunk(chunk& c, chunk_coords_ ch, Vector2b neighbor_offset) noexcept +bool main_impl::draw_lights_for_chunk(chunk& c, Vector2b neighbor_offset) noexcept { + bool ret = false; for (const auto& e_ : c.entities()) { const auto& e = *e_; if (e.type_of() != entity_type::light) continue; - // todo + const auto& li = static_cast<const light&>(e); + if (li.max_distance >= 1e-4f || li.falloff == light_falloff::constant) + { + ret = true; + auto L = light_s { + .center = Vector2(li.coord.local()) * TILE_SIZE2 + Vector2(li.offset), + .dist = li.max_distance, + .color = li.color, + .falloff = li.falloff, + }; + _lightmap_shader.begin_light(neighbor_offset, L); + _lightmap_shader.add_chunk(neighbor_offset, c); + _lightmap_shader.finish_and_blend_light(); + } } + return ret; } -void main_impl::draw_lights(chunk& c, chunk_coords_ ch, const std::array<chunk*, 8>& ns) noexcept +bool main_impl::draw_lights(chunk& c, const std::array<chunk*, 8>& ns) noexcept { + bool ret = false; + _lightmap_shader.bind(); + _lightmap_shader.begin_accum(); + for (auto i = 0uz; i < 8; i++) if (ns[i] != nullptr) { auto off = world::neighbor_offsets[i]; - draw_lights_for_chunk(*ns[i], ch + off, off); + ret |= draw_lights_for_chunk(*ns[i], off); } + ret |= draw_lights_for_chunk(c, {}); - draw_lights_for_chunk(c, ch, {}); + _lightmap_shader.end_accum(); + return ret; } void main_impl::draw_world() noexcept @@ -166,16 +188,19 @@ void main_impl::draw_world() noexcept auto* c_ = _world.at(ch); if (!c_) continue; - std::array<chunk*, 8> ns = {}; - for (auto i = 0uz; i < 8; i++) + auto& c = *c_; { - auto off = world::neighbor_offsets[i]; - auto n = chunk_coords_{int16_t(x + off.x()), int16_t(y + off.y()), z}; - ns[i] = _world.at(n); + std::array<chunk*, 8> ns = {}; + for (auto i = 0uz; i < 8; i++) + { + auto off = world::neighbor_offsets[i]; + auto n = chunk_coords_{int16_t(x + off.x()), int16_t(y + off.y()), z}; + ns[i] = _world.at(n); + } + draw_lights(c, ns); } - auto& c = *c_; - //draw_lights(c, ch, ns); - // tex = _lightmap_shader.texture(); // todo + bind(); + const with_shifted_camera_offset o{_shader, ch, {minx, miny}, {maxx, maxy}}; if (check_chunk_visible(_shader.camera_offset(), sz)) { diff --git a/main/main-impl.hpp b/main/main-impl.hpp index 19edce8b..a6457524 100644 --- a/main/main-impl.hpp +++ b/main/main-impl.hpp @@ -121,8 +121,8 @@ private: void recalc_viewport(Vector2i fb_size, Vector2i win_size) noexcept; void draw_world() noexcept; - void draw_lights(chunk& c, chunk_coords_ ch, const std::array<chunk*, 8>& neighbors) noexcept; - void draw_lights_for_chunk(chunk& c, chunk_coords_ ch, Vector2b neighbor_offset) noexcept; + bool draw_lights(chunk& c, const std::array<chunk*, 8>& neighbors) noexcept; + bool draw_lights_for_chunk(chunk& c, Vector2b neighbor_offset) noexcept; draw_bounds get_draw_bounds() const noexcept override; diff --git a/shaders/lightmap.cpp b/shaders/lightmap.cpp index 72aed74c..62faae0d 100644 --- a/shaders/lightmap.cpp +++ b/shaders/lightmap.cpp @@ -45,13 +45,13 @@ auto lightmap_shader::make_framebuffer(Vector2i size) -> Framebuffer framebuffer.scratch .setWrapping(GL::SamplerWrapping::ClampToBorder) .setBorderColor(Color4{0, 0, 0, 1}) - .setStorage(1, GL::TextureFormat::RGBA8, size); + .setStorage(1, GL::TextureFormat::RGB8, size); framebuffer.accum = GL::Texture2D{}; framebuffer.accum .setWrapping(GL::SamplerWrapping::ClampToBorder) .setBorderColor(Color4{0, 0, 0, 1}) - .setStorage(1, GL::TextureFormat::RGBA8, size); + .setStorage(1, GL::TextureFormat::RGB8, size); //framebuffer.depth = GL::Renderbuffer{}; //framebuffer.depth.setStorage(GL::RenderbufferFormat::DepthComponent32F, size); @@ -60,8 +60,11 @@ auto lightmap_shader::make_framebuffer(Vector2i size) -> Framebuffer framebuffer.fb //.attachRenderbuffer(GL::Framebuffer::BufferAttachment::Depth, framebuffer.depth); .attachTexture(GL::Framebuffer::ColorAttachment{0}, framebuffer.scratch, 0) + .attachTexture(GL::Framebuffer::ColorAttachment{1}, framebuffer.accum, 0) //.clearDepth(0); - .clearColor(0, Color4{0.f, 0.f, 0.f, 1.f}); + .clearColor(0, Color4{0, 0, 0, 1}) + .clearColor(1, Color4{0, 0, 0, 1}); + framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{0}); return framebuffer; } @@ -101,7 +104,8 @@ lightmap_shader::lightmap_shader() : CORRADE_INTERNAL_ASSERT_OUTPUT(link()); setUniform(ModeUniform, DrawLightmapMode); - clear(); + clear_scratch(); + clear_accum(); } void lightmap_shader::flush_vertexes(ShaderMode mode) @@ -132,7 +136,7 @@ std::array<UnsignedShort, 6> lightmap_shader::quad_indexes(size_t N) }; /* 2 2--0 */ } -void lightmap_shader::add_light(Vector2i neighbor_offset, const light_s& light) +void lightmap_shader::add_light(Vector2b neighbor_offset, const light_s& light) { fm_debug_assert(_count == 0); fm_debug_assert(_quads.size() > 0); @@ -176,14 +180,14 @@ void lightmap_shader::add_light(Vector2i neighbor_offset, const light_s& light) setUniform(ColorIntensityUniform, Vector4{Vector3{color} * alpha, I }); setUniform(CenterUniform, center_fragcoord); setUniform(FalloffUniform, (uint32_t)light.falloff); - setUniform(SizeUniform, 1.f/image_size_factor); + setUniform(SizeUniform, image_size_factor / chunk_size); _light_center = center; flush_vertexes(DrawLightmapMode); setUniform(FalloffUniform, (uint32_t)light_falloff::constant); setUniform(ColorIntensityUniform, shadow_color); - setUniform(SamplerUniform, 1); + setUniform(SamplerUniform, TextureSampler); } Vector2 lightmap_shader::project_vertex(Vector2 light, Vector2 vertex, Vector2 length) @@ -197,7 +201,7 @@ Vector2 lightmap_shader::project_vertex(Vector2 light, Vector2 vertex, Vector2 l return ret; } -void lightmap_shader::add_rect(Vector2i neighbor_offset, Vector2 min, Vector2 max) +void lightmap_shader::add_rect(Vector2b neighbor_offset, Vector2 min, Vector2 max) { fm_assert(_light_center && _count != (size_t)-1); @@ -239,7 +243,7 @@ void lightmap_shader::add_rect(Vector2i neighbor_offset, Vector2 min, Vector2 ma } } -void lightmap_shader::add_rect(Vector2i neighbor_offset, Pair<Vector2, Vector2> minmax) +void lightmap_shader::add_rect(Vector2b neighbor_offset, Pair<Vector2, Vector2> minmax) { fm_assert(_light_center && _count != (size_t)-1); @@ -247,13 +251,13 @@ void lightmap_shader::add_rect(Vector2i neighbor_offset, Pair<Vector2, Vector2> add_rect(neighbor_offset, min, max); } -void lightmap_shader::add_chunk(Vector2i neighbor_offset, chunk& c) +void lightmap_shader::add_chunk(Vector2b neighbor_offset, chunk& c) { add_geometry(neighbor_offset, c); add_entities(neighbor_offset, c); } -void lightmap_shader::add_geometry(Vector2i neighbor_offset, chunk& c) +void lightmap_shader::add_geometry(Vector2b neighbor_offset, chunk& c) { fm_assert(_light_center && _count != (size_t)-1); @@ -284,7 +288,7 @@ void lightmap_shader::add_geometry(Vector2i neighbor_offset, chunk& c) } } -void lightmap_shader::add_entities(Vector2i neighbor_offset, chunk& c) +void lightmap_shader::add_entities(Vector2b neighbor_offset, chunk& c) { fm_assert(_light_center && _count != (size_t)-1); @@ -317,21 +321,19 @@ void lightmap_shader::add_quad(const std::array<Vector2, 4>& quad) void lightmap_shader::clear_scratch() { _light_center = {}; - framebuffer.fb.clearColor(0, Vector4ui{0}); + framebuffer.fb.clearColor(0, Color4{0, 0, 0, 0}); } -void lightmap_shader::clear() +void lightmap_shader::clear_accum() { - clear_scratch(); + fm_assert(!_light_center && _count == (size_t)-1); _count = (size_t)-1; - framebuffer.fb.clearColor(1, Vector4ui{0}); - //framebuffer.fb.clearDepth(0); + //framebuffer.fb.clearColor(1, Color4{0, 0, 0, 0}); } void lightmap_shader::bind() { //fm_assert(_count == 0 && !_light_center); - using BF = Magnum::GL::Renderer::BlendFunction; framebuffer.scratch.bind(TextureSampler); framebuffer.fb.bind(); } @@ -341,9 +343,13 @@ void lightmap_shader::begin_accum() fm_assert(!_light_center); fm_assert(_count == (size_t)-1); - clear(); - bind(); + clear_accum(); _count = 0; + + framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{1}); + framebuffer.fb.clearColor(0, Color4{0, 0, 0, 0}); + //framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{0}); + //framebuffer.fb.clearColor(1, Color4{0, 0, 0, 0}); } void lightmap_shader::end_accum() @@ -353,11 +359,13 @@ void lightmap_shader::end_accum() _count = (size_t)-1; } -void lightmap_shader::begin_light(Vector2i neighbor_offset, const light_s& light) +void lightmap_shader::begin_light(Vector2b neighbor_offset, const light_s& light) { fm_assert(_count == 0 && !_light_center); clear_scratch(); _count = 0; + framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{0}); + framebuffer.fb.clearColor(0, Color4{0, 0, 0, 1}); add_light(neighbor_offset, light); flush_vertexes(DrawLightmapMode); } @@ -367,6 +375,7 @@ void lightmap_shader::finish_light_only() fm_assert(_light_center && _count != (size_t)-1); flush_vertexes(DrawLightmapMode); _light_center = {}; + _count = (size_t)0; } void lightmap_shader::finish_and_blend_light() @@ -383,22 +392,24 @@ void lightmap_shader::finish_and_blend_light() }}; using BF = Magnum::GL::Renderer::BlendFunction; + GL::Renderer::setBlendFunction(BF::One, BF::One); - _count = 1; - flush_vertexes(BlendLightmapMode); + framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{1}); + _count = 1; flush_vertexes(BlendLightmapMode); + framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{0}); GL::Renderer::setBlendFunction(BF::SourceAlpha, BF::OneMinusSourceAlpha); } GL::Texture2D& lightmap_shader::scratch_texture() { - fm_assert(_count == 0); + fm_assert(_count == (size_t)-1); fm_debug_assert(framebuffer.scratch.id()); return framebuffer.scratch; } GL::Texture2D& lightmap_shader::accum_texture() { - fm_assert(_count == 0); + fm_assert(_count == (size_t)-1); fm_debug_assert(framebuffer.accum.id()); return framebuffer.accum; } diff --git a/shaders/lightmap.frag b/shaders/lightmap.frag index 1f017fb6..bbf04326 100644 --- a/shaders/lightmap.frag +++ b/shaders/lightmap.frag @@ -9,6 +9,8 @@ layout (location = 5) uniform sampler2D sampler; out vec4 color; +//layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; + void main() { if (mode == 1) // draw { @@ -32,6 +34,6 @@ void main() { } else if (mode == 2) // blend { - color = texture(sampler, gl_FragCoord.xy ); + color = texture(sampler, gl_FragCoord.xy * size); } } diff --git a/shaders/lightmap.hpp b/shaders/lightmap.hpp index f9f29156..e092c78e 100644 --- a/shaders/lightmap.hpp +++ b/shaders/lightmap.hpp @@ -42,18 +42,19 @@ struct lightmap_shader final : GL::AbstractShaderProgram GL::Texture2D scratch{NoCreate}, accum{NoCreate}; }; - void begin_light(Vector2i neighbor_offset, const light_s& light); - void add_chunk(Vector2i neighbor_offset, chunk& c); - void add_entities(Vector2i neighbor_offset, chunk& c); - void add_geometry(Vector2i neighbor_offset, chunk& c); - void add_rect(Vector2i neighbor_offset, Vector2 min, Vector2 max); - void add_rect(Vector2i neighbor_offset, Pair<Vector2, Vector2> minmax); + void begin_light(Vector2b neighbor_offset, const light_s& light); + void add_chunk(Vector2b neighbor_offset, chunk& c); + void add_entities(Vector2b neighbor_offset, chunk& c); + void add_geometry(Vector2b neighbor_offset, chunk& c); + void add_rect(Vector2b neighbor_offset, Vector2 min, Vector2 max); + void add_rect(Vector2b neighbor_offset, Pair<Vector2, Vector2> minmax); void finish_light_only(); void finish_and_blend_light(); GL::Texture2D& scratch_texture(); GL::Texture2D& accum_texture(); void begin_accum(); void end_accum(); + void bind(); private: enum { @@ -76,12 +77,11 @@ private: static Framebuffer make_framebuffer(Vector2i size); GL::Mesh make_mesh(); - void add_light(Vector2i neighbor_offset, const light_s& light); + void add_light(Vector2b neighbor_offset, const light_s& light); void flush_vertexes(ShaderMode mode); void add_quad(const std::array<Vector2, 4>& quad); - void bind(); void clear_scratch(); - void clear(); + void clear_accum(); static std::array<UnsignedShort, 6> quad_indexes(size_t N); static Vector2 project_vertex(Vector2 light, Vector2 vertex, Vector2 length); |