gpt4 book ai didi

c - 带时序的流动动画 (OpenGL)

转载 作者:太空宇宙 更新时间:2023-11-03 23:55:20 25 4
gpt4 key购买 nike

我正在用 opengl 和 C 编写一个小游戏。我遇到了一个问题:由于剪辑...我的动画(实际上基于 glutTimerFunc)没有恒定的 fps。一个变量fps没有问题,但是动画受到影响,所以不对应时序,那么:fps1,pos1; fps2,pos2; fps3,pos3...但是如果 fps 不规则,那么动画就不会。我会像这样实现它:fps1,pos1;(如果没有绘制 fps1)fps2,pos1; (fps1 绘图结束,所以现在,因为我跳过了一帧)fps3,pos3。

我该怎么做?我会使用 clock() 函数,但它总是给出 0

ps: 如何在 opengl 中强制垂直同步?

最佳答案

OpenGL 更新是否与垂直回溯同步将以特定于平台的方式进行通信,因为它与您的平台将 OpenGL 绑定(bind)到自身的方式有关。所以它是 Mac 界面设计器中的一个复选框,在 Windows 上有一个名为 WGL_EXT_swap_control 的 WGL 扩展,在 X11 上有一个 GLX 扩展。

假设您有一些方法来安装在垂直回溯时触发的回调(例如通过 Mac 上的 CVDisplayLink;遗憾的是我没有使用 Windows/Linux 等效项),并且你希望你的物理学以每秒恒定的步数运行,你可以这样写:

void myRetraceFunction()
{
static unsigned int timeError = 0;
static unsigned int timeOfLastFrame = 0;

unsigned int timeNow = getTimeNow(); // assume this returns in ms

// Get time since last frame.
// Since we ignore overflow here, we don't care that the result of
// getTimeNow presumably overflows.
unsigned int timeSinceLastFrame = timeNow - timeOfLastFrame;

// Store this so that we get correct results next time around.
timeOfLastFrame = timeNow;

// Establish the number of times to update physics per second, as the
// name says. So supposing it has been 0.5 of a second since we last
// drew, we'd want to perform 0.5*200 physics updates
const unsigned int numberOfTimesToUpdatePhysicsPerSecond = 200;

// calculate updates as (updatesPerSecond * timeSinceLastFrame / 1000),
// because we're assuming time is in milliseconds and there are 1000
// of them in a second. What we'll do though is preserve any amount we'd
// lose by dividing here, so that errors balance themselves.
//
// We assume that timeSinceLastFrame will be small enough that we won't
// overflow here.
unsigned int timeSinceLastFrameNumerator =
timeSinceLastFrame * numberOfTimesToUpdatePhysicsPerSecond
+ timeError;

// calculate how much of the numerator we're going to lose to
// truncation, so that we add it next frame and don't lose time
timeError = timeSinceLastFrameNumerator % 1000;

// calculate how many physics updates to perform
unsigned int physicsUpdatesToPerform = timeSinceLastFrameNumerator / 1000;

// do the physics work...
while(physicsUpdatesToPerform--)
updatePhysics();

// ... and draw a frame
drawFrame();
}

timeError 的东西是为了防止舍入问题。例如。假设您以每秒 70 帧的恒定速度运行,并且希望物理更新每秒 60 次。如果您忽略了累积的错误,那么您实际上每秒运行零次物理更新,因为在每一刻代码都会得出结论,即自上次绘制帧以来的时间量不足以进行物理更新被要求。如果您采用其他方式,并且任何帧速率不是物理更新速率的整数除数,您也会遇到混叠问题。

如果您没有明确的回溯函数,而是一个推出帧但在垂直回溯上阻塞的永久循环,那么您将编写相同类型的东西。

如果您根本无法阻止垂直回扫,您可以在目标帧速率下安装一个计时器并假装这是一个垂直回扫同步。您可以尽可能快地推出框架,但您可能会收到任何使用笔记本电脑或其他机器的人的投诉,因为当风扇运转时会很明显。

关于c - 带时序的流动动画 (OpenGL),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9227571/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com