根据使用 GLUT/OpenGL 所经过的时间移动我的相机时遇到了一个小问题

Posted

技术标签:

【中文标题】根据使用 GLUT/OpenGL 所经过的时间移动我的相机时遇到了一个小问题【英文标题】:Having a slight problem moving my camera based on time passed using GLUT/OpenGL 【发布时间】:2011-04-09 20:30:42 【问题描述】:

在任何人问之前,这是一个大学项目,我必须使用 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) 静态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)。

那么,我在计时器上做错了什么,以至于负值开始向右移动一瞬间,然后才按应有的方式向左移动?

【问题讨论】:

【参考方案1】:

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

【讨论】:

以上是关于根据使用 GLUT/OpenGL 所经过的时间移动我的相机时遇到了一个小问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 glut、opengl 绘制散点图矩阵

如何在 C++/OpenGL 中获取当前鼠标位置?

GLUT OpenGL Cube 拉伸错误

GLUT OpenGL - 仅使用 GL_POINTS 绘制形状

第一个openGL程序

OpenGL窗口大小渲染问题