Browse Source

sometimes run multiple physics updates in one frame

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
5507e856a8
1 changed files with 54 additions and 22 deletions
  1. 54
    22
      src/main.cc

+ 54
- 22
src/main.cc View File

@@ -10,7 +10,6 @@
#include <string.h>

#include <swan/swan.h>
#include <swan/util.h>

using namespace Swan;

@@ -81,13 +80,18 @@ int main(int argc, char **argv) {
mods.push_back(game.loadMod("core.mod"));
game.createWorld("core::default", std::move(mods));

auto prevTime = std::chrono::steady_clock::now();
PerfCounter pcounter;

auto prev_time = std::chrono::steady_clock::now();

float fps_acc = 0;
float tick_acc = 0;

float fpsAcc = 0;
float tickAcc = 0;
int fcount = 0;
int slowFrames = 0;
int slow_frames = 0;
while (1) {
RTClock total_frame_clock;

SDL_Event evt;
while (SDL_PollEvent(&evt)) {
switch (evt.type) {
@@ -118,44 +122,72 @@ int main(int argc, char **argv) {
}

auto now = std::chrono::steady_clock::now();
std::chrono::duration<float> dur(now - prevTime);
prevTime = now;
std::chrono::duration<float> dur(now - prev_time);
prev_time = now;
float dt = dur.count();

// Display FPS
fpsAcc += dt;
fps_acc += dt;
fcount += 1;
if (fpsAcc >= 4) {
if (fps_acc >= 4) {
info << "FPS: " << fcount / 4.0;
fpsAcc -= 4;
fps_acc -= 4;
fcount = 0;
}

// We want to warn if one frame takes over 0.1 seconds...
if (dt > 0.1) {
if (slowFrames == 0)
if (slow_frames == 0)
warn << "Delta time too high! (" << dt << "s)";
slowFrames += 1;
dt = 0.1;
slow_frames += 1;

// And we never want to do physics as if our one frame is greater than
// 0.5 seconds.
if (dt > 0.5)
dt = 0.5;
} else if (slow_frames > 0) {
if (slow_frames > 1)
warn << slow_frames << " consecutive slow frames.";
slow_frames = 0;
}

game.update(dt);
// Simple case: we can keep up, only need one physics update
RTClock update_clock;
if (dt <= 1 / 25.0) {
pcounter.countGameUpdatesPerFrame(1);
game.update(dt);

if (slowFrames > 0) {
if (slowFrames > 1)
warn << slowFrames << " consecutive slow frames.";
slowFrames = 0;
// Complex case: run multiple steps this iteration
} else {
int count = (int)ceilf(dt / (1/30.0));
pcounter.countGameUpdatesPerFrame(count);
float delta = dt / count;
info << "Delta time " << dt << "s. Running " << count << " updates in one frame, with a delta as if we had " << 1.0 / delta << " FPS.";
for (int i = 0; i < count; ++i)
game.update(delta);
}
pcounter.countGameUpdate(update_clock.duration());

tickAcc += dt;
while (tickAcc >= 1.0 / TICK_RATE) {
tickAcc -= 1.0 / TICK_RATE;
// Tick at a consistent TICK_RATE
tick_acc += dt;
while (tick_acc >= 1.0 / TICK_RATE) {
tick_acc -= 1.0 / TICK_RATE;
RTClock tick_clock;
game.tick(1.0 / TICK_RATE);
pcounter.countGameTick(tick_clock.duration());
}

SDL_RenderClear(renderer.get());

RTClock draw_clock;
game.draw();
pcounter.countGameDraw(draw_clock.duration());

pcounter.countFrameTime(total_frame_clock.duration());

RTClock present_clock;
SDL_RenderPresent(renderer.get());
pcounter.countRenderPresent(present_clock.duration());
}

exit:

Loading…
Cancel
Save