summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--main/app.cpp49
-rw-r--r--main/app.hpp33
-rw-r--r--main/camera.cpp23
-rw-r--r--main/editor.hpp8
-rw-r--r--main/imgui-raii.hpp84
-rw-r--r--main/main.cpp18
-rw-r--r--main/menu.cpp85
-rw-r--r--shaders/tile-shader.cpp2
-rw-r--r--shaders/tile-shader.hpp8
9 files changed, 204 insertions, 106 deletions
diff --git a/main/app.cpp b/main/app.cpp
index e2d51455..9537bf58 100644
--- a/main/app.cpp
+++ b/main/app.cpp
@@ -4,6 +4,8 @@
#include <Magnum/GL/DefaultFramebuffer.h>
#include <Magnum/ImGuiIntegration/Context.h>
#include <Magnum/ImGuiIntegration/Context.hpp>
+#include <SDL_events.h>
+#include <SDL_video.h>
namespace floormat {
@@ -48,12 +50,19 @@ void app::mouseReleaseEvent(Platform::Sdl2Application::MouseEvent& event)
{
if (_imgui.handleMouseReleaseEvent(event))
return event.setAccepted();
+#if 0
+ using Button = Platform::Sdl2Application::MouseEvent::Button;
+ if (event.button() == Button::Left)
+ {
+ }
+#endif
}
void app::mouseMoveEvent(Platform::Sdl2Application::MouseMoveEvent& event)
{
if (_imgui.handleMouseMoveEvent(event))
- return event.setAccepted();
+ return _cursor_pos = {}, event.setAccepted();
+ _cursor_pos = event.position();
}
void app::mouseScrollEvent(Platform::Sdl2Application::MouseScrollEvent& event)
@@ -68,9 +77,47 @@ void app::textInputEvent(Platform::Sdl2Application::TextInputEvent& event)
return keys = {}, event.setAccepted();
}
+void app::anyEvent(SDL_Event& event)
+{
+ if (event.type == SDL_WINDOWEVENT)
+ switch (event.window.event)
+ {
+ case SDL_WINDOWEVENT_FOCUS_LOST:
+ return event_leave();
+ case SDL_WINDOWEVENT_FOCUS_GAINED:
+ return event_enter();
+ case SDL_WINDOWEVENT_LEAVE:
+ return event_mouse_leave();
+ case SDL_WINDOWEVENT_ENTER:
+ return event_mouse_enter();
+ default:
+ printf(""); break; // put breakpoint here
+ }
+}
+
+void app::event_leave()
+{
+ _cursor_pos = std::nullopt;
+}
+
+void app::event_enter()
+{
+
+}
+
+void app::event_mouse_leave()
+{
+ _cursor_pos = std::nullopt;
+}
+
+void app::event_mouse_enter()
+{
+}
+
void app::update(float dt)
{
do_camera(dt);
+ do_menu();
if (keys[key::quit])
Platform::Sdl2Application::exit(0);
}
diff --git a/main/app.hpp b/main/app.hpp
index 7f508de5..0242365c 100644
--- a/main/app.hpp
+++ b/main/app.hpp
@@ -29,6 +29,7 @@ struct app final : Platform::Application
void update(float dt);
void do_camera(float dt);
void reset_camera_offset();
+
void keyPressEvent(KeyEvent& event) override;
void keyReleaseEvent(KeyEvent& event) override;
void mousePressEvent(MouseEvent& event) override;
@@ -36,13 +37,19 @@ struct app final : Platform::Application
void mouseMoveEvent(MouseMoveEvent& event) override;
void mouseScrollEvent(MouseScrollEvent& event) override;
void textInputEvent(TextInputEvent& event) override;
+ void anyEvent(SDL_Event& event) override;
+ void event_leave();
+ void event_enter();
+ void event_mouse_enter();
+ void event_mouse_leave();
+
void do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated);
void draw_chunk(chunk& c);
- void draw_wireframe_quad();
- void draw_wireframe_box();
+ void draw_wireframe_quad(local_coords pt);
+ void draw_wireframe_box(local_coords pt);
void update_window_scale(Vector2i window_size);
void viewportEvent(ViewportEvent& event) override;
- void draw_menu();
+ void do_menu();
void draw_menu_(tile_type& type, float main_menu_height);
void setup_menu();
void display_menu();
@@ -50,6 +57,14 @@ struct app final : Platform::Application
GL::DebugOutput::Severity severity, const std::string& str) const;
void* register_debug_callback();
+ Vector2 pixel_to_tile(Vector2 position) const;
+ void draw_cursor_tile();
+
+ std::optional<Vector2i> _cursor_pos;
+
+ static constexpr Vector2 project(Vector3 pt);
+ static constexpr Vector2 unproject(Vector2 px);
+
enum class key : int {
camera_up, camera_left, camera_right, camera_down, camera_reset,
quit,
@@ -78,4 +93,16 @@ struct app final : Platform::Application
editor_state _editor;
};
+constexpr Vector2 app::project(const Vector3 pt)
+{
+ const float x = -pt[1], y = -pt[0], z = pt[2];
+ return { x-y, (x+y+z*2)*.59f };
+}
+
+constexpr Vector2 app::unproject(const Vector2 px)
+{
+ const float X = px[0], Y = px[1];
+ return { X/2 + 50.f * Y / 59, 50 * Y / 59 - X/2 };
+}
+
} // namespace floormat
diff --git a/main/camera.cpp b/main/camera.cpp
index 967e1496..2bbadd00 100644
--- a/main/camera.cpp
+++ b/main/camera.cpp
@@ -5,7 +5,7 @@ namespace floormat {
void app::do_camera(float dt)
{
- constexpr float pixels_per_second = 512;
+ constexpr float pixels_per_second = 256;
if (keys[key::camera_up])
camera_offset += Vector2(0, 1) * dt * pixels_per_second;
else if (keys[key::camera_down])
@@ -23,7 +23,7 @@ void app::do_camera(float dt)
void app::reset_camera_offset()
{
- camera_offset = _shader.project({TILE_MAX_DIM*TILE_SIZE[0]/2.f, TILE_MAX_DIM*TILE_SIZE[1]/2.f, 0});
+ camera_offset = project({TILE_MAX_DIM*TILE_SIZE[0]/2.f, TILE_MAX_DIM*TILE_SIZE[1]/2.f, 0});
//camera_offset = {};
}
@@ -32,4 +32,23 @@ void app::update_window_scale(Vector2i sz)
_shader.set_scale(Vector2{sz});
}
+Vector2 app::pixel_to_tile(Vector2 position) const
+{
+ const auto px = position - Vector2{windowSize()}*.5f - camera_offset;
+ return unproject(px) / Vector2{TILE_SIZE[0]*.5f, TILE_SIZE[1]*.5f} + Vector2{.5f, .5f};
+}
+
+void app::draw_cursor_tile()
+{
+ if (_cursor_pos)
+ {
+ const auto tile = pixel_to_tile(Vector2(*_cursor_pos));
+ if (std::min(tile[0], tile[1]) >= 0 && std::max(tile[0], tile[1]) < (int)TILE_MAX_DIM)
+ {
+ const auto x = std::uint8_t(tile[0]), y = std::uint8_t(tile[1]);
+ draw_wireframe_quad({x, y});
+ }
+ }
+}
+
} // namespace floormat
diff --git a/main/editor.hpp b/main/editor.hpp
index 1f0a0f72..44149555 100644
--- a/main/editor.hpp
+++ b/main/editor.hpp
@@ -9,7 +9,7 @@
namespace floormat {
enum class editor_mode : unsigned char {
- select, floors, walls,
+ select, floor, walls,
};
struct tile_type final
@@ -60,8 +60,8 @@ struct editor_state final
[[nodiscard]] editor_mode mode() const { return _mode; }
void set_mode(editor_mode mode) { _mode = mode; }
- tile_type& floors() { return _floors; }
- const tile_type& floors() const { return _floors; }
+ tile_type& floor() { return _floor; }
+ const tile_type& floor() const { return _floor; }
editor_state();
@@ -72,7 +72,7 @@ struct editor_state final
editor_state& operator=(editor_state&&) noexcept = default;
private:
- tile_type _floors{editor_mode::floors, "floor"};
+ tile_type _floor{editor_mode::floor, "floor"};
editor_mode _mode = {};
bool _dirty = false;
};
diff --git a/main/imgui-raii.hpp b/main/imgui-raii.hpp
new file mode 100644
index 00000000..931b5189
--- /dev/null
+++ b/main/imgui-raii.hpp
@@ -0,0 +1,84 @@
+#pragma once
+
+#include <Corrade/Containers/StringView.h>
+#include <Magnum/Math/Color.h>
+#include <ImGui.h>
+
+namespace floormat::imgui {
+
+struct raii_wrapper final
+{
+ using F = void(*)(void);
+ raii_wrapper(F fn) : dtor{fn} {}
+ raii_wrapper() = default;
+ ~raii_wrapper() { if (dtor) dtor(); }
+ raii_wrapper(const raii_wrapper&) = delete;
+ raii_wrapper& operator=(const raii_wrapper&) = delete;
+ raii_wrapper& operator=(raii_wrapper&&) = delete;
+ raii_wrapper(raii_wrapper&& other) noexcept : dtor{other.dtor} { other.dtor = nullptr; }
+ inline operator bool() const noexcept { return dtor != nullptr; }
+
+ F dtor = nullptr;
+};
+
+[[nodiscard]] static inline raii_wrapper begin_window(Containers::StringView name = {},
+ ImGuiWindowFlags_ flags = ImGuiWindowFlags_None)
+{
+ if (name.isEmpty())
+ name = "floormat editor";
+ if (ImGui::Begin(name.data(), nullptr, flags))
+ return {&ImGui::End};
+ else
+ return {};
+}
+
+[[nodiscard]] static inline raii_wrapper begin_main_menu()
+{
+ if (ImGui::BeginMainMenuBar())
+ return {&ImGui::EndMainMenuBar};
+ else
+ return {};
+}
+[[nodiscard]] static inline raii_wrapper begin_menu(Containers::StringView name, bool enabled = true)
+{
+ if (ImGui::BeginMenu(name.data(), enabled))
+ return {&ImGui::EndMenu};
+ else
+ return {};
+}
+
+[[nodiscard]] static inline raii_wrapper begin_list_box(Containers::StringView name, ImVec2 size = {})
+{
+ if (ImGui::BeginListBox(name.data(), size))
+ return {&ImGui::EndListBox};
+ else
+ return {};
+}
+
+[[nodiscard]] static inline raii_wrapper tree_node(Containers::StringView name, ImGuiTreeNodeFlags_ flags = ImGuiTreeNodeFlags_None)
+{
+ if (ImGui::TreeNodeEx(name.data(), flags))
+ return {&ImGui::TreePop};
+ else
+ return {};
+}
+
+[[nodiscard]] static inline raii_wrapper push_style_var(ImGuiStyleVar_ var, Vector2 value)
+{
+ ImGui::PushStyleVar(var, {value[0], value[1]});
+ return {[]{ ImGui::PopStyleVar(); }};
+}
+
+[[nodiscard]] static inline raii_wrapper push_style_var(ImGuiStyleVar_ var, float value)
+{
+ ImGui::PushStyleVar(var, value);
+ return {[]{ ImGui::PopStyleVar(); }};
+}
+
+[[nodiscard]] static inline raii_wrapper push_style_color(ImGuiCol_ var, const Color4& value)
+{
+ ImGui::PushStyleColor(var, {value[0], value[1], value[2], value[3]});
+ return {[]{ ImGui::PopStyleColor(); }};
+}
+
+} // namespace floormat::imgui
diff --git a/main/main.cpp b/main/main.cpp
index a5acb0ca..e371713b 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -40,10 +40,9 @@ void app::drawEvent() {
update(dt);
}
+ _shader.set_tint({1, 1, 1, 1});
draw_chunk(_chunk);
- draw_wireframe_quad();
- draw_wireframe_box();
- draw_menu();
+ draw_cursor_tile();
display_menu();
swapBuffers();
@@ -58,30 +57,25 @@ void app::draw_chunk(chunk& c)
_wall_mesh.draw(_shader, c);
}
-void app::draw_wireframe_quad()
+void app::draw_wireframe_quad(local_coords pt)
{
constexpr float LINE_WIDTH = 1;
constexpr auto X = TILE_SIZE[0], Y = TILE_SIZE[1];
- constexpr float N = TILE_MAX_DIM/2.f;
- const Vector3 center {X*N, Y*N, 0};
+ const Vector3 center {X*pt.x, Y*pt.y, 0};
_shader.set_tint({1, 0, 0, 1});
_wireframe_quad.draw(_shader, {center, {TILE_SIZE[0], TILE_SIZE[1]}, LINE_WIDTH});
- _shader.set_tint({1, 1, 1, 1});
}
-void app::draw_wireframe_box()
+void app::draw_wireframe_box(local_coords pt)
{
constexpr float LINE_WIDTH = 1.5;
constexpr auto X = TILE_SIZE[0], Y = TILE_SIZE[1];
- constexpr float N = TILE_MAX_DIM/2.f;
constexpr Vector3 size{TILE_SIZE[0], TILE_SIZE[1], TILE_SIZE[2]*1.5f};
- const Vector3 center1{X*(N+3), Y*(N+2), 0},
- center2{X*(N-2), Y*(N-4), 0};
+ const Vector3 center1{X*pt.x, Y*pt.y, 0};
_shader.set_tint({0, 1, 0, 1});
_wireframe_box.draw(_shader, {center1, size, LINE_WIDTH});
- _wireframe_box.draw(_shader, {center2, size, LINE_WIDTH});
}
} // namespace floormat
diff --git a/main/menu.cpp b/main/menu.cpp
index e5f291af..2874ad96 100644
--- a/main/menu.cpp
+++ b/main/menu.cpp
@@ -1,78 +1,11 @@
#include "app.hpp"
+#include "imgui-raii.hpp"
#include <Magnum/GL/Renderer.h>
#include <Magnum/ImGuiIntegration/Integration.h>
-#include <Magnum/Math/Color.h>
namespace floormat {
-struct raii_wrapper final
-{
- using F = void(*)(void);
- raii_wrapper(F fn) : dtor{fn} {}
- raii_wrapper() = default;
- ~raii_wrapper() { if (dtor) dtor(); }
- raii_wrapper(const raii_wrapper&) = delete;
- raii_wrapper& operator=(const raii_wrapper&) = delete;
- raii_wrapper& operator=(raii_wrapper&&) = delete;
- raii_wrapper(raii_wrapper&& other) noexcept : dtor{other.dtor} { other.dtor = nullptr; }
- inline operator bool() const noexcept { return dtor != nullptr; }
-
- F dtor = nullptr;
-};
-
-constexpr inline const auto* imgui_name = "floormat editor";
-
-[[nodiscard]] static raii_wrapper begin_window(int flags = 0) {
- if (ImGui::Begin(imgui_name, nullptr, flags))
- return {&ImGui::End};
- else
- return {};
-}
-
-[[nodiscard]] static raii_wrapper begin_main_menu() {
- if (ImGui::BeginMainMenuBar())
- return {&ImGui::EndMainMenuBar};
- else
- return {};
-}
-[[nodiscard]] static raii_wrapper begin_menu(Containers::StringView name, bool enabled = true) {
- if (ImGui::BeginMenu(name.data(), enabled))
- return {&ImGui::EndMenu};
- else
- return {};
-}
-
-[[nodiscard]] static raii_wrapper begin_list_box(Containers::StringView name, ImVec2 size = {}) {
- if (ImGui::BeginListBox(name.data(), size))
- return {&ImGui::EndListBox};
- else
- return {};
-}
-
-[[nodiscard]] static raii_wrapper tree_node(Containers::StringView name, ImGuiTreeNodeFlags_ flags = {}) {
- if (ImGui::TreeNodeEx(name.data(), flags))
- return {&ImGui::TreePop};
- else
- return {};
-}
-
-[[nodiscard]] static raii_wrapper push_style_var(ImGuiStyleVar_ var, Vector2 value)
-{
- ImGui::PushStyleVar(var, {value[0], value[1]});
- return {[]{ ImGui::PopStyleVar(); }};
-}
-
-[[nodiscard]] static raii_wrapper push_style_var(ImGuiStyleVar_ var, float value)
-{
- ImGui::PushStyleVar(var, value);
- return {[]{ ImGui::PopStyleVar(); }};
-}
-
-[[nodiscard]] static raii_wrapper push_style_color(ImGuiCol_ var, const Color4& value)
-{
- ImGui::PushStyleColor(var, {value[0], value[1], value[2], value[3]});
- return {[]{ ImGui::PopStyleColor(); }};
-}
+using namespace floormat::imgui;
void app::setup_menu()
{
@@ -90,7 +23,7 @@ void app::display_menu()
GL::Renderer::enable(GL::Renderer::Feature::ScissorTest);
}
-void app::draw_menu()
+void app::do_menu()
{
_imgui.newFrame();
float main_menu_height = 0;
@@ -109,13 +42,13 @@ void app::draw_menu()
if (auto b = begin_menu("Mode"))
{
ImGui::MenuItem("Select", "F1", _editor.mode() == editor_mode::select);
- ImGui::MenuItem("Floors", "F2", _editor.mode() == editor_mode::floors);
+ ImGui::MenuItem("Floor", "F2", _editor.mode() == editor_mode::floor);
ImGui::MenuItem("Walls", "F3", _editor.mode() == editor_mode::walls);
}
main_menu_height = ImGui::GetContentRegionMax().y;
}
- draw_menu_(_editor.floors(), main_menu_height);
+ draw_menu_(_editor.floor(), main_menu_height);
}
void app::draw_menu_(tile_type& type, float main_menu_height)
@@ -138,7 +71,8 @@ void app::draw_menu_(tile_type& type, float main_menu_height)
ImGui::SetNextWindowPos({0, main_menu_height+style.WindowPadding.y});
ImGui::SetNextFrameWantCaptureKeyboard(false);
ImGui::SetNextWindowSize({450, windowSize()[1] - main_menu_height - style.WindowPadding.y});
- if (auto b = begin_window(ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings))
+ if (const auto flags = ImGuiWindowFlags_(ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings);
+ auto b = begin_window({}, flags))
{
const float window_width = ImGui::GetWindowWidth() - 32;
@@ -163,7 +97,8 @@ void app::draw_menu_(tile_type& type, float main_menu_height)
ImGui::Text("%s", buf);
};
const std::size_t N = v->num_tiles().product();
- if (auto b = tree_node(k.data(), ImGuiTreeNodeFlags_(ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Framed)))
+ if (const auto flags = ImGuiTreeNodeFlags_(ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Framed);
+ auto b = tree_node(k.data(), flags))
{
click_event();
add_tile_count();
@@ -175,7 +110,7 @@ void app::draw_menu_(tile_type& type, float main_menu_height)
{
if (i > 0 && i % per_row == 0)
ImGui::NewLine();
- sprintf(buf, "##item_%zu", i);
+ snprintf(buf, sizeof(buf), "##item_%zu", i);
const auto uv = v->texcoords_for_id(i);
ImGui::ImageButton(buf, (void*)&v->texture(), {TILE_SIZE[0]/2, TILE_SIZE[1]/2},
{ uv[3][0], uv[3][1] }, { uv[0][0], uv[0][1] });
diff --git a/shaders/tile-shader.cpp b/shaders/tile-shader.cpp
index b0177997..20b2230f 100644
--- a/shaders/tile-shader.cpp
+++ b/shaders/tile-shader.cpp
@@ -41,7 +41,7 @@ tile_shader& tile_shader::set_camera_offset(Vector2 camera_offset)
CORRADE_INTERNAL_ASSERT(std::fabs(camera_offset[0]) <= std::scalbn(1.f, std::numeric_limits<float>::digits));
CORRADE_INTERNAL_ASSERT(std::fabs(camera_offset[1]) <= std::scalbn(1.f, std::numeric_limits<float>::digits));
if (camera_offset != camera_offset_)
- setUniform(OffsetUniform, camera_offset_ = camera_offset);
+ setUniform(OffsetUniform, 2*(camera_offset_ = camera_offset));
return *this;
}
diff --git a/shaders/tile-shader.hpp b/shaders/tile-shader.hpp
index 0e1e4442..c53dfff5 100644
--- a/shaders/tile-shader.hpp
+++ b/shaders/tile-shader.hpp
@@ -20,8 +20,6 @@ struct tile_shader : GL::AbstractShaderProgram
Vector4 tint() const { return tint_; }
tile_shader& set_tint(const Vector4& tint);
- static constexpr Vector2 project(Vector3 pt);
-
private:
Vector2 scale_, camera_offset_;
Vector4 tint_;
@@ -29,10 +27,4 @@ private:
enum { ScaleUniform = 0, OffsetUniform = 1, TintUniform = 2, };
};
-constexpr Vector2 tile_shader::project(const Vector3 pt)
-{
- float x = -pt[1], y = -pt[0], z = pt[2];
- return { x-y, (x+y+z*2)*.75f };
-}
-
} // namespace floormat