diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-06-12 01:12:32 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-06-12 01:12:32 +0200 |
commit | 6143042c67f5e7adb0e64a81ebaa9c89e398a541 (patch) | |
tree | cf3a5a14b85e0df32555a769f27c31c73d3e577f | |
parent | 04b9df316971e0cb897605fdabb16da712f3f791 (diff) |
wip
-rw-r--r-- | main/draw.cpp | 7 | ||||
-rw-r--r-- | shaders/lightmap.cpp | 95 | ||||
-rw-r--r-- | shaders/lightmap.hpp | 6 |
3 files changed, 102 insertions, 6 deletions
diff --git a/main/draw.cpp b/main/draw.cpp index 909dc13f..2c3156b0 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -116,6 +116,13 @@ auto main_impl::get_draw_bounds() const noexcept -> draw_bounds void main_impl::draw_lights_for_chunk(chunk& c, chunk_coords_ ch, Vector2b neighbor_offset) noexcept { + for (const auto& e_ : c.entities()) + { + const auto& e = *e_; + if (e.type_of() != entity_type::light) + continue; + // todo + } } void main_impl::draw_lights(chunk& c, chunk_coords_ ch, const std::array<chunk*, 8>& ns) noexcept diff --git a/shaders/lightmap.cpp b/shaders/lightmap.cpp index 7c955e1f..1214ab30 100644 --- a/shaders/lightmap.cpp +++ b/shaders/lightmap.cpp @@ -2,7 +2,9 @@ #include "compat/assert.hpp" #include "src/tile-defs.hpp" #include "loader/loader.hpp" +#include "src/chunk.hpp" #include <Corrade/Containers/Iterable.h> +#include <cmath> #include <Magnum/Magnum.h> #include <Magnum/GL/MeshView.h> #include <Magnum/GL/Shader.h> @@ -132,10 +134,10 @@ void lightmap_shader::add_light(Vector2i neighbor_offset, const light_s& light) _indexes[_count] = quad_indexes(0); _quads[_count] = std::array<Vector2, 4>{{ - { I_clip + center_clip.x(), -I_clip + center_clip.y() }, - { I_clip + center_clip.x(), I_clip + center_clip.y() }, + { I_clip + center_clip.x(), -I_clip + center_clip.y() }, + { I_clip + center_clip.x(), I_clip + center_clip.y() }, { -I_clip + center_clip.x(), -I_clip + center_clip.y() }, - { -I_clip + center_clip.x(), I_clip + center_clip.y() }, + { -I_clip + center_clip.x(), I_clip + center_clip.y() }, }}; _count++; @@ -147,13 +149,91 @@ void lightmap_shader::add_light(Vector2i neighbor_offset, const light_s& light) setUniform(CenterUniform, center_fragcoord); setUniform(FalloffUniform, (uint32_t)light.falloff); setUniform(SizeUniform, 1.f/image_size_factor); + + _light_center = center; + flush_vertexes(); + + setUniform(ColorIntensityUniform, Vector4{0, 0, 0, 1}); } -lightmap_shader::~lightmap_shader() = default; +Vector2 lightmap_shader::project_vertex(Vector2 light, Vector2 vertex, Vector2 length) +{ + auto dir = vertex - light; + auto len = dir.length(); + if (std::fabs(len) < 1e-4f) + return vertex; + auto dir_norm = dir * (1/len); + auto ret = vertex + dir_norm * length; + return ret; +} + +void lightmap_shader::add_chunk(Vector2i neighbor_offset, const chunk& c) +{ + fm_assert(_light_center); + + for (const auto& e_ : c.entities()) + { + const auto& e = *e_; + if (e.is_virtual()) + continue; + if (e.pass == pass_mode::pass || e.pass == pass_mode::see_through) + continue; + auto li = *_light_center; + auto center = Vector2(e.offset) + Vector2(e.bbox_offset) + + Vector2(e.coord.local()) * TILE_SIZE2 + + Vector2(neighbor_offset)*chunk_size + chunk_offset; + const auto x = center.x(), y = center.y(), + w = (float)e.bbox_size.x(), h = (float)e.bbox_size.y(); + /* 3--1 1 */ + /* | / /| */ + /* |/ / | */ + /* 2 2--0 */ + const auto vertexes = std::array<Vector2, 4>{{ + { w + x, -h + y }, // bottom right + { w + x, h + y }, // top right + { -w + x, -h + y }, // bottom left + { -w + x, h + y }, // top left + }}; + struct pair { uint8_t first, second; }; + constexpr std::array<pair, 4> from = {{ + { 3, 1 }, // side #1: 3 -> 2, 1 -> 0 + { 1, 0 }, // side #2: 1 -> 3, 0 -> 2 + { 0, 2 }, // side #3: 0 -> 1, 2 -> 3 + { 2, 3 }, // side #4: 2 -> 0, 3 -> 1 + }}; + constexpr std::array<pair, 4> to = {{ + { 2, 0 }, + { 3, 2 }, + { 1, 3 }, + { 0, 1 }, + }}; + for (auto i = 0uz; i < 4; i++) + { + auto [src1, src2] = from[i]; + auto [dest1, dest2] = to[i]; + auto verts = vertexes; + verts[dest1] = project_vertex(li, vertexes[src1], {128, 128}); + verts[dest2] = project_vertex(li, vertexes[src2], {128, 128}); + // todo + } + } +} + +void lightmap_shader::add_quad(const std::array<Vector2, 4>& quad) +{ + fm_debug_assert(_count < buffer_size); + const auto i = _count++; + _quads[i] = quad; + _indexes[i] = quad_indexes(i); + if (i+1 == buffer_size) [[unlikely]] + flush_vertexes(); +} void lightmap_shader::clear() { + _light_center = {}; framebuffer.fb.clearColor(0, Vector4ui{0}); + accum.fb.clearColor(0, Vector4ui{0}); //framebuffer.fb.clearDepth(0); } @@ -164,15 +244,18 @@ void lightmap_shader::bind() void lightmap_shader::begin(Vector2i neighbor_offset, const light_s& light) { - fm_assert(_count == 0); + fm_assert(_count == 0 && !_light_center); clear(); bind(); add_light(neighbor_offset, light); + flush_vertexes(); } void lightmap_shader::end() { + fm_assert(_light_center); flush_vertexes(); + _light_center = {}; } GL::Texture2D& lightmap_shader::texture() @@ -184,4 +267,6 @@ GL::Texture2D& lightmap_shader::texture() bool light_s::operator==(const light_s&) const noexcept = default; +lightmap_shader::~lightmap_shader() = default; + } // namespace floormat diff --git a/shaders/lightmap.hpp b/shaders/lightmap.hpp index 4ae6cb5c..633f7ba0 100644 --- a/shaders/lightmap.hpp +++ b/shaders/lightmap.hpp @@ -3,6 +3,7 @@ #include "light-falloff.hpp" #include <array> #include <Corrade/Containers/Array.h> +#include <Corrade/Containers/Optional.h> #include <Magnum/Math/Vector2.h> #include <Magnum/Math/Vector4.h> #include <Magnum/Math/Color.h> @@ -42,7 +43,7 @@ struct lightmap_shader final : GL::AbstractShaderProgram }; void begin(Vector2i neighbor_offset, const light_s& light); - void add_chunk(Vector2i neighbor_offset, const chunk& ch); + void add_chunk(Vector2i neighbor_offset, const chunk& c); void end(); GL::Texture2D& texture(); @@ -51,9 +52,11 @@ private: GL::Mesh make_mesh(); void add_light(Vector2i neighbor_offset, const light_s& light); void flush_vertexes(); + void add_quad(const std::array<Vector2, 4>& quad); void bind(); void clear(); static std::array<UnsignedShort, 6> quad_indexes(size_t N); + static Vector2 project_vertex(Vector2 light, Vector2 vertex, Vector2 length); enum : int { ColorIntensityUniform = 0, @@ -69,6 +72,7 @@ private: size_t _count = 0; GL::Buffer _vertex_buf{NoCreate}, _index_buf{NoCreate}; GL::Mesh _mesh{NoCreate}; + Optional<Vector2> _light_center; }; } // namespace floormat |