【问题标题】:How to implement an FPS camera without GLU on OSX (Or cross platform) c++如何在 OSX(或跨平台)c++ 上实现没有 GLU 的 FPS 相机
【发布时间】:2011-04-05 00:32:23
【问题描述】:

我正在尝试使用 FPS 风格的相机,同时遵循 openGL SuperBible 书中的示例。

一切都很顺利,直到我遇到了你最终会发生滚动的问题,当你真的只想要俯仰和偏航时。

Similar question

这个问题基本上是在问同样的问题,但我希望有人能够对实现更详细一点,最好是有 SuperBible GLTools 框架的经验。

我已经尝试实现必须编译的GluLookAt code,但是我在复制所需的函数时出错了,或者在使用它时传入了错误的参数。

我想我觉得它有点令人困惑,因为 SuperBible 代码抽象了相机的工作原理,所以我发现很难正确实现它。在测试我当前的版本时,我正在传递这样的参数

M3DMatrix44f mCamera;
cameraFrame.GetCameraMatrix(mCamera);   //returns the matrix of the CameraFrame.

M3DVector3f up =   { 0.0f, 1.0f, 0.0f };    
M3DVector3f look = { xHeading,yHeading,0.0f }; 

//xHeading & yHeading ranges from -1 to 1 based on mouse movement, is this correct?

我应该如何管理和传递外观变量?目前看起来外观值保持在同一个地方,所以如果我向后移动,我最终会在场景中旋转。

glhLookAtf2(mCamera, mCamera, look, up);

我觉得我必须更好地管理我的视线方向,可能还有我的相机位置。看起来位置似乎没有改变,这似乎很奇怪。

任何人都可以提供帮助,或者指出一个可靠的教程路径的方向吗?我试图避免做任何被弃用的事情,但在这一点上,我真的很高兴能让一些东西正常工作。

【问题讨论】:

  • 另外,当我使用 wasd 键移动场景时,预设为 {1.0f,1.0f,1.0f} 他们的相机不会一直聚焦在场景的中间.但是,当我将变量从鼠标看起来 -1 传递到 1 时,相机确实会移动,只是不正确。如果我修复了外观位置,相机不应该一直聚焦在中心吗?

标签: c++ opengl camera 3d


【解决方案1】:

这很容易。您只需要 3 个向量来处理相机: 位置、相对 LookAt 和相对 Up 向量

设置这 3 个之后,您可以像这样将它们提供给 gluLookAt:

gluLookAt(camera.eye.x,camera.eye.y,camera.eye.z,
        camera.lookAt.x,camera.lookAt.y,camera.lookAt.z,
        camera.up.x,camera.up.y,camera.up.z);

别搞混了,camera.lookAt 是真实的 LookAt 加上眼睛矢量:

camera.lookAt = camera.eye + camera.rLookAt;

所以这基本上应该涵盖设置相机。相机的下一个基本任务是移动。这要归功于相对 LookAt 简单的任务,因为您只更新眼睛矢量。您可能还想更新绝对 LookAt,但这与我在上面显示的代码相同。

最后,您需要旋转视图。棘手的是您可以使用 3 种解释 - 矩阵、3 个角度或四元数。因为角度很容易理解(另一方面,它们的性能最差并且受到万向节锁定的影响),我将向您展示如何做到这一点。我不会描述云台锁是什么,你可以谷歌这个,但为了避免它,我们需要限制旋转。我们将使用完整的 360° 进行水平旋转,但仅使用 180° 进行垂直旋转。如果您查看 openGl 坐标系,我们可以定义围绕 Y 轴的水平旋转和围绕 X 轴的垂直旋转。为了在应用程序中旋转矢量,我们使用以下两个代码:

vector3f vector3f::rotateX(const float &radians)
{
    float t_y = y;

    y = t_y*cos(radians) + z*sin(radians);
    z = t_y*-sin(radians) + z*cos(radians);
    return *this;
}

vector3f vector3f::rotateY(const float &radians)
{
    float t_x = x;

    x = t_x*cos(radians) + z*-sin(radians);
    z = t_x*sin(radians) + z*cos(radians);
    return *this;
}

你可以看到我从我的代码中复制了这个。 vector3f 只是一个包含有关 3D 向量的所有内容的类。 x,y 和 z 是定义向量的公共成员。

因此,如果您想要基本上是 rotateX 和 yaw rotateY 的俯仰。 为了更新您的相机,您需要旋转相对 LookAt 和 Up 向量,计算绝对 LookAt 并将它们提供给 gluLookAt。就是这样。。

PS:在 OSX 上编写 opengl 的人很少。我从未运行过 OSX,但作为跨平台的 openGl 绝对仍然很受欢迎。

PSS:我忘了说,永远不要添加旋转。更好地添加角度,每次旋转时将矢量设置为默认位置并以该绝对角度旋转:

rLookAt.set(0,0,-1);
rLookAt.rotateX(rotations.x);
rLookAt.rotateY(rotations.y);
lookAt = eye + rLookAt;

up.set(0,1,0);
up.rotateX(rotations.x);
up.rotateY(rotations.y);

【讨论】:

    【解决方案2】:

    感谢大家的回答,但我遇到的问题是这个。在openGL超级圣经中,我使用的是他们内置的参考框架类,我遇到的问题是两个函数,一个叫做rotate和rotateWorld。

    我需要使用 rotate 进行向上/向下移动,并使用 rotateWorld 进行左右移动。这使相机行为正确(飞行相机)。

    这是有道理的,因为无论您在哪里向上/向下看,您都希望整个世界始终围绕垂直轴旋转。呸!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 2018-06-24
      • 2014-03-22
      • 1970-01-01
      • 2023-03-12
      • 2013-06-23
      • 2014-05-05
      相关资源
      最近更新 更多