diff options
-rw-r--r-- | editor/app.hpp | 1 | ||||
-rw-r--r-- | editor/imgui.cpp | 27 | ||||
-rw-r--r-- | main/draw.cpp | 46 | ||||
-rw-r--r-- | shaders/lightmap.cpp | 66 | ||||
-rw-r--r-- | shaders/lightmap.frag | 10 | ||||
-rw-r--r-- | shaders/lightmap.hpp | 34 | ||||
-rw-r--r-- | shaders/lightmap.vert | 21 |
7 files changed, 50 insertions, 155 deletions
diff --git a/editor/app.hpp b/editor/app.hpp index 37cdcccf..e0168d68 100644 --- a/editor/app.hpp +++ b/editor/app.hpp @@ -170,6 +170,7 @@ private: bool _render_clickables : 1 = false; bool _render_vobjs : 1 = true; bool _render_all_z_levels : 1 = true; + bool _testing_light : 1 = false; }; } // namespace floormat diff --git a/editor/imgui.cpp b/editor/imgui.cpp index b4b17c88..98e6f598 100644 --- a/editor/imgui.cpp +++ b/editor/imgui.cpp @@ -204,7 +204,6 @@ void app::draw_light_info() void app::draw_lightmap_test() { -#if 0 fm_debug_assert(_tested_light != 0); constexpr auto preview_size = ImVec2{512, 512}; @@ -229,21 +228,31 @@ 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_and_blend_light(); - shader.finish_light_only(); - shader.end_accum(); + if (!_testing_light || true) + { + //constexpr auto chunk_offset = Vector2(lightmap_shader::max_chunks)/2; + Vector2 chunk_offset; + _testing_light = true; + shader.begin_occlusion(); +#if 0 + shader.add_chunk(chunk_offset, e_->chunk()); +#endif + shader.end_occlusion(); + shader.bind(); + shader.add_light(chunk_offset, L); + M->bind(); + } + else + _testing_light = false; //constexpr auto img_size = 1 / Vector2(lightmap_shader::max_chunks); ImGui::Image(&shader.scratch_texture(), preview_size, {0, 0}, {1, 1}); M->bind(); } + else + _testing_light = false; ImGui::End(); if (!is_open) _tested_light = 0; -#endif } static constexpr auto SCENERY_POPUP_NAME = "##scenery-popup"_s; diff --git a/main/draw.cpp b/main/draw.cpp index b21bbc8a..7dacc870 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -123,52 +123,6 @@ auto main_impl::get_draw_bounds() const noexcept -> draw_bounds return {x0, x1, y0, y1}; } -#if 0 -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; - 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; -} - -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]; - ret |= draw_lights_for_chunk(*ns[i], off); - } - ret |= draw_lights_for_chunk(c, {}); - - _lightmap_shader.end_accum(); - return ret; -} -#endif - void main_impl::draw_world() noexcept { const auto [z_min, z_max, z_cur, only] = app.get_z_bounds(); diff --git a/shaders/lightmap.cpp b/shaders/lightmap.cpp index ddfa2f46..a022544a 100644 --- a/shaders/lightmap.cpp +++ b/shaders/lightmap.cpp @@ -29,17 +29,13 @@ constexpr auto chunk_size = TILE_SIZE2 * TILE_MAX_DIM; constexpr auto chunk_offset = TILE_SIZE2/2; constexpr auto image_size = max_neighbors * iTILE_SIZE2 * TILE_MAX_DIM; -constexpr auto buffer_size = 256uz; - -constexpr auto clip_start = Vector2{-1, -1}; +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_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> @@ -90,11 +86,6 @@ auto lightmap_shader::make_framebuffer(Vector2i size) -> Framebuffer return framebuffer; } -auto lightmap_shader::output() -> struct output -{ - return { framebuffer.scratch, framebuffer.accum }; -} - GL::Mesh lightmap_shader::make_occlusion_mesh() { GL::Mesh mesh{GL::MeshPrimitive::Triangles}; @@ -107,6 +98,8 @@ GL::Mesh lightmap_shader::make_occlusion_mesh() void lightmap_shader::begin_occlusion() { count = 0; + framebuffer.fb.clearColor(0, Color4{0, 0, 0, 1}); + framebuffer.fb.clearColor(1, Color4{0, 0, 0, 1}); } void lightmap_shader::end_occlusion() @@ -242,7 +235,7 @@ std::array<UnsignedShort, 6> lightmap_shader::quad_indexes(size_t N) void lightmap_shader::add_light(Vector2 neighbor_offset, const light_s& light) { - Vector2 I; + Vector2 I_clip; switch (light.falloff) { @@ -250,15 +243,14 @@ void lightmap_shader::add_light(Vector2 neighbor_offset, const light_s& light) break; case light_falloff::linear: case light_falloff::quadratic: - I = light.dist * TILE_SIZE2; + I_clip = light.dist * TILE_SIZE2; break; } - I = { std::fmax(1.f, I.x()), std::fmax(1.f, I.y()) }; + I_clip = { std::fmax(1.f, I_clip.x()), std::fmax(1.f, I_clip.y()) }; - auto I_clip = I * TILE_SIZE2; // window-relative coordinates - auto center_fragcoord = light.center + chunk_offset + (neighbor_offset+half_neighbors)*chunk_size; + auto center_fragcoord = light.center + chunk_offset + neighbor_offset*chunk_size; auto center_clip = clip_start + center_fragcoord * clip_scale; // clip coordinates float alpha = light.color.a() / 255.f; @@ -285,24 +277,23 @@ void lightmap_shader::add_light(Vector2 neighbor_offset, const light_s& light) { -I_clip.x() + center_clip.x(), I_clip.y() + center_clip.y(), 0 }, }}; light_vertex_buf.setSubData(0, quad); - draw(light_mesh); - - setUniform(ModeUniform, DrawShadowsMode); + AbstractShaderProgram::draw(light_mesh); + setUniform(LightColorUniform, Color3{0, 0, 0}); fm_assert(occlusion_mesh.id()); auto mesh_view = GL::MeshView{occlusion_mesh}; - mesh_view.setCount((int32_t)count); - draw(mesh_view); + mesh_view.setCount((int32_t)count*6); + AbstractShaderProgram::draw(mesh_view); //mesh_view.setIndexRange(0, 0, uint32_t(count*6 - 1)); setUniform(ModeUniform, BlendLightmapMode); framebuffer.fb.mapForDraw(GL::Framebuffer::ColorAttachment{1}); - draw(blend_mesh); + AbstractShaderProgram::draw(blend_mesh); } void lightmap_shader::add_rect(Vector2 neighbor_offset, Vector2 min, Vector2 max) { - auto off = (neighbor_offset+half_neighbors)*chunk_size + chunk_offset; + auto off = neighbor_offset*chunk_size + chunk_offset; min += off; max += off; @@ -401,33 +392,6 @@ void lightmap_shader::add_entities(Vector2 neighbor_offset, chunk& c) } } -#if 0 -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(DrawLightmapMode); -} -#endif - -#if 0 -void lightmap_shader::clear_scratch() -{ - _light_center = {}; - framebuffer.fb.clearColor(0, Color4{0, 0, 0, 0}); -} - -void lightmap_shader::clear_accum() -{ - fm_assert(!_light_center && _count == (size_t)-1); - _count = (size_t)-1; - //framebuffer.fb.clearColor(1, Color4{0, 0, 0, 0}); -} -#endif - void lightmap_shader::bind() { //fm_assert(_count == 0 && !_light_center); @@ -502,21 +466,17 @@ void lightmap_shader::finish_and_blend_light() } #endif -#if 0 GL::Texture2D& lightmap_shader::scratch_texture() { - fm_assert(_count == (size_t)-1); fm_debug_assert(framebuffer.scratch.id()); return framebuffer.scratch; } GL::Texture2D& lightmap_shader::accum_texture() { - fm_assert(_count == (size_t)-1); 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 5e380596..8865e48e 100644 --- a/shaders/lightmap.frag +++ b/shaders/lightmap.frag @@ -14,19 +14,15 @@ out vec4 color; //layout(origin_upper_left, pixel_center_integer) in vec4 gl_FragCoord; void main() { - if (mode == 0) - { - color = vec4(0, 0, 0, 1); - } - else if (mode == 1) // draw + if (mode == 1) { float L = intensity; vec2 pos = gl_FragCoord.xy; float dist = distance(pos, center_fragcoord); float A = 1; - if (frag_falloff == 0) // linear + if (falloff == 0) // linear A = max(0, (L - dist) / L); - else if (frag_falloff == 2) // quadratic + else if (falloff == 2) // quadratic { float tmp = max(0, L - dist); A = tmp*tmp / (L*L); diff --git a/shaders/lightmap.hpp b/shaders/lightmap.hpp index a5564a9b..8e9b77e2 100644 --- a/shaders/lightmap.hpp +++ b/shaders/lightmap.hpp @@ -40,10 +40,6 @@ struct lightmap_shader final : GL::AbstractShaderProgram GL::Texture2D scratch{NoCreate}, accum{NoCreate}; }; - struct output final { - GL::Texture2D &scratch, &accum; - }; - #if 0 const blend_light = { equation: {color: gl.FUNC_ADD, alpha: gl.FUNC_ADD}, @@ -71,26 +67,13 @@ const blend_shadow = { 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 add_light(Vector2 neighbor_offset, const light_s& light); void bind(); - static constexpr auto max_chunks = Vector2s(8, 8); + GL::Texture2D& scratch_texture(); + GL::Texture2D& accum_texture(); -#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 + static constexpr auto max_chunks = Vector2s(8, 8); using Position = GL::Attribute<0, Vector2>; @@ -117,17 +100,8 @@ private: 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_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(); diff --git a/shaders/lightmap.vert b/shaders/lightmap.vert index 479add5c..900038c4 100644 --- a/shaders/lightmap.vert +++ b/shaders/lightmap.vert @@ -9,21 +9,22 @@ 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) out vec2 frag_texcoords; +//layout (location = 1) flat out vec2 frag_light_coord; -layout (location = 0) in vec2 position; +layout (location = 0) in vec3 position; void main() { vec2 pos = position.xy; - vec2 dir = pos - center_clip; - float len = length(dir); - if (len > 1e-6) + if (mode == 0) { - vec2 dir_norm = dir * (1/len); - pos += dir_norm * position.z * 4; + 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); } |