Refactor some code

This commit is contained in:
2020-08-06 20:48:17 +02:00
parent 3673bd0d48
commit 0a693b72dd
14 changed files with 976 additions and 745 deletions

View File

@@ -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 <GLFW/glfw3.h>
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<Input::InputKey::Controller::Axis>(i), state.axes[i]);
}
uint32_t buttonStates = 0;
for (int i = 0; i < 15; i++)
{
buttonStates |= static_cast<uint32_t>(state.buttons[i] != 0) << i;
}
SetButtons(buttonStates);
}
else
{
// Joysticks currently are not supported
}
}
}

View File

@@ -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 #pragma once
#include "../../Base/ITickable.hpp" #include "../../Base/ITickable.hpp"
#include "../../Input/InputDeviceKeyboard.hpp" #include "../../Input/InputDeviceKeyboard.hpp"
#include "../../Input/InputDeviceMouse.hpp" #include "../../Input/InputDeviceMouse.hpp"
#include "../../Input/InputDeviceController.hpp" #include "../../Input/InputDeviceController.hpp"
#include <GLFW/glfw3.h>
namespace openVulkanoCpp namespace openVulkanoCpp::GLFW
{ {
class KeyboardGLFW final : public Input::InputDeviceKeyboard class KeyboardGLFW final : public Input::InputDeviceKeyboard
{ {
public: public:
KeyboardGLFW() = default; KeyboardGLFW() = default;
~KeyboardGLFW() override = default;
using Input::InputDeviceKeyboard::Init; using Input::InputDeviceKeyboard::Init;
using Input::InputDeviceKeyboard::PreTick; using Input::InputDeviceKeyboard::PreTick;
@@ -23,6 +29,7 @@ namespace openVulkanoCpp
{ {
public: public:
MouseGLFW() = default; MouseGLFW() = default;
~MouseGLFW() override = default;
using Input::InputDeviceMouse::Init; using Input::InputDeviceMouse::Init;
using Input::InputDeviceMouse::ClearAxes; using Input::InputDeviceMouse::ClearAxes;
@@ -37,40 +44,10 @@ namespace openVulkanoCpp
bool gamepad = false;; bool gamepad = false;;
public: public:
ControllerGLFW() = default; ControllerGLFW() = default;
~ControllerGLFW() override = default;
void Init(int joystickId) 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 Tick() override void Tick() override;
{
if (GetIndex() == -1) return;
if (gamepad)
{
GLFWgamepadstate state;
glfwGetGamepadState(GetIndex(), &state);
for (int i = 0; i < 6; i++)
{
SetAxis(static_cast<Input::InputKey::Controller::Axis>(i), state.axes[i]);
}
uint32_t buttonStates = 0;
for (int i = 0; i < 15; i++)
{
buttonStates |= static_cast<uint32_t>(state.buttons[i] != 0) << i;
}
SetButtons(buttonStates);
}
else
{
// Joysticks currently are not supported
}
}
}; };
} }

View File

@@ -1,11 +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 #pragma once
#include "../../Input/InputKey.hpp" #include "../../Input/InputKey.hpp"
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
namespace openVulkanoCpp namespace openVulkanoCpp::GLFW
{ {
namespace GLFW
{
struct KeyboardInputMapping struct KeyboardInputMapping
{ {
int mapping[GLFW_KEY_LAST + 1]; int mapping[GLFW_KEY_LAST + 1];
@@ -18,7 +23,7 @@ namespace openVulkanoCpp
if (i == GLFW_KEY_SPACE) if (i == GLFW_KEY_SPACE)
{ {
remappedKey = i; remappedKey = 62;
} }
else if (i >= GLFW_KEY_COMMA && i <= GLFW_KEY_RIGHT_BRACKET) else if (i >= GLFW_KEY_COMMA && i <= GLFW_KEY_RIGHT_BRACKET)
{ {
@@ -47,10 +52,6 @@ namespace openVulkanoCpp
{ {
remappedKey = 17; remappedKey = 17;
} }
else if (i == GLFW_KEY_SPACE)
{
remappedKey = 62;
}
else if (i == GLFW_KEY_APOSTROPHE) else if (i == GLFW_KEY_APOSTROPHE)
{ {
remappedKey = 63; remappedKey = 63;
@@ -89,5 +90,4 @@ namespace openVulkanoCpp
return mapping[glfwKey]; return mapping[glfwKey];
} }
}; };
}
} }

View File

@@ -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/.
*/
#include "InputProviderGLFW.hpp" #include "InputProviderGLFW.hpp"
#include "InputMappingGLFW.hpp" #include "InputMappingGLFW.hpp"
#include "../../Input/InputManager.hpp" #include "../../Input/InputManager.hpp"
#include <GLFW/glfw3.h>
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(); constexpr KeyboardInputMapping keyboardMapping = KeyboardInputMapping();
InputProviderGLFW* InputProviderGLFW::INSTANCE = nullptr; InputProviderGLFW* InputProviderGLFW::INSTANCE = nullptr;
@@ -32,6 +39,12 @@ namespace openVulkanoCpp
Input::InputManager::GetInstace()->RegisterInputDevice(&keyboard); Input::InputManager::GetInstace()->RegisterInputDevice(&keyboard);
} }
void InputProviderGLFW::Close()
{
glfwSetJoystickCallback(NULL);
INSTANCE = nullptr;
}
void InputProviderGLFW::OnJoystickConnect(int joystickId) void InputProviderGLFW::OnJoystickConnect(int joystickId)
{ {
controllers[joystickId].Init(joystickId); controllers[joystickId].Init(joystickId);
@@ -57,5 +70,60 @@ namespace openVulkanoCpp
} }
//TODO handle keyboard notifications //TODO handle keyboard notifications
} }
void InputProviderGLFW::PreTick()
{
mouse.ClearAxes();
keyboard.PreTick();
}
void InputProviderGLFW::Tick()
{
for(ControllerGLFW& controller : controllers)
{
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);
}
} }
} }

View File

@@ -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 #pragma once
#include "../../Base/IInitable.hpp" #include "../../Base/IInitable.hpp"
#include "../../Base/ITickable.hpp" #include "../../Base/ITickable.hpp"
#include "../../Base/ICloseable.hpp" #include "../../Base/ICloseable.hpp"
#include "../../Base/IPlatform.hpp" #include "../../Base/IPlatform.hpp"
#include "InputDeviceGLFW.hpp" #include "InputDeviceGLFW.hpp"
#include <GLFW/glfw3.h>
#include <array> #include <array>
namespace openVulkanoCpp namespace openVulkanoCpp
@@ -18,7 +24,7 @@ namespace openVulkanoCpp
friend WindowGLFW; friend WindowGLFW;
static InputProviderGLFW* INSTANCE; static InputProviderGLFW* INSTANCE;
std::array<ControllerGLFW, GLFW_JOYSTICK_LAST> controllers = {}; std::array<ControllerGLFW, 16> controllers = {};
MouseGLFW mouse; MouseGLFW mouse;
KeyboardGLFW keyboard; KeyboardGLFW keyboard;
uint8_t mouseButtons = 0; uint8_t mouseButtons = 0;
@@ -27,73 +33,23 @@ namespace openVulkanoCpp
public: public:
void Init() override; void Init() override;
void Close() override void Close() override;
{
glfwSetJoystickCallback(NULL);
INSTANCE = nullptr;
}
void PreTick() void PreTick();
{
mouse.ClearAxes();
keyboard.PreTick();
}
void Tick() override void Tick() override;
{
for(ControllerGLFW& controller : controllers)
{
controller.Tick();
}
mouse.UpdateButtons(mouseButtons);
if (activeWindowChanged)
{
mouse.ClearAxes();
activeWindowChanged = false;
}
}
void SetMouseButton(int button, bool state) void SetMouseButton(int button, bool state);
{
const uint8_t bit = 1 << button;
if (state)
{
mouseButtons |= bit;
}
else
{
mouseButtons ^= bit;
}
}
void SetKeyboardKey(IWindow* window, int key, int scanCode, int action, int mods); void SetKeyboardKey(IWindow* window, int key, int scanCode, int action, int mods);
void MouseEnterExitWindow(IWindow* window) void MouseEnterExitWindow(IWindow* window);
{
activeWindowChanged = true;
mouse.UpdateActiveWindow(window);
keyboard.UpdateActiveWindow(window);
}
void OnJoystickConnect(int joystickId); void OnJoystickConnect(int joystickId);
void OnJoystickDisconnect(int joystickId); void OnJoystickDisconnect(int joystickId);
static void JoystickCallback(int joystickId, int joystickEvent) 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);
}
}
}; };
} }
} }

View File

@@ -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 <GLFW/glfw3.h>
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;
}
}

View File

@@ -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 #pragma once
#include "../../Base/IPlatform.hpp" #include "../../Base/IPlatform.hpp"
#include "WindowGLFW.hpp"
#include "InputProviderGLFW.hpp" #include "InputProviderGLFW.hpp"
#include <GLFW/glfw3.h>
namespace openVulkanoCpp namespace openVulkanoCpp
{ {
class IWindow;
namespace GLFW namespace GLFW
{ {
class PlatformGLFW final : public IPlatform class PlatformGLFW final : public IPlatform
@@ -17,47 +24,17 @@ namespace openVulkanoCpp
public: public:
PlatformGLFW() = default; PlatformGLFW() = default;
~PlatformGLFW() override ~PlatformGLFW() override;
{
if (initialized)
{
Close();
}
}
bool IsInitialized() const { return initialized; } [[nodiscard]] bool IsInitialized() const { return initialized; }
void Init() override void Init() override;
{
if (!glfwInit()) throw PlatformInitFailedException("Failed to initialize glfw");
inputProvider.Init();
initialized = true;
}
void Tick() override void Tick() override;
{
inputProvider.PreTick();
glfwPollEvents();
inputProvider.Tick();
}
void Close() override void Close() override;
{
for(const IWindow* window : windows)
{
delete window;
}
windows.clear();
inputProvider.Close();
glfwTerminate();
}
IWindow* MakeWindow() override IWindow* MakeWindow() override;
{
WindowGLFW* window = new WindowGLFW(inputProvider);
windows.push_back(window);
return window;
}
}; };
} }
} }

View File

@@ -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 <GLFW/glfw3.h>
#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<GLFWmonitor*> WindowGLFW::GetMonitors()
{
int count;
GLFWmonitor** monitorsArray = glfwGetMonitors(&count);
std::vector<GLFWmonitor*> 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<vk::Result>(glfwCreateWindowSurface(static_cast<VkInstance>(instance), window, reinterpret_cast<const VkAllocationCallbacks*>(pAllocator), &rawSurface));
return std::move(rawSurface);//createResultValue(result, rawSurface, "vk::CommandBuffer::begin");
}
std::vector<std::string> 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<WindowGLFW*>(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<std::string> WindowGLFW::GetVulkanRequiredInstanceExtensions()
{
std::vector<std::string> 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;
}
}

View File

@@ -1,14 +1,20 @@
/*
* 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 #pragma once
#include <GLFW/glfw3.h>
#include "../../Base/UI/BaseWindow.hpp" #include "../../Base/UI/BaseWindow.hpp"
#include "../../Base/Logger.hpp"
#include "../../Base/IPlatform.hpp" #include "../../Base/IPlatform.hpp"
#include "InputProviderGLFW.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: private:
@@ -17,440 +23,112 @@ namespace openVulkanoCpp
IWindowHandler* handler = nullptr; IWindowHandler* handler = nullptr;
public: public:
WindowGLFW(InputProviderGLFW& inputProvider): inputProvider(inputProvider) {} WindowGLFW(InputProviderGLFW& inputProvider);
virtual ~WindowGLFW() override ~WindowGLFW() noexcept override;
{
if (window != nullptr) Close();
}
protected: protected:
GLFWmonitor* GetCurrentMonitor() const [[nodiscard]] 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;
}
GLFWmonitor* GetTargetMonitor() const [[nodiscard]] GLFWmonitor* GetTargetMonitor() const;
{
if (windowConfig.windowMode == FULLSCREEN)
{
// TODO add config to control used display
return GetPrimaryMonitor();
}
return nullptr;
}
void Create() 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 RegisterCallbacks() const void RegisterCallbacks() const;
{
glfwSetErrorCallback(ErrorCallback);
glfwSetDropCallback(window, DropCallback); static GLFWmonitor* GetPrimaryMonitor();
glfwSetFramebufferSizeCallback(window, ResizeCallback);
glfwSetWindowFocusCallback(window, FocusCallback);
glfwSetWindowRefreshCallback(window, RefreshCallback);
glfwSetWindowIconifyCallback(window, MinimizeCallback);
glfwSetWindowPosCallback(window, WindowMoveCallback);
glfwSetWindowCloseCallback(window, CloseCallback);
// Input Callbacks static std::vector<GLFWmonitor*> GetMonitors();
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 GLFWmonitor* GetPrimaryMonitor()
{
return glfwGetPrimaryMonitor();
}
static std::vector<GLFWmonitor*> GetMonitors()
{
int count;
GLFWmonitor** monitorsArray = glfwGetMonitors(&count);
std::vector<GLFWmonitor*> monitors;
monitors.reserve(count);
for (int i = 0; i < count; i++)
{
monitors[i] = monitorsArray[i];
}
return monitors;
}
public: // IWindow implementation public: // IWindow implementation
void Init(RenderAPI::RenderApi renderApi) override 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 Close() override void Close() override;
{
glfwDestroyWindow(window);
window = nullptr;
Logger::WINDOW->info("GLFW Window destroyed (id: {0})", GetWindowId());
}
void Present() const override void Present() const override;
{
glfwSwapBuffers(window);
}
void Show() override void Show() override;
{
glfwShowWindow(window);
}
void Hide() override void Hide() override;
{
glfwHideWindow(window);
}
void SetTitle(const std::string& title) override void SetTitle(const std::string& title) override;
{
windowConfig.title = title;
glfwSetWindowTitle(window, title.c_str());
}
void SetSize(uint32_t width, uint32_t height) override void SetSize(uint32_t width, uint32_t height) override;
{
windowConfig.width = width;
windowConfig.height = height;
if (window)
{
glfwSetWindowSize(window, width, height);
}
}
void SetPosition(int posX, int posY) override void SetPosition(int posX, int posY) override;
{
windowConfig.posX = posX;
windowConfig.posY = posY;
if (window)
{
glfwSetWindowPos(window, posX, posY);
}
}
void SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) 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 MakeCurrentThread() override void MakeCurrentThread() override;
{
glfwMakeContextCurrent(window);
}
void SetWindowMode(WindowMode windowMode) 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);
}
void SetWindowHandler(IWindowHandler* handler) override void SetWindowHandler(IWindowHandler* handler) override;
{
this->handler = handler;
}
IVulkanWindow* GetVulkanWindow() override IVulkanWindow* GetVulkanWindow() override { return this; };
{
return this;
}
IOpenGlWindow* GetOpenGlWindow() override IOpenGlWindow* GetOpenGlWindow() override { return this; };
{
return this;
}
// Status getter // Status getter
void GetSize(int* width, int* height) override void GetSize(int* width, int* height) override;
{
glfwGetWindowSize(window, width, height);
}
void GetPosition(int* x, int* y) override void GetPosition(int* x, int* y) override;
{
glfwGetWindowPos(window, x, y);
}
IWindowHandler* GetWindowHandler() override IWindowHandler* GetWindowHandler() override { return handler; }
{
return handler;
}
//IVulkanWindow stuff //IVulkanWindow stuff
vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator) override vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator) override;
{
VkSurfaceKHR rawSurface;
const auto result = static_cast<vk::Result>(glfwCreateWindowSurface(static_cast<VkInstance>(instance), window, reinterpret_cast<const VkAllocationCallbacks*>(pAllocator), &rawSurface));
return std::move(rawSurface);//createResultValue(result, rawSurface, "vk::CommandBuffer::begin");
}
std::vector<std::string> GetRequiredInstanceExtensions() override std::vector<std::string> GetRequiredInstanceExtensions() override;
{
return GetVulkanRequiredInstanceExtensions();
}
public: // Window events public: // Window events
void OnResize(const uint32_t newWidth, const uint32_t newHeight) void OnResize(uint32_t newWidth, uint32_t newHeight);
{
Logger::WINDOW->debug("Window (id: {0}) resized (width: {1}, height: {2})", GetWindowId(), newWidth, newHeight);
handler->OnWindowResize(this, newWidth, newHeight);
}
void OnMinimize() void OnMinimize();
{
Logger::WINDOW->debug("Window (id: {0}) minimized", GetWindowId());
handler->OnWindowMinimize(this);
}
void OnRestore() void OnRestore();
{
Logger::WINDOW->debug("Window (id: {0}) restored", GetWindowId());
handler->OnWindowRestore(this);
}
void OnFocusLost() void OnFocusLost();
{
Logger::WINDOW->debug("Window (id: {0}) focus lost", GetWindowId());
handler->OnWindowFocusLost(this);
}
void OnFocusGained() void OnFocusGained();
{
Logger::WINDOW->debug("Window (id: {0}) focus gained", GetWindowId());
handler->OnWindowFocusGained(this);
}
void OnMove(const int posX, const int posY) void OnMove(int posX, 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 OnClose() void OnClose();
{
Logger::WINDOW->debug("Window (id: {0}) closed", GetWindowId());
handler->OnWindowClose(this);
}
protected: protected:
virtual void OnKeyEvent(int key, int scanCode, int action, int mods) 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;
default: break;
}
}
private: // Callbacks private: // Callbacks
static WindowGLFW* GetWindow(GLFWwindow* window) static WindowGLFW* GetWindow(GLFWwindow* window);
{
return static_cast<WindowGLFW*>(glfwGetWindowUserPointer(window));
}
static void KeyboardCallback(GLFWwindow* window, int key, int scanCode, 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 MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) static void MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
{
GetWindow(window)->inputProvider.SetMouseButton(button, action != GLFW_RELEASE);
}
static void MouseMoveCallback(GLFWwindow* window, double posX, double posY) static void MouseMoveCallback(GLFWwindow* window, double posX, double posY);
{
GetWindow(window)->inputProvider.mouse.UpdatePosition(posX, posY);
}
static void MouseScrollCallback(GLFWwindow* window, double xOffset, double yOffset) static void MouseScrollCallback(GLFWwindow* window, double xOffset, double yOffset);
{
GetWindow(window)->inputProvider.mouse.UpdateWheel(xOffset, yOffset);
}
static void MouseEnterExitCallback(GLFWwindow* window, int entered) 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 ResizeCallback(GLFWwindow* window, int width, int height) static void ResizeCallback(GLFWwindow* window, int width, int height);
{
GetWindow(window)->OnResize(width, height);
}
static void FocusCallback(GLFWwindow* window, const int focused) static void FocusCallback(GLFWwindow* window, int focused);
{
if (focused == GLFW_TRUE)
GetWindow(window)->OnFocusGained();
else
GetWindow(window)->OnFocusLost();
}
static void MinimizeCallback(GLFWwindow* window, const int minimized) static void MinimizeCallback(GLFWwindow* window, int minimized);
{
if (minimized == GLFW_TRUE)
GetWindow(window)->OnMinimize();
else
GetWindow(window)->OnRestore();
}
static void RefreshCallback(GLFWwindow* window) 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 WindowMoveCallback(GLFWwindow* window, const int posX, const int posY) static void WindowMoveCallback(GLFWwindow* window, int posX, int posY);
{
GetWindow(window)->OnMove(posX, posY);
}
static void CloseCallback(GLFWwindow* window)
{
GetWindow(window)->OnClose();
}
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);
}
static void CloseCallback(GLFWwindow* window);
static void DropCallback(GLFWwindow* window, int count, const char** paths);
static void ErrorCallback(int error, const char* description);
public: public:
static std::vector<std::string> GetVulkanRequiredInstanceExtensions() static std::vector<std::string> GetVulkanRequiredInstanceExtensions();
{
std::vector<std::string> 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;
}
}; };
}
} }

View File

@@ -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 #pragma once
#include "../Base/ICloseable.hpp" #include "../Base/ICloseable.hpp"
#include "InputKey.hpp" #include "InputKey.hpp"
@@ -24,35 +31,35 @@ namespace openVulkanoCpp
this->name = name; 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: public:
virtual ~InputDevice() = default; ~InputDevice() override = default;
virtual void Close() override void Close() override
{ {
this->deviceType = InputDeviceType::UNKNOWN; this->deviceType = InputDeviceType::UNKNOWN;
this->index = -1; this->index = -1;
this->name = ""; this->name = "";
} }
InputDeviceType GetType() const { return deviceType; } [[nodiscard]] InputDeviceType GetType() const { return deviceType; }
int GetIndex() const { return index; } [[nodiscard]] int GetIndex() const { return index; }
const std::string& GetName() const { return name; } [[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; } void SetAxisAsButtonThreshold(float value) { axisAsButtonThreshold = value; }
float GetButtonAsAxisValue() const { return buttonAsAxisValue; } [[nodiscard]] float GetButtonAsAxisValue() const { return buttonAsAxisValue; }
void SetButtonAsAxisValue(float value) { buttonAsAxisValue = value; } 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.GetInputDeviceType() != deviceType) return false;
if (key.GetInputType() == InputKey::InputType::AXIS) if (key.GetInputType() == InputKey::InputType::AXIS)
@@ -62,7 +69,7 @@ namespace openVulkanoCpp
return ReadButton(key.GetInputKey()); return ReadButton(key.GetInputKey());
} }
bool GetButtonUp(InputKey key) const [[nodiscard]] bool GetButtonUp(InputKey key) const
{ {
if (key.GetInputDeviceType() != deviceType) return false; if (key.GetInputDeviceType() != deviceType) return false;
if (key.GetInputType() == InputKey::InputType::AXIS) if (key.GetInputType() == InputKey::InputType::AXIS)
@@ -73,7 +80,7 @@ namespace openVulkanoCpp
return ReadButtonUp(key.GetInputKey()); return ReadButtonUp(key.GetInputKey());
} }
bool GetButtonDown(InputKey key) const [[nodiscard]] bool GetButtonDown(InputKey key) const
{ {
if (key.GetInputDeviceType() != deviceType) return false; if (key.GetInputDeviceType() != deviceType) return false;
if (key.GetInputType() == InputKey::InputType::AXIS) if (key.GetInputType() == InputKey::InputType::AXIS)
@@ -84,7 +91,7 @@ namespace openVulkanoCpp
return ReadButtonDown(key.GetInputKey()); return ReadButtonDown(key.GetInputKey());
} }
float GetAxis(InputKey key) const [[nodiscard]] float GetAxis(InputKey key) const
{ {
if (key.GetInputDeviceType() != deviceType) return 0; if (key.GetInputDeviceType() != deviceType) return 0;
if (key.GetInputType() == InputKey::InputType::BUTTON) if (key.GetInputType() == InputKey::InputType::BUTTON)
@@ -94,7 +101,7 @@ namespace openVulkanoCpp
return ReadAxis(key.GetInputKey()); return ReadAxis(key.GetInputKey());
} }
float GetAxis(InputKey keyPositive, InputKey keyNegative) const [[nodiscard]] float GetAxis(InputKey keyPositive, InputKey keyNegative) const
{ {
return GetAxis(keyPositive) - GetAxis(keyNegative); return GetAxis(keyPositive) - GetAxis(keyNegative);
} }

View File

@@ -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 #pragma once
#include "../Base/Logger.hpp" #include "../Base/Logger.hpp"
@@ -26,7 +32,7 @@ namespace openVulkanoCpp
uint32_t pressedButtons = 0, lastPressedButtons = 0; uint32_t pressedButtons = 0, lastPressedButtons = 0;
const ControllerType controllerType = ControllerType::GENERIC_JOYSTICK; 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); return lastPressedButtons & (1 << button);
} }
@@ -60,48 +66,48 @@ namespace openVulkanoCpp
pressedButtons = buttonStates; pressedButtons = buttonStates;
} }
float ReadAxis(int16_t key) const override final [[nodiscard]] float ReadAxis(int16_t key) const final
{ {
return GetAxis(static_cast<InputKey::Controller::Axis>(key)); return GetAxis(static_cast<InputKey::Controller::Axis>(key));
} }
bool ReadButton(int16_t key) const override final [[nodiscard]] bool ReadButton(int16_t key) const final
{ {
return GetButton(static_cast<InputKey::Controller::Button>(key)); return GetButton(static_cast<InputKey::Controller::Button>(key));
} }
bool ReadButtonUp(int16_t key) const override final [[nodiscard]] bool ReadButtonUp(int16_t key) const final
{ {
return GetButtonUp(static_cast<InputKey::Controller::Button>(key)); return GetButtonUp(static_cast<InputKey::Controller::Button>(key));
} }
bool ReadButtonDown(int16_t key) const override final [[nodiscard]] bool ReadButtonDown(int16_t key) const final
{ {
return GetButtonDown(static_cast<InputKey::Controller::Button>(key)); return GetButtonDown(static_cast<InputKey::Controller::Button>(key));
} }
public: public:
bool GetButton(const InputKey::Controller::Button button) const [[nodiscard]] bool GetButton(const InputKey::Controller::Button button) const
{ {
return pressedButtons & (1 << button); 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); 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); 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]; return axes[axis];
} }
ControllerType GetControllerType() const [[nodiscard]] ControllerType GetControllerType() const
{ {
return controllerType; return controllerType;
} }

View File

@@ -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 #pragma once
#include "InputDevice.hpp" #include "InputDevice.hpp"
#include <bitset> #include <bitset>
@@ -12,7 +19,7 @@ namespace openVulkanoCpp
{ {
std::bitset<InputKey::Keyboard::KEY_LAST + 1> keyState; std::bitset<InputKey::Keyboard::KEY_LAST + 1> keyState;
std::bitset<InputKey::Keyboard::KEY_LAST + 1> lastKeyState; std::bitset<InputKey::Keyboard::KEY_LAST + 1> lastKeyState;
IWindow* lastWindow; IWindow* lastWindow = nullptr;
protected: protected:
InputDeviceKeyboard() = default; InputDeviceKeyboard() = default;
@@ -37,43 +44,43 @@ namespace openVulkanoCpp
lastWindow = window; lastWindow = window;
} }
float ReadAxis(int16_t key) const override final [[nodiscard]] float ReadAxis(int16_t key) const final
{ {
return 0; return 0;
} }
bool ReadButton(int16_t key) const override final [[nodiscard]] bool ReadButton(int16_t key) const final
{ {
return GetButton(static_cast<InputKey::Keyboard::Key>(key)); return GetButton(static_cast<InputKey::Keyboard::Key>(key));
} }
bool ReadButtonUp(int16_t key) const override final [[nodiscard]] bool ReadButtonUp(int16_t key) const final
{ {
return GetButtonUp(static_cast<InputKey::Keyboard::Key>(key)); return GetButtonUp(static_cast<InputKey::Keyboard::Key>(key));
} }
bool ReadButtonDown(int16_t key) const override final [[nodiscard]] bool ReadButtonDown(int16_t key) const final
{ {
return GetButtonDown(static_cast<InputKey::Keyboard::Key>(key)); return GetButtonDown(static_cast<InputKey::Keyboard::Key>(key));
} }
public: public:
bool GetButton(const InputKey::Keyboard::Key button) const [[nodiscard]] bool GetButton(const InputKey::Keyboard::Key button) const
{ {
return keyState[button] > 0; 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]; 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]; return keyState[button] && !lastKeyState[button];
} }
IWindow* GetActiveWindow() const [[nodiscard]] IWindow* GetActiveWindow() const
{ {
return lastWindow; return lastWindow;
} }

View File

@@ -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<float>(posX - mousePosX);
axes[InputKey::Mouse::AXIS_Y] = static_cast<float>(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;
}
}
}

View File

@@ -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 #pragma once
#include "InputDevice.hpp" #include "InputDevice.hpp"
#include "../Base/Logger.hpp" #include "glm/vec2.hpp"
namespace openVulkanoCpp namespace openVulkanoCpp
{ {
@@ -18,120 +25,82 @@ namespace openVulkanoCpp
protected: protected:
InputDeviceMouse() = default; InputDeviceMouse() = default;
void Init(const int index, const std::string& name) void Init(int index, const std::string& name);
{
InputDevice::Init(InputDeviceType::MOUSE, index, name);
ClearAxes(); void UpdateButtons(uint8_t newPressedButtons);
pressedButtons = 0;
lastPressedButtons = 0;
mousePosX = 0;
mousePosY = 0;
lastWindow = nullptr;
}
void UpdateButtons(uint8_t newPressedButtons) void UpdatePosition(double posX, double posY);
{
lastPressedButtons = pressedButtons;
pressedButtons = newPressedButtons;
if (lastPressedButtons != pressedButtons)
Logger::INPUT->debug("Mouse button state changed {0:08b}", pressedButtons);
}
void UpdatePosition(double posX, double posY) void UpdateWheel(float wheelX, float wheelY);
{
axes[InputKey::Mouse::AXIS_X] = static_cast<float>(posX - mousePosX);
axes[InputKey::Mouse::AXIS_Y] = static_cast<float>(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 UpdateWheel(float wheelX, float wheelY) void UpdateActiveWindow(IWindow* window);
{
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 UpdateActiveWindow(IWindow* window) void ClearAxes();
{
ClearAxes();
lastWindow = window;
}
void ClearAxes()
{
for (float& axis : axes)
{
axis = 0;
}
}
private: private:
bool GetLastButton(InputKey::Mouse::Button button) const [[nodiscard]] bool GetLastButton(InputKey::Mouse::Button button) const
{ {
return lastPressedButtons & (1 << button); return lastPressedButtons & (1 << button);
} }
protected: protected:
float ReadAxis(int16_t key) const override final [[nodiscard]] float ReadAxis(int16_t key) const final
{ {
return GetAxis(static_cast<InputKey::Mouse::Axis>(key)); return GetAxis(static_cast<InputKey::Mouse::Axis>(key));
} }
bool ReadButton(int16_t key) const override final [[nodiscard]] bool ReadButton(int16_t key) const final
{ {
return GetButton(static_cast<InputKey::Mouse::Button>(key)); return GetButton(static_cast<InputKey::Mouse::Button>(key));
} }
bool ReadButtonUp(int16_t key) const override final [[nodiscard]] bool ReadButtonUp(int16_t key) const final
{ {
return GetButtonUp(static_cast<InputKey::Mouse::Button>(key)); return GetButtonUp(static_cast<InputKey::Mouse::Button>(key));
} }
bool ReadButtonDown(int16_t key) const override final [[nodiscard]] bool ReadButtonDown(int16_t key) const final
{ {
return GetButtonDown(static_cast<InputKey::Mouse::Button>(key)); return GetButtonDown(static_cast<InputKey::Mouse::Button>(key));
} }
public: public:
bool GetButton(const InputKey::Mouse::Button button) const [[nodiscard]] bool GetButton(const InputKey::Mouse::Button button) const
{ {
return pressedButtons & (1 << button); 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); 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); 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]; return axes[axis];
} }
float GetWheel() const [[nodiscard]] float GetWheel() const
{ {
return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_Y); return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_Y);
} }
float GetWheelX() const [[nodiscard]] float GetWheelX() const
{ {
return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_X); return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_X);
} }
float GetWheelY() const [[nodiscard]] float GetWheelY() const
{ {
return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_Y); return GetAxis(InputKey::Mouse::Axis::AXIS_WHEEL_Y);
} }
glm::vec2 GetMousePosition() const [[nodiscard]] glm::vec2 GetMousePosition() const
{ {
return { mousePosX, mousePosY }; return { mousePosX, mousePosY };
} }
@@ -146,7 +115,7 @@ namespace openVulkanoCpp
{ {
if (window == lastWindow) if (window == lastWindow)
{ {
return { mousePosX, mousePosY }; return GetMousePosition();
} }
return { std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN() }; return { std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN() };
} }
@@ -165,7 +134,7 @@ namespace openVulkanoCpp
} }
} }
IWindow* GetActiveWindow() const [[nodiscard]] IWindow* GetActiveWindow() const
{ {
return lastWindow; return lastWindow;
} }