none
Calculate ElapsedTime Rendering Frame with QueryPerformanceCounter RRS feed

  • Question

  • Hi, I am just exploring the hi precision timer, I trying to create a music game (similar like Guitar Hero, VOS, IIDX, O2Jam), What I want is get elapsed time since the last frame when game is rendering (elapsed time between 1 frame, its cannot use fps, since fps is frame per second, i need elapsed time between a frame), I need this to calculate the speed of the note falling (I know what I am doing, because I almost done with GetTickCount() but its still not accurate enough)

    I already tried the GetTickCount() from kernel32.dll but its very very very almost accurate, but still not accurate enough, so I try to search high precision timer that higher than GetTickCount(), I hear from my friend, its use QueryPerformanceCounter(), but I don't know how to use QueryPerformanceCounter(), I already tried this, but still not work (The Elapsed Time is stored on Delta variable):

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Diagnostics; using System.Threading; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; using System.Runtime.InteropServices; namespace Render_Preview { public partial class Form1 : Form { [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceCounter( out long lpPerformanceCount); [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceFrequency( out long lpFrequency); bool GameRun; long LastFrameTime; long Now; double Delta; //Elapsed time is stored in Delta public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { GameRun = true; this.Show();

    Initialize();

    Render(); } private void Initialize() { // Let's say all Initializing the game code is here // Set Last Frame Time QueryPerformanceCounter(out LastFrameTime); } private void Render() { do { // Calculate Delta QueryPerformanceCounter(out Now); Delta = (double)(Now - LastFrameTime); LastFrameTime = Now; // Let's say all Drawing code here.. } while(GameRun) } } }

    Please help me, Thanks :D



    • Edited by ChronO2Jam Sunday, June 10, 2012 5:18 PM
    Sunday, June 10, 2012 5:17 PM

Answers

  • The Stopwatch wraps the High Resolution Performance Counter.  It might be easier to use.

    Oh thanks for your answer, but I got this class, and this high resolution:

    using System;
    using System.Runtime.InteropServices;
    
    internal class HiResTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(ref long
       lpPerformanceCount);
    
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(ref long
       lpFrequency);
        private long StartTick = 0;
        private long Freq = 0;
    
        public HiResTimer()
        {
            if (QueryPerformanceFrequency(ref Freq) == false)
            {
                throw new Exception("High resolution performance of timer is not supported by this hardware.");
            }
        }
    
        public void Start()
        {
            QueryPerformanceCounter(ref StartTick);
        }
    
        public void Reset()
        {
            StartTick = 0;
            Start();
        }
    
        public long GetElapsedTicks()
        {
            long currentTick = 0;
            QueryPerformanceCounter(ref currentTick);
    
            return currentTick - StartTick;
        }
    
        public double GetElapsedTimeInSeconds()
        {
            long currentTick = 0;
            QueryPerformanceCounter(ref currentTick);
    
            return (currentTick - StartTick) / (float)Freq;
        }
    
        static public double TicksToSeconds(long ticks)
        {
            long freq = 0;
            QueryPerformanceFrequency(ref freq);
            return (double)ticks / (double)freq;
        }
    
        static public long SecondsToTicks(float seconds)
        {
            long freq = 0;
            QueryPerformanceFrequency(ref freq);
            return (long)(seconds * (float)freq);
        }
    }

    @^ I hope its useful for someone search high resolution timer too, Reset() is function to reset the time and start again.

    I am using it, I think its accurate now.

    • Marked as answer by ChronO2Jam Wednesday, June 13, 2012 5:31 AM
    Monday, June 11, 2012 1:29 AM
  • Hi AmateriaImpure,

      You can read the following article about how to measure execution time in C#.

      http://www.codeproject.com/Tips/162658/How-To-Measure-execution-time-in-C

      Sincerely,

      Jason Wang


    Jason Wang [MSFT]
    MSDN Community Support | Feedback to us

    Monday, June 11, 2012 5:51 AM

All replies

  • The Stopwatch wraps the High Resolution Performance Counter.  It might be easier to use.
    Sunday, June 10, 2012 5:39 PM
  • The Stopwatch wraps the High Resolution Performance Counter.  It might be easier to use.

    Oh thanks for your answer, but I got this class, and this high resolution:

    using System;
    using System.Runtime.InteropServices;
    
    internal class HiResTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(ref long
       lpPerformanceCount);
    
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(ref long
       lpFrequency);
        private long StartTick = 0;
        private long Freq = 0;
    
        public HiResTimer()
        {
            if (QueryPerformanceFrequency(ref Freq) == false)
            {
                throw new Exception("High resolution performance of timer is not supported by this hardware.");
            }
        }
    
        public void Start()
        {
            QueryPerformanceCounter(ref StartTick);
        }
    
        public void Reset()
        {
            StartTick = 0;
            Start();
        }
    
        public long GetElapsedTicks()
        {
            long currentTick = 0;
            QueryPerformanceCounter(ref currentTick);
    
            return currentTick - StartTick;
        }
    
        public double GetElapsedTimeInSeconds()
        {
            long currentTick = 0;
            QueryPerformanceCounter(ref currentTick);
    
            return (currentTick - StartTick) / (float)Freq;
        }
    
        static public double TicksToSeconds(long ticks)
        {
            long freq = 0;
            QueryPerformanceFrequency(ref freq);
            return (double)ticks / (double)freq;
        }
    
        static public long SecondsToTicks(float seconds)
        {
            long freq = 0;
            QueryPerformanceFrequency(ref freq);
            return (long)(seconds * (float)freq);
        }
    }

    @^ I hope its useful for someone search high resolution timer too, Reset() is function to reset the time and start again.

    I am using it, I think its accurate now.

    • Marked as answer by ChronO2Jam Wednesday, June 13, 2012 5:31 AM
    Monday, June 11, 2012 1:29 AM
  • You've reinvented the stopwatch.  Did you copy the Reference Source?
    Monday, June 11, 2012 1:32 AM
  • Hi AmateriaImpure,

      You can read the following article about how to measure execution time in C#.

      http://www.codeproject.com/Tips/162658/How-To-Measure-execution-time-in-C

      Sincerely,

      Jason Wang


    Jason Wang [MSFT]
    MSDN Community Support | Feedback to us

    Monday, June 11, 2012 5:51 AM
  • You've reinvented the stopwatch.  Did you copy the Reference Source?

    No, I am just didn't notice I need to divide the tick with the frequency

    Wednesday, June 13, 2012 5:28 AM
  • Hi AmateriaImpure,

      You can read the following article about how to measure execution time in C#.

      http://www.codeproject.com/Tips/162658/How-To-Measure-execution-time-in-C

      Sincerely,

      Jason Wang


    Jason Wang [MSFT]
    MSDN Community Support | Feedback to us

    hi thanks, that similar like my code, I already done with this, but Thanks for your reply
    Wednesday, June 13, 2012 5:30 AM