summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-06-10 10:57:53 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-06-10 10:57:53 +0200
commit411b53fd96b3e43960fcd1bf4bfeefe4c5e2f164 (patch)
treeb56da1aee8a89e0582b81bf85098c06f837fc6ed
parentbb70c67f77fbd3a8d1af5d73bad27acf1b986fc6 (diff)
wip
-rw-r--r--editor/app.cpp1
-rw-r--r--editor/app.hpp4
-rw-r--r--editor/imgui.cpp42
-rw-r--r--floormat/main.hpp3
-rw-r--r--main/draw.cpp16
-rw-r--r--main/main-impl.cpp1
-rw-r--r--main/main-impl.hpp5
-rw-r--r--main/setup.cpp2
-rw-r--r--shaders/lightmap.cpp61
9 files changed, 105 insertions, 30 deletions
diff --git a/editor/app.cpp b/editor/app.cpp
index f988f230..fa1c9b76 100644
--- a/editor/app.cpp
+++ b/editor/app.cpp
@@ -78,6 +78,7 @@ void app::reset_world(struct world&& w_)
_editor.on_release();
_editor.clear_selection();
kill_popups(true);
+ _tested_light = 0;
clear_keys();
const auto pixel = cursor.pixel;
diff --git a/editor/app.hpp b/editor/app.hpp
index b739d34c..37cdcccf 100644
--- a/editor/app.hpp
+++ b/editor/app.hpp
@@ -114,6 +114,8 @@ private:
void draw_collision_boxes();
void draw_clickables();
void draw_light_info();
+ void draw_lightmap_test();
+
void draw_editor_pane(float main_menu_height);
void draw_inspector();
bool check_inspector_exists(const popup_target& p);
@@ -159,6 +161,8 @@ private:
cursor_state cursor;
popup_target _popup_target;
+ object_id _tested_light = 0;
+
int8_t _z_level = 0;
bool _pending_popup : 1 = false;
diff --git a/editor/imgui.cpp b/editor/imgui.cpp
index df75501a..5b02d134 100644
--- a/editor/imgui.cpp
+++ b/editor/imgui.cpp
@@ -4,6 +4,7 @@
#include "src/world.hpp"
#include "src/anim-atlas.hpp"
#include "shaders/shader.hpp"
+#include "shaders/lightmap.hpp"
#include "main/clickable.hpp"
#include "imgui-raii.hpp"
#include "src/light.hpp"
@@ -109,6 +110,8 @@ void app::draw_ui()
draw_clickables();
if (_render_vobjs)
draw_light_info();
+ if (_tested_light)
+ draw_lightmap_test();
const float main_menu_height = draw_main_menu();
[[maybe_unused]] auto font = font_saver{ctx.FontSize*dpi};
@@ -197,6 +200,41 @@ void app::draw_light_info()
}
}
+void app::draw_lightmap_test()
+{
+ fm_debug_assert(_tested_light != 0);
+
+ ImGui::SetNextWindowSize({1024, 1024});
+
+ auto& w = M->world();
+ auto L = w.find_entity(_tested_light);
+
+ constexpr auto flags =
+ ImGuiWindowFlags_NoTitleBar |
+ ImGuiWindowFlags_NoResize |
+ ImGuiWindowFlags_NoMove |
+ ImGuiWindowFlags_NoScrollbar;
+
+ if (L && ImGui::Begin("Lightmap", nullptr, flags))
+ {
+ fm_assert(L->type() == entity_type::light);
+ auto& shader = M->lightmap_shader();
+ light_s light {
+ .center = {8 * 64, 8 * 64},
+ .dist = 4,
+ .color = {255, 255, 255},
+ .falloff = light_falloff::linear,
+ };
+ shader.begin({0, 0}, light);
+ shader.end();
+ M->bind();
+ ImGui::Image(&shader.texture(), {1024, 1024});
+ ImGui::End();
+ }
+ else
+ _tested_light = 0;
+}
+
static constexpr auto SCENERY_POPUP_NAME = "##scenery-popup"_s;
bool app::check_inspector_exists(const popup_target& p)
@@ -244,6 +282,10 @@ void app::do_popup_menu()
if (bool b_ins = !check_inspector_exists(_popup_target);
ImGui::MenuItem("Inspect", nullptr, !b_ins, b_ins))
inspectors.push_back(std::exchange(_popup_target, {}));
+ if (bool b_testing = e.id == _tested_light;
+ e.type() == entity_type::light)
+ if (ImGui::MenuItem("Test", nullptr, b_testing))
+ _tested_light = e.id;
ImGui::SeparatorText("Modify");
if (auto next_rot = e.atlas->next_rotation_from(e.r);
ImGui::MenuItem("Rotate", nullptr, false, next_rot != e.r && e.can_rotate(next_rot)))
diff --git a/floormat/main.hpp b/floormat/main.hpp
index 95f90610..b80d92ce 100644
--- a/floormat/main.hpp
+++ b/floormat/main.hpp
@@ -13,6 +13,7 @@ namespace floormat {
struct fm_settings;
struct floormat_app;
struct tile_shader;
+struct lightmap_shader;
struct world;
struct scenery;
struct anim_atlas;
@@ -44,7 +45,9 @@ struct floormat_main
virtual Magnum::Math::Vector2<int> window_size() const noexcept;
virtual tile_shader& shader() noexcept = 0;
+ virtual struct lightmap_shader& lightmap_shader() noexcept = 0;
virtual const tile_shader& shader() const noexcept = 0;
+ virtual void bind() noexcept = 0;
constexpr float smoothed_dt() const noexcept { return _frame_time; }
virtual fm_settings& settings() noexcept = 0;
virtual const fm_settings& settings() const noexcept = 0;
diff --git a/main/draw.cpp b/main/draw.cpp
index 322f4f66..40e438c6 100644
--- a/main/draw.cpp
+++ b/main/draw.cpp
@@ -222,20 +222,22 @@ void main_impl::do_update()
app.update(dt);
}
+void main_impl::bind() noexcept
+{
+ framebuffer.fb.bind();
+}
+
void main_impl::drawEvent()
{
_shader.set_tint({1, 1, 1, 1});
- {
- const auto clear_color = 0x222222ff_rgbaf;
+ const auto clear_color = 0x222222ff_rgbaf;
#ifdef FM_USE_DEPTH32
- framebuffer.fb.clearColor(0, clear_color);
+ framebuffer.fb.clearColor(0, clear_color);
#else
- GL::defaultFramebuffer.clearColor(clear_color);
+ GL::defaultFramebuffer.clearColor(clear_color);
#endif
- draw_world();
- GL::Renderer::disable(GL::Renderer::Feature::DepthTest);
- }
+ draw_world();
app.draw();
GL::Renderer::flush();
diff --git a/main/main-impl.cpp b/main/main-impl.cpp
index c774e589..de9fb45b 100644
--- a/main/main-impl.cpp
+++ b/main/main-impl.cpp
@@ -21,6 +21,7 @@ fm_settings& main_impl::settings() noexcept { return s; }
const fm_settings& main_impl::settings() const noexcept { return s; }
tile_shader& main_impl::shader() noexcept { return _shader; }
const tile_shader& main_impl::shader() const noexcept { return _shader; }
+struct lightmap_shader& main_impl::lightmap_shader() noexcept { return _lightmap_shader; }
bool main_impl::is_text_input_active() const noexcept { return const_cast<main_impl&>(*this).isTextInputActive(); }
void main_impl::start_text_input() noexcept { startTextInput(); }
void main_impl::stop_text_input() noexcept { stopTextInput(); }
diff --git a/main/main-impl.hpp b/main/main-impl.hpp
index f5dc5010..97640d15 100644
--- a/main/main-impl.hpp
+++ b/main/main-impl.hpp
@@ -49,6 +49,8 @@ struct main_impl final : Platform::Sdl2Application, floormat_main
tile_shader& shader() noexcept override;
const tile_shader& shader() const noexcept override;
+ struct lightmap_shader& lightmap_shader() noexcept override;
+
struct world& world() noexcept override;
struct world& reset_world() noexcept override;
struct world& reset_world(struct world&& w) noexcept override;
@@ -78,6 +80,7 @@ struct main_impl final : Platform::Sdl2Application, floormat_main
[[maybe_unused]] void anyEvent(SDL_Event& event) override;
void drawEvent() override;
+ void bind() noexcept override;
void do_update();
void update_window_state();
struct meshes meshes() noexcept override;
@@ -96,7 +99,7 @@ private:
[[maybe_unused]] char _dummy = (register_debug_callback(), '\0');
floormat_app& app; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
tile_shader _shader;
- lightmap_shader _lightmap_shader;
+ struct lightmap_shader _lightmap_shader;
std::vector<clickable> _clickable_scenery;
struct world _world{};
Magnum::Timeline timeline;
diff --git a/main/setup.cpp b/main/setup.cpp
index 569e43bb..93f3b943 100644
--- a/main/setup.cpp
+++ b/main/setup.cpp
@@ -56,7 +56,9 @@ auto main_impl::make_gl_conf(const fm_settings&) -> GLConfiguration
flags |= GLConfiguration::Flag::ForwardCompatible;
return GLConfiguration{}
.setFlags(flags)
+#ifdef FM_USE_DEPTH32
.setDepthBufferSize(0)
+#endif
.setColorBufferSize({8, 8, 8, 0})
.setStencilBufferSize(0);
}
diff --git a/shaders/lightmap.cpp b/shaders/lightmap.cpp
index 8e8e1884..a599cfc9 100644
--- a/shaders/lightmap.cpp
+++ b/shaders/lightmap.cpp
@@ -31,7 +31,7 @@ auto lightmap_shader::make_framebuffer() -> Framebuffer
framebuffer.fb = GL::Framebuffer{{ {}, image_size }};
framebuffer.color = GL::Texture2D{};
- framebuffer.color.setStorage(1, GL::TextureFormat::RGBA8, image_size);
+ framebuffer.color.setStorage(1, GL::TextureFormat::RGB8, image_size);
//framebuffer.depth = GL::Renderbuffer{};
//framebuffer.depth.setStorage(GL::RenderbufferFormat::DepthComponent32F, fb_size);
@@ -80,18 +80,17 @@ lightmap_shader::lightmap_shader() :
void lightmap_shader::flush_vertexes()
{
- // todo
-}
-
-void lightmap_shader::clear()
-{
- framebuffer.fb.clearColor(0, Color4{1.f, 0.f, 1.f, 1.f});
- //framebuffer.fb.clearDepth(0);
-}
-
-void lightmap_shader::bind()
-{
- framebuffer.fb.bind();
+ if (_count > 0)
+ {
+ _index_buf.setSubData(0, ArrayView<std::array<UnsignedShort, 6>>{_indexes, 1});
+ _vertex_buf.setSubData(0, ArrayView<std::array<Vector2, 4>>{_quads, 1});
+
+ GL::MeshView mesh{_mesh};
+ mesh.setCount((int)(6 * _count));
+ mesh.setIndexRange(0, 0, (uint32_t)(_count * 6 - 1));
+ AbstractShaderProgram::draw(mesh);
+ _count = 0;
+ }
}
std::array<UnsignedShort, 6> lightmap_shader::quad_indexes(size_t N)
@@ -106,40 +105,51 @@ std::array<UnsignedShort, 6> lightmap_shader::quad_indexes(size_t N)
void lightmap_shader::add_light(Vector2i neighbor_offset, const light_s& light)
{
fm_debug_assert(_count == 0);
+ fm_debug_assert(_quads.size() > 0);
constexpr auto tile_size = TILE_SIZE2.sum()/2;
constexpr auto scale = 2/chunk_size;
auto dist = std::fmax(0.f, light.dist * tile_size);
+ auto dist_clip = dist * tile_size;
auto center = light.center + chunk_offset + Vector2(neighbor_offset)*chunk_size;
auto center_clip = Vector2{center} * scale; // clip coordinate
constexpr auto image_size_factor = Vector2(image_size) / Vector2(chunk_size);
auto center_fragcoord = center * image_size_factor; // window-relative coordinates
- _indexes[0] = quad_indexes(0);
- _quads[0] = std::array<Vector2, 4>{{
- { dist + center_clip.x(), -dist + center_clip.y() },
- { dist + center_clip.x(), dist + center_clip.y() },
- { -dist + center_clip.x(), -dist + center_clip.y() },
- { -dist + center_clip.x(), dist + center_clip.y() },
+ _indexes[_count] = quad_indexes(0);
+ _quads[_count] = std::array<Vector2, 4>{{
+ { dist_clip + center_clip.x(), -dist_clip + center_clip.y() },
+ { dist_clip + center_clip.x(), dist_clip + center_clip.y() },
+ { -dist_clip + center_clip.x(), -dist_clip + center_clip.y() },
+ { -dist_clip + center_clip.x(), dist_clip + center_clip.y() },
}};
- _index_buf.setSubData(0, ArrayView<std::array<UnsignedShort, 6>>{_indexes, 1});
- _vertex_buf.setSubData(0, ArrayView<std::array<Vector2, 4>>{_quads, 1});
+ _count++;
setUniform(ColorIntensityUniform, Vector4{Vector3{light.color}, dist});
setUniform(CenterUniform, center_fragcoord);
setUniform(FalloffUniform, (uint32_t)light.falloff);
setUniform(SizeUniform, chunk_size);
+}
+lightmap_shader::~lightmap_shader() = default;
+void lightmap_shader::clear()
+{
+ framebuffer.fb.clearColor(0, Color4{1.f, 0.f, 1.f, 1.f});
+ //framebuffer.fb.clearDepth(0);
}
-lightmap_shader::~lightmap_shader() = default;
+void lightmap_shader::bind()
+{
+ framebuffer.fb.bind();
+}
void lightmap_shader::begin(Vector2i neighbor_offset, const light_s& light)
{
fm_assert(_count == 0);
clear();
+ bind();
add_light(neighbor_offset, light);
}
@@ -148,6 +158,13 @@ void lightmap_shader::end()
flush_vertexes();
}
+GL::Texture2D& lightmap_shader::texture()
+{
+ fm_assert(_count == 0);
+ fm_debug_assert(framebuffer.color.id());
+ return framebuffer.color;
+}
+
bool light_s::operator==(const light_s&) const noexcept = default;
} // namespace floormat