Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 带计时的流动动画(OpenGL)_C_Opengl - Fatal编程技术网

C 带计时的流动动画(OpenGL)

C 带计时的流动动画(OpenGL),c,opengl,C,Opengl,我正在用opengl和C编写一个小游戏。 我遇到了一个问题: 由于剪辑。。。我的动画(实际上基于GLUTIMERFUNC)没有固定的fps。 可变fps不是问题,但动画会受到影响,因此它与计时不对应,那么:fps1,pos1;fps2,pos2;fps3,位置3。。。 但是如果fps不规则,那么动画就不规则。 我会像这样实现它:fps1,pos1;(如果fps1未被提取)fps2,位置1;(fps1绘图结束,所以现在,因为我跳过了一帧)fps3,pos3 我怎么做?我会使用clock()函数,但

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

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


ps:如何在opengl中强制进行v-sync?

opengl更新是否与垂直回溯同步将以平台特定的方式进行沟通,因为这与您的平台将opengl绑定到自身的方式有关。因此,它是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();
}
那个时间误差的东西是为了防止舍入问题。例如,假设您以每秒70帧的恒定速度运行,并且希望每秒进行60次物理更新。如果忽略累积的错误,那么实际上会在一秒钟内运行零物理更新,因为在每一时刻,代码都会得出结论,即自上次帧绘制以来的时间长度不足以进行物理更新。如果你换一种方式,你也会遇到混叠问题,任何帧速率都不是物理更新率的整数除数

如果你没有一个显式的回溯函数,而是一个永久的循环,在垂直回溯上推出帧,但块,那么你会写同样的东西


如果您根本无法阻止垂直回溯,您可以在目标帧速率下安装一个计时器,并假装这是垂直回溯同步。你可以尽可能快地推出相框,但你可能会收到任何人对笔记本电脑或其他机器的投诉,当粉丝们出现时,这一点很明显。

谢谢你的回答,但我正在寻找一种跨平台的方式,准确地说,只是在帧渲染前后获取计时器的值,没有跨平台的方式,除了实现我给出的基本算法和编写一些特定于平台的代码,以便(I)适当地调用函数;以及(ii)检索当前时间(以毫秒或其他任何单位为单位)。这就是像SDL这样的跨平台库提供SDL_gettick的原因。