Game loop openGL : Fixed time step decoupled render

Hello everyone!

I am in need of some dire help with my openGL game! I have been looking all over the internet for how to create a game loop that is decoupled from the render and does not stutter.

I have read over articles such as

http://www.koonsolo.com/news/dewitters-gameloop/

and

http://gafferongames.com/game-physics/fix-your-timestep/

But nothing seems to work! I always get stuttering! Even if I interpolate!

And I just doing it wrong or am I crazy?

Here is my current game loop (it is based on the first article), I am using SDL and openGL to create the window for rendering. Double buffering is on and there is no vsync enabled (even if I do enable it, it does not seem to do anything)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

//The max amount of time the game logic loop can be updated before forcing the render call
const int MAXUPDATES = 5;

//Time we have updated the game logic loop
int loops = 0;

//The amount of time (in milliseconds) spent updating the game loop in this case 33.33333 milliseconds
double updateTime = 1000.0 / 30.0;

//Used for the interpolation calculation
double interpolation;

/*
   Get the current time before we start the main game loop
   timeGetTime() returns the amount of time since the "system" has started in milliseconds
   In this case the system is Windows
*/
double gameClock = timeGetTime();

while(runGame)
{


   //Reset the loop count
   loops = 0;

   /*
      The GAME LOOP!
      Continue to update the game until the game Clock is greater than the current time ( timeGetTime() )
      OR
      Until we have hit the max amount of time we are allowed to update before we a re forcing the game to render
      ( the loops < MAXUPDATES part)
   */
   while( (timeGetTime() >= gameClock) && (loops < MAXUPDATES))
   {

      
      //Store the previous player position
      player.prevX = player.x;
      player.prevY = player.y;

   
      //Movement right
      if(currentKeystate[SDKL_d])
         player.x += player.speed;

      //Movement left
      if(currentKeystate[SDKL_a])
         player.x -= player.speed;

      //Movement up
      if(currentKeystate[SDKL_w])
         player.y -= player.speed;

      //Movement down
      if(currentKeystate[SDKL_s])
         player.y += player.speed;

      //Add onto the game clock by the update time; Add onto the number of loops
      gameClock += updateTime;
      loops++;
   }

   
   //Calculate for interpolation
   interpolation = ((timeGetTime() - gameClock) + updateTime) / updateTime;

   //Apply the interpolation to the player's render position before actually rendering the game
   player.ViewX = player.prevX + interpolation * (player.x - player.prevX);
   player.ViewY = player.prevY + interpolation * (player.y - player.prevY);

   //Render the game sprites and etc using on the render positions ( player.viewX / player.viewY )
   drawGame();

   //Flip / swap the buffers to draw everything to the screen
   SDL_GL_SwapBuffers();


Any help would be greatly appreciated!

My specs :
Dell Studio XPS 1640 -
Windows 7 64 bit
4.0 GB ram DDR2
Core Duo T955 2.66 Ghz
ATI Mobility Radeon HD 4670 [Drivers up to date]

Other information :
Window mode at 800 x 600
2D sprites only
Last edited on
If you own a low-end PC, no matter what you will get struttering.
If you don't, using AntiAliasing may fix your problem, but using it on 3D-scenes or high-poly-scenes will degrade performance. As you're using it for 2D-Scenes it should be acceptable.

Oh wait here, try this:

while( (timeGetTime() < gameClock) && (loops < MAXUPDATES))
Last edited on
I know I should have put my pc specs!
I'll edit above too

My specs :
Dell Studio XPS 1640 -
Windows 7 64 bit
4.0 GB ram DDR2
Core Duo T955 2.66 Ghz
ATI Mobility Radeon HD 4670 [Drivers up to date]

There is so little going on (There are only 10 sprites moving on the screen)?
I just don't understand?
I can run games like Starcraft 2 on high and be A OK



Last edited on
Your pc is perfectly all right, read my post above as it has been edited, I think you didn't notice the edit.
If I do that I never enter the update loop :(
Let me give you a thing: This is probably the correct way to interpolate and handle user input, substitute all your code with this and give a try:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

static DWORD LastUpdate = timeGetTime();
DWORD ThisUpdate = timeGetTime();
float DeltaTime = (float)(ThisUpdate - LastUpdate) * 0.001f;
// Calculate the Delta Time in Seconds, for a Correct calculation.

if(currentKeystate[SDKL_d])
   player.x += player.speed * DeltaTime;

//Movement left
if(currentKeystate[SDKL_a])
   player.x -= player.speed * DeltaTime;

//Movement up
if(currentKeystate[SDKL_w])
    player.y -= player.speed * DeltaTime;

//Movement down
if(currentKeystate[SDKL_s])
    player.y += player.speed * DeltaTime;

player.ViewX = player.prevX + DeltaTime * (player.x - player.prevX);
player.ViewY = player.prevY + DeltaTime * (player.y - player.prevY);

LastUpdate = ThisUpdate;
// Make sure the next delta time calculation is valid

drawGame();
SDL_GL_SwapBuffers();
Last edited on
I placed all of the code inside my game loop and nothing moves. (I placed LastUpdate = timeGetTime() before I enter the main loop). Also isn't this just variable time step (calculating the delta time and applying it to the game objects)?
Last edited on
Yeah, that's how interpolation works, doesn't it?
Maybe you should increase player.speed to the pixels-per-second the player should move.
LastUpdate isn't used anywhere in that part of the code anyways.
Also notice there is no loop for checking key states.
I don't know why it won't work otherwise, I always used it like this and always worked.

EDIT: Little bugfix, try again?

Also, try with the 'static' keyword and give the results, even just for a try.
Last edited on
Topic archived. No new replies allowed.