QueryPerformanceCounter限制/加快幻灯片速度

时间:2018-04-19 23:42:08

标签: c++

我有一个等待std :: condition_variable的线程然后循环直到它完成。

我试图滑动在opengl中绘制的矩形。

一切都运行良好而不使用delta,但我希望我的rect能够以相同的速度滑动,无论它运行的是什么计算机。

目前它跳了大约一半然后幻灯片很慢。

如果我不使用我的delta,如果在较慢的计算机上运行,​​则它不会以相同的速度运行。

我不确定我是否应该使用if语句并检查时间是否过去然后进行滑动,不使用delta?

    auto toolbarGL::Slide() -> void
    {
        LARGE_INTEGER then, now, freq;
        QueryPerformanceFrequency(&freq);
        QueryPerformanceCounter(&then);

        while (true)
        {
            // Waits to be ready to slide
            // Keeps looping till stopped then starts to wait again
            SlideEvent.wait();

            QueryPerformanceCounter(&now);
            float delta_time_sec = (float)(now.QuadPart - then.QuadPart) / freq.QuadPart;

            if (slideDir == SlideFlag::Right)
            {
                if (this->x < 0)
                {
                    this->x += 10 * delta_time_sec;
                    this->controller->Paint();
                }
                else
                    SlideEvent.stop();
            }
            else if (slideDir == SlideFlag::Left)
            {
                if (this->x > -90)
                {
                    this->x -= 10 * delta_time_sec;
                    this->controller->Paint();
                }
                else
                    SlideEvent.stop();
            }
            else
                SlideEvent.stop();

            then = now;
        }
    }

1 个答案:

答案 0 :(得分:1)

如果你想让你的矩形以稳定的速度移动,无论如何,我建议采用不同的方法 - 而不是依赖你的代码在特定时间执行并导致副作用(如x += 10)时间,提出一个功能,告诉你矩形的位置在任何给定的时间 。这样,无论何时调用Paint()方法,它总是在与该时间对应的位置绘制矩形。

例如:

// Returns the current time, in microseconds-since-some-arbitrary-time-zero
unsigned long long GetCurrentTimeMicroseconds()
{
   static unsigned long long _ticksPerSecond = 0;
   if (_ticksPerSecond == 0) _ticksPerSecond = (QueryPerformanceFrequency(&tps)) ? tps.QuadPart : 0;

   LARGE_INTEGER curTicks;
   if ((_ticksPerSecond > 0)&&(QueryPerformanceCounter(&curTicks)))
   {
      return (curTicks.QuadPart*1000000)/_ticksPerSecond;
   }
   else
   {
      printf("GetCurrentTimeMicroseconds() failed, oh dear\n");
      return 0;
   }
}

[...]

// A particular location on the screen
int startPositionX = 0;

// A clock-value at which the rectangle was known to be at that location
unsigned long long timeStampAtStartPosition = GetCurrentTimeInMicroseconds();

// The rectangle's current velocity, in pixels-per-second
int speedInPixelsPerSecond = 10;

// Given any clock-value (in microseconds), returns the expected position of the rectangle at that time
int GetXAtTime(unsigned long long currentTimeInMicroseconds)
{
   const long long timeSinceMicroseconds = currentTimeInMicroseconds-timeStampAtStartPosition;
   return startPositionX + ((speedInPixelsPerSecond*timeSinceMicroseconds)/1000000);
}

void PaintScene()
{
   const int rectX = GetXAtTime(GetCurrentTimeMicroseconds());

   // code to paint the rectangle at position (rectX) goes here...
}

鉴于上述情况,您的程序可以根据需要尽快或频繁地调用PaintScene(),并且您的矩形屏幕上的速度不会改变(尽管动画看起来或多或少会平滑,取决于你打电话的频率。)

然后,如果你想让矩形改变它的运动方向,你可以这样做:

const unsigned long long now = GetCurrentTimeInMicroseconds();
startPositionX = GetXAtTime(now);
speedInPixelsPerSecond = -speedInPixelsPerSecond;  // reverse course!

上面的示例使用一个提供线性运动的简单y=mx+b式方程,但是您可以使用不同的parametric equations获取许多不同类型的运动,这些{{3}}采用时间值参数并返回相应的位置值。