Direct2D Essay 2 - Timer Precision of Gameloop Creation in WinForm Environment of C# can't reach 60fps

Keywords: Google Windows

http://blog.csdn.net/hitachi_ht/article/details/38150955


The practice of many predecessors proves that the accuracy of Timers in C# can not meet the requirement of 60fps. This can be done as an experiment, using two Timers, one 1s, the other 0.01667s, and then counting + 1 for tick s of the latter timer, counting the number of + 1 for each second in front and counting the number of + 1 for the latter, you will find that there may be only about 30 times per second.

About the better timing system google also has, that is, the use of this performance counter, the measurement of longitude can be very high.

  1. [System.Security.SuppressUnmanagedCodeSecurity]  
  2. [DllImport("kernel32")]  
  3. private static extern bool QueryPerformanceFrequency (ref long PerformanceFrequency);  
  4. [System.Security.SuppressUnmanagedCodeSecurity]  
  5. [DllImport("kernel32")]  
  6. private static extern bool QueryPerformanceCounter (ref long PerformanceCounter);  

To incorporate this into Gameloop, I wrote a class for timing.

  1. public class PreciseTimer {  
  2.       [System.Security.SuppressUnmanagedCodeSecurity]  
  3.       [DllImport("kernel32")]  
  4.       private static extern bool QueryPerformanceFrequency (ref long PerformanceFrequency);  
  5.       [System.Security.SuppressUnmanagedCodeSecurity]  
  6.       [DllImport("kernel32")]  
  7.       private static extern bool QueryPerformanceCounter (ref long PerformanceCounter);  
  8.       long _tickPerSecond = 0;  
  9.       long _previousElapsedTime = 0;  
  10.       public PreciseTimer () {  
  11.             QueryPerformanceFrequency(ref _tickPerSecond);  
  12.             GetElapsedTime();  
  13.       }  
  14.       public double GetElapsedTime () {  
  15.             long Time = 0;  
  16.             QueryPerformanceCounter(ref Time);  
  17.             double ElapsedTime = (double)(Time - _previousElapsedTime) / (double)_tickPerSecond;  
  18.             _previousElapsedTime = Time;  
  19.             return ElapsedTime;  
  20.       }  
  21. }  
In this way, we can get a relatively accurate stopwatch.
Then, we need the Message processing mechanism of windows, where we use the Message in C.

  1. [StructLayout(LayoutKind.Sequential)]  
  2. public struct Message {  
  3.       public IntPtr hWnd;  
  4.       public Int32 Msg;  
  5.       public IntPtr wParam;  
  6.       public IntPtr lParam;  
  7.       public uint time;  
  8.       public System.Drawing.Point P;  
  9. }  
And we need the PeekMessage function in C.
  1. [System.Security.SuppressUnmanagedCodeSecurity]  
  2. [DllImport("User32.dll", CharSet = CharSet.Auto)]  
  3. public static extern bool PeekMessage (  
  4.       out Message Msg,  
  5.       IntPtr hWnd,  
  6.       uint messageFilterMin,  
  7.       uint messageFilterMax,  
  8.       uint flags);  
Then with these things, we came up with a class called TimeController.

  1. PreciseTimer _preciseTimer = new PreciseTimer();  
  2. public delegate void LoopCallBack (double ElapsedTime);  
  3. LoopCallBack _loopCallBack;  
  4. public TimeController (LoopCallBack CallBack) {  
  5.             _loopCallBack = CallBack;  
  6.             Application.Idle += new EventHandler(OnApplicationEnterIdle);  
  7. }  
  8. private void OnApplicationEnterIdle (object sender, EventArgs e) {  
  9.             while (IsAppStillIdle())  
  10.                   _loopCallBack(_preciseTimer.GetElapsedTime());  
  11. }  
  12. private bool IsAppStillIdle () {  
  13.             Message Msg;  
  14.             return !PeekMessage(out Msg, IntPtr.Zero, 0, 0, 0);  
  15. }  
Then we just need to add a Gameloop function to Form1.cs

  1. void GameLoop (double ElapsedTime) {  
  2. }  
Finally, time Controller is defined.
  1. TimeController timeController;  
And put Gameloop in it.

  1. timeController = new TimeController(GameLoop);  

That's it.

These things are hard to find on the Internet, so write them down.

Posted by savio_mf on Wed, 06 Feb 2019 10:18:17 -0800