implemented semi-fixed timestep
authormatthew <matthew@owens.tech>
Tue, 9 Oct 2018 18:45:13 +0000 (19:45 +0100)
committermatthew <matthew@owens.tech>
Tue, 9 Oct 2018 18:45:13 +0000 (19:45 +0100)
gl/main.c
gl/timestep.c [new file with mode: 0644]
gl/timestep.h [new file with mode: 0644]

index 54ff28e..b98bb47 100644 (file)
--- a/gl/main.c
+++ b/gl/main.c
 #include "point.h"
 #include "cube.h"
 #include "camera.h"
+#include "timestep.h"
 
 static SDL_Window *window = NULL;
 static SDL_GLContext *context = NULL;
 static int screen_width = 1280;
 static int screen_height = 720;
 static bool quit = false;
-static Uint32 ltime, ctime, numframes, cftime, lftime;
+//static Uint32 ltime, ctime, numframes, cftime, lftime;
 
 static float vertices[] = {
        // positions            // colours                      // texture coords
@@ -100,7 +101,7 @@ static void initView()
 {
        crpgCameraSetAR((float)screen_width/(float)screen_height);
        camera = crpgCameraNew(vec3(0,0,4), vec3(0,0,0), vec3(0,1,0));
-       crpgCameraSetSpeed(camera, 2);
+       crpgCameraSetSpeed(camera, 20);
        crpgCubeSetCamera(cubes[0], crpgCameraGetMat(camera));
        crpgCubeSetCamera(cubes[1], crpgCameraGetMat(camera));
 
@@ -149,18 +150,8 @@ static bool init()
 
 static void update()
 {
-       // measuring frame times
-       numframes++;
-       ctime = SDL_GetTicks();
-       if(ctime - ltime > 1000){       // if the last printf was more than a second ago
-               printf("%f ms/frame\n", 1000/(double)(numframes));
-               numframes = 0;
-               ltime = ctime;
-       }
-
-       // calculating delta time
-       cftime = SDL_GetTicks();
-       float dtms = cftime - lftime;
+       int physUpdates = 0;
+       crpgTimeStepUpdate();
 
        SDL_Event e;
        while(SDL_PollEvent(&e) != 0){
@@ -201,8 +192,12 @@ static void update()
                }
        }
 
-       crpgCameraUpdate(camera, dtms);
-       lftime = cftime;
+       // Updating physics as many times as we need to consume dt
+       while(crpgTimeStepPhysRequried(physUpdates)){
+               crpgCameraUpdate(camera, crpgTimeStepDelta());
+
+               physUpdates++;
+       }
 }
 
 static void render()
@@ -240,9 +235,7 @@ int main()
 
        initShapes();
        initView();
-
-       ltime = SDL_GetTicks();
-       lftime = SDL_GetTicks();
+       crpgTimeStepInit(60.f);
 
        while(!quit){
                update();
diff --git a/gl/timestep.c b/gl/timestep.c
new file mode 100644 (file)
index 0000000..add1b30
--- /dev/null
@@ -0,0 +1,50 @@
+#include "timestep.h"
+#include <SDL2/SDL.h>
+#include <math.h>
+
+static const int MAX_PHYSICS_STEPS = 6;
+static const float MAX_DELTA_TIME = 1.f;
+static const float MS_PER_SECOND = 1000.f;
+
+static float desiredFrameTime;
+static Uint32 currentT;
+static Uint32 prevT;
+static float frameTime;
+static float totalDeltaTime;
+static float deltaTime;
+
+float crpgTimeStepDelta()
+{
+       return deltaTime;
+}
+
+void crpgTimeStepSetDesiredFT(float desiredFPS)
+{
+       desiredFrameTime = MS_PER_SECOND/desiredFPS;
+}
+
+void crpgTimeStepInit(float desiredFPS)
+{
+       crpgTimeStepSetDesiredFT(desiredFPS);
+
+       currentT = SDL_GetTicks();
+       prevT = SDL_GetTicks();
+}
+
+void crpgTimeStepUpdate()
+{
+       prevT = currentT;
+       currentT = SDL_GetTicks();
+       frameTime = currentT - prevT;
+       totalDeltaTime = frameTime / desiredFrameTime;
+}
+
+bool crpgTimeStepPhysRequried(int updatesThisFrame)
+{
+       if(totalDeltaTime <= 0.f || updatesThisFrame >= MAX_PHYSICS_STEPS){
+               return false;
+       } else {
+               deltaTime = fminf(totalDeltaTime, MAX_DELTA_TIME);
+               totalDeltaTime -= deltaTime;
+       }
+}
diff --git a/gl/timestep.h b/gl/timestep.h
new file mode 100644 (file)
index 0000000..499fe84
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef TIMESTEP_H
+#define TIMESTEP_H
+#include <stdbool.h>
+
+void crpgTimeStepInit(float desiredFPS);
+void crpgTimeStepSetDesiredFT(float desiredUpdateFT);
+void crpgTimeStepUpdate();
+bool crpgTimeStepPhysRequired(int updatesThisFrame);
+float crpgTimeStepDelta();
+#endif//TIMESTEP_H