diff --git a/openVulkanoCpp/Base/EngineConfiguration.hpp b/openVulkanoCpp/Base/EngineConfiguration.hpp index 27f299f..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(); diff --git a/openVulkanoCpp/Base/Version.cpp b/openVulkanoCpp/Base/Version.cpp index c2c6547..f9f39cc 100644 --- a/openVulkanoCpp/Base/Version.cpp +++ b/openVulkanoCpp/Base/Version.cpp @@ -34,7 +34,7 @@ namespace OpenVulkano offset++; ReadTagComponents(tagComponents, versionStr, offset); } - if (versionStr.size() - 3 > offset && versionStr[offset] == ' ' && versionStr[offset + 1] == '(' && versionStr.back() == ')') + if (versionStr.size() > 3 && versionStr.size() - 3 > offset && versionStr[offset] == ' ' && versionStr[offset + 1] == '(' && versionStr.back() == ')') { ReadVersionComponents(appleBuildComponents, versionStr, offset); if (versionStr[offset] != ')') appleBuildComponents.clear(); @@ -69,7 +69,7 @@ namespace OpenVulkano size_t blockStart = offset; while (versionStr.size() > offset && versionStr[offset] != '-' && versionStr[offset] != ' ' && versionStr[offset] != '\0') offset++; tags.emplace_back(versionStr.data() + blockStart, offset - blockStart); - if (versionStr[offset] == ' ' || versionStr[offset] == '\0') break; + if (offset >= versionStr.size() || versionStr[offset] == ' ' || versionStr[offset] == '\0') break; offset++; } while (versionStr.size() > offset); } diff --git a/openVulkanoCpp/Controller/FreeCamCameraController.cpp b/openVulkanoCpp/Controller/FreeCamCameraController.cpp index 71da9cc..8f94d3e 100644 --- a/openVulkanoCpp/Controller/FreeCamCameraController.cpp +++ b/openVulkanoCpp/Controller/FreeCamCameraController.cpp @@ -32,7 +32,7 @@ namespace OpenVulkano vec = Math::Utils::normalize(vec); } - float timeScale = 5 * CURRENT_FRAME.frameTime; //TODO + float timeScale = 3 * CURRENT_FRAME.frameTime; //TODO vec = vec * timeScale * 3.0f; // scale vector if (input->GetButton(m_actionBoost)) { diff --git a/openVulkanoCpp/Host/GraphicsAppManager.cpp b/openVulkanoCpp/Host/GraphicsAppManager.cpp index f9cd1bb..e880467 100644 --- a/openVulkanoCpp/Host/GraphicsAppManager.cpp +++ b/openVulkanoCpp/Host/GraphicsAppManager.cpp @@ -19,6 +19,8 @@ namespace OpenVulkano { + using clock = std::chrono::steady_clock; + GraphicsAppManager::GraphicsAppManager(OpenVulkano::IGraphicsApp* app, RenderAPI::RenderApi renderApi) : app(app), renderApi(renderApi) { @@ -37,6 +39,14 @@ namespace OpenVulkano renderer = std::unique_ptr(PlatformProducer::CreateRenderManager(renderApi)); app->SetGraphicsAppManager(this); 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) @@ -57,11 +67,41 @@ namespace OpenVulkano renderer = std::unique_ptr(PlatformProducer::CreateRenderManager(renderApi)); app->SetGraphicsAppManager(this); 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::microseconds(0); + } + else + { + cappedFrameTime = std::chrono::microseconds(1'000'000 / newFpsCap); + } + } + + void GraphicsAppManager::OnCappedFPS(const auto& frameStartTime) + { + auto frameEndTime = frameStartTime + cappedFrameTime; + while (clock::now() < frameEndTime) + { + std::this_thread::yield(); + } } GraphicsAppManager::~GraphicsAppManager() noexcept { if (windowTitleFormat.empty()) return; + engineConfig->OnFpsCapChanged -= EventHandler(this, &GraphicsAppManager::UpdateCappedFpsInfo); ShutDown(); } @@ -139,9 +179,14 @@ namespace OpenVulkano } else { - Input::InputManager::GetInstance()->Tick(); + auto start = clock::now(); + inputManager->Tick(); app->Tick(); if (CURRENT_FRAME.needsRedraw) renderer->Tick(); + if (cappedFrameTime.count()) + { + OnCappedFPS(start); + } frameTimer.Tick(); UpdateFps(); CURRENT_FRAME.frameId = frameCount; diff --git a/openVulkanoCpp/Host/GraphicsAppManager.hpp b/openVulkanoCpp/Host/GraphicsAppManager.hpp index 5d4b627..d48704a 100644 --- a/openVulkanoCpp/Host/GraphicsAppManager.hpp +++ b/openVulkanoCpp/Host/GraphicsAppManager.hpp @@ -18,6 +18,11 @@ namespace OpenVulkano { class IPlatform; + namespace Input + { + class InputManager; + } + class EngineConfiguration; /** * \brief A simple GraphicsAppManager. It can only handle one window. @@ -33,9 +38,15 @@ namespace OpenVulkano bool paused = false, running = false; float fpsTimer = 0, avgFps = 0, avgFrameTime = 0; uint64_t frameCount = 0, lastFrameCount = 0; + std::chrono::microseconds cappedFrameTime = std::chrono::microseconds(0); Timer frameTimer; std::string windowTitleFormat; + Input::InputManager* inputManager; + EngineConfiguration* engineConfig; + private: + void OnCappedFPS(const auto& frameStartTime); + void UpdateCappedFpsInfo(int32_t newFpsCap); public: explicit GraphicsAppManager(IGraphicsApp* app, RenderAPI::RenderApi renderApi = RenderAPI::Vulkan);