根据使用 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 所经过的时间移动我的相机时遇到了一个小问题的主要内容,如果未能解决你的问题,请参考以下文章