From aac2c51bd57123f980b96996b628dd3bdf75d6f8 Mon Sep 17 00:00:00 2001 From: Light Date: Wed, 21 Jul 2021 20:03:39 +0430 Subject: [PATCH] Input - Added 'Input' - Added - The 'MirrorLayer''s ImGuiWindow, "GameView" will not receive/react to input events if the window is not focused --- Engine/src/Engine/Base.h | 13 ++- Engine/src/Engine/Core/Application.cpp | 11 +- Engine/src/Engine/Core/Application.h | 3 + Engine/src/Engine/Input/Input.cpp | 131 ++++++++++++++++++++++++ Engine/src/Engine/Input/Input.h | 48 +++++++++ Engine/src/Engine/Input/InputCodes.h | 136 +++++++++++++++++++++++++ Engine/src/LightEngine.h | 4 + Mirror/src/MirrorLayer.h | 78 ++++++-------- 8 files changed, 371 insertions(+), 53 deletions(-) create mode 100644 Engine/src/Engine/Input/Input.cpp create mode 100644 Engine/src/Engine/Input/Input.h create mode 100644 Engine/src/Engine/Input/InputCodes.h diff --git a/Engine/src/Engine/Base.h b/Engine/src/Engine/Base.h index 333816a..bbfe9ea 100644 --- a/Engine/src/Engine/Base.h +++ b/Engine/src/Engine/Base.h @@ -11,7 +11,7 @@ // version -#define LT_VERSION "0.7.2" +#define LT_VERSION "0.7.4" ///*** [ CHANGE_LOG ] ***/// // -------------------------------------------------------------------- // Note: change log starts from 2021-07-21, the starting version is 0.7.0, @@ -21,6 +21,7 @@ // platforms: 'Windows', 'Linux' [+0.2] // -------------------------------------------------------------------- // +// // 0.7.0: started the change log // // 0.7.1: [ LT_BREAK ] @@ -30,7 +31,7 @@ // - Separated 'FailedAssertion' into 'FailedEngineAssertion' and 'FailedClientAssertion' // - Minor adjustment to the change log // -// 0.7.3: [ Layer ] +// 0.7.3: [ Layer Improvements ] // - Added 'Layer::OnEvent()', 'Layer' now handles an event by itself and doesn't need another class to determine the event's type // // - Added reverse iterators 'rend()' and 'rbegin()' to 'LayerStack' @@ -43,9 +44,15 @@ // // - Fixed a typo where in 'Mirror' where the name of the 'MirrorLayer' was "SandboxLayer" instead of "MirrorLayer" // +// 0.7.4 [ Input ] +// - Added 'Input' +// - - Added +// - The 'MirrorLayer''s ImGuiWindow, "GameView" will not receive/react to input events if the window is not focused +// +// ///*** [ CHANGE_LOG ] ***/// -// platform +// platform #define LT_WIN(x) // windows #define LT_LIN(x) // linux #define LT_MAC(x) // mac diff --git a/Engine/src/Engine/Core/Application.cpp b/Engine/src/Engine/Core/Application.cpp index d38e7fd..786e873 100644 --- a/Engine/src/Engine/Core/Application.cpp +++ b/Engine/src/Engine/Core/Application.cpp @@ -110,14 +110,15 @@ namespace Light { m_Window->GetGfxContext()->GetRenderer()->OnWindowResize((const WindowResizedEvent&)event); } - // user interface + // input if (event.HasCategory(InputEventCategory)) - m_Window->GetGfxContext()->GetUserInterface()->OnInput(event); - - // #todo: add input manager - // ... + m_Input.OnEvent(event); // layers + // return if the event is an input event and 'Input' has disabled the game events + if (event.HasCategory(InputEventCategory) && !m_Input.IsReceivingGameEvents()) + return; + for (auto it = m_LayerStack.rbegin(); it != m_LayerStack.rend(); it++) if ((*it)->OnEvent(event)) return; } diff --git a/Engine/src/Engine/Core/Application.h b/Engine/src/Engine/Core/Application.h index a29c12c..995585a 100644 --- a/Engine/src/Engine/Core/Application.h +++ b/Engine/src/Engine/Core/Application.h @@ -6,6 +6,8 @@ #include "Layer/LayerStack.h" +#include "Input/Input.h" + namespace Light { class Window; @@ -18,6 +20,7 @@ namespace Light { private: std::unique_ptr m_Instrumentor = nullptr; LayerStack m_LayerStack; + Input m_Input; protected: std::unique_ptr m_Window = nullptr; diff --git a/Engine/src/Engine/Input/Input.cpp b/Engine/src/Engine/Input/Input.cpp new file mode 100644 index 0000000..376312f --- /dev/null +++ b/Engine/src/Engine/Input/Input.cpp @@ -0,0 +1,131 @@ +#include "ltpch.h" +#include "Input.h" + +#include "Events/Event.h" +#include "Events/MouseEvents.h" +#include "Events/KeyboardEvents.h" + +#include + +namespace Light { + + Input* Input::s_Context = nullptr; + + Input::Input() + { + LT_ENGINE_ASSERT(!s_Context, "Input::Input: an instance of 'Input' already exists, do not construct this class!"); + s_Context = this; + + RestartInputState(); + } + + void Input::ReceiveUserInterfaceEventsImpl(bool receive, bool toggle /* = false */) + { + m_UserInterfaceEvents = toggle ? !m_UserInterfaceEvents : receive; + } + + void Input::ReceieveGameEventsImpl(bool receive, bool toggle /*= false*/) + { + bool prev = m_GameEvents; + m_GameEvents = toggle ? !m_UserInterfaceEvents : receive; + + if(m_GameEvents != prev) + RestartInputState(); + } + + void Input::RestartInputState() + { + m_KeyboadKeys.fill(false); + m_MouseButtons.fill(false); + + m_MousePosition = glm::vec2(0.0f); + m_MouseDelta = glm::vec2(0.0f); + m_MouseWheelDelta = 0.0f; + } + + void Input::OnEvent(const Event& inputEvent) + { + ImGuiIO& io = ImGui::GetIO(); + switch (inputEvent.GetEventType()) + { + //** MOUSE_EVENTS **// + case EventType::MouseMoved: + { + const MouseMovedEvent& event = (const MouseMovedEvent&)inputEvent; + + if (m_GameEvents) + { + m_MouseDelta = event.GetPosition() - m_MousePosition; + m_MousePosition = event.GetPosition(); + } + + if(m_UserInterfaceEvents) + ImGui::GetIO().MousePos = ImVec2(event.GetX(), event.GetY()); + + return; + } + case EventType::ButtonPressed: + { + const ButtonPressedEvent& event = (const ButtonPressedEvent&)inputEvent; + + if(m_GameEvents) + m_MouseButtons[event.GetButton()] = true; + + if (m_UserInterfaceEvents) + ImGui::GetIO().MouseDown[event.GetButton()] = true; + + return; + } + case EventType::ButtonReleased: + { + const ButtonReleasedEvent& event = (const ButtonReleasedEvent&)inputEvent; + + if (m_GameEvents) + m_MouseButtons[event.GetButton()] = false; + + if (m_UserInterfaceEvents) + ImGui::GetIO().MouseDown[event.GetButton()] = false; + + return; + } + case EventType::WheelScrolled: + { + const WheelScrolledEvent& event = (const WheelScrolledEvent&)inputEvent; + + if (m_GameEvents) + m_MouseWheelDelta = event.GetOffset(); + + if (m_UserInterfaceEvents) + ImGui::GetIO().MouseWheel = event.GetOffset(); + + return; + } + //** MOUSE_EVENTS **// + case EventType::KeyPressed: + { + const KeyPressedEvent& event = (const KeyPressedEvent&)inputEvent; + + if (m_GameEvents) + m_KeyboadKeys[event.GetKey()] = true; + + if (m_UserInterfaceEvents) + ImGui::GetIO().KeysDown[event.GetKey()] = true; + + return; + } + case EventType::KeyReleased: + { + const KeyReleasedEvent& event = (const KeyReleasedEvent&)inputEvent; + + if (m_GameEvents) + m_KeyboadKeys[event.GetKey()] = false; + + if (m_UserInterfaceEvents) + ImGui::GetIO().KeysDown[event.GetKey()] = false; + + return; + } + } + } + +} \ No newline at end of file diff --git a/Engine/src/Engine/Input/Input.h b/Engine/src/Engine/Input/Input.h new file mode 100644 index 0000000..43ef080 --- /dev/null +++ b/Engine/src/Engine/Input/Input.h @@ -0,0 +1,48 @@ +#pragma once + +#include "Base.h" + +#include + +namespace Light { + + class Event; + + class Input + { + private: + static Input* s_Context; + + std::array m_KeyboadKeys; + std::array m_MouseButtons; + + glm::vec2 m_MousePosition; + glm::vec2 m_MouseDelta; + float m_MouseWheelDelta; + + bool m_UserInterfaceEvents = true; + bool m_GameEvents = true; + public: + Input(); + + static inline void ReceiveUserInterfaceEvents(bool receive, bool toggle = false) { s_Context->ReceiveUserInterfaceEventsImpl(receive, toggle); } + static inline void ReceiveGameEvents(bool receive, bool toggle = false) { s_Context->ReceieveGameEventsImpl(receive, toggle); } + + static inline bool GetKeyboardKey(int code) { return s_Context->m_KeyboadKeys[code]; } + static inline bool GetMouseButton(int code) { return s_Context->m_MouseButtons[code]; } + + static inline const glm::vec2& GetMousePosition(int code) { return s_Context->m_MousePosition; } + + void OnEvent(const Event& inputEvent); + + inline bool IsReceivingInputEvents() const { return m_UserInterfaceEvents; } + inline bool IsReceivingGameEvents() const { return m_GameEvents; } + + private: + void ReceiveUserInterfaceEventsImpl(bool receive, bool toggle = false); + void ReceieveGameEventsImpl(bool receive, bool toggle = false); + + void RestartInputState(); + }; + +} \ No newline at end of file diff --git a/Engine/src/Engine/Input/InputCodes.h b/Engine/src/Engine/Input/InputCodes.h new file mode 100644 index 0000000..74d1a22 --- /dev/null +++ b/Engine/src/Engine/Input/InputCodes.h @@ -0,0 +1,136 @@ +#pragma once + +#define MOUSE_BUTTON_1 0 +#define MOUSE_BUTTON_2 1 +#define MOUSE_BUTTON_3 2 +#define MOUSE_BUTTON_4 3 +#define MOUSE_BUTTON_5 4 +#define MOUSE_BUTTON_6 5 +#define MOUSE_BUTTON_7 6 +#define MOUSE_BUTTON_8 7 + +#define MOUSE_BUTTON_LEFT MOUSE_BUTTON_1 +#define MOUSE_BUTTON_RIGHT MOUSE_BUTTON_2 +#define MOUSE_BUTTON_MIDDLE MOUSE_BUTTON_3 + +#define KEY_SPACE 32 +#define KEY_APOSTROPHE 39 /* ' */ +#define KEY_COMMA 44 /* , */ +#define KEY_MINUS 45 /* - */ +#define KEY_PERIOD 46 /* . */ +#define KEY_SLASH 47 /* / */ +#define KEY_0 48 +#define KEY_1 49 +#define KEY_2 50 +#define KEY_3 51 +#define KEY_4 52 +#define KEY_5 53 +#define KEY_6 54 +#define KEY_7 55 +#define KEY_8 56 +#define KEY_9 57 +#define KEY_SEMICOLON 59 /* ; */ +#define KEY_EQUAL 61 /* = */ +#define KEY_A 65 +#define KEY_B 66 +#define KEY_C 67 +#define KEY_D 68 +#define KEY_E 69 +#define KEY_F 70 +#define KEY_G 71 +#define KEY_H 72 +#define KEY_I 73 +#define KEY_J 74 +#define KEY_K 75 +#define KEY_L 76 +#define KEY_M 77 +#define KEY_N 78 +#define KEY_O 79 +#define KEY_P 80 +#define KEY_Q 81 +#define KEY_R 82 +#define KEY_S 83 +#define KEY_T 84 +#define KEY_U 85 +#define KEY_V 86 +#define KEY_W 87 +#define KEY_X 88 +#define KEY_Y 89 +#define KEY_Z 90 +#define KEY_LEFT_BRACKET 91 /* [ */ +#define KEY_BACKSLASH 92 /* \ */ +#define KEY_RIGHT_BRACKET 93 /* ] */ +#define KEY_GRAVE_ACCENT 96 /* ` */ +#define KEY_WORLD_1 161 /* non-US #1 */ +#define KEY_WORLD_2 162 /* non-US #2 */ +#define KEY_ESCAPE 256 +#define KEY_ESC KEY_ESCAPE +#define KEY_ENTER 257 +#define KEY_TAB 258 +#define KEY_BACKSPACE 259 +#define KEY_INSERT 260 +#define KEY_DELETE 261 +#define KEY_RIGHT 262 +#define KEY_LEFT 263 +#define KEY_DOWN 264 +#define KEY_UP 265 +#define KEY_PAGE_UP 266 +#define KEY_PAGE_DOWN 267 +#define KEY_HOME 268 +#define KEY_END 269 +#define KEY_CAPS_LOCK 280 +#define KEY_SCROLL_LOCK 281 +#define KEY_NUM_LOCK 282 +#define KEY_PRINT_SCREEN 283 +#define KEY_PAUSE 284 +#define KEY_F1 290 +#define KEY_F2 291 +#define KEY_F3 292 +#define KEY_F4 293 +#define KEY_F5 294 +#define KEY_F6 295 +#define KEY_F7 296 +#define KEY_F8 297 +#define KEY_F9 298 +#define KEY_F10 299 +#define KEY_F11 300 +#define KEY_F12 301 +#define KEY_F13 302 +#define KEY_F14 303 +#define KEY_F15 304 +#define KEY_F16 305 +#define KEY_F17 306 +#define KEY_F18 307 +#define KEY_F19 308 +#define KEY_F20 309 +#define KEY_F21 310 +#define KEY_F22 311 +#define KEY_F23 312 +#define KEY_F24 313 +#define KEY_F25 314 +#define KEY_KP_0 320 +#define KEY_KP_1 321 +#define KEY_KP_2 322 +#define KEY_KP_3 323 +#define KEY_KP_4 324 +#define KEY_KP_5 325 +#define KEY_KP_6 326 +#define KEY_KP_7 327 +#define KEY_KP_8 328 +#define KEY_KP_9 329 +#define KEY_KP_DECIMAL 330 +#define KEY_KP_DIVIDE 331 +#define KEY_KP_MULTIPLY 332 +#define KEY_KP_SUBTRACT 333 +#define KEY_KP_ADD 334 +#define KEY_KP_ENTER 335 +#define KEY_KP_EQUAL 336 +#define KEY_LEFT_SHIFT 340 +#define KEY_LEFT_CONTROL 341 +#define KEY_LEFT_ALT 342 +#define KEY_LEFT_SUPER 343 +#define KEY_RIGHT_SHIFT 344 +#define KEY_RIGHT_CONTROL 345 +#define KEY_RIGHT_ALT 346 +#define KEY_RIGHT_SUPER 347 +#define KEY_MENU 348 \ No newline at end of file diff --git a/Engine/src/LightEngine.h b/Engine/src/LightEngine.h index f4a4d67..50e1e00 100644 --- a/Engine/src/LightEngine.h +++ b/Engine/src/LightEngine.h @@ -21,6 +21,10 @@ #include "Graphics/Renderer.h" #include "Graphics/Framebuffer.h" +//** INPUT **// +#include "Input/Input.h" +#include "Input/InputCodes.h" + //** LAYER **// #include "Layer/Layer.h" #include "Layer/LayerStack.h" diff --git a/Mirror/src/MirrorLayer.h b/Mirror/src/MirrorLayer.h index f8bea13..e66b098 100644 --- a/Mirror/src/MirrorLayer.h +++ b/Mirror/src/MirrorLayer.h @@ -15,6 +15,8 @@ private: std::shared_ptr m_Framebuffer; + bool m_GameSceneEvents = false; + public: MirrorLayer(const std::string& name) : Light::Layer(name), m_Direction(glm::vec2(0.0f, 0.0f)) @@ -51,59 +53,45 @@ public: void OnUserInterfaceUpdate() { - ImGui::Begin("GameView"); - - static ImVec2 regionAvailPrev = {0, 0}; - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - - if (regionAvail.x != regionAvailPrev.x || regionAvail.y != regionAvailPrev.y) + if (ImGui::Begin("GameView")) { - m_Framebuffer->Resize({ regionAvail.x, regionAvail.y }); - m_Camera->OnResize({ regionAvail.x, regionAvail.y }); - regionAvailPrev = regionAvail; - } + Light::Input::ReceiveGameEvents(ImGui::IsWindowFocused()); - if(Light::GraphicsContext::GetGraphicsAPI() == Light::GraphicsAPI::DirectX) - ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail); - else - ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + static ImVec2 regionAvailPrev = { 0, 0 }; + ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + + if (regionAvail.x != regionAvailPrev.x || regionAvail.y != regionAvailPrev.y) + { + m_Framebuffer->Resize({ regionAvail.x, regionAvail.y }); + m_Camera->OnResize({ regionAvail.x, regionAvail.y }); + regionAvailPrev = regionAvail; + } + + if (Light::GraphicsContext::GetGraphicsAPI() == Light::GraphicsAPI::DirectX) + ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail); + else + ImGui::Image(m_Framebuffer->GetColorAttachment(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + } ImGui::End(); } - bool OnKeyPressed(const Light::KeyPressedEvent& event) override - { - if (event.GetKey() == 65) // GLFW_KEY_A - m_Direction.x += -1.0f; - if(event.GetKey() == 68) // GLFW_KEY_D - m_Direction.x += 1.0f; - - if (event.GetKey() == 87) // GLFW_KEY_W - m_Direction.y += 1.0f; - if (event.GetKey() == 83) // GLFW_KEY_S - m_Direction.y += -1.0f; - - return true; - } - - bool OnKeyReleased(const Light::KeyReleasedEvent& event) override - { - // #todo: add input class - if (event.GetKey() == 65) // GLFW_KEY_A - m_Direction.x -= -1.0f; - if (event.GetKey() == 68) // GLFW_KEY_D - m_Direction.x -= 1.0f; - - if (event.GetKey() == 87) // GLFW_KEY_W - m_Direction.y -= 1.0f; - if (event.GetKey() == 83) // GLFW_KEY_S - m_Direction.y -= -1.0f; - - return true; - } - void OnUpdate(float deltaTime) override { + if (Light::Input::GetKeyboardKey(KEY_A)) + m_Direction.x = -1.0f; + else if (Light::Input::GetKeyboardKey(KEY_D)) + m_Direction.x = 1.0f; + else + m_Direction.x = 0.0f; + + if (Light::Input::GetKeyboardKey(KEY_W)) + m_Direction.y = 1.0f; + else if (Light::Input::GetKeyboardKey(KEY_S)) + m_Direction.y = -1.0f; + else + m_Direction.y = 0.0f; + m_Camera->Move(m_Direction * m_Speed * deltaTime); }