   need advice about Timer class and GameLoop
  I wrote a small program that automatically rotate the cube but i encounter a strange problem with Timer . First i will introduce my code and then i will describe my problemHere is the main loop :   while(!isFinised){if(PeekMessage( &wndMsg, null, 0, 0, PM_REMOVE)){if(wndMsg.message == WM_QUIT)isFinised = true;else{TranslateMessage(&wndMsg);DispatchMessage(&wndMsg);}}Timer::tick();if(m_gr_Renderer != null)m_gr_Renderer->render();}And here is the code i used to rotate the box:void autoRotate(){   float totalElapsed = Timer::getElapsedTime();float x = (*m_v3_Rotation)['x'] + (*m_v3_RotationSpeed)['x'] *   totalElapsed ;float y = (*m_v3_Rotation)['y'] + (*m_v3_RotationSpeed)['y'] * totalElapsed ;float z = (*m_v3_Rotation)['z'] + (*m_v3_RotationSpeed)['z'] * totalElapsed ;(*m_v3_Rotation)['x'] = fmod(x, 360);(*m_v3_Rotation)['y'] = fmod(y, 360);(*m_v3_Rotation)['z'] = fmod(z, 360);m_mat_Transform->setRotation((*m_v3_Rotation)['x'], (*m_v3_Rotation)['y'], (*m_v3_Rotation)['z']);}... and a simple Timer class:float Timer::s_f_ElapsedTime = 0;int64 Timer::s_i64_TickPerSec = 0;int64 Timer::s_i64_LastTime = 0;void Timer::init(){#if OS == WIN32LARGE_INTEGER freq , ticks;QueryPerformanceCounter(&ticks);QueryPerformanceFrequency(&freq);s_i64_TickPerSec = freq.QuadPart;s_i64_LastTime = ticks.QuadPart;#endif}void Timer::set(){#if OS == WIN32LARGE_INTEGER curTime;QueryPerformanceCounter(&curTime);int64 elapsedTick = curTime.QuadPart - s_i64_LastTime;s_f_ElapsedTime = ((float)elapsedTick * 1000) / (float)s_i64_TickPerSec;s_i64_LastTime = curTime.QuadPart;#endif}float Timer::getElapsedTime(){return s_f_ElapsedTime / 1000.0f;}float Timer::getElapsedTimeInMs(){return s_f_ElapsedTime;}The program run well and the cube is automatically rotated but every time i invoke an event (moving mouse , etc ...) the cube rotate faster although i didn't handle any events yetIf there is no events , the cube rotate slowly and laggy .... I realized that whenever a event happens , the value elaspedTime is bigger that make the new calculated rotation angle bigger and then the cube rotate faster .... Anyone have any ideas that make the cube rotate normally with or without events , Plz tell me   
  your problem lies in the message loop.you need to process all the window messages before doing your game/render frame.while(!isFinised){if(PeekMessage( &wndMsg, null, 0, 0, PM_REMOVE)){  if(wndMsg.message == WM_QUIT)isFinised = true;  else  {TranslateMessage(&wndMsg);DispatchMessage(&wndMsg);  }}else{  Timer::tick();  if(m_gr_Renderer != null)    m_gr_Renderer->render();}}Edit:Also you are multiplying the rotation speed by time elapsed which will make the object rotate faster and faster the longer you run the program, what you want is to multiply by delta time.   ;Quote:Original post by Molle85your problem lies in the message loop.you need to process all the window messages before doing your game/render frame.while(!isFinised){if(PeekMessage( &wndMsg, null, 0, 0, PM_REMOVE)){  if(wndMsg.message == WM_QUIT)isFinised = true;  else  {TranslateMessage(&wndMsg);DispatchMessage(&wndMsg);  }}else{  Timer::tick();  if(m_gr_Renderer != null)    m_gr_Renderer->render();}}Edit:Also you are multiplying the rotation speed by time elapsed which will make the object rotate faster and faster the longer you run the program, what you want is to multiply by delta time.I already did use the game loop like you said . the cube stop rotating whenever an event happens . also the elasped time i used to multiply with rotation speed is the delta time u can see it in my Timer class code;  Just change your Get functions to calculate the elapsed time directly from the QueryPerformanceCounter() function instead of relying on your main loop to adjust the latest time captured.Why wouldn't you do that anyway?   ;  I think we lack some information... When are the methods of your timer object called?Timer::set() is called once per frame I guess? But from where? A nice place to put it would be in your main loop after processing messages, but as Molle85 pointed out you need to modify it a bit to make sure you process all messages and not just the first.   ;s_f_ElapsedTime = ((float)elapsedTick * 1000) / (float)s_i64_TickPerSec;Cast to double instead of float. Your problem might simply be precision loss. Keep in mind that when the message loop is empty, you're rendering frames much faster than when processing messages, so the timestep values become smaller.   ;Quote:Original post by BeerNuttsJust change your Get functions to calculate the elapsed time directly from the QueryPerformanceCounter() function instead of relying on your main loop to adjust the latest time captured.Why wouldn't you do that anyway?#1:Querying timers from hardware is costly on some hardware.It is always more costly than reading from a variable.#2:You will have inconsistent updates.As an example, if you are running a physics routine and each object updates by querying the hardware directly, each object will be updated by a slightly different amount of time, since the hardware will return different values each time it is queried.Two objects falling at the same speed from the same height.  Object A updates first and drops by 14000 microseconds.  Object B updates, but time has passed during the update of object A, and object B drops by 14120 microseconds.  Object B reaches the ground first when it should have been a tie.Using milliseconds for time is unacceptable.  If using milliseconds, they would both drop by 14, but computers are faster these days and my computer frequently gets over 1,000 FPS (it is a $4,500 super gaming computer), and a higher precision is necessary to avoid problems in these situations.You should always cache the time at the start of the frame, once and only once (per thread).Not only this, but you should be running a second synchronized timer for pausing.  “Virtual” timers, as they are called, are not advanced when the game is paused, allowing anything using these timers to stop without a problem and resume again when the game resumes.A proper timer update looks like this (4 variables kept are real ticks, virtual ticks, real frame count, and virtual frame count):Start by getting the timer resolution.LSSTD_CALL CTime::CTime() :m_ui64CurTime( 0ULL ),m_ui64LastTime( 0ULL ),m_ui64CurVirtTime( 0ULL ),m_ui64LastVirtTime( 0ULL ),m_ui32Frame( 0UL ),m_ui32VirtFrame( 0UL ) {#if defined( WIN32 ) || defined( _WIN32 ) || defined( _WIN64 )m_bHiRes = ::QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER *>(&m_ui64Resolution) );if ( !m_bHiRes ) {m_ui64Resolution = CLOCKS_PER_SEC;}#endif// #if defined( WIN32 ) || defined( _WIN32 ) || defined( _WIN64 )m_ui64LastRealTime = GetRealTime();}Make a wrapper to get the real system time, unmodified./** * Get the real system time.  Not to be used for any other purpose besides random-number *seeding. * * \return Returns the real system time in system tick units. */LSSUINT64 LSSTD_CALL CTime::GetRealTime() const {#if defined( WIN32 ) || defined( _WIN32 ) || defined( _WIN64 )if ( m_bHiRes ) {LSSUINT64 ui64Ret;if ( ::QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER *>(&ui64Ret) ) ) { return ui64Ret; }}return ::clock();#else#error "No implementation for CTime on this platform."#endif// #if defined( WIN32 ) || defined( _WIN32 ) || defined( _WIN64 )}A function to allow updating by ANY system time unit.  Normally not called directly except outside of this class.  This updates the timer values by the given amount./** * Update the time by a certain amount. * * \param _ui64Amnt Number of ticks by which to update the time. * \param _bUpdateVirtuals If true, virtual values are updated as well. */LSSVOID LSSTD_CALL CTime::UpdateBy( LSSUINT64 _ui64Amnt, LSSBOOL _bUpdateVirtuals ) {m_ui64LastTime = m_ui64CurTime;m_ui64CurTime += _ui64Amnt;// Always update the last virtual frame.m_ui64LastVirtTime = m_ui64CurVirtTime;++m_ui32Frame;// Optionally update virtuals.if ( _bUpdateVirtuals ) {m_ui64CurVirtTime += _ui64Amnt;++m_ui32VirtFrame;}}And finally a function that determines how many ticks by which to update the timer since the last time it was updated, and performs the actual updating by calling the above function with that value.  This function correctly calculates the number of ticks that have passed even if the system timer overflows./** * Update the time. * * \param _bUpdateVirtuals If true, virtual values are updated as well. */LSSVOID LSSTD_CALL CTime::Update( LSSBOOL _bUpdateVirtuals ) {LSSUINT64 ui64TimeNow = GetRealTime();LSSUINT64 ui64Dif;// Handle wrapping gracefully.if ( ui64TimeNow >= m_ui64LastRealTime ) {ui64Dif = ui64TimeNow - m_ui64LastRealTime;}else {ui64Dif = (0xFFFFFFFFFFFFFFFFULL - m_ui64LastRealTime) + ui64TimeNow + 1ULL;}m_ui64LastRealTime = ui64TimeNow;UpdateBy( ui64Dif, _bUpdateVirtuals );}This timer always counts from 0 ticks, even if the system timer is not 0 (which will always be the case).  It counts up from there, which means that the timer itself will never overflow unless the game is left on for weeks (depending on the resolution of the system timer).Additionally, floating-point values are avoided, as they must always be in timers.Do not count time in microsecond or millisecond (definitely a sin) units, as they accumulate errors over time.  Store the time in system units and convert to microseconds when needed.The conversion to microseconds is (this only applies to Windows; Macintosh code removed):/** * Get the current microseconds. * * \return Returns an LSSUINT64 value containing the current microseconds. */LSSTD_INLINE LSSUINT64 LSSTD_CALL CTime::GetCurMicros() const {return m_ui64CurTime * 1000000ULL / m_ui64Resolution;}/** * Get the current virtual microseconds. * * \return Returns an LSSUINT64 value containing the current virtual microseconds */LSSTD_INLINE LSSUINT64 LSSTD_CALL CTime::GetCurVirtMicros() const {return m_ui64CurVirtTime * 1000000ULL / m_ui64Resolution;}You can either perform this calculation each time the function is called to get the current microseconds or you can cache these values once per update, which will make your timer class larger but improve performance.Your timer should not be static.  Why would you have only one timer in your game?  What about the sound thread?  It is going to keep its own instance of a CTime class which it updates as frequently as it needs, which may be entirely out of sync with the game timer.Your game class should just have 2 CTime objects.  One for logical updates and one for render updates (which again are not the same thing).  Temporarily, you may get away with keeping one timer and performing one logical update per render update (though right now I see you are only doing a render update).Keep the timer on your CGame class and update it once per frame, not updating virtuals when the game is paused.CGame::Tick() {    m_tTime.Update( !IsPaused() );}Finally, you need to know how much time has passed since the last update.  Again, these values could be cached if you want to improve speed./** * Get the microseconds since last frame. * * \return Returns the number of microseconds since the last frame. */LSSTD_INLINE LSSUINT64 LSSTD_CALL CTime::GetMicrosSinceLastFrame() const {return GetCurMicros() - (m_ui64LastTime * 1000000ULL / m_ui64Resolution);}/** * Get the virtual microseconds since last frame. * * \return Returns the number of virtual microseconds since the last frame. */LSSTD_INLINE LSSUINT64 LSSTD_CALL CTime::GetVirtMicrosSinceLastFrame() const {return GetCurVirtMicros() - (m_ui64LastVirtTime * 1000000ULL / m_ui64Resolution);}When you want your time as a float (or double), these are the values you convert, because they will always be reasonably small enough not to cause many problems in floating-point format.// Convert the time of this frame to floating-point.FLOAT fTime = m_tTime.GetVirtMicrosSinceLastFrame() * (1.0f / 1000000.0f);L. Spiro   