This commit is contained in:
2026-03-21 23:10:48 +01:00
parent 8cbb794dba
commit 3153735d0c
18 changed files with 249 additions and 195 deletions
+39 -66
View File
@@ -3,6 +3,7 @@
#include <destrum/App.h>
#include <destrum/FS/AssetFS.h>
#include <destrum/Util/DeltaTime.h>
#include "glm/gtx/transform.hpp"
#include "spdlog/spdlog.h"
@@ -35,41 +36,33 @@ void App::init(const AppParams& params) {
gfxDevice.init(window, params.appName, false);
InputManager::GetInstance().Init();
Time::GetInstance().Update();
customInit();
}
void App::run() {
using clock = std::chrono::steady_clock;
Time::GetInstance().Update(); // initialize delta timing
const float targetHz = 60.0f;
const float dt = 1.0f / targetHz;
const float maxFrameTime = 0.25f; // clamp big hitches
const int maxSteps = 5; // prevent spiral of death
auto prevTime = clock::now();
const float fixedDt = static_cast<float>(Time::GetInstance().FixedDeltaTime());
const int maxSteps = 5; // prevent spiral of death
float accumulator = 0.0f;
isRunning = true;
while (isRunning) {
const auto frameStart = clock::now();
float frameTimeSec = std::chrono::duration<float>(frameStart - prevTime).count();
prevTime = frameStart;
// ---- Update timing ---
Time::GetInstance().Update();
float dt = static_cast<float>(Time::GetInstance().DeltaTime());
if (frameTimeSec > 0.07f && frameTimeSec < 5.f) {
spdlog::warn("Frame drop detected, time: {:.4f}s", frameTimeSec);
}
if (dt > 0.25f) dt = 0.25f;
if (frameTimeSec > maxFrameTime) frameTimeSec = maxFrameTime;
if (frameTimeSec < 0.0f) frameTimeSec = 0.0f;
accumulator += frameTimeSec;
if (frameTimeSec > 0.0f) {
const float newFPS = 1.0f / frameTimeSec;
if (dt > 0.0f) {
float newFPS = 1.0f / dt;
avgFPS = std::lerp(avgFPS, newFPS, 0.1f);
}
accumulator += dt;
InputManager::GetInstance().BeginFrame();
camera.Update(dt);
@@ -92,63 +85,43 @@ void App::run() {
}
}
if (!isRunning) break;
customUpdate(dt);
// ---- Swapchain resize check once per frame ----
int steps = 0;
while (accumulator >= fixedDt && steps < maxSteps) {
// physics.Update(fixedDt);
SDL_SetWindowTitle(
window,
fmt::format("{} - FPS: {:.2f}", m_params.windowTitle, avgFPS).c_str()
);
accumulator -= fixedDt;
steps++;
}
if (steps == maxSteps) accumulator = 0.0f;
const float alpha = accumulator / fixedDt;
if (!gfxDevice.needsSwapchainRecreate()) {
customDraw();
}
if (gfxDevice.needsSwapchainRecreate()) {
spdlog::info("Recreating swapchain to size: {}x{}", m_params.windowSize.x, m_params.windowSize.y);
gfxDevice.recreateSwapchain(m_params.windowSize.x, m_params.windowSize.y);
onWindowResize(m_params.windowSize.x, m_params.windowSize.y);
}
// ---- Fixed updates (no event polling inside) ----
int steps = 0;
while (accumulator >= dt && steps < maxSteps) {
//Set window title to fps
SDL_SetWindowTitle(
window,
fmt::format("{} - FPS: {:.2f}", m_params.windowTitle, avgFPS).c_str());
accumulator -= dt;
steps++;
}
// If we hit the step cap, drop leftover time to recover smoothly
if (steps == maxSteps) accumulator = 0.0f;
// Optional interpolation factor for rendering
const float alpha = accumulator / dt;
// ---- Render ----
if (!gfxDevice.needsSwapchainRecreate()) {
// glm::mat4 objMatrix = glm::translate(glm::mat4(1.f), glm::vec3(0.f, -3.0f, 0.f));
//
// renderer.beginDrawing(gfxDevice);
// renderer.drawMesh(testMeshID, glm::mat4(1.f), testMaterialID);
// renderer.drawMesh(testMeshID, objMatrix, 0);
// renderer.endDrawing();
//
// const auto cmd = gfxDevice.beginFrame();
// const auto& drawImage = renderer.getDrawImage(gfxDevice);
//
// renderer.draw(cmd, gfxDevice, camera, GameRenderer::SceneData{
// camera, glm::vec3(0.1f), 0.5f, glm::vec3(0.5f), 0.01f
// });
//
// gfxDevice.endFrame(cmd, drawImage, {
// .clearColor = {{0.f, 0.f, 0.5f, 1.f}},
// .drawImageBlitRect = glm::ivec4{}
// });
customDraw();
}
// ---- Frame cap (if you still want it) ----
if (frameLimit) {
const auto targetEnd = frameStart + std::chrono::duration_cast<clock::duration>(
std::chrono::duration<float>(dt)
);
std::this_thread::sleep_until(targetEnd);
auto sleepTime = Time::GetInstance().SleepDuration();
if (sleepTime.count() > 0) {
std::this_thread::sleep_for(sleepTime);
}
}
}
gfxDevice.waitIdle();
}