From 962e66396a476ce5ddce8a3daead103d7df719e8 Mon Sep 17 00:00:00 2001 From: Thraix Date: Wed, 15 Jul 2026 17:38:09 +0200 Subject: [PATCH] Add Application class --- CopiumEngine/src/copium/app/Application.cpp | 20 +++ CopiumEngine/src/copium/app/Application.h | 19 +++ .../src/copium/app/Basic2DApplication.cpp | 134 ++++++++++++++++++ .../src/copium/app/Basic2DApplication.h | 57 ++++++++ CopiumEngine/src/copium/asset/AssetRef.h | 6 + CopiumEngine/src/copium/core/Vulkan.cpp | 1 + 6 files changed, 237 insertions(+) create mode 100644 CopiumEngine/src/copium/app/Application.cpp create mode 100644 CopiumEngine/src/copium/app/Application.h create mode 100644 CopiumEngine/src/copium/app/Basic2DApplication.cpp create mode 100644 CopiumEngine/src/copium/app/Basic2DApplication.h diff --git a/CopiumEngine/src/copium/app/Application.cpp b/CopiumEngine/src/copium/app/Application.cpp new file mode 100644 index 0000000..4d24518 --- /dev/null +++ b/CopiumEngine/src/copium/app/Application.cpp @@ -0,0 +1,20 @@ +#include "copium/app/Application.h" + +#include + +#include "copium/event/EventDispatcher.h" +#include "copium/event/Input.h" + +namespace Copium +{ + + void Application::Run() + { + while (Update()) + { + Input::Update(); + glfwPollEvents(); + EventDispatcher::Dispatch(); + } + } +} diff --git a/CopiumEngine/src/copium/app/Application.h b/CopiumEngine/src/copium/app/Application.h new file mode 100644 index 0000000..6c90628 --- /dev/null +++ b/CopiumEngine/src/copium/app/Application.h @@ -0,0 +1,19 @@ +#pragma once + +#include "copium/util/Common.h" + +namespace Copium +{ + + class Application + { + public: + Application() = default; + virtual ~Application() = default; + void Run(); + virtual bool Update() = 0; + + private: + CP_DELETE_COPY_AND_MOVE_CTOR(Application); + }; +} diff --git a/CopiumEngine/src/copium/app/Basic2DApplication.cpp b/CopiumEngine/src/copium/app/Basic2DApplication.cpp new file mode 100644 index 0000000..18a2d3a --- /dev/null +++ b/CopiumEngine/src/copium/app/Basic2DApplication.cpp @@ -0,0 +1,134 @@ +#include "copium/app/Basic2DApplication.h" + +#include +#include + +#include "copium/core/Vulkan.h" +#include "copium/event/EventDispatcher.h" +#include "copium/event/WindowResizeEvent.h" +#include "copium/renderer/RendererVertex.h" + +namespace Copium +{ + Basic2DApplication::Basic2DApplication(bool realTimeApplication, + const std::string& vertexShader, + const std::string& fragmentShader) + : realTimeApplication{realTimeApplication} + { + EventDispatcher::AddEventHandler(this); + + PipelineCreator pipelineCreator{Vulkan::GetSwapChain().GetRenderPass(), vertexShader, fragmentShader}; + pipelineCreator.SetVertexDescriptor(RendererVertex::GetDescriptor()); + renderer = std::make_unique(AssetRef(std::make_unique(pipelineCreator))); + + Pipeline& pl = renderer->GetGraphicsPipeline(); + + commandBuffer = std::make_unique(CommandBufferType::Dynamic); + descriptorPool = std::make_unique(SwapChain::MAX_FRAMES_IN_FLIGHT * 2, 0); + + projectionDescriptorSet = pl.CreateDescriptorSet(*descriptorPool, 1); + viewDescriptorSet = pl.CreateDescriptorSet(*descriptorPool, 2); + + float ratio = Vulkan::GetWindow().GetWidth() / (float)Vulkan::GetWindow().GetHeight(); + SetViewMatrixStatic(glm::translate(glm::mat4{1}, glm::vec3{0, 0, 0})); + SetProjectionMatrixStatic(glm::ortho(0, ratio, 0, 1)); + + pl.SetDescriptorSet(*viewDescriptorSet); + pl.SetDescriptorSet(*projectionDescriptorSet); + } + + Basic2DApplication::~Basic2DApplication() + { + EventDispatcher::RemoveEventHandler(this); + } + + EventResult Basic2DApplication::OnEvent(const Event& event) + { + switch (event.GetType()) + { + case Copium::EventType::WindowResize: + { + const WindowResizeEvent& windowResize = static_cast(event); + float ratio = windowResize.GetWidth() / (float)windowResize.GetHeight(); + SetProjectionMatrixStatic(glm::ortho(0, ratio, 0, 1)); + Redraw(); + break; + } + default: + break; + } + return EventResult::Continue; + } + + void Basic2DApplication::PreRender() + { + } + + void Basic2DApplication::PostRender() + { + } + + bool Basic2DApplication::Update() + { + PreRender(); + if (!realTimeApplication && redrawCount <= 0) + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + return !Vulkan::GetWindow().ShouldClose(); + } + + if (!Vulkan::GetSwapChain().BeginPresent()) + return true; + + commandBuffer->Begin(); + + Vulkan::GetSwapChain().BeginFrameBuffer(*commandBuffer); + renderer->Begin(*commandBuffer); + Render(*renderer); + renderer->End(); + Vulkan::GetSwapChain().EndFrameBuffer(*commandBuffer); + + commandBuffer->End(); + + Vulkan::GetSwapChain().SubmitToGraphicsQueue(*commandBuffer); + + Vulkan::GetSwapChain().EndPresent(); + if (!realTimeApplication) + redrawCount--; + PostRender(); + return !Vulkan::GetWindow().ShouldClose(); + } + + void Basic2DApplication::SetViewMatrix(const glm::mat4& viewMatrix) + { + UniformBuffer& viewUbo = viewDescriptorSet->GetUniformBuffer("viewUbo"); + viewUbo.Set("view", glm::translate(glm::mat4{1}, glm::vec3{0, 0, 0})); + viewUbo.Update(); + } + + void Basic2DApplication::SetViewMatrixStatic(const glm::mat4& viewMatrix) + { + UniformBuffer& viewUbo = viewDescriptorSet->GetUniformBuffer("viewUbo"); + viewUbo.Set("view", glm::translate(glm::mat4{1}, glm::vec3{0, 0, 0})); + viewUbo.UpdateStatic(); + } + + void Basic2DApplication::SetProjectionMatrix(const glm::mat4& projectionMatrix) + { + UniformBuffer& projectionUbo = projectionDescriptorSet->GetUniformBuffer("projectionUbo"); + projectionUbo.Set("projection", projectionMatrix); + projectionUbo.Update(); + } + + void Basic2DApplication::SetProjectionMatrixStatic(const glm::mat4& projectionMatrix) + { + UniformBuffer& projectionUbo = projectionDescriptorSet->GetUniformBuffer("projectionUbo"); + projectionUbo.Set("projection", projectionMatrix); + projectionUbo.UpdateStatic(); + } + + void Basic2DApplication::Redraw() + { + redrawCount = SwapChain::MAX_FRAMES_IN_FLIGHT; + } +} diff --git a/CopiumEngine/src/copium/app/Basic2DApplication.h b/CopiumEngine/src/copium/app/Basic2DApplication.h new file mode 100644 index 0000000..3dd4d0d --- /dev/null +++ b/CopiumEngine/src/copium/app/Basic2DApplication.h @@ -0,0 +1,57 @@ +#pragma once +#include + +#include "copium/app/Application.h" +#include "copium/buffer/CommandBuffer.h" +#include "copium/core/Vulkan.h" +#include "copium/event/EventHandler.h" +#include "copium/renderer/Renderer.h" + +namespace Copium +{ + // TODO: Better name? + class Basic2DApplication : public Application, public EventHandler + { + private: + struct VulkanWrapper + { + VulkanWrapper() + { + Vulkan::Initialize(); + } + + ~VulkanWrapper() + { + Vulkan::Destroy(); + } + }; + + public: + Basic2DApplication(bool realTimeApplication, const std::string& vertexShader, const std::string& fragmentShader); + ~Basic2DApplication(); + + virtual EventResult OnEvent(const Event& event) override; + + virtual void PreRender(); + virtual void Render(Renderer& renderer) = 0; + virtual void PostRender(); + bool Update() override; + + void SetViewMatrix(const glm::mat4& viewMatrix); + void SetViewMatrixStatic(const glm::mat4& viewMatrix); + void SetProjectionMatrix(const glm::mat4& projectionMatrix); + void SetProjectionMatrixStatic(const glm::mat4& projectionMatrix); + void Redraw(); + + private: + bool realTimeApplication; + int redrawCount{2}; + + VulkanWrapper vulkan; + std::unique_ptr renderer; + std::unique_ptr commandBuffer; + std::unique_ptr descriptorPool; + std::unique_ptr projectionDescriptorSet; + std::unique_ptr viewDescriptorSet; + }; +} diff --git a/CopiumEngine/src/copium/asset/AssetRef.h b/CopiumEngine/src/copium/asset/AssetRef.h index 106ace2..47cc39c 100644 --- a/CopiumEngine/src/copium/asset/AssetRef.h +++ b/CopiumEngine/src/copium/asset/AssetRef.h @@ -73,6 +73,12 @@ namespace Copium return *id != NULL_ASSET_ID; } + void Reset() + { + AssetManager::UnloadAsset(*id); + *id = NULL_ASSET_ID; + } + private: struct AssetIdUnloader { diff --git a/CopiumEngine/src/copium/core/Vulkan.cpp b/CopiumEngine/src/copium/core/Vulkan.cpp index b6272b9..4baf2ab 100644 --- a/CopiumEngine/src/copium/core/Vulkan.cpp +++ b/CopiumEngine/src/copium/core/Vulkan.cpp @@ -66,6 +66,7 @@ namespace Copium device.reset(); window.reset(); instance.reset(); + glfwTerminate(); } Instance& Vulkan::GetInstance()