From cc26ee1cc875db50884fe244e0a3195dd730a1ef Mon Sep 17 00:00:00 2001 From: TheCherno Date: Tue, 21 Jun 2022 10:47:47 +1000 Subject: [PATCH 1/2] Added Resize function to Image class for convenience --- Walnut/src/Walnut/Image.cpp | 50 ++++++++++++++++++++++++++++--------- Walnut/src/Walnut/Image.h | 3 +++ 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/Walnut/src/Walnut/Image.cpp b/Walnut/src/Walnut/Image.cpp index 436dd653..d1fc3166 100644 --- a/Walnut/src/Walnut/Image.cpp +++ b/Walnut/src/Walnut/Image.cpp @@ -81,18 +81,7 @@ namespace Walnut { Image::~Image() { - Application::SubmitResourceFree([sampler = m_Sampler, imageView = m_ImageView, image = m_Image, - memory = m_Memory, stagingBuffer = m_StagingBuffer, stagingBufferMemory = m_StagingBufferMemory]() - { - VkDevice device = Application::GetDevice(); - - vkDestroySampler(device, sampler, nullptr); - vkDestroyImageView(device, imageView, nullptr); - vkDestroyImage(device, image, nullptr); - vkFreeMemory(device, memory, nullptr); - vkDestroyBuffer(device, stagingBuffer, nullptr); - vkFreeMemory(device, stagingBufferMemory, nullptr); - }); + Release(); } void Image::AllocateMemory(uint64_t size) @@ -168,6 +157,29 @@ namespace Walnut { m_DescriptorSet = (VkDescriptorSet)ImGui_ImplVulkan_AddTexture(m_Sampler, m_ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); } + void Image::Release() + { + Application::SubmitResourceFree([sampler = m_Sampler, imageView = m_ImageView, image = m_Image, + memory = m_Memory, stagingBuffer = m_StagingBuffer, stagingBufferMemory = m_StagingBufferMemory]() + { + VkDevice device = Application::GetDevice(); + + vkDestroySampler(device, sampler, nullptr); + vkDestroyImageView(device, imageView, nullptr); + vkDestroyImage(device, image, nullptr); + vkFreeMemory(device, memory, nullptr); + vkDestroyBuffer(device, stagingBuffer, nullptr); + vkFreeMemory(device, stagingBufferMemory, nullptr); + }); + + m_Sampler = nullptr; + m_ImageView = nullptr; + m_Image = nullptr; + m_Memory = nullptr; + m_StagingBuffer = nullptr; + m_StagingBufferMemory = nullptr; + } + void Image::SetData(const void* data) { VkDevice device = Application::GetDevice(); @@ -261,4 +273,18 @@ namespace Walnut { } } + void Image::Resize(uint32_t width, uint32_t height) + { + if (m_Image && m_Width == width && m_Height == height) + return; + + // TODO: max size? + + m_Width = width; + m_Height = height; + + Release(); + AllocateMemory(m_Width * m_Height * Utils::BytesPerPixel(m_Format)); + } + } \ No newline at end of file diff --git a/Walnut/src/Walnut/Image.h b/Walnut/src/Walnut/Image.h index a70b1446..e7a848d3 100644 --- a/Walnut/src/Walnut/Image.h +++ b/Walnut/src/Walnut/Image.h @@ -24,10 +24,13 @@ namespace Walnut { VkDescriptorSet GetDescriptorSet() const { return m_DescriptorSet; } + void Resize(uint32_t width, uint32_t height); + uint32_t GetWidth() const { return m_Width; } uint32_t GetHeight() const { return m_Height; } private: void AllocateMemory(uint64_t size); + void Release(); private: uint32_t m_Width = 0, m_Height = 0; From 20f940b9d23946d4836b8549ff3e2c0750c5d985 Mon Sep 17 00:00:00 2001 From: TheCherno Date: Tue, 23 Aug 2022 10:11:55 +1000 Subject: [PATCH 2/2] Added Input class and Layer::OnUpdate with timestep - Input class supports querying keyboard and mouse states --- Walnut/premake5.lua | 2 + Walnut/src/Walnut/Application.cpp | 25 ++++ Walnut/src/Walnut/Application.h | 9 ++ Walnut/src/Walnut/Input/Input.cpp | 38 ++++++ Walnut/src/Walnut/Input/Input.h | 20 ++++ Walnut/src/Walnut/Input/KeyCodes.h | 184 +++++++++++++++++++++++++++++ Walnut/src/Walnut/Layer.h | 1 + 7 files changed, 279 insertions(+) create mode 100644 Walnut/src/Walnut/Input/Input.cpp create mode 100644 Walnut/src/Walnut/Input/Input.h create mode 100644 Walnut/src/Walnut/Input/KeyCodes.h diff --git a/Walnut/premake5.lua b/Walnut/premake5.lua index d53fe2cf..c2d4b3e4 100644 --- a/Walnut/premake5.lua +++ b/Walnut/premake5.lua @@ -9,6 +9,8 @@ project "Walnut" includedirs { + "src", + "../vendor/imgui", "../vendor/glfw/include", "../vendor/stb_image", diff --git a/Walnut/src/Walnut/Application.cpp b/Walnut/src/Walnut/Application.cpp index cee68754..583b1066 100644 --- a/Walnut/src/Walnut/Application.cpp +++ b/Walnut/src/Walnut/Application.cpp @@ -12,6 +12,7 @@ #define GLFW_INCLUDE_VULKAN #include #include +#include #include @@ -54,6 +55,8 @@ static std::vector>> s_ResourceFreeQueue; // and is always guaranteed to increase (eg. 0, 1, 2, 0, 1, 2) static uint32_t s_CurrentFrameIndex = 0; +static Walnut::Application* s_Instance = nullptr; + void check_vk_result(VkResult err) { if (err == 0) @@ -384,12 +387,21 @@ namespace Walnut { Application::Application(const ApplicationSpecification& specification) : m_Specification(specification) { + s_Instance = this; + Init(); } Application::~Application() { Shutdown(); + + s_Instance = nullptr; + } + + Application& Application::Get() + { + return *s_Instance; } void Application::Init() @@ -557,6 +569,9 @@ namespace Walnut { // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); + for (auto& layer : m_LayerStack) + layer->OnUpdate(m_TimeStep); + // Resize swap chain? if (g_SwapChainRebuild) { @@ -659,6 +674,11 @@ namespace Walnut { // Present Main Platform Window if (!main_is_minimized) FramePresent(wd); + + float time = GetTime(); + m_FrameTime = time - m_LastFrameTime; + m_TimeStep = glm::min(m_FrameTime, 0.0333f); + m_LastFrameTime = time; } } @@ -668,6 +688,11 @@ namespace Walnut { m_Running = false; } + float Application::GetTime() + { + return (float)glfwGetTime(); + } + VkInstance Application::GetInstance() { return g_Instance; diff --git a/Walnut/src/Walnut/Application.h b/Walnut/src/Walnut/Application.h index 1e966a32..e4080eae 100644 --- a/Walnut/src/Walnut/Application.h +++ b/Walnut/src/Walnut/Application.h @@ -29,6 +29,8 @@ namespace Walnut { Application(const ApplicationSpecification& applicationSpecification = ApplicationSpecification()); ~Application(); + static Application& Get(); + void Run(); void SetMenubarCallback(const std::function& menubarCallback) { m_MenubarCallback = menubarCallback; } @@ -43,6 +45,9 @@ namespace Walnut { void Close(); + float GetTime(); + GLFWwindow* GetWindowHandle() const { return m_WindowHandle; } + static VkInstance GetInstance(); static VkPhysicalDevice GetPhysicalDevice(); static VkDevice GetDevice(); @@ -59,6 +64,10 @@ namespace Walnut { GLFWwindow* m_WindowHandle = nullptr; bool m_Running = false; + float m_TimeStep = 0.0f; + float m_FrameTime = 0.0f; + float m_LastFrameTime = 0.0f; + std::vector> m_LayerStack; std::function m_MenubarCallback; }; diff --git a/Walnut/src/Walnut/Input/Input.cpp b/Walnut/src/Walnut/Input/Input.cpp new file mode 100644 index 00000000..6f2340e2 --- /dev/null +++ b/Walnut/src/Walnut/Input/Input.cpp @@ -0,0 +1,38 @@ +#include "Input.h" + +#include "Walnut/Application.h" + +#include + +namespace Walnut { + + bool Input::IsKeyDown(KeyCode keycode) + { + GLFWwindow* windowHandle = Application::Get().GetWindowHandle(); + int state = glfwGetKey(windowHandle, (int)keycode); + return state == GLFW_PRESS || state == GLFW_REPEAT; + } + + bool Input::IsMouseButtonDown(MouseButton button) + { + GLFWwindow* windowHandle = Application::Get().GetWindowHandle(); + int state = glfwGetMouseButton(windowHandle, (int)button); + return state == GLFW_PRESS; + } + + glm::vec2 Input::GetMousePosition() + { + GLFWwindow* windowHandle = Application::Get().GetWindowHandle(); + + double x, y; + glfwGetCursorPos(windowHandle, &x, &y); + return { (float)x, (float)y }; + } + + void Input::SetCursorMode(CursorMode mode) + { + GLFWwindow* windowHandle = Application::Get().GetWindowHandle(); + glfwSetInputMode(windowHandle, GLFW_CURSOR, GLFW_CURSOR_NORMAL + (int)mode); + } + +} \ No newline at end of file diff --git a/Walnut/src/Walnut/Input/Input.h b/Walnut/src/Walnut/Input/Input.h new file mode 100644 index 00000000..de4192c6 --- /dev/null +++ b/Walnut/src/Walnut/Input/Input.h @@ -0,0 +1,20 @@ +#pragma once + +#include "KeyCodes.h" + +#include + +namespace Walnut { + + class Input + { + public: + static bool IsKeyDown(KeyCode keycode); + static bool IsMouseButtonDown(MouseButton button); + + static glm::vec2 GetMousePosition(); + + static void SetCursorMode(CursorMode mode); + }; + +} diff --git a/Walnut/src/Walnut/Input/KeyCodes.h b/Walnut/src/Walnut/Input/KeyCodes.h new file mode 100644 index 00000000..638926b1 --- /dev/null +++ b/Walnut/src/Walnut/Input/KeyCodes.h @@ -0,0 +1,184 @@ +#pragma once + +#include +#include + +namespace Walnut { + + typedef enum class KeyCode : uint16_t + { + // From glfw3.h + Space = 32, + Apostrophe = 39, /* ' */ + Comma = 44, /* , */ + Minus = 45, /* - */ + Period = 46, /* . */ + Slash = 47, /* / */ + + D0 = 48, /* 0 */ + D1 = 49, /* 1 */ + D2 = 50, /* 2 */ + D3 = 51, /* 3 */ + D4 = 52, /* 4 */ + D5 = 53, /* 5 */ + D6 = 54, /* 6 */ + D7 = 55, /* 7 */ + D8 = 56, /* 8 */ + D9 = 57, /* 9 */ + + Semicolon = 59, /* ; */ + Equal = 61, /* = */ + + A = 65, + B = 66, + C = 67, + D = 68, + E = 69, + F = 70, + G = 71, + H = 72, + I = 73, + J = 74, + K = 75, + L = 76, + M = 77, + N = 78, + O = 79, + P = 80, + Q = 81, + R = 82, + S = 83, + T = 84, + U = 85, + V = 86, + W = 87, + X = 88, + Y = 89, + Z = 90, + + LeftBracket = 91, /* [ */ + Backslash = 92, /* \ */ + RightBracket = 93, /* ] */ + GraveAccent = 96, /* ` */ + + World1 = 161, /* non-US #1 */ + World2 = 162, /* non-US #2 */ + + /* Function keys */ + Escape = 256, + Enter = 257, + Tab = 258, + Backspace = 259, + Insert = 260, + Delete = 261, + Right = 262, + Left = 263, + Down = 264, + Up = 265, + PageUp = 266, + PageDown = 267, + Home = 268, + End = 269, + CapsLock = 280, + ScrollLock = 281, + NumLock = 282, + PrintScreen = 283, + Pause = 284, + F1 = 290, + F2 = 291, + F3 = 292, + F4 = 293, + F5 = 294, + F6 = 295, + F7 = 296, + F8 = 297, + F9 = 298, + F10 = 299, + F11 = 300, + F12 = 301, + F13 = 302, + F14 = 303, + F15 = 304, + F16 = 305, + F17 = 306, + F18 = 307, + F19 = 308, + F20 = 309, + F21 = 310, + F22 = 311, + F23 = 312, + F24 = 313, + F25 = 314, + + /* Keypad */ + KP0 = 320, + KP1 = 321, + KP2 = 322, + KP3 = 323, + KP4 = 324, + KP5 = 325, + KP6 = 326, + KP7 = 327, + KP8 = 328, + KP9 = 329, + KPDecimal = 330, + KPDivide = 331, + KPMultiply = 332, + KPSubtract = 333, + KPAdd = 334, + KPEnter = 335, + KPEqual = 336, + + LeftShift = 340, + LeftControl = 341, + LeftAlt = 342, + LeftSuper = 343, + RightShift = 344, + RightControl = 345, + RightAlt = 346, + RightSuper = 347, + Menu = 348 + } Key; + + enum class KeyState + { + None = -1, + Pressed, + Held, + Released + }; + + enum class CursorMode + { + Normal = 0, + Hidden = 1, + Locked = 2 + }; + + typedef enum class MouseButton : uint16_t + { + Button0 = 0, + Button1 = 1, + Button2 = 2, + Button3 = 3, + Button4 = 4, + Button5 = 5, + Left = Button0, + Right = Button1, + Middle = Button2 + } Button; + + + inline std::ostream& operator<<(std::ostream& os, KeyCode keyCode) + { + os << static_cast(keyCode); + return os; + } + + inline std::ostream& operator<<(std::ostream& os, MouseButton button) + { + os << static_cast(button); + return os; + } +} + diff --git a/Walnut/src/Walnut/Layer.h b/Walnut/src/Walnut/Layer.h index d53142f8..0e82f8e1 100644 --- a/Walnut/src/Walnut/Layer.h +++ b/Walnut/src/Walnut/Layer.h @@ -10,6 +10,7 @@ namespace Walnut { virtual void OnAttach() {} virtual void OnDetach() {} + virtual void OnUpdate(float ts) {} virtual void OnUIRender() {} };