aboutsummaryrefslogtreecommitdiff
path: root/src/Core/Application.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Core/Application.cpp')
-rw-r--r--src/Core/Application.cpp124
1 files changed, 92 insertions, 32 deletions
diff --git a/src/Core/Application.cpp b/src/Core/Application.cpp
index df42877..c73dc6d 100644
--- a/src/Core/Application.cpp
+++ b/src/Core/Application.cpp
@@ -8,10 +8,14 @@
#include "States/WorldBuilderState.h"
#include <GLFW/glfw3.h>
+#include <imgui.h>
#include <ImGuizmo.h>
+#include "Platform/Vulkan/VulkanRenderer.h"
+
#ifdef __APPLE__
#include "Platform/Metal/MetalContext.h"
+#include "Platform/Vulkan/VulkanContext.h"
#endif
namespace Donut
@@ -23,8 +27,21 @@ namespace Donut
{
s_Instance = this;
+ // Select the render API before the window is created: the window is
+ // built differently for Vulkan (GLFW_NO_API) than for OpenGL.
+ Logger::Init();
+ SettingsManager::Initialize();
+ {
+ const auto& settings = SettingsManager::GetSettingsConst();
+ RendererAPI::SetAPI(settings.graphics.renderAPI == "Vulkan"
+ ? RendererAPI::API::Vulkan : RendererAPI::API::OpenGL);
+ }
+
+ if (RendererAPI::GetAPI() == RendererAPI::API::Vulkan)
+ VulkanPrepareGLFW(); // must precede glfwInit() inside the Window ctor
+
m_Window = CreateScope<Window>(name, width, height);
- m_Window->SetEventCallback([this](Event& event)
+ m_Window->SetEventCallback([this](Event& event)
{
OnEvent(event);
});
@@ -42,16 +59,39 @@ namespace Donut
{
while (m_Running)
{
- if (!m_Minimized)
+ if (m_VulkanRenderer)
{
- OnUpdate();
- OnRender();
+ glfwPollEvents(); // before the ImGui frame so input is current
+ if (!m_Minimized)
+ m_VulkanRenderer->DrawFrame(glm::vec4(0.05f, 0.06f, 0.10f, 1.0f),
+ [this] { BuildVulkanUI(); });
+ }
+ else
+ {
+ if (!m_Minimized)
+ {
+ OnUpdate();
+ OnRender();
+ }
+ m_Window->OnUpdate(); // polls events + swaps buffers (OpenGL)
}
-
- m_Window->OnUpdate();
}
}
+ void Application::BuildVulkanUI()
+ {
+ // Placeholder UI proving the ImGui Vulkan backend renders. The real
+ // application UI (states' OnImUIRender) moves here once the scene is
+ // ported to Vulkan (B-3).
+ ImGui::Begin("Donut - Vulkan backend");
+ ImGui::Text("Geodesic black hole through Vulkan (MoltenVK).");
+ ImGui::Text("%.1f FPS", ImGui::GetIO().Framerate);
+ ImGui::Separator();
+ ImGui::TextWrapped("Drag to orbit, scroll to zoom. HDRI starfield is live; "
+ "next is porting the simulation UI to Vulkan.");
+ ImGui::End();
+ }
+
void Application::Close()
{
m_Running = false;
@@ -73,15 +113,24 @@ namespace Donut
m_Minimized = true;
else
m_Minimized = false;
-
- Renderer::OnWindowResize(e.GetWidth(), e.GetHeight());
- m_Engine->SetWindowDimensions(e.GetWidth(), e.GetHeight());
+
+ if (m_VulkanRenderer)
+ {
+ m_VulkanRenderer->OnResize(e.GetWidth(), e.GetHeight());
+ }
+ else
+ {
+ Renderer::OnWindowResize(e.GetWidth(), e.GetHeight());
+ if (m_Engine) m_Engine->SetWindowDimensions(e.GetWidth(), e.GetHeight());
+ }
event.Handled = true;
return true;
});
- dispatcher.Dispatch<KeyPressedEvent>([this, &event](KeyPressedEvent& e)
+ dispatcher.Dispatch<KeyPressedEvent>([this, &event](KeyPressedEvent& e)
{
+ if (!m_StateManager)
+ return true;
if (e.GetKeyCode() == GLFW_KEY_1)
{
m_StateManager->SwitchToState("Config");
@@ -103,34 +152,38 @@ namespace Donut
return true;
});
-
- m_StateManager->OnEvent(event);
+
+ if (m_StateManager)
+ m_StateManager->OnEvent(event);
}
void Application::OnInit()
{
- Logger::Init();
+ // (Logger, settings and API selection happen in the constructor.)
+
+ if (RendererAPI::GetAPI() == RendererAPI::API::Vulkan)
+ {
+ int w = 0, h = 0;
+ glfwGetFramebufferSize((GLFWwindow*)m_Window->GetNativeWindow(), &w, &h);
+ m_VulkanRenderer = CreateScope<VulkanRenderer>();
+ if (!m_VulkanRenderer->Init(m_Window->GetNativeWindow(), w, h))
+ DONUT_ERROR("Vulkan renderer initialization failed");
+ else
+ m_VulkanRenderer->InitImGui();
+ // Scene rendering hooks in here in the B-3 phase; the Vulkan path now
+ // clears, presents, and draws the ImGui UI.
+ return;
+ }
-#ifdef __APPLE__
- MetalProbe(); // Phase 1: native Metal device available?
- MetalComputeSelfTest(); // Phase 1: full compute dispatch + read-back works?
-#endif
-
- SettingsManager::Initialize();
-
- const auto& settings = SettingsManager::GetSettingsConst();
- RendererAPI::API api = (settings.graphics.renderAPI == "Vulkan") ? RendererAPI::API::Vulkan : RendererAPI::API::OpenGL;
- RendererAPI::SetAPI(api);
-
Renderer::Init();
m_Window->InitImGui();
-
+
Renderer::OnWindowResize(1280, 720);
RenderCommand::SetFaceCulling(false);
m_Engine = CreateScope<Engine>();
m_Engine->SetWindowDimensions(1280, 720);
-
+
m_StateManager = CreateScope<StateManager>();
m_StateManager->RegisterState("Config", CreateScope<ConfigState>());
m_StateManager->RegisterState("Simulation", CreateScope<SimulationState>());
@@ -138,12 +191,19 @@ namespace Donut
m_StateManager->SwitchToState("Config");
}
- void Application::OnShutdown()
- {
- if (m_StateManager)
- m_StateManager->Shutdown();
-
- Renderer::Shutdown();
+ void Application::OnShutdown()
+ {
+ if (m_VulkanRenderer)
+ {
+ m_VulkanRenderer->Shutdown();
+ m_VulkanRenderer.reset();
+ }
+ else
+ {
+ if (m_StateManager)
+ m_StateManager->Shutdown();
+ Renderer::Shutdown();
+ }
SettingsManager::Shutdown();
Logger::Shutdown();
}