diff options
Diffstat (limited to 'src/Core/Application.cpp')
| -rw-r--r-- | src/Core/Application.cpp | 124 |
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(); } |
