summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--draw/anim.cpp7
-rw-r--r--draw/anim.hpp2
-rw-r--r--editor/app.cpp2
-rw-r--r--editor/app.hpp2
-rw-r--r--editor/events.cpp1
-rw-r--r--editor/imgui-raii.cpp18
-rw-r--r--editor/imgui-raii.hpp12
-rw-r--r--editor/imgui.cpp87
-rw-r--r--editor/keys.hpp2
-rw-r--r--editor/update.cpp2
-rw-r--r--floormat/main.hpp4
-rw-r--r--main/draw.cpp2
-rw-r--r--main/main-impl.cpp3
-rw-r--r--src/entity.hpp2
-rw-r--r--src/light.cpp1
-rw-r--r--src/light.hpp1
16 files changed, 130 insertions, 18 deletions
diff --git a/draw/anim.cpp b/draw/anim.cpp
index 87003f82..03f6df76 100644
--- a/draw/anim.cpp
+++ b/draw/anim.cpp
@@ -55,7 +55,7 @@ void anim_mesh::add_clickable(tile_shader& shader, const Vector2i& win_size,
}
}
-void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, std::vector<clickable>& list)
+void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, std::vector<clickable>& list, bool draw_vobjs)
{
constexpr auto quad_index_count = 6;
@@ -78,6 +78,7 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, st
fm_assert(x.e);
add_clickable(shader, win_size, x.data.in, x.data, list);
auto& e = *x.e;
+
auto& atlas = *e.atlas;
fm_assert(e.is_dynamic() == (x.mesh_idx == (uint32_t)-1));
if (!e.is_dynamic())
@@ -88,6 +89,10 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, st
}
else
{
+ if (!draw_vobjs) [[likely]]
+ if (e.is_virtual()) [[unlikely]]
+ continue;
+
const auto depth0 = e.depth_offset();
const auto depth = tile_shader::depth_value(e.coord.local(), depth0);
draw(shader, atlas, e.r, e.frame, e.coord.local(), e.offset, depth);
diff --git a/draw/anim.hpp b/draw/anim.hpp
index a7129fe1..ebee14be 100644
--- a/draw/anim.hpp
+++ b/draw/anim.hpp
@@ -26,7 +26,7 @@ struct anim_mesh final
{
anim_mesh();
- void draw(tile_shader& shader, const Vector2i& win_size, chunk& c, std::vector<clickable>& list);
+ void draw(tile_shader& shader, const Vector2i& win_size, chunk& c, std::vector<clickable>& list, bool draw_vobjs);
void draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, const Vector3& pos, float depth);
void draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, local_coords xy, Vector2b offset, float dpeth);
static void add_clickable(tile_shader& shader, const Vector2i& win_size,
diff --git a/editor/app.cpp b/editor/app.cpp
index f2caeaef..f988f230 100644
--- a/editor/app.cpp
+++ b/editor/app.cpp
@@ -25,6 +25,7 @@ app::app(fm_settings&& opts) :
constexpr chunk_coords_ coord{0, 0, 0};
maybe_initialize_chunk_(coord, w[coord]);
reset_camera_offset();
+ M->set_render_vobjs(_render_vobjs);
inspectors.reserve(16);
}
@@ -82,6 +83,7 @@ void app::reset_world(struct world&& w_)
const auto pixel = cursor.pixel;
cursor = {};
_character_id = 0;
+ _render_vobjs = true;
_render_all_z_levels = true;
auto& w = M->reset_world(Utility::move(w_));
diff --git a/editor/app.hpp b/editor/app.hpp
index 51ea0296..b739d34c 100644
--- a/editor/app.hpp
+++ b/editor/app.hpp
@@ -113,6 +113,7 @@ private:
void draw_collision_boxes();
void draw_clickables();
+ void draw_light_info();
void draw_editor_pane(float main_menu_height);
void draw_inspector();
bool check_inspector_exists(const popup_target& p);
@@ -163,6 +164,7 @@ private:
bool _pending_popup : 1 = false;
bool _render_bboxes : 1 = false;
bool _render_clickables : 1 = false;
+ bool _render_vobjs : 1 = true;
bool _render_all_z_levels : 1 = true;
};
diff --git a/editor/events.cpp b/editor/events.cpp
index ed263bdc..b99e5e30 100644
--- a/editor/events.cpp
+++ b/editor/events.cpp
@@ -135,6 +135,7 @@ auto app::resolve_keybinding(int k_, int mods_) -> std::tuple<key, int>
case SDLK_5: return { key_mode_vobj, mods };
case SDLK_c | ALT: return { key_render_collision_boxes, mods };
case SDLK_l | ALT: return { key_render_clickables, mods };
+ case SDLK_v | ALT: return { key_render_vobjs, mods };
case SDLK_t: return { key_render_all_z_levels, mods };
case SDLK_F5: return { key_quicksave, mods };
case SDLK_F9: return { key_quickload, mods };
diff --git a/editor/imgui-raii.cpp b/editor/imgui-raii.cpp
index c348eea6..5396196c 100644
--- a/editor/imgui-raii.cpp
+++ b/editor/imgui-raii.cpp
@@ -13,14 +13,26 @@ font_saver::~font_saver()
ctx.FontBaseSize = font_base_size;
}
-font_saver::font_saver(ImGuiContext& ctx, float size) :
- font_size{ctx.FontSize}, font_base_size{ctx.FontBaseSize}
+font_saver::font_saver(float size) :
+ font_size{ImGui::GetCurrentContext()->FontSize},
+ font_base_size{ImGui::GetCurrentContext()->FontBaseSize}
{
+ auto& ctx = *ImGui::GetCurrentContext();
ctx.FontSize = size;
ctx.FontBaseSize = size;
}
-font_saver::font_saver(float size) : font_saver{*ImGui::GetCurrentContext(), size} {}
+draw_list_font_saver::draw_list_font_saver(float size) :
+ font_size{ImGui::GetForegroundDrawList()->_Data->FontSize}
+{
+ ImGui::GetForegroundDrawList()->_Data->FontSize = size;
+}
+
+draw_list_font_saver::~draw_list_font_saver()
+{
+ ImGui::GetForegroundDrawList()->_Data->FontSize = font_size;
+}
+
style_saver::style_saver() : style{ImGui::GetStyle()} {}
style_saver::~style_saver() { ImGui::GetStyle() = style; }
diff --git a/editor/imgui-raii.hpp b/editor/imgui-raii.hpp
index 05f4239d..3a18f84f 100644
--- a/editor/imgui-raii.hpp
+++ b/editor/imgui-raii.hpp
@@ -58,10 +58,18 @@ struct font_saver final
{
font_saver(float size);
~font_saver();
-private:
- font_saver(ImGuiContext& ctx, float size);
+private:
float font_size, font_base_size;
};
+struct draw_list_font_saver final
+{
+ draw_list_font_saver(float size);
+ ~draw_list_font_saver();
+
+private:
+ float font_size;
+};
+
} // namespace floormat::imgui
diff --git a/editor/imgui.cpp b/editor/imgui.cpp
index b465bc3e..c6a5bff9 100644
--- a/editor/imgui.cpp
+++ b/editor/imgui.cpp
@@ -6,6 +6,7 @@
#include "shaders/shader.hpp"
#include "main/clickable.hpp"
#include "imgui-raii.hpp"
+#include "src/light.hpp"
namespace floormat {
@@ -53,21 +54,24 @@ float app::draw_main_menu()
using m = editor_mode;
const auto* ed_sc = _editor.current_scenery_editor();
const auto* ed_w = _editor.current_tile_editor();
- bool b_none = mode == m::none, b_floor = mode == m::floor, b_walls = mode == m::walls,
- b_scenery = mode == m::scenery, b_vobj = mode == m::vobj, b_collisions = _render_bboxes,
- b_clickables = _render_clickables, b_all_z_levels = _render_all_z_levels;
const bool b_rotate = ed_sc && ed_sc->is_anything_selected() ||
mode == editor_mode::walls && ed_w;
+
+ bool m_none = mode == m::none, m_floor = mode == m::floor, m_walls = mode == m::walls,
+ m_scenery = mode == m::scenery, m_vobjs = mode == m::vobj,
+ b_collisions = _render_bboxes, b_clickables = _render_clickables,
+ b_vobjs = _render_vobjs, b_all_z_levels = _render_all_z_levels;
+
ImGui::SeparatorText("Mode");
- if (ImGui::MenuItem("Select", "1", b_none))
+ if (ImGui::MenuItem("Select", "1", m_none))
do_key(key_mode_none);
- if (ImGui::MenuItem("Floor", "2", b_floor))
+ if (ImGui::MenuItem("Floor", "2", m_floor))
do_key(key_mode_floor);
- if (ImGui::MenuItem("Walls", "3", b_walls))
+ if (ImGui::MenuItem("Walls", "3", m_walls))
do_key(key_mode_walls);
- if (ImGui::MenuItem("Scenery", "4", b_scenery))
+ if (ImGui::MenuItem("Scenery", "4", m_scenery))
do_key(key_mode_scenery);
- if (ImGui::MenuItem("Virtual objects", "5", b_vobj))
+ if (ImGui::MenuItem("Virtual objects", "5", m_vobjs))
do_key(key_mode_vobj);
ImGui::SeparatorText("Modify");
if (ImGui::MenuItem("Rotate", "R", false, b_rotate))
@@ -77,6 +81,8 @@ float app::draw_main_menu()
do_key(key_render_collision_boxes);
if (ImGui::MenuItem("Show clickables", "Alt+L", b_clickables))
do_key(key_render_clickables);
+ if (ImGui::MenuItem("Render virtual objects", "Alt+V", b_vobjs))
+ do_key(key_render_vobjs);
if (ImGui::MenuItem("Show all Z levels", "T", b_all_z_levels))
do_key(key_render_all_z_levels);
}
@@ -101,12 +107,15 @@ void app::draw_ui()
if (_render_clickables)
draw_clickables();
+ if (_render_vobjs)
+ draw_light_info();
const float main_menu_height = draw_main_menu();
[[maybe_unused]] auto font = font_saver{ctx.FontSize*dpi};
if (_editor.current_tile_editor() || _editor.current_scenery_editor() || _editor.current_vobj_editor())
draw_editor_pane(main_menu_height);
draw_fps();
+
draw_tile_under_cursor();
if (_editor.mode() == editor_mode::none)
draw_inspector();
@@ -135,6 +144,65 @@ void app::draw_clickables()
}
}
+void app::draw_light_info()
+{
+ ImDrawList& draw = *ImGui::GetForegroundDrawList();
+ const auto dpi = M->dpi_scale();
+ constexpr float font_size = 12;
+ const auto& style = ImGui::GetStyle();
+ const ImVec2 pad { style.FramePadding.x*.5f, 0 };
+ const auto font_size_ = dpi.sum()*.5f * font_size;
+
+ draw_list_font_saver saver2{font_size_};
+ imgui::font_saver saver{font_size_};
+
+ for (const auto& x : M->clickable_scenery())
+ {
+ if (x.e->type() == entity_type::light)
+ {
+ const auto dest = Math::Range2D<float>(x.dest);
+ const auto& e = static_cast<const light&>(*x.e);
+
+ if (e.id == _popup_target.id) // TODO use z order instead
+ continue;
+
+ StringView falloff;
+ switch (e.falloff)
+ {
+ default: falloff = "?"_s; break;
+ case light_falloff::constant: falloff = "Constant"_s; break;
+ case light_falloff::linear: falloff = "Linear"_s; break;
+ case light_falloff::quadratic: falloff = "Quadratic"_s; break;
+ }
+
+ char dist[32];
+ if (!e.symmetric)
+ snformat(dist, "{{{}, {}}}"_cf, e.half_dist.x(), e.half_dist.y());
+ else
+ snformat(dist, "{}"_cf, e.half_dist.x());
+
+ // todo add rendering color as part of the lightbulb icon
+#if 0
+ char color[8];
+ snformat(color, "{:2X}{:2X}{:2X}"_cf, e.color.x(), e.color.y(), e.color.z());
+#endif
+
+ char buf[128];
+ if (e.falloff == light_falloff::constant)
+ snformat(buf, "{}"_cf, falloff);
+ else
+ snformat(buf, "{} D={}"_cf, falloff, dist);
+ auto text_size = ImGui::CalcTextSize(buf);
+
+ float offy = dest.max().y() + 5 * dpi.y();
+ float offx = dest.min().x() + (dest.max().x() - dest.min().x())*.5f - text_size.x*.5f;
+
+ draw.AddRectFilled({offx-pad.x, offy-pad.y}, {offx + text_size.x + pad.x, offy + text_size.y + pad.y}, ImGui::ColorConvertFloat4ToU32({0, 0, 0, 1}));
+ draw.AddText({offx, offy}, ImGui::ColorConvertFloat4ToU32({1, 1, 0, 1}), buf);
+ }
+ }
+}
+
static constexpr auto SCENERY_POPUP_NAME = "##scenery-popup"_s;
bool app::check_inspector_exists(const popup_target& p)
@@ -174,6 +242,7 @@ void app::do_popup_menu()
if (auto b1 = begin_popup(SCENERY_POPUP_NAME))
{
+ ImGui::BringWindowToDisplayFront(ImGui::GetCurrentWindow());
ImGui::SeparatorText("Setup");
const auto i = e.index();
if (ImGui::MenuItem("Activate", nullptr, false, e.can_activate(i)))
@@ -188,6 +257,8 @@ void app::do_popup_menu()
if (ImGui::MenuItem("Delete", nullptr, false))
e.chunk().remove_entity(e.index());
}
+ else
+ _popup_target = {};
}
void app::kill_popups(bool hard)
diff --git a/editor/keys.hpp b/editor/keys.hpp
index 197cfb9a..79cd695b 100644
--- a/editor/keys.hpp
+++ b/editor/keys.hpp
@@ -18,7 +18,7 @@ enum key : unsigned {
key_NO_REPEAT,
key_rotate_tile,
key_mode_none, key_mode_floor, key_mode_walls, key_mode_scenery, key_mode_vobj,
- key_render_collision_boxes, key_render_clickables, key_render_all_z_levels,
+ key_render_collision_boxes, key_render_clickables, key_render_vobjs, key_render_all_z_levels,
key_GLOBAL,
key_new_file,
key_quit,
diff --git a/editor/update.cpp b/editor/update.cpp
index 5ab588d1..64d6a2a6 100644
--- a/editor/update.cpp
+++ b/editor/update.cpp
@@ -181,6 +181,8 @@ void app::do_key(key k, int mods)
return void(_render_bboxes = !_render_bboxes);
case key_render_clickables:
return void(_render_clickables = !_render_clickables);
+ case key_render_vobjs:
+ return M->set_render_vobjs(_render_vobjs = !_render_vobjs);
case key_render_all_z_levels:
return void(_render_all_z_levels = !_render_all_z_levels);
case key_quicksave:
diff --git a/floormat/main.hpp b/floormat/main.hpp
index 1854010e..95f90610 100644
--- a/floormat/main.hpp
+++ b/floormat/main.hpp
@@ -71,6 +71,9 @@ struct floormat_main
Vector2 dpi_scale() const noexcept { return _dpi_scale; }
static int get_mods() noexcept;
+ void set_render_vobjs(bool value);
+ bool is_rendering_vobjs() const;
+
[[nodiscard]] static floormat_main* create(floormat_app& app, fm_settings&& options);
[[maybe_unused]] static void debug_break();
@@ -78,6 +81,7 @@ protected:
float _frame_time = 0;
Vector2 _dpi_scale{1, 1}, _virtual_scale{1, 1};
Vector2i _framebuffer_size;
+ bool _do_render_vobjs : 1 = true;
};
} // namespace floormat
diff --git a/main/draw.cpp b/main/draw.cpp
index a8bac01c..322f4f66 100644
--- a/main/draw.cpp
+++ b/main/draw.cpp
@@ -171,7 +171,7 @@ void main_impl::draw_world() noexcept
auto& c = *c_;
const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}};
if (check_chunk_visible(_shader.camera_offset(), sz))
- _anim_mesh.draw(_shader, sz, c, _clickable_scenery);
+ _anim_mesh.draw(_shader, sz, c, _clickable_scenery, _do_render_vobjs);
}
_shader.set_tint({1, 1, 1, 1});
diff --git a/main/main-impl.cpp b/main/main-impl.cpp
index f6a3dff0..c774e589 100644
--- a/main/main-impl.cpp
+++ b/main/main-impl.cpp
@@ -46,6 +46,9 @@ Vector2i floormat_main::window_size() const noexcept
return _framebuffer_size;
}
+void floormat_main::set_render_vobjs(bool value) { _do_render_vobjs = value; }
+bool floormat_main::is_rendering_vobjs() const { return _do_render_vobjs; }
+
void main_impl::set_cursor(uint32_t cursor) noexcept
{
if (cursor != _mouse_cursor || _mouse_cursor == (uint32_t)-1)
diff --git a/src/entity.hpp b/src/entity.hpp
index b49999e7..21628a19 100644
--- a/src/entity.hpp
+++ b/src/entity.hpp
@@ -73,7 +73,7 @@ struct entity
entity_type type_of() const noexcept;
static Pair<global_coords, Vector2b> normalize_coords(global_coords coord, Vector2b cur_offset, Vector2i delta);
- bool is_dynamic() const;
+ virtual bool is_dynamic() const;
bool can_rotate(rotation new_r);
bool can_move_to(Vector2i delta);
size_t move_to(size_t& i, Vector2i delta, rotation new_r);
diff --git a/src/light.cpp b/src/light.cpp
index 551e931d..ed7c4ae1 100644
--- a/src/light.cpp
+++ b/src/light.cpp
@@ -40,6 +40,7 @@ Vector2 light::ordinal_offset(Vector2b) const
entity_type light::type() const noexcept { return entity_type::light; }
bool light::update(size_t, float) { return false; }
+bool light::is_dynamic() const { return true; }
bool light::is_virtual() const { return true; }
float light::calc_intensity(float half_dist, light_falloff falloff)
diff --git a/src/light.hpp b/src/light.hpp
index 73d28272..15dbc7c6 100644
--- a/src/light.hpp
+++ b/src/light.hpp
@@ -34,6 +34,7 @@ struct light final : entity
float depth_offset() const override;
entity_type type() const noexcept override;
bool update(size_t i, float dt) override;
+ bool is_dynamic() const override;
bool is_virtual() const override;
static float calc_intensity(float half_dist, light_falloff falloff);