diff --git a/examples/47-pixelformats/pixelformats.cpp b/examples/47-pixelformats/pixelformats.cpp index 92afe7484..f53b459e8 100644 --- a/examples/47-pixelformats/pixelformats.cpp +++ b/examples/47-pixelformats/pixelformats.cpp @@ -523,6 +523,8 @@ public: } imguiCreate(); + + m_frameTime.reset(); } int32_t shutdown() override @@ -596,8 +598,7 @@ public: { if (bgfx::isValid(m_checkerboard) ) { - static int64_t timeOffset = bx::getHPCounter(); - const float time = float( (bx::getHPCounter()-timeOffset)/double(bx::getHPFrequency() ) ); + const float time = bx::toSeconds(m_frameTime.getDurationTime() ); const float animate = float(m_animate)*0.5f; const float xx = bx::sin(time * 0.37f) * animate; const float yy = bx::cos(time * 0.43f) * animate; @@ -631,6 +632,8 @@ public: { if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) ) { + m_frameTime.frame(); + imguiBeginFrame(m_mouseState.m_mx , m_mouseState.m_my , (m_mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0) @@ -832,6 +835,7 @@ public: } entry::MouseState m_mouseState; + FrameTime m_frameTime; uint32_t m_width; uint32_t m_height; diff --git a/examples/common/common.h b/examples/common/common.h index b41025d19..d1fee5359 100644 --- a/examples/common/common.h +++ b/examples/common/common.h @@ -25,15 +25,21 @@ struct FrameTime /// void reset() { - m_start = m_current; - frame(); + m_current = bx::getNow(); + m_start = m_current; + m_last = m_current; } /// void frame() { + const bx::Ticks step = entry::getFixedTimeStep(); + m_last = m_current; - m_current = bx::getNow(); + m_current = bx::Ticks(bx::InitZero) == step + ? bx::getNow() + : m_current + step + ; } /// diff --git a/examples/common/entry/entry.cpp b/examples/common/entry/entry.cpp index a6dc8a42a..adabe7d89 100644 --- a/examples/common/entry/entry.cpp +++ b/examples/common/entry/entry.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -553,6 +554,71 @@ BX_PRAGMA_DIAGNOSTIC_POP(); return s_numApps; } + static bx::Ticks s_fixedTimeStep = bx::InitZero; + + bx::Ticks getFixedTimeStep() + { + return s_fixedTimeStep; + } + + /// + struct TestRun + { + TestRun(int _argc, const char* const* _argv) + : m_frame(0) + , m_screenshotFrame(0) + { + bx::CommandLine cmdLine(_argc, _argv); + + const char* screenshot = cmdLine.findOption("screenshot"); + if (NULL != screenshot) + { + bx::strCopy(m_screenshot, sizeof(m_screenshot), screenshot); + m_screenshotFrame = 60; + + const char* frame = cmdLine.findOption("screenshot-frame"); + if (NULL != frame) + { + bx::fromString(&m_screenshotFrame, frame); + } + } + + uint32_t fps = 0 != m_screenshotFrame ? 60 : 0; + const char* fixedFps = cmdLine.findOption("fixed-fps"); + if (NULL != fixedFps) + { + bx::fromString(&fps, fixedFps); + } + + s_fixedTimeStep = 0 != fps + ? bx::Ticks(bx::Ticks::s_kFreq.ticks/fps) + : bx::Ticks(bx::InitZero) + ; + } + + /// + bool frame() + { + if (0 == m_screenshotFrame) + { + return true; + } + + ++m_frame; + + if (m_frame == m_screenshotFrame) + { + bgfx::requestScreenShot(BGFX_INVALID_HANDLE, m_screenshot); + } + + return m_frame < m_screenshotFrame + 3; + } + + uint32_t m_frame; + uint32_t m_screenshotFrame; + char m_screenshot[bx::kMaxFilePath]; + }; + int runApp(AppI* _app, int _argc, const char* const* _argv) { setWindowSize(kDefaultWindowHandle, s_width, s_height); @@ -564,6 +630,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); bx::snprintf(title, BX_COUNTOF(title), "%S - %s", &exeName, _app->getName() ); setWindowTitle(kDefaultWindowHandle, title); + TestRun test(_argc, _argv); + _app->init(_argc, _argv, s_width, s_height); bgfx::frame(); @@ -573,7 +641,8 @@ BX_PRAGMA_DIAGNOSTIC_POP(); #else while (_app->update() ) { - if (0 != bx::strLen(s_restartApp) ) + if (0 != bx::strLen(s_restartApp) + || !test.frame() ) { break; } diff --git a/examples/common/entry/entry.h b/examples/common/entry/entry.h index 09eede8ef..68ebb97ca 100644 --- a/examples/common/entry/entry.h +++ b/examples/common/entry/entry.h @@ -373,6 +373,9 @@ namespace entry /// void setRestartArgs(const char* _args); + /// + bx::Ticks getFixedTimeStep(); + } // namespace entry #endif // ENTRY_H_HEADER_GUARD diff --git a/examples/common/example-glue.cpp b/examples/common/example-glue.cpp index 78bdad180..d75dd3781 100644 --- a/examples/common/example-glue.cpp +++ b/examples/common/example-glue.cpp @@ -417,7 +417,11 @@ void showExampleDialog(entry::AppI* _app, const char* _errorText) const bgfx::Stats* stats = bgfx::getStats(); const double toMsCpu = 1000.0/stats->cpuTimerFreq; const double toMsGpu = 1000.0/stats->gpuTimerFreq; - const double frameMs = double(stats->cpuTimeFrame)*toMsCpu; + const bool fixedTime = bx::Ticks(bx::InitZero) != entry::getFixedTimeStep(); + const double frameMs = fixedTime + ? bx::toMilliseconds(entry::getFixedTimeStep() ) + : double(stats->cpuTimeFrame)*toMsCpu + ; s_frameTime.pushSample(float(frameMs) ); @@ -444,8 +448,8 @@ void showExampleDialog(entry::AppI* _app, const char* _errorText) ImGui::PopStyleColor(); ImGui::Text("Submit CPU %0.3f, GPU %0.3f (L: %d)" - , double(stats->cpuTimeEnd - stats->cpuTimeBegin)*toMsCpu - , double(stats->gpuTimeEnd - stats->gpuTimeBegin)*toMsGpu + , fixedTime ? 0.0 : double(stats->cpuTimeEnd - stats->cpuTimeBegin)*toMsCpu + , fixedTime ? 0.0 : double(stats->gpuTimeEnd - stats->gpuTimeBegin)*toMsGpu , stats->maxGpuLatency ); diff --git a/examples/common/imgui/imgui.cpp b/examples/common/imgui/imgui.cpp index ec9a910fe..9464b3651 100644 --- a/examples/common/imgui/imgui.cpp +++ b/examples/common/imgui/imgui.cpp @@ -531,6 +531,14 @@ struct OcornutImguiContext const double freq = double(bx::getHPFrequency() ); io.DeltaTime = float(frameTime/freq); +#if USE_ENTRY + const bx::Ticks step = entry::getFixedTimeStep(); + if (bx::Ticks(bx::InitZero) != step) + { + io.DeltaTime = bx::toSeconds(step); + } +#endif // USE_ENTRY + io.AddMousePosEvent( (float)_mx, (float)_my); io.AddMouseButtonEvent(ImGuiMouseButton_Left, 0 != (_button & IMGUI_MBUT_LEFT ) ); io.AddMouseButtonEvent(ImGuiMouseButton_Right, 0 != (_button & IMGUI_MBUT_RIGHT ) );