From abf3f27b3d9585508e0780747401497c071b7d3e Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Fri, 24 May 2024 02:40:55 +0400 Subject: [PATCH 01/10] Add editor_window class and a singleton pattern --- src/CMakeLists.txt | 2 ++ src/experimental/editor_window.cpp | 10 ++++++++++ src/experimental/editor_window.hpp | 22 ++++++++++++++++++++++ src/utils.hpp | 23 +++++++++++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 src/experimental/editor_window.cpp create mode 100644 src/experimental/editor_window.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 12947cd..5394965 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -62,6 +62,8 @@ add_library( viewport.cpp window.hpp window.cpp + experimental/editor_window.hpp + experimental/editor_window.cpp experimental/input_system.hpp experimental/input_system.cpp experimental/viewport.hpp diff --git a/src/experimental/editor_window.cpp b/src/experimental/editor_window.cpp new file mode 100644 index 0000000..88a3f11 --- /dev/null +++ b/src/experimental/editor_window.cpp @@ -0,0 +1,10 @@ +#include "experimental/editor_window.hpp" + +namespace experimental +{ + +editor_window::editor_window() { } + +editor_window::~editor_window() { } + +} // namespace experimental diff --git a/src/experimental/editor_window.hpp b/src/experimental/editor_window.hpp new file mode 100644 index 0000000..76ef9c7 --- /dev/null +++ b/src/experimental/editor_window.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "experimental/window.hpp" +#include "utils.hpp" + +namespace experimental +{ + +class editor_window + : public window + , public singleton +{ +public: + ~editor_window(); + +private: + editor_window(); + + friend singleton_t; +}; + +} // namespace experimental diff --git a/src/utils.hpp b/src/utils.hpp index 3f14a66..bae19e4 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -44,3 +44,26 @@ bool rect_contains(glm::vec<2, T, glm::defaultp> top_left, return is_in_range(tl.x, br.x, pos.x) && is_in_range(tl.y, br.y, pos.y); } + +template +class singleton +{ +public: + static std::shared_ptr get() + { + static std::shared_ptr instance = std::shared_ptr(new T()); + return instance; + } + +private: + using singleton_t = singleton; + + singleton() = default; + singleton(const singleton&) = delete; + singleton& operator=(const singleton&) = delete; + singleton(singleton&&) = delete; + singleton& operator=(singleton&&) = delete; + ~singleton() = default; + + friend T; +}; From 06edb368c75e159233742247ebd656fd0a347f32 Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Fri, 24 May 2024 03:11:45 +0400 Subject: [PATCH 02/10] Set window events non-pointer --- src/experimental/window.cpp | 116 +++++++++++++---------------- src/experimental/window.hpp | 6 +- src/main.cpp | 30 ++++---- src/samples/multiple_viewports.cpp | 6 +- src/samples/scene_load.cpp | 6 +- src/samples/viewport.cpp | 6 +- src/samples/window.cpp | 32 ++++---- src/utils.hpp | 11 +-- 8 files changed, 98 insertions(+), 115 deletions(-) diff --git a/src/experimental/window.cpp b/src/experimental/window.cpp index 53ab52b..7a37446 100644 --- a/src/experimental/window.cpp +++ b/src/experimental/window.cpp @@ -8,6 +8,7 @@ #include "experimental/window.hpp" +#include "experimental/editor_window.hpp" #include "experimental/window_events.hpp" #include "input_system.hpp" #include "logging.hpp" @@ -37,10 +38,9 @@ struct window::window_private_data GLFWwindow* _glfw_window_handle { nullptr }; glm::uvec2 _size { 800, 600 }; glm::uvec2 _position { 200, 200 }; - std::shared_ptr _events { nullptr }; + window_events _events; std::vector> _viewports; std::string _title { "Window" }; - bool _is_main_window { false }; bool _can_grab { false }; bool _has_grab { false }; bool _is_input_source { false }; @@ -74,12 +74,6 @@ void window::init() } std::string title = _p->_title; - if (!_main_window) - { - _main_window = shared_from_this(); - _p->_is_main_window = true; - _p->_is_input_source = true; - } glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); glfwWindowHint(GLFW_SAMPLES, 8); @@ -87,12 +81,12 @@ void window::init() glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - _p->_glfw_window_handle = glfwCreateWindow( - static_cast(get_width()), - static_cast(get_height()), - title.c_str(), - nullptr, - _p->_is_main_window ? nullptr : _main_window->_p->_glfw_window_handle); + _p->_glfw_window_handle = + glfwCreateWindow(static_cast(get_width()), + static_cast(get_height()), + title.c_str(), + nullptr, + editor_window::get()->_p->_glfw_window_handle); if (_p->_glfw_window_handle == nullptr) { log()->error("Failed to create GLFW window"); @@ -109,7 +103,7 @@ void window::init() auto _this = static_cast(glfwGetWindowUserPointer(wnd)); glm::uvec2 old_size = _this->_p->_size; _this->_p->_size = { w, h }; - _this->get_events()->resize( + _this->get_events().resize( resize_event(old_size, _this->_p->_size, _this)); }); @@ -119,7 +113,7 @@ void window::init() auto _this = static_cast(glfwGetWindowUserPointer(wnd)); glm::uvec2 old_pos = _this->_p->_position; _this->_p->_position = { xpos, ypos }; - _this->get_events()->move( + _this->get_events().move( move_event(old_pos, _this->_p->_position, _this)); }); @@ -194,9 +188,9 @@ void window::update() if (glfwWindowShouldClose(_p->_glfw_window_handle)) { + get_events().close(close_event(this)); glfwDestroyWindow(_p->_glfw_window_handle); _p->_glfw_window_handle = nullptr; - get_events()->close(close_event(this)); return; } @@ -209,7 +203,7 @@ void window::update() activate(); - get_events()->render(render_event(window_event::type::Render, this)); + get_events().render(render_event(window_event::type::Render, this)); glfwSwapBuffers(_p->_glfw_window_handle); glfwPollEvents(); @@ -255,12 +249,7 @@ std::vector> window::get_viewports() return _p->_viewports; } -std::shared_ptr window::get_events() const -{ - return _p->_events; -} - -std::shared_ptr window::get_main_window() { return _main_window; } +window_events& window::get_events() const { return _p->_events; } void window::setup_mouse_callbacks() { @@ -276,24 +265,25 @@ void window::setup_mouse_enter_callback() [](GLFWwindow* wnd, int entered) { auto _this = static_cast(glfwGetWindowUserPointer(wnd)); - std::shared_ptr events = _this->get_events(); + window_events& events = _this->get_events(); if (entered == 0) { - events->leave(window_event(window_event::type::Leave, _this)); + events.leave(window_event(window_event::type::Leave, _this)); return; } + _this->set_as_input_source(true); glm::dvec2 pos; glfwGetCursorPos(wnd, &pos.x, &pos.y); _this->_p->_mouse_state._position = pos; - events->enter(enter_event(window_event::type::Enter, - _this->_p->_mouse_state._position, - _this->_p->_mouse_state._position, - _this->_p->_mouse_state._position, - 0, - _this->_p->_mouse_state._buttons, - _this->_p->_mouse_state._mods, - _this)); + events.enter(enter_event(window_event::type::Enter, + _this->_p->_mouse_state._position, + _this->_p->_mouse_state._position, + _this->_p->_mouse_state._position, + 0, + _this->_p->_mouse_state._buttons, + _this->_p->_mouse_state._mods, + _this)); }); } @@ -304,7 +294,7 @@ void window::setup_mouse_move_callback() [](GLFWwindow* wnd, double x_position, double y_position) { auto _this = static_cast(glfwGetWindowUserPointer(wnd)); - std::shared_ptr events = _this->get_events(); + window_events& events = _this->get_events(); _this->_p->_mouse_state._position = { x_position, y_position }; if (_this->_p->_mouse_state._buttons) @@ -312,14 +302,14 @@ void window::setup_mouse_move_callback() _this->check_for_drag(); } - events->mouse_move(mouse_event(window_event::type::MouseMove, - _this->_p->_mouse_state._position, - _this->_p->_mouse_state._position, - _this->_p->_mouse_state._position, - 0, - _this->_p->_mouse_state._buttons, - _this->_p->_mouse_state._mods, - _this)); + events.mouse_move(mouse_event(window_event::type::MouseMove, + _this->_p->_mouse_state._position, + _this->_p->_mouse_state._position, + _this->_p->_mouse_state._position, + 0, + _this->_p->_mouse_state._buttons, + _this->_p->_mouse_state._mods, + _this)); if (_this->get_is_input_source()) { @@ -335,21 +325,20 @@ void window::setup_mouse_button_callback() [](GLFWwindow* wnd, int button, int action, int mods) { auto _this = static_cast(glfwGetWindowUserPointer(wnd)); - std::shared_ptr events = _this->get_events(); + window_events& events = _this->get_events(); if (action == GLFW_PRESS) { _this->_p->_mouse_state._press_started_position = _this->_p->_mouse_state._position; _this->_p->_mouse_state._buttons |= (1 << button); - events->mouse_press( - mouse_event(window_event::type::MouseButtonPress, - _this->_p->_mouse_state._position, - _this->_p->_mouse_state._position, - _this->_p->_mouse_state._position, - button, - _this->_p->_mouse_state._buttons, - _this->_p->_mouse_state._mods, - _this)); + events.mouse_press(mouse_event(window_event::type::MouseButtonPress, + _this->_p->_mouse_state._position, + _this->_p->_mouse_state._position, + _this->_p->_mouse_state._position, + button, + _this->_p->_mouse_state._buttons, + _this->_p->_mouse_state._mods, + _this)); if (_this->get_can_grab()) { @@ -360,7 +349,7 @@ void window::setup_mouse_button_callback() { _this->_p->_mouse_state._buttons ^= (1 << button); - events->mouse_release( + events.mouse_release( mouse_event(window_event::type::MouseButtonRelease, _this->_p->_mouse_state._position, _this->_p->_mouse_state._position, @@ -413,19 +402,19 @@ void window::setup_mouse_button_callback() case 1: { event_type = window_event::type::MouseButtonClick; - f = &events->mouse_click; + f = &events.mouse_click; break; } case 2: { event_type = window_event::type::MouseButtonDoubleClick; - f = &events->mouse_double_click; + f = &events.mouse_double_click; break; } case 3: { event_type = window_event::type::MouseButtonTripleClick; - f = &events->mouse_triple_click; + f = &events.mouse_triple_click; break; } default: @@ -461,9 +450,9 @@ void window::setup_mouse_wheel_callback() [](GLFWwindow* wnd, double x_offset, double y_offset) { auto _this = static_cast(glfwGetWindowUserPointer(wnd)); - std::shared_ptr events = _this->get_events(); + window_events& events = _this->get_events(); - events->mouse_scroll(wheel_event( + events.mouse_scroll(wheel_event( window_event::type::MouseWheel, _this->_p->_mouse_state._position, _this->_p->_mouse_state._position, @@ -490,7 +479,6 @@ void window::check_for_drag() void window::configure_input_system() { - _p->_events = std::make_shared(); setup_mouse_callbacks(); glfwSetKeyCallback( @@ -500,7 +488,7 @@ void window::configure_input_system() auto _this = static_cast(glfwGetWindowUserPointer(wnd)); window_event::type type = window_event::type::KeyRelease; - event* f = &_this->_p->_events->key_release; + event* f = &_this->_p->_events.key_release; bool is_repeat = false; _this->_p->_mouse_state._mods = @@ -509,12 +497,12 @@ void window::configure_input_system() if (action == GLFW_PRESS) { type = window_event::type::KeyPress; - f = &_this->_p->_events->key_press; + f = &_this->_p->_events.key_press; } else if (action == GLFW_REPEAT) { type = window_event::type::KeyRepeat; - f = &_this->_p->_events->key_repeat; + f = &_this->_p->_events.key_repeat; is_repeat = true; } (*f)(key_event( @@ -527,6 +515,4 @@ void window::configure_input_system() }); } -std::shared_ptr window::_main_window = nullptr; - } // namespace experimental diff --git a/src/experimental/window.hpp b/src/experimental/window.hpp index 69d1ac1..12487ac 100644 --- a/src/experimental/window.hpp +++ b/src/experimental/window.hpp @@ -55,12 +55,10 @@ class window : public std::enable_shared_from_this void remove_viewport(std::shared_ptr vp); std::vector> get_viewports(); - std::shared_ptr get_events() const; + window_events& get_events() const; event)> on_user_initialize; - static std::shared_ptr get_main_window(); - private: void setup_mouse_callbacks(); @@ -76,8 +74,6 @@ class window : public std::enable_shared_from_this private: struct window_private_data; std::unique_ptr _p { nullptr }; - - static std::shared_ptr _main_window; }; } // namespace experimental diff --git a/src/main.cpp b/src/main.cpp index 61c0842..e12fc97 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ #include "components/text_component.hpp" #include "components/text_renderer_component.hpp" #include "components/walking_component.hpp" +#include "experimental/editor_window.hpp" #include "experimental/input_system.hpp" #include "experimental/viewport.hpp" #include "experimental/window.hpp" @@ -235,25 +236,25 @@ int main(int argc, char** argv) void initMainWindow() { - windows.push_back(std::make_shared()); - auto& wnd = windows.back(); + auto wnd = experimental::editor_window::get(); + windows.push_back(wnd); wnd->init(); wnd->resize(800, 800); - wnd->get_events()->close += [](auto ce) + wnd->get_events().close += [](auto ce) { std::erase(windows, ce.get_sender()->shared_from_this()); }; std::shared_ptr vp = std::make_shared(); vp->initialize(); wnd->add_viewport(vp); main_camera = std::make_shared(); vp->set_camera(main_camera); - wnd->get_events()->resize += + wnd->get_events().resize += [ vp ](auto re) { vp->set_size(re.get_new_size()); }; - wnd->get_events()->render += [ vp ](auto re) + wnd->get_events().render += [ vp ](auto re) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); vp->render(); }; - windows.back()->get_events()->resize += [ vp ](auto re) + wnd->get_events().resize += [ vp ](auto re) { vp->set_size( { re.get_sender()->get_width(), re.get_sender()->get_height() }); @@ -269,11 +270,11 @@ void initViewports() auto wnd = windows.back(); wnd->init(); wnd->resize(400, 1200); - windows[ 0 ]->set_position(windows[ 1 ]->get_position().x + - windows[ 1 ]->get_width(), - windows[ 1 ]->get_position().y); + experimental::editor_window::get()->set_position( + windows[ 1 ]->get_position().x + windows[ 1 ]->get_width(), + windows[ 1 ]->get_position().y); - wnd->get_events()->close += [](auto ce) + wnd->get_events().close += [](auto ce) { std::erase(windows, ce.get_sender()->shared_from_this()); }; for (int i = 0; i < _view_cameras.size(); ++i) @@ -285,7 +286,7 @@ void initViewports() vp->set_camera(cam); cam->set_ortho(true); wnd->add_viewport(vp); - wnd->get_events()->mouse_scroll += [ cam, vp ](auto we) + wnd->get_events().mouse_scroll += [ cam, vp ](auto we) { auto pos = we.get_local_position(); pos.y = we.get_sender()->get_height() - pos.y; @@ -300,7 +301,7 @@ void initViewports() cam->get_transform().get_position() * std::pow(1.2, we.get_delta().y)); }; - windows.back()->get_events()->resize += [ vp, i ](auto re) + windows.back()->get_events().resize += [ vp, i ](auto re) { vp->set_size({ re.get_new_size().x, re.get_new_size().y / 3.0 }); vp->set_position({ 0, re.get_new_size().y / 3.0 * i }); @@ -310,7 +311,7 @@ void initViewports() vp->set_position({ 0, wnd->get_height() / 3.0 * i }); } - windows.back()->get_events()->render += [](auto re) + windows.back()->get_events().render += [](auto re) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); for (auto vp : re.get_sender()->get_viewports()) @@ -333,8 +334,7 @@ void initViewports() void setupMouseEvents() { - experimental::window::get_main_window()->get_events()->mouse_move += - [](auto me) + experimental::editor_window::get()->get_events().mouse_move += [](auto me) { if (me.get_sender()->get_has_grab()) { diff --git a/src/samples/multiple_viewports.cpp b/src/samples/multiple_viewports.cpp index 53606b7..cdff99a 100644 --- a/src/samples/multiple_viewports.cpp +++ b/src/samples/multiple_viewports.cpp @@ -72,10 +72,10 @@ int main(int argc, char** argv) exp_window->set_can_grab(true); - exp_window->get_events()->close += [ &windows ](auto ce) + exp_window->get_events().close += [ &windows ](auto ce) { std::erase(windows, ce.get_sender()->shared_from_this()); }; - exp_window->get_events()->resize += [](auto re) + exp_window->get_events().resize += [](auto re) { auto wnd = re.get_sender(); if (auto vp = wnd->get_viewports()[ 0 ]) @@ -85,7 +85,7 @@ int main(int argc, char** argv) }; int frame_counter = 0; - exp_window->get_events()->render += [ &frame_counter ](auto re) + exp_window->get_events().render += [ &frame_counter ](auto re) { if (frame_counter % 30 == 0) { diff --git a/src/samples/scene_load.cpp b/src/samples/scene_load.cpp index 14d59c5..663ebb1 100644 --- a/src/samples/scene_load.cpp +++ b/src/samples/scene_load.cpp @@ -59,10 +59,10 @@ int main(int argc, char** argv) exp_window->set_can_grab(true); - exp_window->get_events()->close += [ &windows ](auto ce) + exp_window->get_events().close += [ &windows ](auto ce) { std::erase(windows, ce.get_sender()->shared_from_this()); }; - exp_window->get_events()->resize += [](auto re) + exp_window->get_events().resize += [](auto re) { auto wnd = re.get_sender(); if (auto vp = wnd->get_viewports()[ 0 ]) @@ -72,7 +72,7 @@ int main(int argc, char** argv) }; int frame_counter = 0; - exp_window->get_events()->render += [ &frame_counter ](auto re) + exp_window->get_events().render += [ &frame_counter ](auto re) { if (frame_counter % 30 == 0) { diff --git a/src/samples/viewport.cpp b/src/samples/viewport.cpp index 7afee72..38e174d 100644 --- a/src/samples/viewport.cpp +++ b/src/samples/viewport.cpp @@ -65,10 +65,10 @@ int main(int argc, char** argv) exp_window->set_can_grab(true); - exp_window->get_events()->close += [ &windows ](auto ce) + exp_window->get_events().close += [ &windows ](auto ce) { std::erase(windows, ce.get_sender()->shared_from_this()); }; - exp_window->get_events()->resize += [](auto re) + exp_window->get_events().resize += [](auto re) { auto wnd = re.get_sender(); if (auto vp = wnd->get_viewports()[ 0 ]) @@ -78,7 +78,7 @@ int main(int argc, char** argv) }; int frame_counter = 0; - exp_window->get_events()->render += [ &frame_counter ](auto re) + exp_window->get_events().render += [ &frame_counter ](auto re) { if (frame_counter % 30 == 0) { diff --git a/src/samples/window.cpp b/src/samples/window.cpp index fc78ff7..7547d62 100644 --- a/src/samples/window.cpp +++ b/src/samples/window.cpp @@ -3,9 +3,9 @@ #include /* clang-format on */ +#include #include #include -#include #include @@ -40,7 +40,7 @@ int main(int argc, char** argv) exp_window->set_can_grab(true); - exp_window->get_events()->close += [ &windows ](auto ce) + exp_window->get_events().close += [ &windows ](auto ce) { (void)ce; assert(ce.get_sender() != nullptr); @@ -48,14 +48,14 @@ int main(int argc, char** argv) std::erase(windows, ce.get_sender()->shared_from_this()); }; - exp_window->get_events()->leave += [](auto ee) + exp_window->get_events().leave += [](auto ee) { (void)ee; assert(ee.get_sender() != nullptr); log()->info("Cursor left the window"); }; - exp_window->get_events()->enter += [](auto ee) + exp_window->get_events().enter += [](auto ee) { assert(ee.get_sender() != nullptr); log()->info("Cursor entered the window at: {}x{}", @@ -63,7 +63,7 @@ int main(int argc, char** argv) ee.get_local_position().y); }; - exp_window->get_events()->move += [](auto me) + exp_window->get_events().move += [](auto me) { assert(me.get_sender() != nullptr); log()->info("Window moved from: {}x{} to: {}x{}", @@ -73,7 +73,7 @@ int main(int argc, char** argv) me.get_new_position().y); }; - exp_window->get_events()->resize += [](auto re) + exp_window->get_events().resize += [](auto re) { assert(re.get_sender() != nullptr); log()->info("Window resized from: {}x{} to: {}x{}", @@ -83,7 +83,7 @@ int main(int argc, char** argv) re.get_new_size().y); }; - exp_window->get_events()->mouse_move += [](auto me) + exp_window->get_events().mouse_move += [](auto me) { assert(me.get_sender() != nullptr); log()->info("Mouse position: {}x{}", @@ -91,55 +91,55 @@ int main(int argc, char** argv) me.get_local_position().y); }; - exp_window->get_events()->mouse_release += [](auto me) + exp_window->get_events().mouse_release += [](auto me) { assert(me.get_sender() != nullptr); log()->info("Mouse release: {}", me.get_button()); }; - exp_window->get_events()->mouse_press += [](auto me) + exp_window->get_events().mouse_press += [](auto me) { assert(me.get_sender() != nullptr); log()->info("Mouse press: {}", me.get_button()); }; - exp_window->get_events()->mouse_click += [](auto me) + exp_window->get_events().mouse_click += [](auto me) { assert(me.get_sender() != nullptr); log()->info("Mouse click: {}", me.get_button()); }; - exp_window->get_events()->mouse_double_click += [](auto me) + exp_window->get_events().mouse_double_click += [](auto me) { assert(me.get_sender() != nullptr); log()->info("Mouse double click: {}", me.get_button()); }; - exp_window->get_events()->mouse_triple_click += [](auto me) + exp_window->get_events().mouse_triple_click += [](auto me) { assert(me.get_sender() != nullptr); log()->info("Mouse triple click: {}", me.get_button()); }; - exp_window->get_events()->mouse_scroll += [](auto we) + exp_window->get_events().mouse_scroll += [](auto we) { assert(we.get_sender() != nullptr); log()->info("Mouse scroll: {}x{}", we.get_delta().x, we.get_delta().y); }; - exp_window->get_events()->key_press += [](auto ke) + exp_window->get_events().key_press += [](auto ke) { assert(ke.get_sender() != nullptr); log()->info("Key pressed: {}", ke.get_scancode()); }; - exp_window->get_events()->key_repeat += [](auto ke) + exp_window->get_events().key_repeat += [](auto ke) { assert(ke.get_sender() != nullptr); log()->info("Key repeated: {}", ke.get_scancode()); }; - exp_window->get_events()->key_release += [](auto ke) + exp_window->get_events().key_release += [](auto ke) { assert(ke.get_sender() != nullptr); log()->info("Key released: {}", ke.get_scancode()); diff --git a/src/utils.hpp b/src/utils.hpp index bae19e4..7ec94ee 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -49,11 +49,7 @@ template class singleton { public: - static std::shared_ptr get() - { - static std::shared_ptr instance = std::shared_ptr(new T()); - return instance; - } + static std::shared_ptr get() { return _instance; } private: using singleton_t = singleton; @@ -66,4 +62,9 @@ class singleton ~singleton() = default; friend T; + + static std::shared_ptr _instance; }; + +template +std::shared_ptr singleton::_instance = std::shared_ptr(new T()); From a87a68b42fb11e52e5d9f753f47e7305925853ee Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Tue, 28 May 2024 02:18:15 +0400 Subject: [PATCH 03/10] Add grid rendering functionality --- resources/shaders/grid.frag | 27 ++++++++++++++++ resources/shaders/grid.vert | 55 +++++++++++++++++++++++++++++++ resources/standard/grid.shader | 2 ++ src/renderer/renderer_3d.cpp | 59 ++++++++++++++++++++++++++++++++++ src/renderer/renderer_3d.hpp | 8 +++++ 5 files changed, 151 insertions(+) create mode 100644 resources/shaders/grid.frag create mode 100644 resources/shaders/grid.vert create mode 100644 resources/standard/grid.shader diff --git a/resources/shaders/grid.frag b/resources/shaders/grid.frag new file mode 100644 index 0000000..1ab9af2 --- /dev/null +++ b/resources/shaders/grid.frag @@ -0,0 +1,27 @@ +#version 460 core + +in vec2 fragment_position; +flat in int line_segment_index; + +uniform float u_grid_size; +uniform int u_grid_count; + +out vec4 o_color; + +vec3 lighten(vec3 color, float percent) { return color * percent; } + +float is_nth(int i, int n) { return (1 - sign(i % n - .5)) / 2.0; } + +void main() +{ + vec3 color = vec3(0.4); + const float max_distance = (u_grid_count / 4) * u_grid_size; + + float nth = is_nth(abs(line_segment_index), 10); + color = lighten(color, 1.0 + nth * .5); + + float falloff = 1 - distance(fragment_position, vec2(0)) / max_distance; + falloff = clamp(falloff, 0, 1); + + o_color = vec4(color * falloff, 1); +} diff --git a/resources/shaders/grid.vert b/resources/shaders/grid.vert new file mode 100644 index 0000000..61f7476 --- /dev/null +++ b/resources/shaders/grid.vert @@ -0,0 +1,55 @@ +#version 460 core + +layout(location = 0) in vec2 i_vertex_position; + +uniform vec3 u_grid_origin; +uniform mat4 u_model_matrix; +uniform mat4 u_vp_matrix; +uniform float u_grid_size; +uniform int u_grid_count; + +out vec2 fragment_position; +flat out int line_segment_index; + +void main() +{ + const int grid_count_half = u_grid_count / 2; + const int grid_count_quarter = u_grid_count / 4; + + /* + Determine, whether the x and y coordinates should be swapped. + Basically, the upper half number of instances will be used as y axis + grid. + */ + int switch_factor = gl_InstanceID / grid_count_half; + + /* + Calculates the the index of the line in the axis range. Counts from 0. + */ + int index_per_axis = gl_InstanceID % grid_count_half; + + /* + Calculate the displacement across the axis. + */ + int symmetric_index = index_per_axis - grid_count_quarter; + float position_per_axis = symmetric_index * u_grid_size; + + vec2 pos = i_vertex_position; + pos.x = position_per_axis; + + /* + Calculate the length of each line, so that the grid closes complete + */ + pos.y *= u_grid_size * grid_count_quarter; + + /* + Based on the instance id, determine whether this is an x axis or y axis + grid line + */ + pos = mix(pos.xy, pos.yx, switch_factor); + + mat4 mvp = u_vp_matrix * u_model_matrix; + gl_Position = mvp * vec4(pos.x, 0, pos.y, 1); + fragment_position = pos; + line_segment_index = symmetric_index; +} diff --git a/resources/standard/grid.shader b/resources/standard/grid.shader new file mode 100644 index 0000000..f6d8e51 --- /dev/null +++ b/resources/standard/grid.shader @@ -0,0 +1,2 @@ +../shaders/grid.vert +../shaders/grid.frag diff --git a/src/renderer/renderer_3d.cpp b/src/renderer/renderer_3d.cpp index 106dcfb..a100782 100644 --- a/src/renderer/renderer_3d.cpp +++ b/src/renderer/renderer_3d.cpp @@ -9,6 +9,7 @@ #include "graphics_buffer.hpp" #include "material.hpp" #include "mesh.hpp" +#include "shader.hpp" #include "vaomap.hpp" #include "vertex.hpp" @@ -39,3 +40,61 @@ void renderer_3d::draw_mesh(mesh* m, material* mat) GL_UNSIGNED_INT, 0); } + +void renderer_3d::draw_grid(float grid_size, + const glm::mat4& model, + const glm::mat4& view, + const glm::mat4& proj) +{ + auto sp = prof::profile(__FUNCTION__); + std::array line; + line[ 0 ].position() = glm::vec2 { 0, -1 }; + line[ 1 ].position() = glm::vec2 { 0, 1 }; + std::array indices = { 0, 1 }; + + graphics_buffer vbo(graphics_buffer::type::vertex); + graphics_buffer ebo(graphics_buffer::type::index); + + vbo.set_element_count(2); + vbo.set_element_stride(simple_vertex2d::size); + vbo.set_data(line.data()); + + ebo.set_element_count(2); + ebo.set_element_stride(sizeof(unsigned)); + ebo.set_data(indices.data()); + + // TODO: crashes when changing to instance()._vao.activate() + vao_map vao; + if (vao.activate()) + { + glBindBuffer(GL_ARRAY_BUFFER, vbo.get_handle()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo.get_handle()); + + simple_vertex2d::initialize_attributes(); + } + + simple_vertex2d::activate_attributes(); + + constexpr int grid_count = 82; + + auto grid_shader = + asset_manager::default_asset_manager()->get_shader("grid"); + grid_shader->set_uniform("u_grid_count", grid_count); + grid_shader->set_uniform("u_grid_size", grid_size / 2.0f); + grid_shader->set_uniform("u_model_matrix", model); + grid_shader->set_uniform("u_vp_matrix", proj * view); + + grid_shader->use(); + glDrawElementsInstanced(GL_LINES, 2, GL_UNSIGNED_INT, nullptr, grid_count); +} + +renderer_3d& renderer_3d::instance() +{ + if (!_instance) + { + _instance = std::make_unique(); + } + return *_instance; +} + +std::unique_ptr renderer_3d::_instance = nullptr; diff --git a/src/renderer/renderer_3d.hpp b/src/renderer/renderer_3d.hpp index 9ee0b8d..6114e32 100644 --- a/src/renderer/renderer_3d.hpp +++ b/src/renderer/renderer_3d.hpp @@ -11,6 +11,14 @@ class renderer_3d : public renderer public: void draw_mesh(mesh* m, material* mat); + static void draw_grid(float grid_size, + const glm::mat4& model, + const glm::mat4& view, + const glm::mat4& proj); + + static renderer_3d& instance(); + private: vao_map _vao; + static std::unique_ptr _instance; }; From ac756f9c2a96cff0db106f1ed6b8a5cec78728f8 Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Tue, 28 May 2024 02:25:45 +0400 Subject: [PATCH 04/10] Update the editor window to draw grid --- src/experimental/editor_window.cpp | 34 +++++++++++++++++++++++++++++- src/experimental/editor_window.hpp | 7 ++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/experimental/editor_window.cpp b/src/experimental/editor_window.cpp index 88a3f11..09d9446 100644 --- a/src/experimental/editor_window.cpp +++ b/src/experimental/editor_window.cpp @@ -1,10 +1,42 @@ #include "experimental/editor_window.hpp" +#include "asset_manager.hpp" +#include "renderer_3d.hpp" + namespace experimental { -editor_window::editor_window() { } +editor_window::editor_window() +{ + on_user_initialize += [ this ](auto) { initialize(); }; +} editor_window::~editor_window() { } +void editor_window::initialize() +{ + asset_manager::default_asset_manager()->load_asset( + "resources/standard/grid.shader"); + + get_events().key_press += [ this ](auto ke) + { + // control local camera movement + }; + get_events().render += [ this ](auto re) { render_grid(); }; +} + +void editor_window::render_grid() +{ + // TODO: need to calculate from the camera + glm::mat4 view = glm::lookAt({ 5, 5, 5 }, { 0, 0, 0 }, glm::vec3(0, 1, 0)); + glm::mat4 projection = + glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f); + + glViewport(0, 0, get_width(), get_height()); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + renderer_3d::draw_grid(0.3f, glm::identity(), view, projection); +} + } // namespace experimental diff --git a/src/experimental/editor_window.hpp b/src/experimental/editor_window.hpp index 76ef9c7..1423b6b 100644 --- a/src/experimental/editor_window.hpp +++ b/src/experimental/editor_window.hpp @@ -16,7 +16,14 @@ class editor_window private: editor_window(); + void initialize(); + void render_grid(); + friend singleton_t; + +private: + glm::vec3 _camera_position; + glm::vec3 _camera_direction; }; } // namespace experimental From 8de7fe51ce193dca47c1e0745e19369c15850e36 Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Wed, 29 May 2024 01:32:19 +0400 Subject: [PATCH 05/10] Improve editor base view - Set the background color to gray - Fix the fragment shader to control the alpha instead of the color - Set the blending mode to respect the alpha channel --- resources/shaders/grid.frag | 2 +- src/experimental/editor_window.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/shaders/grid.frag b/resources/shaders/grid.frag index 1ab9af2..e180223 100644 --- a/resources/shaders/grid.frag +++ b/resources/shaders/grid.frag @@ -23,5 +23,5 @@ void main() float falloff = 1 - distance(fragment_position, vec2(0)) / max_distance; falloff = clamp(falloff, 0, 1); - o_color = vec4(color * falloff, 1); + o_color = vec4(color, falloff); } diff --git a/src/experimental/editor_window.cpp b/src/experimental/editor_window.cpp index 09d9446..d562fcf 100644 --- a/src/experimental/editor_window.cpp +++ b/src/experimental/editor_window.cpp @@ -34,8 +34,10 @@ void editor_window::render_grid() glViewport(0, 0, get_width(), get_height()); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClearColor(0, 0, 0, 0); + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); renderer_3d::draw_grid(0.3f, glm::identity(), view, projection); } From c821d45f58aab62257b4d9cd6f21c7089f5c0a16 Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Wed, 29 May 2024 02:27:57 +0400 Subject: [PATCH 06/10] Implement simple 3d ray rendering --- resources/shaders/3d_project.vert | 11 ++++++ resources/shaders/simple_coloring.frag | 7 ++++ resources/standard/line.shader | 2 ++ src/renderer/renderer_3d.cpp | 46 ++++++++++++++++++++++++++ src/renderer/renderer_3d.hpp | 6 ++++ 5 files changed, 72 insertions(+) create mode 100644 resources/shaders/3d_project.vert create mode 100644 resources/shaders/simple_coloring.frag create mode 100644 resources/standard/line.shader diff --git a/resources/shaders/3d_project.vert b/resources/shaders/3d_project.vert new file mode 100644 index 0000000..cc0f1b0 --- /dev/null +++ b/resources/shaders/3d_project.vert @@ -0,0 +1,11 @@ +#version 460 core + +layout(location = 0) in vec3 i_vertex_position; + +uniform mat4 u_model_matrix; +uniform mat4 u_vp_matrix; + +void main() +{ + gl_Position = u_vp_matrix * u_model_matrix * vec4(i_vertex_position, 1.0); +} diff --git a/resources/shaders/simple_coloring.frag b/resources/shaders/simple_coloring.frag new file mode 100644 index 0000000..96df5b6 --- /dev/null +++ b/resources/shaders/simple_coloring.frag @@ -0,0 +1,7 @@ +#version 460 core + +uniform vec4 u_color = vec4(1, 0, 1, 1); + +out vec4 o_color; + +void main() { o_color = u_color; } diff --git a/resources/standard/line.shader b/resources/standard/line.shader new file mode 100644 index 0000000..546a370 --- /dev/null +++ b/resources/standard/line.shader @@ -0,0 +1,2 @@ +../shaders/3d_project.vert +../shaders/simple_coloring.frag diff --git a/src/renderer/renderer_3d.cpp b/src/renderer/renderer_3d.cpp index a100782..b9020a7 100644 --- a/src/renderer/renderer_3d.cpp +++ b/src/renderer/renderer_3d.cpp @@ -88,6 +88,52 @@ void renderer_3d::draw_grid(float grid_size, glDrawElementsInstanced(GL_LINES, 2, GL_UNSIGNED_INT, nullptr, grid_count); } +void renderer_3d::draw_ray(const glm::vec3& origin, + const glm::vec3& direction, + float length, + const glm::vec4& color, + const glm::mat4& view, + const glm::mat4& proj) +{ + auto sp = prof::profile(__FUNCTION__); + std::array line; + line[ 0 ].position() = origin; + line[ 1 ].position() = origin + glm::normalize(direction) * length; + std::array indices = { 0, 1 }; + + graphics_buffer vbo(graphics_buffer::type::vertex); + graphics_buffer ebo(graphics_buffer::type::index); + + vbo.set_element_count(2); + vbo.set_element_stride(simple_vertex3d::size); + vbo.set_data(line.data()); + + ebo.set_element_count(2); + ebo.set_element_stride(sizeof(unsigned)); + ebo.set_data(indices.data()); + + // TODO: crashes when changing to instance()._vao.activate() + vao_map vao; + if (vao.activate()) + { + glBindBuffer(GL_ARRAY_BUFFER, vbo.get_handle()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo.get_handle()); + + simple_vertex3d::initialize_attributes(); + } + + simple_vertex3d::activate_attributes(); + + auto line_shader = + asset_manager::default_asset_manager()->get_shader("line"); + line_shader->set_uniform("u_color", color); + line_shader->set_uniform("u_model_matrix", glm::identity()); + line_shader->set_uniform("u_vp_matrix", proj * view); + + line_shader->use(); + glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, nullptr); +} + renderer_3d& renderer_3d::instance() { if (!_instance) diff --git a/src/renderer/renderer_3d.hpp b/src/renderer/renderer_3d.hpp index 6114e32..79cd7fe 100644 --- a/src/renderer/renderer_3d.hpp +++ b/src/renderer/renderer_3d.hpp @@ -15,6 +15,12 @@ class renderer_3d : public renderer const glm::mat4& model, const glm::mat4& view, const glm::mat4& proj); + static void draw_ray(const glm::vec3& origin, + const glm::vec3& direction, + float length, + const glm::vec4& color, + const glm::mat4& view, + const glm::mat4& proj); static renderer_3d& instance(); From f528c9480d17c71ee80bfc7a7d0f3da6f798ac26 Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Wed, 29 May 2024 02:28:20 +0400 Subject: [PATCH 07/10] Add axis rendering in the editor window Add simple camera movement in the editor window --- src/experimental/editor_window.cpp | 71 +++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/experimental/editor_window.cpp b/src/experimental/editor_window.cpp index d562fcf..f9f83ff 100644 --- a/src/experimental/editor_window.cpp +++ b/src/experimental/editor_window.cpp @@ -1,6 +1,7 @@ #include "experimental/editor_window.hpp" #include "asset_manager.hpp" +#include "experimental/input_system.hpp" #include "renderer_3d.hpp" namespace experimental @@ -17,10 +18,47 @@ void editor_window::initialize() { asset_manager::default_asset_manager()->load_asset( "resources/standard/grid.shader"); + asset_manager::default_asset_manager()->load_asset( + "resources/standard/line.shader"); + + _camera_position = { 5, 5, 5 }; - get_events().key_press += [ this ](auto ke) + input_system::on_keypress += [ this ](int keycode) { // control local camera movement + switch (keycode) + { + case GLFW_KEY_D: + { + _camera_position.x += .1; + break; + } + case GLFW_KEY_A: + { + _camera_position.x -= .1; + break; + } + case GLFW_KEY_SPACE: + { + _camera_position.y += .1; + break; + } + case GLFW_KEY_LEFT_CONTROL: + { + _camera_position.y -= .1; + break; + } + case GLFW_KEY_W: + { + _camera_position.z += .1; + break; + } + case GLFW_KEY_S: + { + _camera_position.z -= .1; + break; + } + } }; get_events().render += [ this ](auto re) { render_grid(); }; } @@ -28,7 +66,8 @@ void editor_window::initialize() void editor_window::render_grid() { // TODO: need to calculate from the camera - glm::mat4 view = glm::lookAt({ 5, 5, 5 }, { 0, 0, 0 }, glm::vec3(0, 1, 0)); + glm::mat4 view = + glm::lookAt(_camera_position, { 0, 0, 0 }, glm::vec3(0, 1, 0)); glm::mat4 projection = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f); @@ -38,7 +77,35 @@ void editor_window::render_grid() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + renderer_3d::draw_grid(0.3f, glm::identity(), view, projection); + + unsigned axis_viewport_size = 80; + glViewport(get_width() - axis_viewport_size - 20, + get_height() - axis_viewport_size - 20, + axis_viewport_size, + axis_viewport_size); + view = glm::lookAt(glm::normalize(_camera_position) * 3.0f, + { 0, 0, 0 }, + glm::vec3(0, 1, 0)); + renderer_3d::draw_ray(glm::vec3 { 0, 0, 0 }, + glm::vec3 { 1, 0, 0 }, + 1.0f, + { 1, 0, 0, 1 }, + view, + projection); + renderer_3d::draw_ray(glm::vec3 { 0, 0, 0 }, + glm::vec3 { 0, 1, 0 }, + 1.0f, + { 0, 1, 0, 1 }, + view, + projection); + renderer_3d::draw_ray(glm::vec3 { 0, 0, 0 }, + glm::vec3 { 0, 0, 1 }, + 1.0f, + { 0, 0, 1, 1 }, + view, + projection); } } // namespace experimental From 8049a4fc2048c455fa7d190200fbfcb769ae2651 Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Wed, 29 May 2024 15:27:22 +0400 Subject: [PATCH 08/10] Fix axis rendering based on the camera direction --- src/experimental/editor_window.cpp | 103 +++++++++++++++++++---------- src/experimental/editor_window.hpp | 1 + 2 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/experimental/editor_window.cpp b/src/experimental/editor_window.cpp index f9f83ff..73ddd00 100644 --- a/src/experimental/editor_window.cpp +++ b/src/experimental/editor_window.cpp @@ -1,3 +1,5 @@ +#include + #include "experimental/editor_window.hpp" #include "asset_manager.hpp" @@ -22,54 +24,86 @@ void editor_window::initialize() "resources/standard/line.shader"); _camera_position = { 5, 5, 5 }; + _camera_direction = glm::normalize(glm::vec3 { 1, 1, 1 }); input_system::on_keypress += [ this ](int keycode) { // control local camera movement switch (keycode) { - case GLFW_KEY_D: + // case GLFW_KEY_D: + // { + // _camera_position.x += .1; + // break; + // } + // case GLFW_KEY_A: + // { + // _camera_position.x -= .1; + // break; + // } + // case GLFW_KEY_SPACE: + // { + // _camera_position.y += .1; + // break; + // } + // case GLFW_KEY_LEFT_CONTROL: + // { + // _camera_position.y -= .1; + // break; + // } + case GLFW_KEY_W: { - _camera_position.x += .1; + _camera_position -= _camera_direction * .07f; break; } - case GLFW_KEY_A: + case GLFW_KEY_S: { - _camera_position.x -= .1; + _camera_position += _camera_direction * .07f; break; } - case GLFW_KEY_SPACE: - { - _camera_position.y += .1; - break; } - case GLFW_KEY_LEFT_CONTROL: - { - _camera_position.y -= .1; - break; - } - case GLFW_KEY_W: + }; + get_events().render += [ this ](auto re) { render_grid(); }; + get_events().mouse_move += [ this ](auto me) + { + if (!get_has_grab()) { - _camera_position.z += .1; - break; + _mouse_position = std::nullopt; + return; } - case GLFW_KEY_S: + + if (!_mouse_position) { - _camera_position.z -= .1; - break; - } + _mouse_position = me.get_local_position(); + return; } + + auto diff = me.get_local_position() - _mouse_position.value(); + _mouse_position = me.get_local_position(); + + _camera_direction = + glm::normalize(glm::rotate(glm::rotate(glm::identity(), + glm::radians(diff.x), + glm::vec3(0, 1, 0)), + glm::radians(-diff.y), + glm::vec3(1, 0, 0)) * + _camera_direction); }; - get_events().render += [ this ](auto re) { render_grid(); }; } void editor_window::render_grid() { - // TODO: need to calculate from the camera - glm::mat4 view = - glm::lookAt(_camera_position, { 0, 0, 0 }, glm::vec3(0, 1, 0)); - glm::mat4 projection = - glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f); + auto camera_right = + glm::normalize(glm::cross(_camera_direction, { 0, 1, 0 })); + auto camera_up = + glm::normalize(glm::cross(camera_right, _camera_direction)); + auto inverse_view_from_origin = + glm::mat4(glm::mat3(camera_right, camera_up, _camera_direction)); + auto inverse_view = + glm::translate(glm::identity(), _camera_position) * + inverse_view_from_origin; + auto view = glm::inverse(inverse_view); + auto projection = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f); glViewport(0, 0, get_width(), get_height()); glBindFramebuffer(GL_FRAMEBUFFER, 0); @@ -85,24 +119,23 @@ void editor_window::render_grid() get_height() - axis_viewport_size - 20, axis_viewport_size, axis_viewport_size); - view = glm::lookAt(glm::normalize(_camera_position) * 3.0f, - { 0, 0, 0 }, - glm::vec3(0, 1, 0)); - renderer_3d::draw_ray(glm::vec3 { 0, 0, 0 }, + view = glm::inverse(inverse_view_from_origin); + + renderer_3d::draw_ray(glm::vec3 { -_camera_direction }, glm::vec3 { 1, 0, 0 }, - 1.0f, + 0.3f, { 1, 0, 0, 1 }, view, projection); - renderer_3d::draw_ray(glm::vec3 { 0, 0, 0 }, + renderer_3d::draw_ray(glm::vec3 { -_camera_direction }, glm::vec3 { 0, 1, 0 }, - 1.0f, + 0.3f, { 0, 1, 0, 1 }, view, projection); - renderer_3d::draw_ray(glm::vec3 { 0, 0, 0 }, + renderer_3d::draw_ray(glm::vec3 { -_camera_direction }, glm::vec3 { 0, 0, 1 }, - 1.0f, + 0.3f, { 0, 0, 1, 1 }, view, projection); diff --git a/src/experimental/editor_window.hpp b/src/experimental/editor_window.hpp index 1423b6b..787b2b6 100644 --- a/src/experimental/editor_window.hpp +++ b/src/experimental/editor_window.hpp @@ -24,6 +24,7 @@ class editor_window private: glm::vec3 _camera_position; glm::vec3 _camera_direction; + std::optional _mouse_position; }; } // namespace experimental From 7e8bc16281e2aaa01c6b002e6c11867fbb7904da Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Wed, 29 May 2024 18:00:39 +0400 Subject: [PATCH 09/10] Extract axis rendering as separate function --- src/experimental/editor_window.cpp | 21 ++++++++++++++++++++- src/experimental/editor_window.hpp | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/experimental/editor_window.cpp b/src/experimental/editor_window.cpp index 73ddd00..91658f1 100644 --- a/src/experimental/editor_window.cpp +++ b/src/experimental/editor_window.cpp @@ -63,7 +63,11 @@ void editor_window::initialize() } } }; - get_events().render += [ this ](auto re) { render_grid(); }; + get_events().render += [ this ](auto re) + { + render_grid(); + render_axis(); + }; get_events().mouse_move += [ this ](auto me) { if (!get_has_grab()) @@ -113,6 +117,21 @@ void editor_window::render_grid() glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); renderer_3d::draw_grid(0.3f, glm::identity(), view, projection); +} + +void editor_window::render_axis() +{ + auto camera_right = + glm::normalize(glm::cross(_camera_direction, { 0, 1, 0 })); + auto camera_up = + glm::normalize(glm::cross(camera_right, _camera_direction)); + auto inverse_view_from_origin = + glm::mat4(glm::mat3(camera_right, camera_up, _camera_direction)); + auto inverse_view = + glm::translate(glm::identity(), _camera_position) * + inverse_view_from_origin; + auto view = glm::inverse(inverse_view); + auto projection = glm::perspective(glm::radians(45.0f), 1.0f, 0.1f, 100.0f); unsigned axis_viewport_size = 80; glViewport(get_width() - axis_viewport_size - 20, diff --git a/src/experimental/editor_window.hpp b/src/experimental/editor_window.hpp index 787b2b6..0ae04a2 100644 --- a/src/experimental/editor_window.hpp +++ b/src/experimental/editor_window.hpp @@ -18,6 +18,7 @@ class editor_window void initialize(); void render_grid(); + void render_axis(); friend singleton_t; From b01a4561ad3e2ceed5e4daa44edad7b0fc378149 Mon Sep 17 00:00:00 2001 From: Arsen Gharagyozyan Date: Thu, 30 May 2024 03:05:00 +0400 Subject: [PATCH 10/10] Implement translation transform controls rendering --- resources/meshes/translation_arrow.fbx | Bin 0 -> 16492 bytes resources/standard/basic_lit.shader | 2 + src/renderer/renderer_3d.cpp | 54 +++++++++++++++++++++++++ src/renderer/renderer_3d.hpp | 3 ++ 4 files changed, 59 insertions(+) create mode 100644 resources/meshes/translation_arrow.fbx create mode 100644 resources/standard/basic_lit.shader diff --git a/resources/meshes/translation_arrow.fbx b/resources/meshes/translation_arrow.fbx new file mode 100644 index 0000000000000000000000000000000000000000..ec259a8b6b0f02cdbca374c77f46f603714c70fb GIT binary patch literal 16492 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 Yf0gE?8{RAb`(}D=&7jJpjT6oO4?Hrget_mesh( + "translation_arrow_mesh"); + auto shader = + asset_manager::default_asset_manager()->get_shader("basic_lit"); + + vao_map vao; + if (vao.activate()) + { + glBindBuffer(GL_ARRAY_BUFFER, + arrow_mesh->get_vertex_buffer().get_handle()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, + arrow_mesh->get_index_buffer().get_handle()); + + vertex3d::initialize_attributes(); + } + vertex3d::activate_attributes(); + + shader->set_uniform("u_vp_matrix", proj * view); + shader->set_uniform("u_model_matrix", glm::identity()); + shader->set_uniform("u_color", glm::vec4 { 0.82, 0.33, 0.35, 1.0 }); + shader->use(); + glDrawElements(GL_TRIANGLES, + arrow_mesh->get_index_buffer().get_element_count(), + GL_UNSIGNED_INT, + nullptr); + shader->set_uniform("u_color", glm::vec4 { 0.46, 0.61, 0.11, 1.0 }); + shader->set_uniform("u_model_matrix", + glm::rotate(glm::identity(), + glm::radians(90.0f), + glm::vec3 { 0, 0, 1 })); + shader->use(); + glDrawElements(GL_TRIANGLES, + arrow_mesh->get_index_buffer().get_element_count(), + GL_UNSIGNED_INT, + nullptr); + shader->set_uniform("u_color", glm::vec4 { 0.2, 0.42, 0.64, 1.0 }); + shader->set_uniform("u_model_matrix", + glm::rotate(glm::identity(), + glm::radians(-90.0f), + glm::vec3 { 0, 1, 0 })); + shader->use(); + glDrawElements(GL_TRIANGLES, + arrow_mesh->get_index_buffer().get_element_count(), + GL_UNSIGNED_INT, + nullptr); +} + void renderer_3d::draw_ray(const glm::vec3& origin, const glm::vec3& direction, float length, diff --git a/src/renderer/renderer_3d.hpp b/src/renderer/renderer_3d.hpp index 79cd7fe..b809be0 100644 --- a/src/renderer/renderer_3d.hpp +++ b/src/renderer/renderer_3d.hpp @@ -15,6 +15,9 @@ class renderer_3d : public renderer const glm::mat4& model, const glm::mat4& view, const glm::mat4& proj); + static void render_transform_controls(transform& t, + const glm::mat4& view, + const glm::mat4& proj); static void draw_ray(const glm::vec3& origin, const glm::vec3& direction, float length,