Jump to content

  • Log In with Google      Sign In   
  • Create Account

14 years ago on June 15th Gamedev.net was first launched! We want to thank all of you for being part of our community and hope the best years are ahead of us. Happy birthday Gamedev.net!

Aerodactyl55

Member Since 07 Jun 2009
Offline Last Active May 28 2013 11:52 AM
-----

Posts I've Made

In Topic: game loop

07 December 2012 - 02:20 AM

After so much frustration this is what worked for me:


int accumulator = ( int )( ( ( tNow - tPrev ) * 1000 ) / tFreq );
tPrev = tNow;

while( accumulator > 0 )
{
	 Update( DELTA_TIME )
	 accumulator -= UPDATE_TICKS;
}

//Compensate for the extra update loop that consumes the remainder
if( accumulator != 0 ) Sleep( abs( accumulator ) );

Render();


And i removed the interpolation.
Thanks everyone.

In Topic: game loop

06 December 2012 - 12:54 AM

Khatharr, your pseudocode seem to suggest a variable time step which i have used in previous projects, and it works. The problem is if the game slows down a big delta time is passed to Update(), which may result in missed collisions.

Try this:

lerp = (float)accumulator / UPDATE_TICKS;


Doesnt help.

In Topic: game loop

05 December 2012 - 08:42 AM

According to this article interpolation is needed to avoid stuttering and this seems to be true because removing the interpolation doesn't help. Maybe I should use the next position instead of the previous. I dont see any error in the way i am calculating the interpolation yet the movement of the sprite is not smooth. I tried putting some sleep calls and it does minimize the stuttering but it doesn't eliminate it completely.

In Topic: game loop

05 December 2012 - 03:26 AM

i decided to refine the code a little to make it easier to understand, but i didnt add "g_" to variables because 99% of them are globals.


#include "core.h"


struct OBJECT
{
	  IDirect3DTexture9*	  Tex;  //Object texture
	  D3DXVECTOR2			 Pos;  //Current position
	  D3DXVECTOR2			 prevPos;//Previous position, this will be used for interpolation
	  D3DXVECTOR2			 Vel;  //Velocity
};


LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
BOOL Init();
void Update( float dt );
void Render();
void Cleanup();


Core::CGraphics gfx;
Core::CSprite sprite;
OBJECT star;


ULONGLONG tNow = 0;
ULONGLONG tPrev = 0;
ULONGLONG tFreq = 0;
DWORD accumulator = 0;

const int UPDATE_TICKS = 10;						  //10ms
const float DELTA_TIME = UPDATE_TICKS * 0.001f; //The dt passed to the update function
float lerp = 0.0f;												//The interpolation value to be used during rendering


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	  if( !gfx.InitWindow( hInstance, WndProc, L"Game Loop Test", nCmdShow ) ) return 0;

	  if( !Init() )
	  {
			gfx.MsgBoxError( L"Init() Failed!" );
			return 0;
	  }

	  MSG msg = { 0 };
	
	  QueryPerformanceFrequency( ( LARGE_INTEGER* )&tFreq );
	  QueryPerformanceCounter( ( LARGE_INTEGER* )&tPrev );

	  while( WM_QUIT != msg.message )
	  {
			if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
			{
				  TranslateMessage( &msg );
				  DispatchMessage( &msg );
			}
			else
			{
				  QueryPerformanceCounter( ( LARGE_INTEGER* )&tNow );

				  accumulator += ( DWORD )( ( ( tNow - tPrev ) * 1000 ) / tFreq );
				  tPrev = tNow;

				  while( accumulator >= UPDATE_TICKS )
				  {
						Update( DELTA_TIME );
						accumulator -= UPDATE_TICKS;
				  }

				  //Compute the interpolation value for this frame
				  lerp = accumulator / ( float )UPDATE_TICKS;

				  Render();
			}
	  }

	  return static_cast< int >( msg.wParam );
}


BOOL Init()
{
	  if( !gfx.CreateDirect3D9() ) return FALSE;

	  if( FAILED( gfx.CreateDevice9() ) ) return FALSE;

	  if( FAILED( sprite.Init( &gfx ) ) ) return FALSE;

	  ZeroMemory( &star, sizeof( OBJECT ) );

	  //Load the texture
	  if( FAILED( gfx.LoadTextureFromFile( L"star.png", &star.Tex ) ) ) return FALSE;
	
	  star.Pos.y = 284.0f;
	  star.Vel.x = 500.0f;	//The sprite only moves on the x-axis

	  star.prevPos = star.Pos;

	  return TRUE;
}


void Update( float dt )
{
	  //Store the position before updating
	  star.prevPos = star.Pos;

	  //Move the sprite
	  star.Pos = star.Pos + star.Vel * dt;

	  //Prevent the sprite from leaving the screen boundaries [0 - 800]
	  if( star.Pos.x + 32.0f > 800.0f )
	  {
			star.Pos.x = 768.0f;
			star.Vel.x = -star.Vel.x;
			star.prevPos = star.Pos;
	  }
	  else if( star.Pos.x < 0.0f )
	  {
			star.Pos.x = 0.0f;
			star.Vel.x = -star.Vel.x;
			star.prevPos = star.Pos;
	  }
}


void Render()
{
	  gfx.Clear();

	  gfx.BeginScene();

	  sprite.Begin();

	  D3DXVECTOR2 p;	//interpolated position

	  //Interpolate between the previous and the current position
	  p = star.prevPos * lerp + star.Pos * ( 1.0f - lerp );
	
	  //Draw the sprite
	  sprite.Translate( &p );
	  sprite.Draw( star.Tex, NULL, BLUE_COLOR );

	  sprite.End();

	  gfx.EndScene();

	  gfx.Present();
}

void Cleanup()
{
	  //Release the texture
	  Core::ReleaseCOM( star.Tex );
}


LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	  switch( msg )
	  {
	  case WM_DESTROY: Cleanup(); PostQuitMessage( 0 ); break;
	  default: return DefWindowProc( hwnd, msg, wParam, lParam );
	  }

	  return 0;
}

I am still unable to find any mistake but the stuttering is still there.
And thanks for the replies.

In Topic: game loop

05 December 2012 - 12:07 AM

First i am really sorry about bad coding, this isnt my real coding style. This application was rushed just to test how the fixed time-step loop behaved.
This test application only moves a 32x32 sprite left-right. There is visible stuttering in the motion which i was unable to fix even with interpolation. I am not sure if it is the loop itself or something else.

PARTNERS