Last active
June 12, 2023 01:13
-
-
Save m4saka/227b88b19567439574f181278214decc to your computer and use it in GitHub Desktop.
FrameRateLimit addon for OpenSiv3D 0.6.x
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// License: CC0 1.0 | |
# include <Siv3D.hpp> | |
class FrameRateLimit : public IAddon | |
{ | |
private: | |
static constexpr std::chrono::steady_clock::duration kMaxDrift = 10ms; | |
int32 m_targetFPS; | |
std::chrono::time_point<std::chrono::steady_clock> m_sleepUntil; | |
public: | |
explicit FrameRateLimit(int32 targetFPS) | |
: m_targetFPS(targetFPS) | |
, m_sleepUntil(std::chrono::steady_clock::now() - kMaxDrift) | |
{ | |
} | |
virtual void postPresent() override | |
{ | |
// Determine the end time of sleep until the next frame | |
m_sleepUntil += std::chrono::duration_cast<std::chrono::steady_clock::duration>(1s) / m_targetFPS; | |
// Set a lower limit so that m_sleepUntil does not go back in time from the current time if the target frame rate is not reached | |
// (Because even if you sleep until the exact current time, there might be a long wait time depending on the environment, | |
// so as a countermeasure, we are setting the time subtracted by kMaxDrift as the lower limit) | |
const auto sleepUntilLowerLimit = std::chrono::steady_clock::now() - kMaxDrift; | |
if (m_sleepUntil < sleepUntilLowerLimit) | |
{ | |
m_sleepUntil = sleepUntilLowerLimit; | |
} | |
// Execute sleep | |
std::this_thread::sleep_until(m_sleepUntil); | |
} | |
void setTargetFPS(int32 targetFPS) | |
{ | |
m_targetFPS = targetFPS; | |
} | |
}; | |
void Main() | |
{ | |
// Set frame rate | |
constexpr int32 kTargetFPS = 300; | |
Addon::Register(U"FrameRateLimit", std::make_unique<FrameRateLimit>(kTargetFPS)); | |
// Disable VSync | |
Graphics::SetVSyncEnabled(false); | |
const Font font{ FontMethod::MSDF, 48, Typeface::Bold }; | |
while (System::Update()) | |
{ | |
// Show frame rate | |
font(U"{}fps"_fmt(Profiler::FPS())).draw(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment