From 0a693b72ddc186b7d813a920a4aab71a9d2cc69c Mon Sep 17 00:00:00 2001 From: GeorgH93 Date: Thu, 6 Aug 2020 20:48:17 +0200 Subject: [PATCH] Refactor some code --- openVulkanoCpp/Host/GLFW/InputDeviceGLFW.cpp | 46 ++ openVulkanoCpp/Host/GLFW/InputDeviceGLFW.hpp | 47 +- openVulkanoCpp/Host/GLFW/InputMappingGLFW.hpp | 154 +++--- .../Host/GLFW/InputProviderGLFW.cpp | 148 ++++-- .../Host/GLFW/InputProviderGLFW.hpp | 72 +-- openVulkanoCpp/Host/GLFW/PlatformGLFW.cpp | 52 ++ openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp | 57 +-- openVulkanoCpp/Host/GLFW/WindowGLFW.cpp | 427 ++++++++++++++++ openVulkanoCpp/Host/GLFW/WindowGLFW.hpp | 474 +++--------------- openVulkanoCpp/Input/InputDevice.hpp | 39 +- .../Input/InputDeviceController.hpp | 28 +- openVulkanoCpp/Input/InputDeviceKeyboard.hpp | 27 +- openVulkanoCpp/Input/InputDeviceMouse.cpp | 61 +++ openVulkanoCpp/Input/InputDeviceMouse.hpp | 89 ++-- 14 files changed, 976 insertions(+), 745 deletions(-) create mode 100644 openVulkanoCpp/Host/GLFW/InputDeviceGLFW.cpp create mode 100644 openVulkanoCpp/Host/GLFW/PlatformGLFW.cpp create mode 100644 openVulkanoCpp/Host/GLFW/WindowGLFW.cpp create mode 100644 openVulkanoCpp/Input/InputDeviceMouse.cpp diff --git a/openVulkanoCpp/Host/GLFW/InputDeviceGLFW.cpp b/openVulkanoCpp/Host/GLFW/InputDeviceGLFW.cpp new file mode 100644 index 0000000..b28c14f --- /dev/null +++ b/openVulkanoCpp/Host/GLFW/InputDeviceGLFW.cpp @@ -0,0 +1,46 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "InputDeviceGLFW.hpp" +#include + +namespace openVulkanoCpp::GLFW +{ + void ControllerGLFW::Init(int joystickId) + { + if (GetIndex() != -1) return; + gamepad = glfwJoystickIsGamepad(joystickId); + std::string name = glfwGetJoystickName(joystickId); + if (gamepad) name += " - " + std::string(glfwGetGamepadName(joystickId)); + InputDeviceController::Init(joystickId, name); + if (!gamepad) Logger::INPUT->warn("Joysticks currently are not supported"); + } + + void ControllerGLFW::Tick() + { + if (GetIndex() == -1) return; + if (gamepad) + { + GLFWgamepadstate state; + glfwGetGamepadState(GetIndex(), &state); + for (int i = 0; i < 6; i++) + { + SetAxis(static_cast(i), state.axes[i]); + } + + uint32_t buttonStates = 0; + for (int i = 0; i < 15; i++) + { + buttonStates |= static_cast(state.buttons[i] != 0) << i; + } + SetButtons(buttonStates); + } + else + { + // Joysticks currently are not supported + } + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/GLFW/InputDeviceGLFW.hpp b/openVulkanoCpp/Host/GLFW/InputDeviceGLFW.hpp index 43be00e..f931e07 100644 --- a/openVulkanoCpp/Host/GLFW/InputDeviceGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/InputDeviceGLFW.hpp @@ -1,17 +1,23 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once #include "../../Base/ITickable.hpp" #include "../../Input/InputDeviceKeyboard.hpp" #include "../../Input/InputDeviceMouse.hpp" #include "../../Input/InputDeviceController.hpp" -#include -namespace openVulkanoCpp +namespace openVulkanoCpp::GLFW { class KeyboardGLFW final : public Input::InputDeviceKeyboard { public: KeyboardGLFW() = default; + ~KeyboardGLFW() override = default; using Input::InputDeviceKeyboard::Init; using Input::InputDeviceKeyboard::PreTick; @@ -23,6 +29,7 @@ namespace openVulkanoCpp { public: MouseGLFW() = default; + ~MouseGLFW() override = default; using Input::InputDeviceMouse::Init; using Input::InputDeviceMouse::ClearAxes; @@ -37,40 +44,10 @@ namespace openVulkanoCpp bool gamepad = false;; public: ControllerGLFW() = default; + ~ControllerGLFW() override = default; - void Init(int joystickId) - { - if (GetIndex() != -1) return; - gamepad = glfwJoystickIsGamepad(joystickId); - std::string name = glfwGetJoystickName(joystickId); - if (gamepad) name += " - " + std::string(glfwGetGamepadName(joystickId)); - InputDeviceController::Init(joystickId, name); - if (!gamepad) Logger::INPUT->warn("Joysticks currently are not supported"); - } + void Init(int joystickId); - void Tick() override - { - if (GetIndex() == -1) return; - if (gamepad) - { - GLFWgamepadstate state; - glfwGetGamepadState(GetIndex(), &state); - for (int i = 0; i < 6; i++) - { - SetAxis(static_cast(i), state.axes[i]); - } - - uint32_t buttonStates = 0; - for (int i = 0; i < 15; i++) - { - buttonStates |= static_cast(state.buttons[i] != 0) << i; - } - SetButtons(buttonStates); - } - else - { - // Joysticks currently are not supported - } - } + void Tick() override; }; } \ No newline at end of file diff --git a/openVulkanoCpp/Host/GLFW/InputMappingGLFW.hpp b/openVulkanoCpp/Host/GLFW/InputMappingGLFW.hpp index e62b4fa..c6dcca8 100644 --- a/openVulkanoCpp/Host/GLFW/InputMappingGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/InputMappingGLFW.hpp @@ -1,93 +1,93 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once + #include "../../Input/InputKey.hpp" #include -namespace openVulkanoCpp +namespace openVulkanoCpp::GLFW { - namespace GLFW + struct KeyboardInputMapping { - struct KeyboardInputMapping + int mapping[GLFW_KEY_LAST + 1]; + + constexpr KeyboardInputMapping() : mapping() { - int mapping[GLFW_KEY_LAST + 1]; - - constexpr KeyboardInputMapping() : mapping() + for (int i = 0; i <= GLFW_KEY_LAST; i++) { - for (int i = 0; i <= GLFW_KEY_LAST; i++) - { - int remappedKey = -1; + int remappedKey = -1; - if (i == GLFW_KEY_SPACE) + if (i == GLFW_KEY_SPACE) + { + remappedKey = 62; + } + else if (i >= GLFW_KEY_COMMA && i <= GLFW_KEY_RIGHT_BRACKET) + { + if (i != 58 && i != 60 && i != 62 && i != 63 && i != 64) { remappedKey = i; } - else if (i >= GLFW_KEY_COMMA && i <= GLFW_KEY_RIGHT_BRACKET) - { - if (i != 58 && i != 60 && i != 62 && i != 63 && i != 64) - { - remappedKey = i; - } - } - else if (i == GLFW_KEY_GRAVE_ACCENT) - { - remappedKey = 64; - } - else if (i == GLFW_KEY_WORLD_1) - { - remappedKey = 58; - } - else if (i == GLFW_KEY_WORLD_2) - { - remappedKey = 60; - } - else if (i >= GLFW_KEY_KP_0 && i <= GLFW_KEY_KP_EQUAL) - { - remappedKey = i - 320; - } - else if (i >= GLFW_KEY_NUM_LOCK) - { - remappedKey = 17; - } - else if (i == GLFW_KEY_SPACE) - { - remappedKey = 62; - } - else if (i == GLFW_KEY_APOSTROPHE) - { - remappedKey = 63; - } - else if (i >= GLFW_KEY_ESCAPE && i <= GLFW_KEY_END) - { - remappedKey = i - 238; - } - else if (i >= GLFW_KEY_CAPS_LOCK && i <= GLFW_KEY_SCROLL_LOCK) - { - remappedKey = i - 248; - } - else if (i >= GLFW_KEY_PRINT_SCREEN && i <= GLFW_KEY_PAUSE) - { - remappedKey = i - 249; - } - else if (i >= GLFW_KEY_LEFT_SHIFT && i <= GLFW_KEY_RIGHT_SUPER) - { - remappedKey = i - 304; - } - else if (i == GLFW_KEY_MENU) - { - remappedKey = 99; - } - else if (i >= GLFW_KEY_F1 && i <= GLFW_KEY_F25) - { - remappedKey = i - 189; - } - mapping[i] = remappedKey; } + else if (i == GLFW_KEY_GRAVE_ACCENT) + { + remappedKey = 64; + } + else if (i == GLFW_KEY_WORLD_1) + { + remappedKey = 58; + } + else if (i == GLFW_KEY_WORLD_2) + { + remappedKey = 60; + } + else if (i >= GLFW_KEY_KP_0 && i <= GLFW_KEY_KP_EQUAL) + { + remappedKey = i - 320; + } + else if (i >= GLFW_KEY_NUM_LOCK) + { + remappedKey = 17; + } + else if (i == GLFW_KEY_APOSTROPHE) + { + remappedKey = 63; + } + else if (i >= GLFW_KEY_ESCAPE && i <= GLFW_KEY_END) + { + remappedKey = i - 238; + } + else if (i >= GLFW_KEY_CAPS_LOCK && i <= GLFW_KEY_SCROLL_LOCK) + { + remappedKey = i - 248; + } + else if (i >= GLFW_KEY_PRINT_SCREEN && i <= GLFW_KEY_PAUSE) + { + remappedKey = i - 249; + } + else if (i >= GLFW_KEY_LEFT_SHIFT && i <= GLFW_KEY_RIGHT_SUPER) + { + remappedKey = i - 304; + } + else if (i == GLFW_KEY_MENU) + { + remappedKey = 99; + } + else if (i >= GLFW_KEY_F1 && i <= GLFW_KEY_F25) + { + remappedKey = i - 189; + } + mapping[i] = remappedKey; } + } - constexpr int Map(int glfwKey) const - { - if (glfwKey < 0) return -1; - return mapping[glfwKey]; - } - }; - } + constexpr int Map(int glfwKey) const + { + if (glfwKey < 0) return -1; + return mapping[glfwKey]; + } + }; } \ No newline at end of file diff --git a/openVulkanoCpp/Host/GLFW/InputProviderGLFW.cpp b/openVulkanoCpp/Host/GLFW/InputProviderGLFW.cpp index dc4695e..815fd8d 100644 --- a/openVulkanoCpp/Host/GLFW/InputProviderGLFW.cpp +++ b/openVulkanoCpp/Host/GLFW/InputProviderGLFW.cpp @@ -1,61 +1,129 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #include "InputProviderGLFW.hpp" #include "InputMappingGLFW.hpp" #include "../../Input/InputManager.hpp" +#include -namespace openVulkanoCpp +static_assert(GLFW_JOYSTICK_LAST == 15); // if this fails, please update it and resize the controllers array accordingly as GLFW_JOYSTICK_LAST + 1 + +namespace openVulkanoCpp::GLFW { - namespace GLFW + constexpr KeyboardInputMapping keyboardMapping = KeyboardInputMapping(); + + InputProviderGLFW* InputProviderGLFW::INSTANCE = nullptr; + + void InputProviderGLFW::Init() { - constexpr KeyboardInputMapping keyboardMapping = KeyboardInputMapping(); + if (INSTANCE) throw PlatformInitFailedException("An instance of the GLFW input provider has already been initialized!"); + INSTANCE = this; + glfwSetJoystickCallback(&JoystickCallback); - InputProviderGLFW* InputProviderGLFW::INSTANCE = nullptr; - - void InputProviderGLFW::Init() + // register already connected controller + for (int i = 0; i < GLFW_JOYSTICK_LAST; i++) { - if (INSTANCE) throw PlatformInitFailedException("An instance of the GLFW input provider has already been initialized!"); - INSTANCE = this; - glfwSetJoystickCallback(&JoystickCallback); - - // register already connected controller - for (int i = 0; i < GLFW_JOYSTICK_LAST; i++) + if (glfwJoystickPresent(i) == GLFW_TRUE) { - if (glfwJoystickPresent(i) == GLFW_TRUE) - { - OnJoystickConnect(i); - } + OnJoystickConnect(i); } - mouseButtons = 0; - - keyboard.Init(0, "Keyboard"); - mouse.Init(0, "Mouse"); - Input::InputManager::GetInstace()->RegisterInputDevice(&mouse); - Input::InputManager::GetInstace()->RegisterInputDevice(&keyboard); } + mouseButtons = 0; - void InputProviderGLFW::OnJoystickConnect(int joystickId) + keyboard.Init(0, "Keyboard"); + mouse.Init(0, "Mouse"); + Input::InputManager::GetInstace()->RegisterInputDevice(&mouse); + Input::InputManager::GetInstace()->RegisterInputDevice(&keyboard); + } + + void InputProviderGLFW::Close() + { + glfwSetJoystickCallback(NULL); + INSTANCE = nullptr; + } + + void InputProviderGLFW::OnJoystickConnect(int joystickId) + { + controllers[joystickId].Init(joystickId); + Input::InputManager::GetInstace()->RegisterInputDevice(&controllers[joystickId]); + } + + void InputProviderGLFW::OnJoystickDisconnect(int joystickId) + { + Input::InputManager::GetInstace()->UnregisterInputDevice(&controllers[joystickId]); + + controllers[joystickId].Close(); + } + + void InputProviderGLFW::SetKeyboardKey(IWindow* window, int key, int scanCode, int action, int mods) + { + if (action == GLFW_REPEAT) { - controllers[joystickId].Init(joystickId); - Input::InputManager::GetInstace()->RegisterInputDevice(&controllers[joystickId]); + //TODO handle repeat for text inputs } - - void InputProviderGLFW::OnJoystickDisconnect(int joystickId) + else { - Input::InputManager::GetInstace()->UnregisterInputDevice(&controllers[joystickId]); - - controllers[joystickId].Close(); + keyboard.UpdateKey(static_cast(keyboardMapping.Map(key)), action == GLFW_PRESS); } + //TODO handle keyboard notifications + } - void InputProviderGLFW::SetKeyboardKey(IWindow* window, int key, int scanCode, int action, int mods) + void InputProviderGLFW::PreTick() + { + mouse.ClearAxes(); + keyboard.PreTick(); + } + + void InputProviderGLFW::Tick() + { + for(ControllerGLFW& controller : controllers) { - if (action == GLFW_REPEAT) - { - //TODO handle repeat for text inputs - } - else - { - keyboard.UpdateKey(static_cast(keyboardMapping.Map(key)), action == GLFW_PRESS); - } - //TODO handle keyboard notifications + controller.Tick(); + } + mouse.UpdateButtons(mouseButtons); + if (activeWindowChanged) + { + mouse.ClearAxes(); + activeWindowChanged = false; + } + } + + void InputProviderGLFW::SetMouseButton(int button, bool state) + { + const uint8_t bit = 1 << button; + if (state) + { + mouseButtons |= bit; + } + else + { + mouseButtons ^= bit; + } + } + + void InputProviderGLFW::MouseEnterExitWindow(IWindow* window) + { + activeWindowChanged = true; + mouse.UpdateActiveWindow(window); + keyboard.UpdateActiveWindow(window); + } + + void InputProviderGLFW::JoystickCallback(int joystickId, int joystickEvent) + { + if (joystickEvent == GLFW_CONNECTED) + { + INSTANCE->OnJoystickConnect(joystickId); + } + else if (joystickEvent == GLFW_DISCONNECTED) + { + INSTANCE->OnJoystickDisconnect(joystickId); + } + else + { + Logger::INPUT->warn("Unknown GLFW joystick event {0} for joystick {1}", joystickEvent, joystickId); } } } \ No newline at end of file diff --git a/openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp b/openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp index 23a0f22..2ee9dfd 100644 --- a/openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/InputProviderGLFW.hpp @@ -1,10 +1,16 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once + #include "../../Base/IInitable.hpp" #include "../../Base/ITickable.hpp" #include "../../Base/ICloseable.hpp" #include "../../Base/IPlatform.hpp" #include "InputDeviceGLFW.hpp" -#include #include namespace openVulkanoCpp @@ -18,7 +24,7 @@ namespace openVulkanoCpp friend WindowGLFW; static InputProviderGLFW* INSTANCE; - std::array controllers = {}; + std::array controllers = {}; MouseGLFW mouse; KeyboardGLFW keyboard; uint8_t mouseButtons = 0; @@ -27,73 +33,23 @@ namespace openVulkanoCpp public: void Init() override; - void Close() override - { - glfwSetJoystickCallback(NULL); - INSTANCE = nullptr; - } + void Close() override; - void PreTick() - { - mouse.ClearAxes(); - keyboard.PreTick(); - } + void PreTick(); - void Tick() override - { - for(ControllerGLFW& controller : controllers) - { - controller.Tick(); - } - mouse.UpdateButtons(mouseButtons); - if (activeWindowChanged) - { - mouse.ClearAxes(); - activeWindowChanged = false; - } - } + void Tick() override; - void SetMouseButton(int button, bool state) - { - const uint8_t bit = 1 << button; - if (state) - { - mouseButtons |= bit; - } - else - { - mouseButtons ^= bit; - } - } + void SetMouseButton(int button, bool state); void SetKeyboardKey(IWindow* window, int key, int scanCode, int action, int mods); - void MouseEnterExitWindow(IWindow* window) - { - activeWindowChanged = true; - mouse.UpdateActiveWindow(window); - keyboard.UpdateActiveWindow(window); - } + void MouseEnterExitWindow(IWindow* window); void OnJoystickConnect(int joystickId); void OnJoystickDisconnect(int joystickId); - static void JoystickCallback(int joystickId, int joystickEvent) - { - if (joystickEvent == GLFW_CONNECTED) - { - INSTANCE->OnJoystickConnect(joystickId); - } - else if (joystickEvent == GLFW_DISCONNECTED) - { - INSTANCE->OnJoystickDisconnect(joystickId); - } - else - { - Logger::INPUT->warn("Unknown GLFW joystick event {0} for joystick {1}", joystickEvent, joystickId); - } - } + static void JoystickCallback(int joystickId, int joystickEvent); }; } } diff --git a/openVulkanoCpp/Host/GLFW/PlatformGLFW.cpp b/openVulkanoCpp/Host/GLFW/PlatformGLFW.cpp new file mode 100644 index 0000000..5a55108 --- /dev/null +++ b/openVulkanoCpp/Host/GLFW/PlatformGLFW.cpp @@ -0,0 +1,52 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "PlatformGLFW.hpp" +#include "WindowGLFW.hpp" +#include + +namespace openVulkanoCpp::GLFW +{ + PlatformGLFW::~PlatformGLFW() + { + if (IsInitialized()) + { + Close(); + } + } + + void PlatformGLFW::Init() + { + if (!glfwInit()) throw PlatformInitFailedException("Failed to initialize glfw"); + inputProvider.Init(); + initialized = true; + } + + void PlatformGLFW::Tick() + { + inputProvider.PreTick(); + glfwPollEvents(); + inputProvider.Tick(); + } + + void PlatformGLFW::Close() + { + for(const IWindow* window : windows) + { + delete window; + } + windows.clear(); + inputProvider.Close(); + glfwTerminate(); + } + + IWindow* PlatformGLFW::MakeWindow() + { + WindowGLFW* window = new WindowGLFW(inputProvider); + windows.push_back(window); + return window; + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp b/openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp index 4d035ac..0de39bb 100644 --- a/openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/PlatformGLFW.hpp @@ -1,11 +1,18 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once + #include "../../Base/IPlatform.hpp" -#include "WindowGLFW.hpp" #include "InputProviderGLFW.hpp" -#include namespace openVulkanoCpp { + class IWindow; + namespace GLFW { class PlatformGLFW final : public IPlatform @@ -17,47 +24,17 @@ namespace openVulkanoCpp public: PlatformGLFW() = default; - ~PlatformGLFW() override - { - if (initialized) - { - Close(); - } - } + ~PlatformGLFW() override; - bool IsInitialized() const { return initialized; } + [[nodiscard]] bool IsInitialized() const { return initialized; } - void Init() override - { - if (!glfwInit()) throw PlatformInitFailedException("Failed to initialize glfw"); - inputProvider.Init(); - initialized = true; - } + void Init() override; - void Tick() override - { - inputProvider.PreTick(); - glfwPollEvents(); - inputProvider.Tick(); - } + void Tick() override; - void Close() override - { - for(const IWindow* window : windows) - { - delete window; - } - windows.clear(); - inputProvider.Close(); - glfwTerminate(); - } - - IWindow* MakeWindow() override - { - WindowGLFW* window = new WindowGLFW(inputProvider); - windows.push_back(window); - return window; - } + void Close() override; + + IWindow* MakeWindow() override; }; } -} +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp b/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp new file mode 100644 index 0000000..a11f9f0 --- /dev/null +++ b/openVulkanoCpp/Host/GLFW/WindowGLFW.cpp @@ -0,0 +1,427 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "WindowGLFW.hpp" +#include +#include "../../Base/Logger.hpp" + +namespace openVulkanoCpp::GLFW +{ + WindowGLFW::WindowGLFW(openVulkanoCpp::GLFW::InputProviderGLFW& inputProvider) + : inputProvider(inputProvider) + {} + + WindowGLFW::~WindowGLFW() noexcept + { + if (window) + { + Close(); + } + } + + GLFWmonitor* WindowGLFW::GetCurrentMonitor() const + { + int monitorCount = 0; + GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); + for (int i = 0; i < monitorCount; i++) + { + int posX, posY, sizeX, sizeY; + glfwGetMonitorWorkarea(monitors[i], &posX, &posY, &sizeX, &sizeY); + if (windowConfig.posX >= posX && windowConfig.posX < posX + sizeX && + windowConfig.posY >= posY && windowConfig.posY < posY + sizeY) + { + return monitors[i]; + } + } + return nullptr; + } + + GLFWmonitor* WindowGLFW::GetTargetMonitor() const + { + if (windowConfig.windowMode == FULLSCREEN) + { + // TODO add config to control used display + return GetPrimaryMonitor(); + } + return nullptr; + } + + void WindowGLFW::Create() + { + glfwWindowHint(GLFW_DECORATED, (~windowConfig.windowMode) & 1); + //TODO handle full screen resolutions + window = glfwCreateWindow(windowConfig.width, windowConfig.height, windowConfig.title.c_str(), GetTargetMonitor(), nullptr); + if (!window) return; + glfwSetWindowUserPointer(window, this); + RegisterCallbacks(); + } + + void WindowGLFW::RegisterCallbacks() const + { + glfwSetErrorCallback(ErrorCallback); + + glfwSetDropCallback(window, DropCallback); + glfwSetFramebufferSizeCallback(window, ResizeCallback); + glfwSetWindowFocusCallback(window, FocusCallback); + glfwSetWindowRefreshCallback(window, RefreshCallback); + glfwSetWindowIconifyCallback(window, MinimizeCallback); + glfwSetWindowPosCallback(window, WindowMoveCallback); + glfwSetWindowCloseCallback(window, CloseCallback); + + // Input Callbacks + glfwSetKeyCallback(window, KeyboardCallback); + glfwSetMouseButtonCallback(window, MouseButtonCallback); + glfwSetCursorPosCallback(window, MouseMoveCallback); + glfwSetScrollCallback(window, MouseScrollCallback); + glfwSetCursorEnterCallback(window, MouseEnterExitCallback); + //glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); + //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } + + GLFWmonitor* WindowGLFW::GetPrimaryMonitor() + { + return glfwGetPrimaryMonitor(); + } + + std::vector WindowGLFW::GetMonitors() + { + int count; + GLFWmonitor** monitorsArray = glfwGetMonitors(&count); + std::vector monitors; + monitors.reserve(count); + for (int i = 0; i < count; i++) + { + monitors[i] = monitorsArray[i]; + } + return monitors; + } + + void WindowGLFW::Init(RenderAPI::RenderApi renderApi) + { + if (renderApi == RenderAPI::VULKAN) glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + Create(); + if (!window) + { + throw WindowInitFailedException("Failed to initialize window"); + } + if (renderApi != RenderAPI::VULKAN) MakeCurrentThread(); + Logger::WINDOW->info("GLFW Window created (id: {0})", GetWindowId()); + } + + void WindowGLFW::Close() + { + glfwDestroyWindow(window); + window = nullptr; + Logger::WINDOW->info("GLFW Window destroyed (id: {0})", GetWindowId()); + } + + void WindowGLFW::Present() const + { + glfwSwapBuffers(window); + } + + void WindowGLFW::Show() + { + glfwShowWindow(window); + } + + void WindowGLFW::Hide() + { + glfwHideWindow(window); + } + + void WindowGLFW::SetTitle(const std::string& title) + { + windowConfig.title = title; + if (window) + { + glfwSetWindowTitle(window, title.c_str()); + } + } + + void WindowGLFW::SetSize(uint32_t width, uint32_t height) + { + windowConfig.width = width; + windowConfig.height = height; + if (window) + { + glfwSetWindowSize(window, width, height); + } + } + + void WindowGLFW::SetPosition(int posX, int posY) + { + windowConfig.posX = posX; + windowConfig.posY = posY; + if (window) + { + glfwSetWindowPos(window, posX, posY); + } + } + + void WindowGLFW::SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) + { + minWidth = (minWidth < 0) ? GLFW_DONT_CARE : minWidth; + minHeight = (minHeight < 0) ? GLFW_DONT_CARE : minHeight; + maxWidth = (maxWidth < 0) ? GLFW_DONT_CARE : maxWidth; + maxHeight = (maxHeight < 0) ? GLFW_DONT_CARE : maxHeight; + glfwSetWindowSizeLimits(window, minWidth, minHeight, maxWidth, maxHeight); + } + + void WindowGLFW::MakeCurrentThread() + { + glfwMakeContextCurrent(window); + } + + void WindowGLFW::SetWindowMode(WindowMode windowMode) + { + if (windowMode == this->windowConfig.windowMode) return; // Nothing to change here + if (!window) return; // Window not yet created + this->windowConfig.windowMode = windowMode; + uint32_t sizeX = 0, sizeY = 0; + int posX = 0, posY = 0; + GLFWmonitor* monitor = nullptr; + glfwWindowHint(GLFW_DECORATED, (~windowMode) & 1); + if (windowMode == WINDOWED || windowMode == BORDERLESS) + { + sizeX = windowConfig.width; + sizeY = windowConfig.height; + posX = windowConfig.posX; + posY = windowConfig.posY; + monitor = nullptr; + if (windowMode == WINDOWED) + { + Logger::WINDOW->info("Switching to Windowed mode"); + } + else + { + Logger::WINDOW->info("Switching to Borderless Windowed mode"); + } + } + else + { // Fullscreen + GetPosition(&windowConfig.posX, &windowConfig.posY); // Backup current window position + monitor = GetCurrentMonitor(); + if (!monitor) monitor = GetPrimaryMonitor(); + if (!monitor) return; // We don't have a monitor to set the fullscreen window to + const GLFWvidmode* videoMode = glfwGetVideoMode(monitor ? monitor : GetPrimaryMonitor()); + sizeX = videoMode->width; + sizeY = videoMode->height; + if (windowMode == FULLSCREEN) + { + // TODO find video mode that best matches user settings + Logger::WINDOW->info("Switching to Fullscreen mode"); + } + else if (windowMode == BORDERLESS_FULLSCREEN) + { + int sX, sY; + glfwGetMonitorWorkarea(monitor, &posX, &posY, &sX, &sY); + monitor = nullptr; + Logger::WINDOW->info("Switching to Borderless Fullscreen mode"); + } + } + glfwSetWindowMonitor(this->window, monitor, posX, posY, sizeX, sizeY, GLFW_DONT_CARE); + } + + void WindowGLFW::SetWindowHandler(IWindowHandler* handler) + { + this->handler = handler; + } + + void WindowGLFW::GetSize(int* width, int* height) + { + glfwGetWindowSize(window, width, height); + } + + void WindowGLFW::GetPosition(int* x, int* y) + { + glfwGetWindowPos(window, x, y); + } + + vk::SurfaceKHR WindowGLFW::CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator) + { + VkSurfaceKHR rawSurface; + const auto result = static_cast(glfwCreateWindowSurface(static_cast(instance), window, reinterpret_cast(pAllocator), &rawSurface)); + return std::move(rawSurface);//createResultValue(result, rawSurface, "vk::CommandBuffer::begin"); + } + + std::vector WindowGLFW::GetRequiredInstanceExtensions() + { + return GetVulkanRequiredInstanceExtensions(); + } + + void WindowGLFW::OnResize(const uint32_t newWidth, const uint32_t newHeight) + { + Logger::WINDOW->debug("Window (id: {0}) resized (width: {1}, height: {2})", GetWindowId(), newWidth, newHeight); + handler->OnWindowResize(this, newWidth, newHeight); + } + + void WindowGLFW::OnMinimize() + { + Logger::WINDOW->debug("Window (id: {0}) minimized", GetWindowId()); + handler->OnWindowMinimize(this); + } + + void WindowGLFW::OnRestore() + { + Logger::WINDOW->debug("Window (id: {0}) restored", GetWindowId()); + handler->OnWindowRestore(this); + } + + void WindowGLFW::OnFocusLost() + { + Logger::WINDOW->debug("Window (id: {0}) focus lost", GetWindowId()); + handler->OnWindowFocusLost(this); + } + + void WindowGLFW::OnFocusGained() + { + Logger::WINDOW->debug("Window (id: {0}) focus gained", GetWindowId()); + handler->OnWindowFocusGained(this); + } + + void WindowGLFW::OnMove(const int posX, const int posY) + { + Logger::WINDOW->debug("Window (id: {0}) moved (x: {1}, y: {2})", GetWindowId(), posX, posY); + if (windowConfig.windowMode == WINDOWED || windowConfig.windowMode == BORDERLESS) + { // Don't save window position for fullscreen + windowConfig.posX = posX; + windowConfig.posY = posY; + } + handler->OnWindowMove(this, posX, posY); + } + + void WindowGLFW::OnClose() + { + Logger::WINDOW->debug("Window (id: {0}) closed", GetWindowId()); + handler->OnWindowClose(this); + } + + void WindowGLFW::OnKeyEvent(int key, int scanCode, int action, int mods) + { + if (key == GLFW_KEY_ENTER && action == GLFW_PRESS && mods == GLFW_MOD_ALT) + { + WindowMode newMode = FULLSCREEN; + switch (windowConfig.windowMode) + { + case WINDOWED: newMode = FULLSCREEN; break; + case BORDERLESS: newMode = BORDERLESS_FULLSCREEN; break; + case FULLSCREEN: newMode = WINDOWED; break; + case BORDERLESS_FULLSCREEN: newMode = BORDERLESS; break; + } + SetWindowMode(newMode); + } + switch (action) + { + case GLFW_PRESS:// OnKeyPressed(key, mods); + Logger::INPUT->debug("Key Pressed: {0} Mod: {1} ScanCode: {2}", key, mods, scanCode); + break; + case GLFW_RELEASE:// OnKeyReleased(key, mods); + Logger::INPUT->debug("Key Released: {0} Mod: {1} ScanCode: {2}", key, mods, scanCode); + break; + case GLFW_REPEAT: + Logger::INPUT->debug("Key Repeat: {0} Mod: {1} ScanCode: {2}", key, mods, scanCode); + break; + + default: break; + } + } + + WindowGLFW* WindowGLFW::GetWindow(GLFWwindow* window) + { + return static_cast(glfwGetWindowUserPointer(window)); + } + + void WindowGLFW::KeyboardCallback(GLFWwindow* window, int key, int scanCode, int action, int mods) + { + GetWindow(window)->OnKeyEvent(key, scanCode, action, mods); + const auto windowInstance = GetWindow(window); + windowInstance->inputProvider.SetKeyboardKey(windowInstance, key, scanCode, action, mods); + } + + void WindowGLFW::MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) + { + GetWindow(window)->inputProvider.SetMouseButton(button, action != GLFW_RELEASE); + } + + void WindowGLFW::MouseMoveCallback(GLFWwindow* window, double posX, double posY) + { + GetWindow(window)->inputProvider.mouse.UpdatePosition(posX, posY); + } + + void WindowGLFW::MouseScrollCallback(GLFWwindow* window, double xOffset, double yOffset) + { + GetWindow(window)->inputProvider.mouse.UpdateWheel(xOffset, yOffset); + } + + void WindowGLFW::MouseEnterExitCallback(GLFWwindow* window, int entered) + { + const auto windowInstance = GetWindow(window); + windowInstance->inputProvider.MouseEnterExitWindow(windowInstance); + Logger::INPUT->info("Mouse enter/exit: {}", entered); + } + + void WindowGLFW::ResizeCallback(GLFWwindow* window, int width, int height) + { + GetWindow(window)->OnResize(width, height); + } + + void WindowGLFW::FocusCallback(GLFWwindow* window, const int focused) + { + if (focused == GLFW_TRUE) + GetWindow(window)->OnFocusGained(); + else + GetWindow(window)->OnFocusLost(); + } + + void WindowGLFW::MinimizeCallback(GLFWwindow* window, const int minimized) + { + if (minimized == GLFW_TRUE) + GetWindow(window)->OnMinimize(); + else + GetWindow(window)->OnRestore(); + } + + void WindowGLFW::RefreshCallback(GLFWwindow* window) + { + //TODO is there really anything to do? or is it ok if the window is only redrawn on the next frame? + } + + void WindowGLFW::WindowMoveCallback(GLFWwindow* window, const int posX, const int posY) + { + GetWindow(window)->OnMove(posX, posY); + } + + void WindowGLFW::CloseCallback(GLFWwindow* window) + { + GetWindow(window)->OnClose(); + } + + void WindowGLFW::DropCallback(GLFWwindow* window, const int count, const char** paths) + { + //TODO something useful + } + + void WindowGLFW::ErrorCallback(const int error, const char* description) + { + Logger::WINDOW->error("GLFW error (e{0}): {1}", error, description); + } + + std::vector WindowGLFW::GetVulkanRequiredInstanceExtensions() + { + std::vector result; + uint32_t count = 0; + const char** names = glfwGetRequiredInstanceExtensions(&count); + if (names && count) + { + for (uint32_t i = 0; i < count; ++i) + { + result.emplace_back(names[i]); + } + } + return result; + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp b/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp index 252c8e4..221e417 100644 --- a/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp +++ b/openVulkanoCpp/Host/GLFW/WindowGLFW.hpp @@ -1,456 +1,134 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once -#include + #include "../../Base/UI/BaseWindow.hpp" -#include "../../Base/Logger.hpp" #include "../../Base/IPlatform.hpp" #include "InputProviderGLFW.hpp" -namespace openVulkanoCpp +struct GLFWmonitor; +struct GLFWwindow; + +namespace openVulkanoCpp::GLFW { - namespace GLFW + class WindowGLFW final : public BaseWindow, virtual public IVulkanWindow, virtual public IOpenGlWindow { - class WindowGLFW final : public BaseWindow, virtual public IVulkanWindow, virtual public IOpenGlWindow - { - private: - InputProviderGLFW& inputProvider; - GLFWwindow* window = nullptr; - IWindowHandler* handler = nullptr; + private: + InputProviderGLFW& inputProvider; + GLFWwindow* window = nullptr; + IWindowHandler* handler = nullptr; - public: - WindowGLFW(InputProviderGLFW& inputProvider): inputProvider(inputProvider) {} + public: + WindowGLFW(InputProviderGLFW& inputProvider); - virtual ~WindowGLFW() override - { - if (window != nullptr) Close(); - } + ~WindowGLFW() noexcept override; - protected: - GLFWmonitor* GetCurrentMonitor() const - { - int monitorCount = 0; - GLFWmonitor** monitors = glfwGetMonitors(&monitorCount); - for (int i = 0; i < monitorCount; i++) - { - int posX, posY, sizeX, sizeY; - glfwGetMonitorWorkarea(monitors[i], &posX, &posY, &sizeX, &sizeY); - if (windowConfig.posX >= posX && windowConfig.posX < posX + sizeX && - windowConfig.posY >= posY && windowConfig.posY < posY + sizeY) - { - return monitors[i]; - } - } - return nullptr; - } + protected: + [[nodiscard]] GLFWmonitor* GetCurrentMonitor() const; - GLFWmonitor* GetTargetMonitor() const - { - if (windowConfig.windowMode == FULLSCREEN) - { - // TODO add config to control used display - return GetPrimaryMonitor(); - } - return nullptr; - } + [[nodiscard]] GLFWmonitor* GetTargetMonitor() const; - void Create() - { - glfwWindowHint(GLFW_DECORATED, (~windowConfig.windowMode) & 1); - //TODO handle full screen resolutions - window = glfwCreateWindow(windowConfig.width, windowConfig.height, windowConfig.title.c_str(), GetTargetMonitor(), nullptr); - if (!window) return; - glfwSetWindowUserPointer(window, this); - RegisterCallbacks(); - } + void Create(); - void RegisterCallbacks() const - { - glfwSetErrorCallback(ErrorCallback); + void RegisterCallbacks() const; - glfwSetDropCallback(window, DropCallback); - glfwSetFramebufferSizeCallback(window, ResizeCallback); - glfwSetWindowFocusCallback(window, FocusCallback); - glfwSetWindowRefreshCallback(window, RefreshCallback); - glfwSetWindowIconifyCallback(window, MinimizeCallback); - glfwSetWindowPosCallback(window, WindowMoveCallback); - glfwSetWindowCloseCallback(window, CloseCallback); + static GLFWmonitor* GetPrimaryMonitor(); - // Input Callbacks - glfwSetKeyCallback(window, KeyboardCallback); - glfwSetMouseButtonCallback(window, MouseButtonCallback); - glfwSetCursorPosCallback(window, MouseMoveCallback); - glfwSetScrollCallback(window, MouseScrollCallback); - glfwSetCursorEnterCallback(window, MouseEnterExitCallback); - //glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); - //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - } + static std::vector GetMonitors(); - static GLFWmonitor* GetPrimaryMonitor() - { - return glfwGetPrimaryMonitor(); - } + public: // IWindow implementation + void Init(RenderAPI::RenderApi renderApi) override; - static std::vector GetMonitors() - { - int count; - GLFWmonitor** monitorsArray = glfwGetMonitors(&count); - std::vector monitors; - monitors.reserve(count); - for (int i = 0; i < count; i++) - { - monitors[i] = monitorsArray[i]; - } - return monitors; - } + void Close() override; - public: // IWindow implementation - void Init(RenderAPI::RenderApi renderApi) override - { - if (renderApi == RenderAPI::VULKAN) glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - Create(); - if (!window) - { - throw WindowInitFailedException("Failed to initialize window"); - } - if (renderApi != RenderAPI::VULKAN) MakeCurrentThread(); - Logger::WINDOW->info("GLFW Window created (id: {0})", GetWindowId()); - } + void Present() const override; - void Close() override - { - glfwDestroyWindow(window); - window = nullptr; - Logger::WINDOW->info("GLFW Window destroyed (id: {0})", GetWindowId()); - } + void Show() override; - void Present() const override - { - glfwSwapBuffers(window); - } + void Hide() override; - void Show() override - { - glfwShowWindow(window); - } + void SetTitle(const std::string& title) override; - void Hide() override - { - glfwHideWindow(window); - } + void SetSize(uint32_t width, uint32_t height) override; - void SetTitle(const std::string& title) override - { - windowConfig.title = title; - glfwSetWindowTitle(window, title.c_str()); - } + void SetPosition(int posX, int posY) override; - void SetSize(uint32_t width, uint32_t height) override - { - windowConfig.width = width; - windowConfig.height = height; - if (window) - { - glfwSetWindowSize(window, width, height); - } - } + void SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) override; - void SetPosition(int posX, int posY) override - { - windowConfig.posX = posX; - windowConfig.posY = posY; - if (window) - { - glfwSetWindowPos(window, posX, posY); - } - } + void MakeCurrentThread() override; - void SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) override - { - minWidth = (minWidth < 0) ? GLFW_DONT_CARE : minWidth; - minHeight = (minHeight < 0) ? GLFW_DONT_CARE : minHeight; - maxWidth = (maxWidth < 0) ? GLFW_DONT_CARE : maxWidth; - maxHeight = (maxHeight < 0) ? GLFW_DONT_CARE : maxHeight; - glfwSetWindowSizeLimits(window, minWidth, minHeight, maxWidth, maxHeight); - } + void SetWindowMode(WindowMode windowMode) override; - void MakeCurrentThread() override - { - glfwMakeContextCurrent(window); - } + void SetWindowHandler(IWindowHandler* handler) override; - void SetWindowMode(WindowMode windowMode) override - { - if (windowMode == this->windowConfig.windowMode) return; // Nothing to change here - if (!window) return; // Window not yet created - this->windowConfig.windowMode = windowMode; - uint32_t sizeX = 0, sizeY = 0; - int posX = 0, posY = 0; - GLFWmonitor* monitor = nullptr; - glfwWindowHint(GLFW_DECORATED, (~windowMode) & 1); - if (windowMode == WINDOWED || windowMode == BORDERLESS) - { - sizeX = windowConfig.width; - sizeY = windowConfig.height; - posX = windowConfig.posX; - posY = windowConfig.posY; - monitor = nullptr; - if (windowMode == WINDOWED) - { - Logger::WINDOW->info("Switching to Windowed mode"); - } - else - { - Logger::WINDOW->info("Switching to Borderless Windowed mode"); - } - } - else - { // Fullscreen - GetPosition(&windowConfig.posX, &windowConfig.posY); // Backup current window position - monitor = GetCurrentMonitor(); - if (!monitor) monitor = GetPrimaryMonitor(); - if (!monitor) return; // We don't have a monitor to set the fullscreen window to - const GLFWvidmode* videoMode = glfwGetVideoMode(monitor ? monitor : GetPrimaryMonitor()); - sizeX = videoMode->width; - sizeY = videoMode->height; - if (windowMode == FULLSCREEN) - { - // TODO find video mode that best matches user settings - Logger::WINDOW->info("Switching to Fullscreen mode"); - } - else if (windowMode == BORDERLESS_FULLSCREEN) - { - int sX, sY; - glfwGetMonitorWorkarea(monitor, &posX, &posY, &sX, &sY); - monitor = nullptr; - Logger::WINDOW->info("Switching to Borderless Fullscreen mode"); - } - } - glfwSetWindowMonitor(this->window, monitor, posX, posY, sizeX, sizeY, GLFW_DONT_CARE); - } + IVulkanWindow* GetVulkanWindow() override { return this; }; - void SetWindowHandler(IWindowHandler* handler) override - { - this->handler = handler; - } + IOpenGlWindow* GetOpenGlWindow() override { return this; }; - IVulkanWindow* GetVulkanWindow() override - { - return this; - } + // Status getter + void GetSize(int* width, int* height) override; - IOpenGlWindow* GetOpenGlWindow() override - { - return this; - } + void GetPosition(int* x, int* y) override; - // Status getter - void GetSize(int* width, int* height) override - { - glfwGetWindowSize(window, width, height); - } + IWindowHandler* GetWindowHandler() override { return handler; } - void GetPosition(int* x, int* y) override - { - glfwGetWindowPos(window, x, y); - } + //IVulkanWindow stuff + vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator) override; - IWindowHandler* GetWindowHandler() override - { - return handler; - } + std::vector GetRequiredInstanceExtensions() override; - //IVulkanWindow stuff - vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator) override - { - VkSurfaceKHR rawSurface; - const auto result = static_cast(glfwCreateWindowSurface(static_cast(instance), window, reinterpret_cast(pAllocator), &rawSurface)); - return std::move(rawSurface);//createResultValue(result, rawSurface, "vk::CommandBuffer::begin"); - } + public: // Window events + void OnResize(uint32_t newWidth, uint32_t newHeight); - std::vector GetRequiredInstanceExtensions() override - { - return GetVulkanRequiredInstanceExtensions(); - } + void OnMinimize(); - public: // Window events - void OnResize(const uint32_t newWidth, const uint32_t newHeight) - { - Logger::WINDOW->debug("Window (id: {0}) resized (width: {1}, height: {2})", GetWindowId(), newWidth, newHeight); - handler->OnWindowResize(this, newWidth, newHeight); - } + void OnRestore(); - void OnMinimize() - { - Logger::WINDOW->debug("Window (id: {0}) minimized", GetWindowId()); - handler->OnWindowMinimize(this); - } + void OnFocusLost(); - void OnRestore() - { - Logger::WINDOW->debug("Window (id: {0}) restored", GetWindowId()); - handler->OnWindowRestore(this); - } + void OnFocusGained(); - void OnFocusLost() - { - Logger::WINDOW->debug("Window (id: {0}) focus lost", GetWindowId()); - handler->OnWindowFocusLost(this); - } + void OnMove(int posX, int posY); - void OnFocusGained() - { - Logger::WINDOW->debug("Window (id: {0}) focus gained", GetWindowId()); - handler->OnWindowFocusGained(this); - } + void OnClose(); - void OnMove(const int posX, const int posY) - { - Logger::WINDOW->debug("Window (id: {0}) moved (x: {1}, y: {2})", GetWindowId(), posX, posY); - if (windowConfig.windowMode == WINDOWED || windowConfig.windowMode == BORDERLESS) - { // Don't save window position for fullscreen - windowConfig.posX = posX; - windowConfig.posY = posY; - } - handler->OnWindowMove(this, posX, posY); - } + protected: + virtual void OnKeyEvent(int key, int scanCode, int action, int mods); - void OnClose() - { - Logger::WINDOW->debug("Window (id: {0}) closed", GetWindowId()); - handler->OnWindowClose(this); - } - - protected: - virtual void OnKeyEvent(int key, int scanCode, int action, int mods) - { - if (key == GLFW_KEY_ENTER && action == GLFW_PRESS && mods == GLFW_MOD_ALT) - { - WindowMode newMode = FULLSCREEN; - switch (windowConfig.windowMode) - { - case WINDOWED: newMode = FULLSCREEN; break; - case BORDERLESS: newMode = BORDERLESS_FULLSCREEN; break; - case FULLSCREEN: newMode = WINDOWED; break; - case BORDERLESS_FULLSCREEN: newMode = BORDERLESS; break; - } - SetWindowMode(newMode); - } - switch (action) - { - case GLFW_PRESS:// OnKeyPressed(key, mods); - Logger::INPUT->info("Key Pressed: {0} Mod: {1} ScanCode: {2}", key, mods, scanCode); - break; - case GLFW_RELEASE:// OnKeyReleased(key, mods); - Logger::INPUT->info("Key Released: {0} Mod: {1} ScanCode: {2}", key, mods, scanCode); - break; - case GLFW_REPEAT: - Logger::INPUT->info("Key Repeat: {0} Mod: {1} ScanCode: {2}", key, mods, scanCode); - break; + private: // Callbacks + static WindowGLFW* GetWindow(GLFWwindow* window); - default: break; - } - } + static void KeyboardCallback(GLFWwindow* window, int key, int scanCode, int action, int mods); - private: // Callbacks - static WindowGLFW* GetWindow(GLFWwindow* window) - { - return static_cast(glfwGetWindowUserPointer(window)); - } + static void MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); - static void KeyboardCallback(GLFWwindow* window, int key, int scanCode, int action, int mods) - { - GetWindow(window)->OnKeyEvent(key, scanCode, action, mods); - const auto windowInstance = GetWindow(window); - windowInstance->inputProvider.SetKeyboardKey(windowInstance, key, scanCode, action, mods); - } + static void MouseMoveCallback(GLFWwindow* window, double posX, double posY); - static void MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) - { - GetWindow(window)->inputProvider.SetMouseButton(button, action != GLFW_RELEASE); - } + static void MouseScrollCallback(GLFWwindow* window, double xOffset, double yOffset); - static void MouseMoveCallback(GLFWwindow* window, double posX, double posY) - { - GetWindow(window)->inputProvider.mouse.UpdatePosition(posX, posY); - } + static void MouseEnterExitCallback(GLFWwindow* window, int entered); - static void MouseScrollCallback(GLFWwindow* window, double xOffset, double yOffset) - { - GetWindow(window)->inputProvider.mouse.UpdateWheel(xOffset, yOffset); - } + static void ResizeCallback(GLFWwindow* window, int width, int height); - static void MouseEnterExitCallback(GLFWwindow* window, int entered) - { - const auto windowInstance = GetWindow(window); - windowInstance->inputProvider.MouseEnterExitWindow(windowInstance); - Logger::INPUT->info("Mouse enter/exit: {}", entered); - } + static void FocusCallback(GLFWwindow* window, int focused); - static void ResizeCallback(GLFWwindow* window, int width, int height) - { - GetWindow(window)->OnResize(width, height); - } + static void MinimizeCallback(GLFWwindow* window, int minimized); - static void FocusCallback(GLFWwindow* window, const int focused) - { - if (focused == GLFW_TRUE) - GetWindow(window)->OnFocusGained(); - else - GetWindow(window)->OnFocusLost(); - } + static void RefreshCallback(GLFWwindow* window); - static void MinimizeCallback(GLFWwindow* window, const int minimized) - { - if (minimized == GLFW_TRUE) - GetWindow(window)->OnMinimize(); - else - GetWindow(window)->OnRestore(); - } + static void WindowMoveCallback(GLFWwindow* window, int posX, int posY); - static void RefreshCallback(GLFWwindow* window) - { - //TODO is there really anything to do? or is it ok if the window is only redrawn on the next frame? - } + static void CloseCallback(GLFWwindow* window); - static void WindowMoveCallback(GLFWwindow* window, const int posX, const int posY) - { - GetWindow(window)->OnMove(posX, posY); - } + static void DropCallback(GLFWwindow* window, int count, const char** paths); - static void CloseCallback(GLFWwindow* window) - { - GetWindow(window)->OnClose(); - } + static void ErrorCallback(int error, const char* description); - static void DropCallback(GLFWwindow* window, const int count, const char** paths) - { - //TODO something useful - } - - static void ErrorCallback(const int error, const char* description) - { - Logger::WINDOW->error("GLFW error (e{0}): {1}", error, description); - } - - - - - public: - static std::vector GetVulkanRequiredInstanceExtensions() - { - std::vector result; - uint32_t count = 0; - const char** names = glfwGetRequiredInstanceExtensions(&count); - if (names && count) - { - for (uint32_t i = 0; i < count; ++i) - { - result.emplace_back(names[i]); - } - } - return result; - } - - - }; - } + public: + static std::vector GetVulkanRequiredInstanceExtensions(); + }; } diff --git a/openVulkanoCpp/Input/InputDevice.hpp b/openVulkanoCpp/Input/InputDevice.hpp index 0e4d7f6..045a441 100644 --- a/openVulkanoCpp/Input/InputDevice.hpp +++ b/openVulkanoCpp/Input/InputDevice.hpp @@ -1,4 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once + #include "../Base/ICloseable.hpp" #include "InputKey.hpp" @@ -24,35 +31,35 @@ namespace openVulkanoCpp this->name = name; } - virtual float ReadAxis(int16_t key) const = 0; + [[nodiscard]] virtual float ReadAxis(int16_t key) const = 0; - virtual bool ReadButton(int16_t key) const = 0; + [[nodiscard]] virtual bool ReadButton(int16_t key) const = 0; - virtual bool ReadButtonUp(int16_t key) const = 0; + [[nodiscard]] virtual bool ReadButtonUp(int16_t key) const = 0; - virtual bool ReadButtonDown(int16_t key) const = 0; + [[nodiscard]] virtual bool ReadButtonDown(int16_t key) const = 0; public: - virtual ~InputDevice() = default; + ~InputDevice() override = default; - virtual void Close() override + void Close() override { this->deviceType = InputDeviceType::UNKNOWN; this->index = -1; this->name = ""; } - InputDeviceType GetType() const { return deviceType; } - int GetIndex() const { return index; } - const std::string& GetName() const { return name; } + [[nodiscard]] InputDeviceType GetType() const { return deviceType; } + [[nodiscard]] int GetIndex() const { return index; } + [[nodiscard]] const std::string& GetName() const { return name; } - float GetAxisAsButtonThreshold() const { return axisAsButtonThreshold; } + [[nodiscard]] float GetAxisAsButtonThreshold() const { return axisAsButtonThreshold; } void SetAxisAsButtonThreshold(float value) { axisAsButtonThreshold = value; } - float GetButtonAsAxisValue() const { return buttonAsAxisValue; } + [[nodiscard]] float GetButtonAsAxisValue() const { return buttonAsAxisValue; } void SetButtonAsAxisValue(float value) { buttonAsAxisValue = value; } - bool GetButton(InputKey key) const + [[nodiscard]] bool GetButton(InputKey key) const { if (key.GetInputDeviceType() != deviceType) return false; if (key.GetInputType() == InputKey::InputType::AXIS) @@ -62,7 +69,7 @@ namespace openVulkanoCpp return ReadButton(key.GetInputKey()); } - bool GetButtonUp(InputKey key) const + [[nodiscard]] bool GetButtonUp(InputKey key) const { if (key.GetInputDeviceType() != deviceType) return false; if (key.GetInputType() == InputKey::InputType::AXIS) @@ -73,7 +80,7 @@ namespace openVulkanoCpp return ReadButtonUp(key.GetInputKey()); } - bool GetButtonDown(InputKey key) const + [[nodiscard]] bool GetButtonDown(InputKey key) const { if (key.GetInputDeviceType() != deviceType) return false; if (key.GetInputType() == InputKey::InputType::AXIS) @@ -84,7 +91,7 @@ namespace openVulkanoCpp return ReadButtonDown(key.GetInputKey()); } - float GetAxis(InputKey key) const + [[nodiscard]] float GetAxis(InputKey key) const { if (key.GetInputDeviceType() != deviceType) return 0; if (key.GetInputType() == InputKey::InputType::BUTTON) @@ -94,7 +101,7 @@ namespace openVulkanoCpp return ReadAxis(key.GetInputKey()); } - float GetAxis(InputKey keyPositive, InputKey keyNegative) const + [[nodiscard]] float GetAxis(InputKey keyPositive, InputKey keyNegative) const { return GetAxis(keyPositive) - GetAxis(keyNegative); } diff --git a/openVulkanoCpp/Input/InputDeviceController.hpp b/openVulkanoCpp/Input/InputDeviceController.hpp index 332e1d8..e0495d2 100644 --- a/openVulkanoCpp/Input/InputDeviceController.hpp +++ b/openVulkanoCpp/Input/InputDeviceController.hpp @@ -1,3 +1,9 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once #include "../Base/Logger.hpp" @@ -26,7 +32,7 @@ namespace openVulkanoCpp uint32_t pressedButtons = 0, lastPressedButtons = 0; const ControllerType controllerType = ControllerType::GENERIC_JOYSTICK; - bool GetLastButton(InputKey::Controller::Button button) const + [[nodiscard]] bool GetLastButton(InputKey::Controller::Button button) const { return lastPressedButtons & (1 << button); } @@ -59,49 +65,49 @@ namespace openVulkanoCpp lastPressedButtons = pressedButtons; pressedButtons = buttonStates; } - - float ReadAxis(int16_t key) const override final + + [[nodiscard]] float ReadAxis(int16_t key) const final { return GetAxis(static_cast(key)); } - bool ReadButton(int16_t key) const override final + [[nodiscard]] bool ReadButton(int16_t key) const final { return GetButton(static_cast(key)); } - bool ReadButtonUp(int16_t key) const override final + [[nodiscard]] bool ReadButtonUp(int16_t key) const final { return GetButtonUp(static_cast(key)); } - bool ReadButtonDown(int16_t key) const override final + [[nodiscard]] bool ReadButtonDown(int16_t key) const final { return GetButtonDown(static_cast(key)); } public: - bool GetButton(const InputKey::Controller::Button button) const + [[nodiscard]] bool GetButton(const InputKey::Controller::Button button) const { return pressedButtons & (1 << button); } - bool GetButtonUp(const InputKey::Controller::Button button) const + [[nodiscard]] bool GetButtonUp(const InputKey::Controller::Button button) const { return !GetButton(button) && GetLastButton(button); } - bool GetButtonDown(const InputKey::Controller::Button button) const + [[nodiscard]] bool GetButtonDown(const InputKey::Controller::Button button) const { return GetButton(button) && !GetLastButton(button); } - float GetAxis(const InputKey::Controller::Axis axis) const + [[nodiscard]] float GetAxis(const InputKey::Controller::Axis axis) const { return axes[axis]; } - ControllerType GetControllerType() const + [[nodiscard]] ControllerType GetControllerType() const { return controllerType; } diff --git a/openVulkanoCpp/Input/InputDeviceKeyboard.hpp b/openVulkanoCpp/Input/InputDeviceKeyboard.hpp index 34d3652..a67f7d7 100644 --- a/openVulkanoCpp/Input/InputDeviceKeyboard.hpp +++ b/openVulkanoCpp/Input/InputDeviceKeyboard.hpp @@ -1,4 +1,11 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once + #include "InputDevice.hpp" #include @@ -12,7 +19,7 @@ namespace openVulkanoCpp { std::bitset keyState; std::bitset lastKeyState; - IWindow* lastWindow; + IWindow* lastWindow = nullptr; protected: InputDeviceKeyboard() = default; @@ -36,44 +43,44 @@ namespace openVulkanoCpp { lastWindow = window; } - - float ReadAxis(int16_t key) const override final + + [[nodiscard]] float ReadAxis(int16_t key) const final { return 0; } - bool ReadButton(int16_t key) const override final + [[nodiscard]] bool ReadButton(int16_t key) const final { return GetButton(static_cast(key)); } - bool ReadButtonUp(int16_t key) const override final + [[nodiscard]] bool ReadButtonUp(int16_t key) const final { return GetButtonUp(static_cast(key)); } - bool ReadButtonDown(int16_t key) const override final + [[nodiscard]] bool ReadButtonDown(int16_t key) const final { return GetButtonDown(static_cast(key)); } public: - bool GetButton(const InputKey::Keyboard::Key button) const + [[nodiscard]] bool GetButton(const InputKey::Keyboard::Key button) const { return keyState[button] > 0; } - bool GetButtonUp(const InputKey::Keyboard::Key button) const + [[nodiscard]] bool GetButtonUp(const InputKey::Keyboard::Key button) const { return !keyState[button] && lastKeyState[button]; } - bool GetButtonDown(const InputKey::Keyboard::Key button) const + [[nodiscard]] bool GetButtonDown(const InputKey::Keyboard::Key button) const { return keyState[button] && !lastKeyState[button]; } - IWindow* GetActiveWindow() const + [[nodiscard]] IWindow* GetActiveWindow() const { return lastWindow; } diff --git a/openVulkanoCpp/Input/InputDeviceMouse.cpp b/openVulkanoCpp/Input/InputDeviceMouse.cpp new file mode 100644 index 0000000..4457bec --- /dev/null +++ b/openVulkanoCpp/Input/InputDeviceMouse.cpp @@ -0,0 +1,61 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "InputDeviceMouse.hpp" +#include "../Base/Logger.hpp" + +namespace openVulkanoCpp::Input +{ + void InputDeviceMouse::Init(const int index, const std::string& name) + { + InputDevice::Init(InputDeviceType::MOUSE, index, name); + + ClearAxes(); + pressedButtons = 0; + lastPressedButtons = 0; + mousePosX = 0; + mousePosY = 0; + lastWindow = nullptr; + } + + void InputDeviceMouse::UpdateButtons(uint8_t newPressedButtons) + { + lastPressedButtons = pressedButtons; + pressedButtons = newPressedButtons; + if (lastPressedButtons != pressedButtons) + Logger::INPUT->debug("Mouse button state changed {0:08b}", pressedButtons); + } + + void InputDeviceMouse::UpdatePosition(double posX, double posY) + { + axes[InputKey::Mouse::AXIS_X] = static_cast(posX - mousePosX); + axes[InputKey::Mouse::AXIS_Y] = static_cast(posY - mousePosY); + mousePosX = posX; + mousePosY = posY; + Logger::INPUT->debug("Mouse moved posX: {0} posY: {1}, relativeX: {2}, relativeY: {3}", posX, posY, axes[InputKey::Mouse::AXIS_X], axes[InputKey::Mouse::AXIS_Y]); + } + + void InputDeviceMouse::UpdateWheel(float wheelX, float wheelY) + { + axes[InputKey::Mouse::AXIS_WHEEL_X] = wheelX; + axes[InputKey::Mouse::AXIS_WHEEL_Y] = wheelY; + Logger::INPUT->debug("Mouse scrolled x: {0} y: {1}", wheelX, wheelY); + } + + void InputDeviceMouse::UpdateActiveWindow(IWindow* window) + { + ClearAxes(); + lastWindow = window; + } + + void InputDeviceMouse::ClearAxes() + { + for (float& axis : axes) + { + axis = 0; + } + } +} \ No newline at end of file diff --git a/openVulkanoCpp/Input/InputDeviceMouse.hpp b/openVulkanoCpp/Input/InputDeviceMouse.hpp index 3e6f739..a44fd34 100644 --- a/openVulkanoCpp/Input/InputDeviceMouse.hpp +++ b/openVulkanoCpp/Input/InputDeviceMouse.hpp @@ -1,6 +1,13 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + #pragma once + #include "InputDevice.hpp" -#include "../Base/Logger.hpp" +#include "glm/vec2.hpp" namespace openVulkanoCpp { @@ -18,120 +25,82 @@ namespace openVulkanoCpp protected: InputDeviceMouse() = default; - void Init(const int index, const std::string& name) - { - InputDevice::Init(InputDeviceType::MOUSE, index, name); - - ClearAxes(); - pressedButtons = 0; - lastPressedButtons = 0; - mousePosX = 0; - mousePosY = 0; - lastWindow = nullptr; - } + void Init(int index, const std::string& name); - void UpdateButtons(uint8_t newPressedButtons) - { - lastPressedButtons = pressedButtons; - pressedButtons = newPressedButtons; - if (lastPressedButtons != pressedButtons) - Logger::INPUT->debug("Mouse button state changed {0:08b}", pressedButtons); - } + void UpdateButtons(uint8_t newPressedButtons); - void UpdatePosition(double posX, double posY) - { - axes[InputKey::Mouse::AXIS_X] = static_cast(posX - mousePosX); - axes[InputKey::Mouse::AXIS_Y] = static_cast(posY - mousePosY); - mousePosX = posX; - mousePosY = posY; - Logger::INPUT->debug("Mouse moved posX: {0} posY: {1}, relativeX: {2}, relativeY: {3}", posX, posY, axes[InputKey::Mouse::AXIS_X], axes[InputKey::Mouse::AXIS_Y]); - } + void UpdatePosition(double posX, double posY); - void UpdateWheel(float wheelX, float wheelY) - { - axes[InputKey::Mouse::AXIS_WHEEL_X] = wheelX; - axes[InputKey::Mouse::AXIS_WHEEL_Y] = wheelY; - Logger::INPUT->debug("Mouse scrolled x: {0} y: {1}", wheelX, wheelY); - } + void UpdateWheel(float wheelX, float wheelY); - void UpdateActiveWindow(IWindow* window) - { - ClearAxes(); - lastWindow = window; - } + void UpdateActiveWindow(IWindow* window); - void ClearAxes() - { - for (float& axis : axes) - { - axis = 0; - } - } + void ClearAxes(); private: - bool GetLastButton(InputKey::Mouse::Button button) const + [[nodiscard]] bool GetLastButton(InputKey::Mouse::Button button) const { return lastPressedButtons & (1 << button); } protected: - float ReadAxis(int16_t key) const override final + [[nodiscard]] float ReadAxis(int16_t key) const final { return GetAxis(static_cast(key)); } - bool ReadButton(int16_t key) const override final + [[nodiscard]] bool ReadButton(int16_t key) const final { return GetButton(static_cast(key)); } - bool ReadButtonUp(int16_t key) const override final + [[nodiscard]] bool ReadButtonUp(int16_t key) const final { return GetButtonUp(static_cast(key)); } - bool ReadButtonDown(int16_t key) const override final + [[nodiscard]] bool ReadButtonDown(int16_t key) const final { return GetButtonDown(static_cast(key)); } public: - bool GetButton(const InputKey::Mouse::Button button) const + [[nodiscard]] bool GetButton(const InputKey::Mouse::Button button) const { return pressedButtons & (1 << button); } - bool GetButtonUp(const InputKey::Mouse::Button button) const + [[nodiscard]] bool GetButtonUp(const InputKey::Mouse::Button button) const { return !GetButton(button) && GetLastButton(button); } - bool GetButtonDown(const InputKey::Mouse::Button button) const + [[nodiscard]] bool GetButtonDown(const InputKey::Mouse::Button button) const { return GetButton(button) && !GetLastButton(button); } - float GetAxis(const InputKey::Mouse::Axis axis) const + [[nodiscard]] float GetAxis(const InputKey::Mouse::Axis axis) const { return axes[axis]; } - float GetWheel() const + [[nodiscard]] float GetWheel() const { return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_Y); } - float GetWheelX() const + [[nodiscard]] float GetWheelX() const { return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_X); } - float GetWheelY() const + [[nodiscard]] float GetWheelY() const { return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_Y); } - glm::vec2 GetMousePosition() const + [[nodiscard]] glm::vec2 GetMousePosition() const { return { mousePosX, mousePosY }; } @@ -146,7 +115,7 @@ namespace openVulkanoCpp { if (window == lastWindow) { - return { mousePosX, mousePosY }; + return GetMousePosition(); } return { std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN() }; } @@ -165,7 +134,7 @@ namespace openVulkanoCpp } } - IWindow* GetActiveWindow() const + [[nodiscard]] IWindow* GetActiveWindow() const { return lastWindow; }