#include #include #include #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_vulkan.h" #include "utilities/Logger.h" #include "GlfwWindowManager.h" #include "VulkanContext.h" struct AppConfig { std::string Title = "Learning Vulkan"; uint32_t Width = 800; uint32_t Height = 600; bool bResizable = true; bool bFullscreen = false; bool bValidationEnabled = false; bool bVerboseLogging = false; }; // const std::vector TriangleVertices = { // { { 0.0f, -0.5f }, { 1.0f, 1.0f, 1.0f } }, // { { 0.5f, 0.5f }, { 0.0f, 1.0f, 0.0f } }, // { { -0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f } } // }; const std::vector SquareVertices = { { { -0.5f, -0.5f }, { 1.0f, 0.0f, 0.0f } }, { { 0.5f, -0.5f }, { 0.0f, 1.0f, 0.0f } }, { { 0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f } }, { { -0.5f, 0.5f }, { 1.0f, 1.0f, 1.0f } } }; const std::vector SquareIndices = { 0, 1, 2, 2, 3, 0 }; class HelloTriangleApplication { public: void Run() { Initialization(); Log::Info("Initialization finished..."); MainLoop(); Cleanup(); } private: AppConfig Settings = {}; GlfwWindowManager WindowManager; VulkanContext VkContext; bool bShowImGui = false; bool bShowDemo = false; static void KeyCallback(GLFWwindow* Window, int Key, int Scancode, int Action, int Mods) { auto App = reinterpret_cast(glfwGetWindowUserPointer(Window)); if (Action == GLFW_PRESS || Action == GLFW_REPEAT) { App->OnKey(Key); } } void OnKey(int Key) { switch (Key) { case GLFW_KEY_O: bShowImGui = !bShowImGui; Log::Info("ImGui visibility toggled: " + std::string(bShowImGui ? "ON" : "OFF")); break; case GLFW_KEY_L: bShowDemo = !bShowDemo; Log::Info("Demo window toggled: " + std::string(bShowDemo ? "ON" : "OFF")); break; } } void Initialization() { InitGlfw(); InitVulkan(); IMGUI_CHECKVERSION(); ImGui::CreateContext(); VkContext.InitImGui(); } void InitVulkan() { FVulkanConfig Config = { Settings.bValidationEnabled, Settings.bVerboseLogging, WindowManager.GetWindow(), }; VkContext.Initialize(Config, SquareVertices, SquareIndices); } void InitGlfw() { FWindowConfig Config = { Settings.Title, Settings.Width, Settings.Height, Settings.bResizable, Settings.bFullscreen }; WindowManager.Initialize(Config); glfwSetWindowUserPointer(WindowManager.GetWindow(), this); glfwSetFramebufferSizeCallback(WindowManager.GetWindow(), FramebufferResizeCallback); WindowManager.SetKeyCallback(KeyCallback); } static void FramebufferResizeCallback(GLFWwindow* Window, int Width, int Height) { auto App = reinterpret_cast(glfwGetWindowUserPointer(Window)); App->VkContext.SetFramebufferResized(true); } void MainLoop() { VkPhysicalDeviceProperties Properties{}; vkGetPhysicalDeviceProperties(VkContext.DeviceManager.GetPhysicalDevice(), &Properties); while (!WindowManager.ShouldClose()) { WindowManager.PollEvents(); if (bShowImGui) { ImGui_ImplVulkan_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); if (bShowDemo) { ImGui::ShowDemoWindow(); } else { ImGui::Begin(Properties.deviceName); ImGui::Text("Application average %.1f FPS", ImGui::GetIO().Framerate); ImGui::End(); } } VkContext.DrawFrame(bShowImGui, SquareVertices.size(), SquareIndices.size()); } } void Cleanup() { Log::Info("Cleaning up..."); VkContext.Cleanup(); WindowManager.Cleanup(); ImGui::DestroyContext(); } }; int main() { HelloTriangleApplication app; try { app.Run(); } catch (const std::exception& e) { Log::Error(e.what()); return EXIT_FAILURE; } return EXIT_SUCCESS; }