diff options
-rw-r--r-- | draw/anim.cpp | 7 | ||||
-rw-r--r-- | draw/anim.hpp | 2 | ||||
-rw-r--r-- | editor/app.cpp | 2 | ||||
-rw-r--r-- | editor/app.hpp | 2 | ||||
-rw-r--r-- | editor/events.cpp | 1 | ||||
-rw-r--r-- | editor/imgui-raii.cpp | 18 | ||||
-rw-r--r-- | editor/imgui-raii.hpp | 12 | ||||
-rw-r--r-- | editor/imgui.cpp | 87 | ||||
-rw-r--r-- | editor/keys.hpp | 2 | ||||
-rw-r--r-- | editor/update.cpp | 2 | ||||
-rw-r--r-- | floormat/main.hpp | 4 | ||||
-rw-r--r-- | main/draw.cpp | 2 | ||||
-rw-r--r-- | main/main-impl.cpp | 3 | ||||
-rw-r--r-- | src/entity.hpp | 2 | ||||
-rw-r--r-- | src/light.cpp | 1 | ||||
-rw-r--r-- | src/light.hpp | 1 |
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); |