我有一个等待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;
}
}
答案 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}}采用时间值参数并返回相应的位置值。