Add Event system
- Add abstract Event class - Add EventDispatcher - Add Mouse, Key and Window Events
This commit is contained in:
@@ -1,6 +1,13 @@
|
||||
#include "copium/core/Application.h"
|
||||
|
||||
#include "copium/core/Vulkan.h"
|
||||
#include "copium/event/EventDispatcher.h"
|
||||
#include "copium/event/MouseMoveEvent.h"
|
||||
#include "copium/event/MouseScrollEvent.h"
|
||||
#include "copium/event/MousePressEvent.h"
|
||||
#include "copium/event/KeyPressEvent.h"
|
||||
#include "copium/event/WindowFocusEvent.h"
|
||||
#include "copium/event/WindowResizeEvent.h"
|
||||
#include "copium/mesh/Vertex.h"
|
||||
#include "copium/mesh/VertexPassthrough.h"
|
||||
#include "copium/asset/AssetManager.h"
|
||||
@@ -38,6 +45,7 @@ namespace Copium
|
||||
|
||||
Application::Application()
|
||||
{
|
||||
EventDispatcher::AddEventHandler(this);
|
||||
InitializeFrameBuffer();
|
||||
InitializeRenderer();
|
||||
InitializeGraphicsPipeline();
|
||||
@@ -55,6 +63,7 @@ namespace Copium
|
||||
AssetManager::UnloadAsset(graphicsPipeline);
|
||||
AssetManager::UnloadAsset(graphicsPipelinePassthrough);
|
||||
AssetManager::UnloadAsset(framebuffer);
|
||||
EventDispatcher::RemoveEventHandler(this);
|
||||
}
|
||||
|
||||
bool Application::Update()
|
||||
@@ -69,6 +78,58 @@ namespace Copium
|
||||
return !glfwWindowShouldClose(Vulkan::GetWindow().GetWindow());
|
||||
}
|
||||
|
||||
EventResult Application::OnEvent(const Event& event)
|
||||
{
|
||||
switch (event.GetType())
|
||||
{
|
||||
case EventType::WindowResize:
|
||||
{
|
||||
const WindowResizeEvent& windowResizeEvent = static_cast<const WindowResizeEvent&>(event);
|
||||
AssetManager::GetAsset<Framebuffer>(framebuffer).Resize(windowResizeEvent.GetWidth(), windowResizeEvent.GetHeight());
|
||||
descriptorSetPassthrough->SetSampler(AssetManager::GetAsset<Framebuffer>(framebuffer).GetColorAttachment(), 0);
|
||||
|
||||
return EventResult::Continue;
|
||||
}
|
||||
case EventType::MouseMove:
|
||||
{
|
||||
const MouseMoveEvent& mouseMoveEvent = static_cast<const MouseMoveEvent&>(event);
|
||||
mousePos = {mouseMoveEvent.GetPos().x / Vulkan::GetSwapChain().GetExtent().width, mouseMoveEvent.GetPos().y / Vulkan::GetSwapChain().GetExtent().height};
|
||||
|
||||
return EventResult::Continue;
|
||||
}
|
||||
case EventType::MousePress:
|
||||
{
|
||||
const MousePressEvent& mousePressEvent = static_cast<const MousePressEvent&>(event);
|
||||
CP_INFO("%d", mousePressEvent.GetButton());
|
||||
|
||||
return EventResult::Focus;
|
||||
}
|
||||
case EventType::KeyPress:
|
||||
{
|
||||
const KeyPressEvent& keyPressEvent = static_cast<const KeyPressEvent&>(event);
|
||||
CP_INFO("%d", keyPressEvent.GetButton());
|
||||
|
||||
return EventResult::Handled;
|
||||
}
|
||||
case EventType::MouseScroll:
|
||||
{
|
||||
const MouseScrollEvent& mouseScrollEvent = static_cast<const MouseScrollEvent&>(event);
|
||||
CP_INFO("%d %d", mouseScrollEvent.GetScrollX(), mouseScrollEvent.GetScrollY());
|
||||
|
||||
return EventResult::Continue;
|
||||
}
|
||||
case EventType::WindowFocus:
|
||||
{
|
||||
const WindowFocusEvent& windowFocusEvent = static_cast<const WindowFocusEvent&>(event);
|
||||
CP_INFO("Window Focused: %s", windowFocusEvent.IsFocused() ? "true" : "false");
|
||||
|
||||
return EventResult::Continue;
|
||||
}
|
||||
}
|
||||
|
||||
return EventResult::Continue;
|
||||
}
|
||||
|
||||
void Application::InitializeFrameBuffer()
|
||||
{
|
||||
framebuffer = AssetManager::LoadAsset<Framebuffer>("framebuffer.meta");
|
||||
@@ -143,6 +204,7 @@ namespace Copium
|
||||
}
|
||||
renderer->Quad(glm::vec2{-0.9, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D));
|
||||
renderer->Quad(glm::vec2{ 0.1, -0.4}, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D2));
|
||||
renderer->Quad(mousePos, glm::vec2{0.8, 0.8}, AssetManager::GetAsset<Texture2D>(texture2D2));
|
||||
renderer->End();
|
||||
|
||||
fb.Unbind(*commandBuffer);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "copium/asset/AssetMeta.h"
|
||||
#include "copium/buffer/Framebuffer.h"
|
||||
#include "copium/event/EventHandler.h"
|
||||
#include "copium/mesh/Mesh.h"
|
||||
#include "copium/pipeline/DescriptorPool.h"
|
||||
#include "copium/pipeline/DescriptorSet.h"
|
||||
@@ -10,7 +11,7 @@
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
class Application final
|
||||
class Application final : EventHandler
|
||||
{
|
||||
CP_DELETE_COPY_AND_MOVE_CTOR(Application);
|
||||
private:
|
||||
@@ -27,12 +28,14 @@ namespace Copium
|
||||
std::unique_ptr<Mesh> mesh;
|
||||
std::unique_ptr<Mesh> meshPassthrough;
|
||||
std::unique_ptr<CommandBuffer> commandBuffer;
|
||||
glm::vec2 mousePos;
|
||||
|
||||
public:
|
||||
Application();
|
||||
~Application();
|
||||
|
||||
bool Update();
|
||||
EventResult OnEvent(const Event& event) override;
|
||||
private:
|
||||
void InitializeFrameBuffer();
|
||||
void InitializeRenderer();
|
||||
|
||||
@@ -1,75 +1,120 @@
|
||||
#include "copium/core/Window.h"
|
||||
|
||||
#include "copium/core/Vulkan.h"
|
||||
#include "copium/event/EventDispatcher.h"
|
||||
#include "copium/event/KeyPressEvent.h"
|
||||
#include "copium/event/KeyReleaseEvent.h"
|
||||
#include "copium/event/MouseMoveEvent.h"
|
||||
#include "copium/event/MousePressEvent.h"
|
||||
#include "copium/event/MouseReleaseEvent.h"
|
||||
#include "copium/event/MouseScrollEvent.h"
|
||||
#include "copium/event/WindowResizeEvent.h"
|
||||
#include "copium/event/WindowFocusEvent.h"
|
||||
|
||||
namespace Copium
|
||||
{
|
||||
Window::Window(const std::string& windowName, int width, int height, Mode mode)
|
||||
Window::Window(const std::string& windowName, int width, int height, Mode mode)
|
||||
{
|
||||
InitializeWindow(windowName, width, height, mode);
|
||||
InitializeSurface();
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
vkDestroySurfaceKHR(Vulkan::GetInstance(), surface, nullptr);
|
||||
glfwDestroyWindow(window);
|
||||
}
|
||||
|
||||
VkSurfaceKHR Window::GetSurface() const
|
||||
{
|
||||
return surface;
|
||||
}
|
||||
|
||||
GLFWwindow* Window::GetWindow()
|
||||
{
|
||||
return window;
|
||||
}
|
||||
|
||||
void Window::InitializeWindow(const std::string& windowName, int width, int height, Mode mode)
|
||||
{
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
InitializeWindow(windowName, width, height, mode);
|
||||
InitializeSurface();
|
||||
case Mode::Fullscreen:
|
||||
{
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
window = glfwCreateWindow(mode->width, mode->height, windowName.c_str(), glfwGetPrimaryMonitor(), nullptr);
|
||||
break;
|
||||
}
|
||||
case Mode::BorderlessWindowed:
|
||||
{
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
window = glfwCreateWindow(mode->width, mode->height, windowName.c_str(), nullptr, nullptr);
|
||||
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
|
||||
break;
|
||||
}
|
||||
case Mode::Windowed:
|
||||
{
|
||||
window = glfwCreateWindow(width, height, windowName.c_str(), nullptr, nullptr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CP_ABORT("Unreachable switch case");
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
{
|
||||
vkDestroySurfaceKHR(Vulkan::GetInstance(), surface, nullptr);
|
||||
glfwDestroyWindow(window);
|
||||
}
|
||||
CP_ASSERT(window, "Failed to initialize glfw window");
|
||||
|
||||
VkSurfaceKHR Window::GetSurface() const
|
||||
{
|
||||
return surface;
|
||||
}
|
||||
glfwSetWindowUserPointer(window, this);
|
||||
glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback);
|
||||
glfwSetKeyCallback(window, KeyCallback);
|
||||
glfwSetMouseButtonCallback(window, MouseButtonCallback);
|
||||
glfwSetCursorPosCallback(window, MouseMoveCallback);
|
||||
glfwSetWindowFocusCallback(window, WindowFocusCallback);
|
||||
glfwSetScrollCallback(window, MouseScrollCallback);
|
||||
}
|
||||
|
||||
GLFWwindow* Window::GetWindow()
|
||||
{
|
||||
return window;
|
||||
}
|
||||
void Window::InitializeSurface()
|
||||
{
|
||||
CP_VK_ASSERT(glfwCreateWindowSurface(Vulkan::GetInstance(), window, nullptr, &surface), "Failed to create Vulkan surface");
|
||||
}
|
||||
|
||||
void Window::InitializeWindow(const std::string& windowName, int width, int height, Mode mode)
|
||||
{
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
void Window::FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height)
|
||||
{
|
||||
Vulkan::GetSwapChain().ResizeFramebuffer();
|
||||
EventDispatcher::QueueEvent(WindowResizeEvent{width, height});
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case Mode::Fullscreen:
|
||||
{
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
window = glfwCreateWindow(mode->width, mode->height, windowName.c_str(), glfwGetPrimaryMonitor(), nullptr);
|
||||
break;
|
||||
}
|
||||
case Mode::BorderlessWindowed:
|
||||
{
|
||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||
window = glfwCreateWindow(mode->width, mode->height, windowName.c_str(), nullptr, nullptr);
|
||||
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
|
||||
break;
|
||||
}
|
||||
case Mode::Windowed:
|
||||
{
|
||||
window = glfwCreateWindow(width, height, windowName.c_str(), nullptr, nullptr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CP_ABORT("Unreachable switch case");
|
||||
}
|
||||
void Window::KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
{
|
||||
if (action == GLFW_PRESS)
|
||||
EventDispatcher::QueueEvent(KeyPressEvent(key));
|
||||
else if (action == GLFW_RELEASE)
|
||||
EventDispatcher::QueueEvent(KeyReleaseEvent(key));
|
||||
}
|
||||
|
||||
CP_ASSERT(window, "Failed to initialize glfw window");
|
||||
void Window::MouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
|
||||
{
|
||||
if (action == GLFW_PRESS)
|
||||
EventDispatcher::QueueEvent(MousePressEvent{button});
|
||||
else if (action == GLFW_RELEASE)
|
||||
EventDispatcher::QueueEvent(MouseReleaseEvent{button});
|
||||
}
|
||||
|
||||
glfwSetWindowUserPointer(window, this);
|
||||
glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback);
|
||||
}
|
||||
void Window::MouseMoveCallback(GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
EventDispatcher::QueueEvent(MouseMoveEvent{glm::vec2{xpos, ypos}}); // TODO: Convert to Vulkan coordinates
|
||||
}
|
||||
|
||||
void Window::InitializeSurface()
|
||||
{
|
||||
CP_VK_ASSERT(glfwCreateWindowSurface(Vulkan::GetInstance(), window, nullptr, &surface), "Failed to create Vulkan surface");
|
||||
}
|
||||
|
||||
void Window::FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height)
|
||||
{
|
||||
Vulkan::GetSwapChain().ResizeFramebuffer(); // TODO: Should maybe be handled by an event system?
|
||||
}
|
||||
void Window::WindowFocusCallback(GLFWwindow* window, int focused)
|
||||
{
|
||||
EventDispatcher::QueueEvent(WindowFocusEvent{focused == GLFW_TRUE});
|
||||
}
|
||||
|
||||
void Window::MouseScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
EventDispatcher::QueueEvent(MouseScrollEvent{(int)xoffset, (int)yoffset});
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,12 @@ namespace Copium
|
||||
private:
|
||||
void InitializeWindow(const std::string& windowName, int width, int height, Mode mode);
|
||||
void InitializeSurface();
|
||||
static void FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height);
|
||||
|
||||
static void FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height);
|
||||
static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
static void MouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
|
||||
static void MouseMoveCallback(GLFWwindow* window, double xpos, double ypos);
|
||||
static void WindowFocusCallback(GLFWwindow* window, int focused);
|
||||
static void MouseScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user