From 32ffd21076bfd0704e3eff0eef3b8bba97e31638 Mon Sep 17 00:00:00 2001 From: ohyzha Date: Sun, 25 Aug 2024 16:21:31 +0300 Subject: [PATCH] main loop improvements --- openVulkanoCpp/Base/EngineConfiguration.hpp | 14 +++++++-- openVulkanoCpp/Host/GraphicsAppManager.cpp | 34 ++++++++++++++++++--- openVulkanoCpp/Host/GraphicsAppManager.hpp | 2 ++ 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/openVulkanoCpp/Base/EngineConfiguration.hpp b/openVulkanoCpp/Base/EngineConfiguration.hpp index 347fec7..61ef440 100644 --- a/openVulkanoCpp/Base/EngineConfiguration.hpp +++ b/openVulkanoCpp/Base/EngineConfiguration.hpp @@ -9,6 +9,7 @@ #include #include #include +#include "Base/Event.hpp" #undef max namespace OpenVulkano @@ -34,10 +35,19 @@ namespace OpenVulkano void SetVSync(bool vSync) { m_vSync = vSync; } [[nodiscard]] int32_t GetFpsCap() const { return m_fpsCap; } - void SetFpsCap(int32_t fpsCap) { m_fpsCap = fpsCap; } + void SetFpsCap(int32_t fpsCap) + { + if (m_fpsCap != fpsCap) + { + m_fpsCap = fpsCap; + OnFpsCapChanged(fpsCap); + } + } [[nodiscard]] uint32_t GetPrefferedSwapChainImageCount() const { return m_preferredImageCount; } void SetPrefferedSwapChainImageCount(uint32_t preferredImageCount) { m_preferredImageCount = preferredImageCount; } + public: + Event OnFpsCapChanged; private: EngineConfiguration(); @@ -48,7 +58,7 @@ namespace OpenVulkano bool m_preferFramebufferFormatSRGB = true; bool m_lazyRendering = false; bool m_vSync = false; - int32_t m_fpsCap = 500; // -1 = no fps cap. 0 = fps cap if vsync, no cap otherwise. > 0 = set fps cap + int32_t m_fpsCap = -1; // -1 = no fps cap. 0 = fps cap if vsync, no cap otherwise. > 0 = set fps cap #ifdef __APPLE__ uint32_t m_preferredImageCount = 3; #else diff --git a/openVulkanoCpp/Host/GraphicsAppManager.cpp b/openVulkanoCpp/Host/GraphicsAppManager.cpp index 6d29b66..9377b56 100644 --- a/openVulkanoCpp/Host/GraphicsAppManager.cpp +++ b/openVulkanoCpp/Host/GraphicsAppManager.cpp @@ -41,6 +41,12 @@ namespace OpenVulkano window->SetWindowHandler(this); inputManager = Input::InputManager::GetInstance(); engineConfig = EngineConfiguration::GetEngineConfiguration(); + engineConfig->OnFpsCapChanged += EventHandler(this, &GraphicsAppManager::UpdateCappedFpsInfo); + // set initial values + if (engineConfig->GetFpsCap() > 0) + { + UpdateCappedFpsInfo(engineConfig->GetFpsCap()); + } } GraphicsAppManager::GraphicsAppManager(IGraphicsApp* app, IWindow* window, RenderAPI::RenderApi renderApi) @@ -63,19 +69,38 @@ namespace OpenVulkano window->SetWindowHandler(this); inputManager = OpenVulkano::Input::InputManager::GetInstance(); engineConfig = OpenVulkano::EngineConfiguration::GetEngineConfiguration(); + engineConfig->OnFpsCapChanged += EventHandler(this, &GraphicsAppManager::UpdateCappedFpsInfo); + // set initial values + if (engineConfig->GetFpsCap() > 0) + { + UpdateCappedFpsInfo(engineConfig->GetFpsCap()); + } + } + + void GraphicsAppManager::UpdateCappedFpsInfo(int32_t newFpsCap) + { + if (newFpsCap < 0) + { + cappedFrameTime = std::chrono::milliseconds(0); + } + else + { + cappedFrameTime = std::chrono::milliseconds(1000 / newFpsCap); + } } void GraphicsAppManager::OnCappedFPS(const auto& frameStartTime) { int32_t fpsCap = engineConfig->GetFpsCap(); fpsCapRemainder += 1000 % fpsCap; - auto frameTime = std::chrono::milliseconds(1000 / fpsCap); + auto expectedFrameTime = cappedFrameTime; if (fpsCapRemainder >= fpsCap) { - frameTime += std::chrono::milliseconds(1); + expectedFrameTime += std::chrono::milliseconds(1); fpsCapRemainder -= fpsCap; } - while (clock::now() < frameStartTime + frameTime) + auto frameEndTime = frameStartTime + expectedFrameTime; + while (clock::now() < frameEndTime) { std::this_thread::yield(); } @@ -84,6 +109,7 @@ namespace OpenVulkano GraphicsAppManager::~GraphicsAppManager() noexcept { if (windowTitleFormat.empty()) return; + engineConfig->OnFpsCapChanged -= EventHandler(this, &GraphicsAppManager::UpdateCappedFpsInfo); ShutDown(); } @@ -165,7 +191,7 @@ namespace OpenVulkano inputManager->Tick(); app->Tick(); if (CURRENT_FRAME.needsRedraw) renderer->Tick(); - if (engineConfig->GetFpsCap() > 0 && !engineConfig->GetVSync()) + if (cappedFrameTime.count()) { OnCappedFPS(start); } diff --git a/openVulkanoCpp/Host/GraphicsAppManager.hpp b/openVulkanoCpp/Host/GraphicsAppManager.hpp index d264e1b..d28490b 100644 --- a/openVulkanoCpp/Host/GraphicsAppManager.hpp +++ b/openVulkanoCpp/Host/GraphicsAppManager.hpp @@ -38,6 +38,7 @@ namespace OpenVulkano bool paused = false, running = false; float fpsTimer = 0, avgFps = 0, avgFrameTime = 0; uint64_t frameCount = 0, lastFrameCount = 0, fpsCapRemainder = 0; + std::chrono::milliseconds cappedFrameTime = std::chrono::milliseconds(0); Timer frameTimer; std::string windowTitleFormat; Input::InputManager* inputManager; @@ -45,6 +46,7 @@ namespace OpenVulkano private: void OnCappedFPS(const auto& frameStartTime); + void UpdateCappedFpsInfo(int32_t newFpsCap); public: explicit GraphicsAppManager(IGraphicsApp* app, RenderAPI::RenderApi renderApi = RenderAPI::Vulkan);