1

在有人问之前,这是一个大学项目,我必须使用 GLUT。我没有将此标记为作业,因为这不是必需的,我也不会为此加分。

使用 GLUT,对于不知情的人,您可以:

  • glutIdleFunc(func): 注册渲染函数,这意味着当 GLUT 没有做任何其他事情时,它会调用这个函数。换句话说,它将尽可能快地保持渲染。
  • glutTimerFunc(msecs, func, val): 注册一个将被调用的函数,msecs并且递归地注册相同的函数将允许基于固定时间的移动。

现在,为了这个目的,我试图避免使用这些功能,并且我发现的关于 GLUT 的大多数讨论/文章都将它们用于基于时间的移动。所以我又来了……但是如果我不使用这些功能中的任何一个,帧是如何渲染的?我只是打电话glutPostRedisplay,一个单一的帧将被渲染。

我设法以一种简单的方式在 GLUT 中实现了基于时间的运动。可能不是最好的实现,但它并不过分复杂且有效。好吧,只有一个小问题,这就是我在这里的原因。

我的相机运动基于牛顿第二运动定律,我计算位移运动如下:

Vector3D displacement = (CurrentVelocity * elapsedTime) +
    (Acceleration * 0.5f * elapsedTime * elapsedTime);

elapsedTime来自我的计时器实现,我认为这就是问题所在。问题是它displacement应该是正数还是负数取决于运动方向,但如果CurrentVelocity是一个非常低的值(即:-0.1f),那么displacement当它应该是负数时它将是正数。其余代码将加速或减速相机,因此问题仅在加速时发生,因为那时CurrentVelocity会很小,发生的情况是相机略微向右(正)移动,然后向左(负)移动获得足够的动量以给出负值displacement

现在,当场景中没有运动时,根本没有渲染任何内容。当我按下移动键时,我会这样做:

CameraDirection.z = CAMERA_WALK_BACKWARD;
SceneTimer.PostRedisplayWindow();

这也来自我的计时器类,我这样做而不是调用glutPostRedisplay,原因是:

void Timer::PostRedisplayWindow(void) {
    currentTime = glutGet(GLUT_ELAPSED_TIME);
    glutPostRedisplay();
}

我需要得到currentTime(这将成为previousTime我需要计算经过时间的时间),然后我打电话给glutPostRedisplay. 将呈现单个帧,这意味着renderScene将调用:

void renderScene(void) {
    (...)

    glLoadIdentity();

    elapsedTime = SceneTimer.GetElapsedTimeInSeconds();

    SceneCamera.Move(CameraDirection, elapsedTime);
    SceneCamera.LookAt();

    drawCompleteScene();

    glutSwapBuffers();

    checkAnimationRedisplay();
}

如您所见,计算了经过的时间,并在其上移动了相机。场景中的所有内容都被绘制,交换缓冲区,然后我有这个额外的功能,它将检查是否需要动画,在这种情况下,相机需要:

void checkAnimationRedisplay(void) {
    if(SceneCamera.IsCameraMoving()) {
        glutPostRedisplay();
        return;
    }
}

它会一直调用glutPostRedisplay,直到相机停止移动。意思是,renderScene每次都会调用,计算经过的时间并根据时间移动相机,一切正常;此外,当然,还有已经提到的小故障,只是让我提出这个长问题的小故障(对此感到抱歉)。

缺少的只是这个问题最重要的功能,即计算经过时间的功能,简单如下:

float Timer::GetElapsedTimeInSeconds(void) { static int previousTime = 0; 静态int elapsedTime = 0;

previousTime = currentTime;
currentTime = glutGet(GLUT_ELAPSED_TIME);
elapsedTime = currentTime - previousTime;

return elapsedTime / 1000.0f;

}

我的计时器代码可能有问题,对吗?我的意思是,向前或向右(正值),没有问题。运动平稳且基于时间。例如,如果我将移动速度设置为 5m/s,实际上移动 25 米需要 5 秒(我假设 1m = 1.0f)。

那么,我在计时器上做错了什么,以至于负值开始向右移动一秒钟,然后才向左移动?

4

1 回答 1

0

可以在这里找到解决我的问题的一个答案: https ://gamedev.stackexchange.com/questions/10902/having-a-slight-problem-moving-my-camera-based-on-time-passed-using-glut -opengl

于 2011-04-12T10:50:15.957 回答