diff options
Diffstat (limited to 'shaders')
-rw-r--r-- | shaders/lightmap.cpp | 268 | ||||
-rw-r--r-- | shaders/lightmap.frag | 37 | ||||
-rw-r--r-- | shaders/lightmap.hpp | 125 | ||||
-rw-r--r-- | shaders/lightmap.vert | 29 |
4 files changed, 317 insertions, 142 deletions
diff --git a/shaders/lightmap.cpp b/shaders/lightmap.cpp index ce841509..d857f3ba 100644 --- a/shaders/lightmap.cpp +++ b/shaders/lightmap.cpp @@ -3,6 +3,7 @@ #include "src/tile-defs.hpp" #include "loader/loader.hpp" #include "src/chunk.hpp" +#include <Corrade/Utility/Move.h> #include <Corrade/Containers/PairStl.h> #include <Corrade/Containers/Iterable.h> #include <cmath> @@ -33,10 +34,24 @@ constexpr auto buffer_size = 256uz; constexpr auto clip_start = Vector2{-1, -1}; constexpr auto clip_scale = 2/(chunk_size * max_neighbors); -constexpr auto shadow_length = chunk_size * 2 * max_neighbors; +//constexpr auto shadow_length = chunk_size * 2 * max_neighbors; constexpr auto shadow_color = Vector4{0, 0, 0, 1}; constexpr auto shadow_wall_depth = 4.f; +constexpr auto half_neighbors = Vector2(max_neighbors)/2; + +using Utility::forward; + +template<typename T> +GL::Mesh make_light_mesh(T&& vert, T&& index) +{ + GL::Mesh mesh{GL::MeshPrimitive::Triangles}; + mesh.addVertexBuffer(forward<T>(vert), 0, lightmap_shader::Position{}) + .setIndexBuffer(forward<T>(index), 0, GL::MeshIndexType::UnsignedShort) + .setCount(6); + return mesh; +} + } // namespace auto lightmap_shader::make_framebuffer(Vector2i size) -> Framebuffer @@ -68,25 +83,89 @@ auto lightmap_shader::make_framebuffer(Vector2i size) -> Framebuffer .clearColor(1, Color4{0, 0, 0, 1}); framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{0}); + using BF = Magnum::GL::Renderer::BlendFunction; + GL::Renderer::setBlendFunction(0, BF::One, BF::Zero, BF::One, BF::Zero); + GL::Renderer::setBlendFunction(1, BF::One, BF::One, BF::One, BF::One); + return framebuffer; } -GL::Mesh lightmap_shader::make_mesh() +auto lightmap_shader::output() -> struct output +{ + return { framebuffer.scratch, framebuffer.accum }; +} + +GL::Mesh lightmap_shader::make_occlusion_mesh() { GL::Mesh mesh{GL::MeshPrimitive::Triangles}; - mesh.addVertexBuffer(_vertex_buf, 0, Position{}) - .setIndexBuffer(_index_buf, 0, GL::MeshIndexType::UnsignedShort) - .setCount(int32_t(6 * buffer_size)); + mesh.addVertexBuffer(vertex_buf, 0, Position{}) + .setIndexBuffer(index_buf, 0, GL::MeshIndexType::UnsignedShort) + .setCount(int32_t(6 * capacity)); return mesh; } -lightmap_shader::lightmap_shader() : - framebuffer { make_framebuffer(image_size) }, - _quads { ValueInit, buffer_size }, - _indexes { ValueInit, buffer_size }, - _vertex_buf { _quads }, - _index_buf { _indexes }, - _mesh { make_mesh() } +void lightmap_shader::begin_occlusion() +{ + count = 0; +} + +void lightmap_shader::end_occlusion() +{ + bool create_mesh = !vertex_buf.id(); + + if (create_mesh) + { + occlusion_mesh = GL::Mesh{NoCreate}; + vertex_buf = GL::Buffer{vertexes.prefix(capacity), GL::BufferUsage::DynamicDraw}; + index_buf = GL::Buffer{indexes.prefix(capacity)}; + occlusion_mesh = make_occlusion_mesh(); + } + else + { + if (!occlusion_mesh.id()) + occlusion_mesh = make_occlusion_mesh(); + vertex_buf.setSubData(0, vertexes.prefix(count)); + index_buf.setSubData(0, indexes.prefix(count)); + } +} + +std::array<Vector3, 4>& lightmap_shader::alloc_rect() +{ + if (count == capacity) + { + if (capacity == 0) + capacity = starting_capacity; + else + capacity <<= 1; + fm_debug_assert(count < capacity); + + occlusion_mesh = GL::Mesh{NoCreate}; + vertex_buf = GL::Buffer{NoCreate}; + index_buf = GL::Buffer{NoCreate}; + auto vertexes_ = std::move(vertexes); + auto indexes_ = std::move(indexes); + vertexes = Array<std::array<Vector3, 4>>{ValueInit, capacity}; + indexes = Array<std::array<UnsignedShort, 6>>{ValueInit, capacity}; + for (auto i = 0uz; i < count; i++) + vertexes[i] = vertexes_[i]; + for (auto i = 0uz; i < count; i++) + indexes[i] = indexes_[i]; + indexes[count] = quad_indexes(count); + auto& ret = vertexes[count]; + count++; + return ret; + } + else + { + fm_debug_assert(count < capacity); + auto& ret = vertexes[count]; + indexes[count] = quad_indexes(count); + count++; + return ret; + } +} + +lightmap_shader::lightmap_shader() { constexpr auto min_version = GL::Version::GL330; const auto version = GL::Context::current().version(); @@ -105,11 +184,33 @@ lightmap_shader::lightmap_shader() : attachShaders({vert, frag}); CORRADE_INTERNAL_ASSERT_OUTPUT(link()); + framebuffer = make_framebuffer(image_size); + + auto blend_vertexes = std::array<Vector3, 4>{{ + { 1, -1, 0 }, /* 3--1 1 */ + { 1, 1, 0 }, /* | / /| */ + { -1, -1, 0 }, /* |/ / | */ + { -1, 1, 0 }, /* 2 2--0 */ + }}; + blend_mesh = make_light_mesh<GL::Buffer&&>(GL::Buffer{blend_vertexes}, GL::Buffer{quad_indexes(0)}); + + light_vertex_buf = GL::Buffer{std::array<Vector3, 4>{}}; + light_mesh = GL::Mesh{GL::MeshPrimitive::Triangles}; + light_mesh.addVertexBuffer(light_vertex_buf, 0, lightmap_shader::Position{}) + .setIndexBuffer(GL::Buffer{quad_indexes(0)}, 0, GL::MeshIndexType::UnsignedShort) + .setCount(6); + + setUniform(SamplerUniform, TextureSampler); + setUniform(LightColorUniform, Color3{1, 1, 1}); + setUniform(SizeUniform, Vector2(1 / (chunk_size * max_neighbors))); + setUniform(CenterFragcoordUniform, Vector2(0, 0)); + setUniform(CenterClipUniform, Vector2(-1, 1)); + setUniform(IntensityUniform, 1.f); setUniform(ModeUniform, DrawLightmapMode); - clear_scratch(); - clear_accum(); + setUniform(FalloffUniform, (uint32_t)light_falloff::constant); } +#if 0 void lightmap_shader::flush_vertexes(ShaderMode mode) { fm_assert(_count != (size_t)-1); @@ -128,6 +229,7 @@ void lightmap_shader::flush_vertexes(ShaderMode mode) } _count = 0; } +#endif std::array<UnsignedShort, 6> lightmap_shader::quad_indexes(size_t N) { @@ -138,83 +240,77 @@ std::array<UnsignedShort, 6> lightmap_shader::quad_indexes(size_t N) }; /* 2 2--0 */ } -void lightmap_shader::add_light(Vector2b neighbor_offset, const light_s& light) +void lightmap_shader::add_light(Vector2 neighbor_offset, const light_s& light) { - fm_debug_assert(_count == 0); - fm_debug_assert(_quads.size() > 0); - fm_assert(!_light_center); + Vector2 I; - constexpr auto tile_size = TILE_SIZE2.sum()/2; - float I; switch (light.falloff) { default: - I = 1; break; case light_falloff::linear: case light_falloff::quadratic: - I = light.dist * tile_size; + I = light.dist * TILE_SIZE2; break; } - I = std::fmax(1.f, I); + I = { std::fmax(1.f, I.x()), std::fmax(1.f, I.y()) }; - auto I_clip = I * tile_size; - auto center = light.center + chunk_offset + Vector2(neighbor_offset)*chunk_size; - auto center_clip = clip_start + Vector2{center} * clip_scale; // clip coordinates - auto center_fragcoord = center; // window-relative coordinates - - _indexes[0] = quad_indexes(0); - _quads[0] = 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() }, - }}; - _count = 1; + auto I_clip = I * TILE_SIZE2; + // window-relative coordinates + auto center_fragcoord = light.center + chunk_offset + (neighbor_offset+half_neighbors)*chunk_size; + auto center_clip = clip_start + center_fragcoord * clip_scale; // clip coordinates float alpha = light.color.a() / 255.f; auto color = Vector3{light.color.rgb()} / 255.f; - setUniform(ColorIntensityUniform, Vector4{Vector3{color} * alpha, I }); - setUniform(CenterUniform, center_fragcoord); - setUniform(FalloffUniform, (uint32_t)light.falloff); + setUniform(SamplerUniform, TextureSampler); + setUniform(LightColorUniform, color); setUniform(SizeUniform, 1 / (chunk_size * max_neighbors)); + setUniform(CenterFragcoordUniform, center_fragcoord); + setUniform(CenterClipUniform, center_clip); + setUniform(IntensityUniform, alpha); + setUniform(FalloffUniform, (uint32_t)light.falloff); - _light_center = center; - flush_vertexes(DrawLightmapMode); + framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{0}); + framebuffer.fb.clearColor(0, Color4{0, 0, 0, 1}); - setUniform(FalloffUniform, (uint32_t)light_falloff::constant); - setUniform(ColorIntensityUniform, shadow_color); - setUniform(SamplerUniform, TextureSampler); -} + fm_debug_assert(light_vertex_buf.id()); + fm_debug_assert(light_mesh.id()); + setUniform(ModeUniform, DrawLightmapMode); + auto quad = std::array<Vector3, 4>{{ + { I_clip.x() + center_clip.x(), -I_clip.y() + center_clip.y(), 0 }, + { I_clip.x() + center_clip.x(), I_clip.y() + center_clip.y(), 0 }, + { -I_clip.x() + center_clip.x(), -I_clip.y() + center_clip.y(), 0 }, + { -I_clip.x() + center_clip.x(), I_clip.y() + center_clip.y(), 0 }, + }}; + light_vertex_buf.setSubData(0, quad); + draw(light_mesh); -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; -} + setUniform(ModeUniform, DrawShadowsMode); -void lightmap_shader::add_rect(Vector2b neighbor_offset, Vector2 min, Vector2 max) -{ - fm_assert(_light_center && _count != (size_t)-1); + fm_assert(occlusion_mesh.id()); + auto mesh_view = GL::MeshView{occlusion_mesh}; + mesh_view.setCount((int32_t)count); + draw(mesh_view); + //mesh_view.setIndexRange(0, 0, uint32_t(count*6 - 1)); - auto li = *_light_center; + setUniform(ModeUniform, BlendLightmapMode); + framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{1}); + draw(blend_mesh); +} - auto off = Vector2(neighbor_offset)*chunk_size + chunk_offset; +void lightmap_shader::add_rect(Vector2 neighbor_offset, Vector2 min, Vector2 max) +{ + auto off = (neighbor_offset+half_neighbors)*chunk_size + chunk_offset; min += off; max += off; - const auto vertexes = std::array<Vector2, 4>{{ - { max.x(), min.y() }, - { max.x(), max.y() }, - { min.x(), min.y() }, - { min.x(), max.y() }, + const auto vertexes = std::array<Vector3, 4>{{ + { max.x(), min.y(), 0 }, + { max.x(), max.y(), 0 }, + { min.x(), min.y(), 0 }, + { min.x(), max.y(), 0 }, }}; struct pair { uint8_t first, second; }; constexpr std::array<pair, 4> from = {{ @@ -234,32 +330,32 @@ void lightmap_shader::add_rect(Vector2b neighbor_offset, Vector2 min, Vector2 ma auto [src1, src2] = from[i]; auto [dest1, dest2] = to[i]; auto verts = vertexes; - verts[dest1] = project_vertex(li, vertexes[src1], shadow_length); - verts[dest2] = project_vertex(li, vertexes[src2], shadow_length); + auto s1 = vertexes[src1], s2 = vertexes[src2]; + verts[dest1] = Vector3(s1.x(), s1.y(), 1); + verts[dest2] = Vector3(s2.x(), s2.y(), 1); + constexpr auto scale = Vector3(clip_scale, 1); + constexpr auto start = Vector3(clip_start, 0); for (auto& x : verts) - x = clip_start + x * clip_scale; - add_quad(verts); + x = start + x * scale; + for (auto i = 0uz; i < 4; i++) + alloc_rect() = verts; } } -void lightmap_shader::add_rect(Vector2b neighbor_offset, Pair<Vector2, Vector2> minmax) +void lightmap_shader::add_rect(Vector2 neighbor_offset, Pair<Vector2, Vector2> minmax) { - fm_assert(_light_center && _count != (size_t)-1); - auto [min, max] = minmax; add_rect(neighbor_offset, min, max); } -void lightmap_shader::add_chunk(Vector2b neighbor_offset, chunk& c) +void lightmap_shader::add_chunk(Vector2 neighbor_offset, chunk& c) { add_geometry(neighbor_offset, c); add_entities(neighbor_offset, c); } -void lightmap_shader::add_geometry(Vector2b neighbor_offset, chunk& c) +void lightmap_shader::add_geometry(Vector2 neighbor_offset, chunk& c) { - fm_assert(_light_center && _count != (size_t)-1); - for (auto i = 0uz; i < TILE_COUNT; i++) { auto t = c[i]; @@ -287,10 +383,8 @@ void lightmap_shader::add_geometry(Vector2b neighbor_offset, chunk& c) } } -void lightmap_shader::add_entities(Vector2b neighbor_offset, chunk& c) +void lightmap_shader::add_entities(Vector2 neighbor_offset, chunk& c) { - fm_assert(_light_center && _count != (size_t)-1); - for (const auto& e_ : c.entities()) { const auto& e = *e_; @@ -307,6 +401,7 @@ void lightmap_shader::add_entities(Vector2b neighbor_offset, chunk& c) } } +#if 0 void lightmap_shader::add_quad(const std::array<Vector2, 4>& quad) { fm_debug_assert(_count < buffer_size); @@ -316,7 +411,9 @@ void lightmap_shader::add_quad(const std::array<Vector2, 4>& quad) if (i+1 == buffer_size) [[unlikely]] flush_vertexes(DrawLightmapMode); } +#endif +#if 0 void lightmap_shader::clear_scratch() { _light_center = {}; @@ -329,6 +426,7 @@ void lightmap_shader::clear_accum() _count = (size_t)-1; //framebuffer.fb.clearColor(1, Color4{0, 0, 0, 0}); } +#endif void lightmap_shader::bind() { @@ -337,6 +435,7 @@ void lightmap_shader::bind() framebuffer.fb.bind(); } +#if 0 void lightmap_shader::begin_accum() { fm_assert(!_light_center); @@ -350,15 +449,16 @@ void lightmap_shader::begin_accum() //framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{0}); //framebuffer.fb.clearColor(1, Color4{0, 0, 0, 0}); } - void lightmap_shader::end_accum() { fm_assert(!_light_center); fm_assert(_count == 0); _count = (size_t)-1; } +#endif -void lightmap_shader::begin_light(Vector2b neighbor_offset, const light_s& light) +#if 0 +void lightmap_shader::begin_light(Vector2 neighbor_offset, const light_s& light) { fm_assert(_count == 0 && !_light_center); clear_scratch(); @@ -391,15 +491,18 @@ void lightmap_shader::finish_and_blend_light() { -1, 1 }, /* 2 2--0 */ }}; - using BF = Magnum::GL::Renderer::BlendFunction; + using BF = Magnum::GL::Renderer::BF; + //GL::Renderer::setBlendColor(0x000000ff_rgbf); GL::Renderer::setBlendFunction(BF::One, BF::One); 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); } +#endif +#if 0 GL::Texture2D& lightmap_shader::scratch_texture() { fm_assert(_count == (size_t)-1); @@ -413,6 +516,7 @@ GL::Texture2D& lightmap_shader::accum_texture() fm_debug_assert(framebuffer.accum.id()); return framebuffer.accum; } +#endif bool light_s::operator==(const light_s&) const noexcept = default; diff --git a/shaders/lightmap.frag b/shaders/lightmap.frag index bbf04326..5e380596 100644 --- a/shaders/lightmap.frag +++ b/shaders/lightmap.frag @@ -1,36 +1,37 @@ precision mediump float; -layout (location = 0) uniform vec4 color_intensity; -layout (location = 1) uniform vec2 center; -layout (location = 2) uniform uint falloff; -layout (location = 3) uniform vec2 size; -layout (location = 4) uniform uint mode; -layout (location = 5) uniform sampler2D sampler; +layout (location = 0) uniform sampler2D sampler; +layout (location = 1) uniform vec3 light_color; +layout (location = 2) uniform vec2 size; +layout (location = 3) uniform vec2 center_fragcoord; +layout (location = 4) uniform vec2 center_clip; +layout (location = 5) uniform float intensity; +layout (location = 6) uniform uint mode; +layout (location = 7) uniform uint falloff; out vec4 color; //layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; void main() { - if (mode == 1) // draw + if (mode == 0) { + color = vec4(0, 0, 0, 1); + } + else if (mode == 1) // draw + { + float L = intensity; vec2 pos = gl_FragCoord.xy; - float L = color_intensity.w; - float dist = distance(pos, center); - //float dist = sqrt(tmp.x*tmp.x + tmp.y*tmp.y); + float dist = distance(pos, center_fragcoord); float A = 1; - //attenuation = ((light_dist - dist)**exponent) / (light_dist**exponent) - if (falloff == 0) // linear + if (frag_falloff == 0) // linear A = max(0, (L - dist) / L); - else if (falloff == 2) // quadratic + else if (frag_falloff == 2) // quadratic { float tmp = max(0, L - dist); - A = max(0, tmp*tmp / (L*L)); + A = tmp*tmp / (L*L); } - //I = sqrt(color_intensity.w*1.5)*16; - //dist = sqrt(tmp.x*tmp.x + tmp.y*tmp.y); - //float alpha = 1 - min(1, dist / I); - color = vec4(color_intensity.xyz, A); + color = vec4(light_color, A); } else if (mode == 2) // blend { diff --git a/shaders/lightmap.hpp b/shaders/lightmap.hpp index f5c7d8c1..e48d4b5d 100644 --- a/shaders/lightmap.hpp +++ b/shaders/lightmap.hpp @@ -31,8 +31,6 @@ struct chunk; struct lightmap_shader final : GL::AbstractShaderProgram { - using Position = GL::Attribute<0, Vector2>; - explicit lightmap_shader(); ~lightmap_shader() override; @@ -42,58 +40,115 @@ struct lightmap_shader final : GL::AbstractShaderProgram GL::Texture2D scratch{NoCreate}, accum{NoCreate}; }; - 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(); + struct output final { + GL::Texture2D &scratch, &accum; + }; + +#if 0 +const blend_light = { + equation: {color: gl.FUNC_ADD, alpha: gl.FUNC_ADD}, + function: {color_src:gl.DST_ALPHA, alpha_src:gl.ONE, + color_dst:gl.ONE, alpha_dst:gl.ZERO}, +}; + +// Shadows should only be drawn into the alpha channel and should leave color untouched. +// You could also do this with a write mask if that's supported. +const blend_shadow = { + equation: {color: gl.FUNC_ADD, alpha: gl.FUNC_ADD}, + function: {color_src:gl.ZERO, alpha_src:gl.ZERO, + color_dst:gl.ONE_MINUS_SRC_COLOR, alpha_dst:GL_ONE}, +}; +#endif + + //void begin_light(Vector2 neighbor_offset, const light_s& light); + + void begin_occlusion(); + void end_occlusion(); + void add_chunk(Vector2 neighbor_offset, chunk& c); + void add_entities(Vector2 neighbor_offset, chunk& c); + void add_geometry(Vector2 neighbor_offset, chunk& c); + void add_rect(Vector2 neighbor_offset, Vector2 min, Vector2 max); + void add_rect(Vector2 neighbor_offset, Pair<Vector2, Vector2> minmax); + //void finish_light_only(); + //void finish_and_blend_light(); + struct output output(); + + //GL::Texture2D& scratch_texture(); + //GL::Texture2D& accum_texture(); + //void begin_accum(); + //void end_accum(); void bind(); static constexpr auto max_chunks = Vector2s(8, 8); +#if 0 +layout (location = 0) uniform sampler2D sampler; +layout (location = 1) uniform vec3 light_color; +layout (location = 2) uniform vec2 size; +layout (location = 3) uniform vec2 center_fragcoord; +layout (location = 4) uniform vec2 center_clip; +layout (location = 5) uniform float intensity; +layout (location = 6) uniform uint mode; +layout (location = 7) uniform uint falloff; +#endif + + using Position = GL::Attribute<0, Vector2>; + private: - enum { - ColorIntensityUniform = 0, - CenterUniform = 1, - FalloffUniform = 2, - SizeUniform = 3, - ModeUniform = 4, - SamplerUniform = 5, + enum : Int { + SamplerUniform = 0, + LightColorUniform = 1, + SizeUniform = 2, + CenterFragcoordUniform = 3, + CenterClipUniform = 4, + IntensityUniform = 5, + ModeUniform = 6, + FalloffUniform = 7, }; enum : Int { TextureSampler = 1, }; - enum ShaderMode : uint32_t { + enum ShaderMode : uint32_t + { + DrawShadowsMode = 0, DrawLightmapMode = 1, BlendLightmapMode = 2, }; +#if 0 + _mesh.setCount(6) + .addVertexBuffer(_vertex_buffer, 0, tile_shader::Position{}, + tile_shader::TextureCoordinates{}, tile_shader::Depth{}) + .setIndexBuffer(_index_buffer, 0, GL::MeshIndexType::UnsignedShort); + CORRADE_INTERNAL_ASSERT(_mesh.isIndexed()); +#endif + static Framebuffer make_framebuffer(Vector2i size); - GL::Mesh make_mesh(); - 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 clear_scratch(); - void clear_accum(); + GL::Mesh make_occlusion_mesh(); + void add_light(Vector2 neighbor_offset, const light_s& light); + //void flush_vertexes(ShaderMode mode); + //void add_quad(const std::array<Vector2, 4>& quad); + //void clear_scratch(); + //void clear_accum(); static std::array<UnsignedShort, 6> quad_indexes(size_t N); - static Vector2 project_vertex(Vector2 light, Vector2 vertex, Vector2 length); + GL::Buffer vertex_buf{NoCreate}, index_buf{NoCreate}; // set to {NoCreate} on capacity change + Array<std::array<Vector3, 4>> vertexes; // todo make a contiguous allocation + Array<std::array<UnsignedShort, 6>> indexes; + size_t count = 0, capacity = 0; Framebuffer framebuffer; - Array<std::array<Vector2, 4>> _quads; - Array<std::array<UnsignedShort, 6>> _indexes; - size_t _count = (size_t)-1; - GL::Buffer _vertex_buf{NoCreate}, _index_buf{NoCreate}; - GL::Mesh _mesh{NoCreate}; - Optional<Vector2> _light_center; + GL::Mesh occlusion_mesh{NoCreate}; + static constexpr auto starting_capacity = 1; // todo + + std::array<Vector3, 4> light_vertexes; + GL::Buffer light_vertex_buf{NoCreate}; + GL::Mesh light_mesh{NoCreate}; + + GL::Mesh blend_mesh{NoCreate}; + + [[nodiscard]] std::array<Vector3, 4>& alloc_rect(); }; } // namespace floormat diff --git a/shaders/lightmap.vert b/shaders/lightmap.vert index 21a4d7a9..479add5c 100644 --- a/shaders/lightmap.vert +++ b/shaders/lightmap.vert @@ -1,14 +1,29 @@ precision mediump float; -layout (location = 0) uniform vec4 color_intensity; -layout (location = 1) uniform vec2 center; -layout (location = 2) uniform uint falloff; -layout (location = 3) uniform vec2 size; -layout (location = 4) uniform uint mode; -layout (location = 5) uniform sampler2D sampler; +layout (location = 0) uniform sampler2D sampler; +layout (location = 1) uniform vec3 light_color; +layout (location = 2) uniform vec2 size; +layout (location = 3) uniform vec2 center_fragcoord; +layout (location = 4) uniform vec2 center_clip; +layout (location = 5) uniform float intensity; +layout (location = 6) uniform uint mode; +layout (location = 7) uniform uint falloff; + +layout (location = 0) flat out vec3 frag_color; +layout (location = 1) flat out float frag_intensity; layout (location = 0) in vec2 position; void main() { - gl_Position = vec4(position.x, position.y, 0, 1); + vec2 pos = position.xy; + vec2 dir = pos - center_clip; + float len = length(dir); + if (len > 1e-6) + { + vec2 dir_norm = dir * (1/len); + pos += dir_norm * position.z * 4; + } + gl_Position = vec4(pos, 0, 1); + frag_intensity = color_intensity.a; + frag_falloff = uint(position_falloff.w); } |