如何在OSX(或跨平台)c ++上实现没有GLU的FPS摄像机

时间:2011-04-05 00:32:24

标签: c++ opengl camera 3d

我正在努力让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);

我觉得我必须更好地管理我的外观方向,也可能是我的相机位置。外观位置似乎没有改变,这似乎很奇怪。

任何人都可以提供帮助,还是指向一个可靠的教程路径?我试图避免做任何弃用的事情,但在这一点上,我真的很高兴只是为了让事情有效。

2 个答案:

答案 0 :(得分:0)

这很容易。你只需要3个矢量来处理相机: 位置,相对LookAt和相对向上向量

设置完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.look是一个实用的LookAt添加了眼睛矢量:

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

所以这基本上应该包括设置相机。相机的下一个基本任务是什么?这要归功于相对LookAt简单任务,因为您只更新眼睛向量。您可能也想要更新绝对的LookAt,但这是我在上面显示的相同代码。

最后,您需要旋转视图。棘手的是你可以使用3个解释 - 矩阵,3个角度或四分之一。因为角度很容易理解(另一方面它们具有最差的性能并且受到万向节锁定的影响)我将告诉你如何做到这一点。我不会描述万向锁是什么,你可以google这个,但为了避免它,我们需要限制旋转。我们将使用全360°水平但垂直旋转仅180°。如果你看一下openGl坐标系,我们可以定义关于Y轴和垂直的X轴的水平旋转。要在app中旋转矢量,我们使用这两个代码:

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是定义向量的公共成员。

所以,如果你想要基本旋转X和偏航旋转的音高。 要更新相机,您需要旋转相对的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);

答案 1 :(得分:0)

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

我需要使用旋转进行上/下移动,并旋转世界以进行左右移动。这使得相机表现正常(飞行相机)。

无论你向上/向下看,你都希望整个世界始终围绕垂直轴旋转,这是有道理的。呼!