LearnOpenGL学习笔记(七):一个FPS摄像机系统
LearnOpenGL学习笔记(七)
1.摄像机概述
1.1LookAt矩阵
要想在OpenGL中顺利的使用摄像机,我们需要借助GLM来构建一个LookAt矩阵,形式如下:
glm::mat4 view;
view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f));
lookAt 函数需要接受三个vec3参数,分别是摄像机的位置向量、目标以及上向量。这里的位置向量是从原点指向摄像头位置的向量,目标是摄像头镜头所对着的地方,而上向量是表示世界空间中的上向量。
一个合格的摄像机系统应当能做到视角的*切换,那我们就需要将lookAt的三个参数用变量来代替,这样才能做到实时变化:
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
//用三个变量作为参数
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
这里的cameraPos仍然是摄像机的位置向量,而cameraFront则是当前摄像头镜头的朝向方向,cameraUp仍然是上向量。
由于lookAt函数接受的第二个参数是目标向量,故需要将cameraPos向量与cameraFront向量求和,才能得到代表目标位置的向量,如下图所示:
cameraPos代表的摄像头的位置向量,cameraFront代表的是摄像机镜头朝向的方向,将这两个向量相加才是我们想要的目标向量(可以理解成获得了镜头目标的世界坐标)。
1.2真实的FPS——不能飞行
为了让摄像机系统更符合实际,也就是不能随意飞行,我们需要设定摄像机的位置的y坐标始终是一个固定值,也就是说只在x轴与z轴上活动,但视角仍然是可以随意转动的。这就需要在处理WASD的函数中将Position.y始终置为0.0f 。
void ProcessKeyboard(Camera_Movement direction, float deltaTime)
{
float velocity = MovementSpeed * deltaTime;
if (direction == FORWARD)
//真正的FPS摄像机(也就是说不能够随意飞行)
Position += Front * velocity;
if (direction == BACKWARD)
Position -= Front * velocity;
if (direction == LEFT)
Position -= Right * velocity;
if (direction == RIGHT)
Position += Right * velocity;
//不能随意飞行
Position.y = 0.0f;
}
2.代码及运行结果
完整的代码点击这里,给出的是一个真正的FPS摄像机(也就是说不能够随意飞行),视角可以随意转动,但是移动的时候只能在一个平面。
运行结果如下图所示:
通过 WASD移动并辅以鼠标转动视角则如下图所示:
正确的程序应当使我们能够随意转动视角,但只能在一个平面移动。