OpenGL 摄像机类的创建
基础知识储备(参考详细描述)
- 欧拉角
2.三维坐标系中的Pitch和Yaw
代码
头文件Camera.h
#pragma once
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
class Camera
{
public:
//构造函数
Camera(glm::vec3 position, float pitch, float row, glm::vec3 worldup);
//析构函数
~Camera();
float Pitch; //绕x轴旋转度数
float Yaw; //绕y轴旋转度数
//一般不需要绕z轴旋转,除非想要做出天旋地转的效果
float speedZ; //可用WS按键操作前进后退,按一下平移距离是speedZ
float speedY; //可用QE按键操作上升下降,按一下平移距离是speedY
float speedX; //可用AD按键操作左移右移,按一下平移距离是speedX
glm::vec3 Position; //位置坐标
glm::vec3 Forward; //前向向量(计算方式:glm::normalize(target-position))
glm::vec3 Right; //指向camera右侧的向量(计算方式:glm::normalize(glm::cross(Forward,WorldUp)))
glm::vec3 Up; //指向上的向量(计算方式:glm::normalize(glm::cross(Forward, Right)))
glm::vec3 WorldUp; //世界向上的坐标,用来辅助计算camera的朝向向量
glm::mat4 GetViewMatrix(); //用lookAt函数获得viewmatrix矩阵(viewMat = camera.GetViewMatrix();)
void ProcessMouseMovement(float deltaX, float deltaY); //由鼠标控制函数获得Δx和Δy进而对朝向进行更新;
void UpdateCameraPos(); //对camera位置更新
private:
void UpdateCameraVectors(); //对camera朝向进行更新
};
源文件Camera.cpp
1.构造函数 Camera
#include "Camera.h"
//构造函数
Camera::Camera(glm::vec3 position, float pitch, float yaw, glm::vec3 worldup)
{
//给类对象进行赋值
Pitch = pitch; //注意此处不要写成重新定义float Pitch,否则并未访问类成员;
Yaw = yaw;
Position = position;
WorldUp = worldup;
//初始化的时候Yaw=glm::radians(-90.0f),看向z轴的负方向
Forward.x = glm::cos(Pitch) * glm::cos(Yaw);
Forward.y = glm::sin(Pitch);
Forward.z = glm::cos(Pitch) * glm::sin(Yaw);
Right = glm::normalize(glm::cross(Forward, WorldUp));
Up = glm::normalize(glm::cross(Right,Forward));
//这里并未采用教程中的direction(与前向相反的方向)来计算另right和up,而是直接采用了camera的正面朝向,但direction才是右手坐标系的一个正向轴,在理论上不可或缺,但在此项操作中使用前向向量Forward更直接;
}
2.获取viewmat GetViewMatrix()
glm::mat4 Camera::GetViewMatrix()
{
//lookAt()参数:camera位置,target位置(与Position和Forward相联系实时更新看向的位置);世界坐标向上向量;
return glm::lookAt(Position, Position + Forward, WorldUp);
}
3.更新camera朝向 UpdateCameraVectors()
//实时更新camera朝向
void Camera::UpdateCameraVectors()
{
Forward.x = glm::cos(Pitch) * glm::cos(Yaw);
Forward.y = glm::sin(Pitch);
Forward.z = glm::cos(Pitch) * glm::sin(Yaw);
Right = glm::normalize(glm::cross(Forward, WorldUp));
Up = glm::normalize(glm::cross(Right, Forward));
}
4.检测鼠标移动 ProcessMouseMovement()<按键控制和鼠标移动实现方法>
//检测鼠标移动,同时调用camera更新函数
void Camera::ProcessMouseMovement(float deltaX,float deltaY)
{
Pitch += deltaY*0.001;
Yaw += deltaX*0.001;
UpdateCameraVectors();
}
5.更新camera的位置 (检测按键控制) UpdateCameraPos()<按键控制和鼠标移动实现方法>
//更新camera的位置,此处的speed可用processinput()操纵WASD按键控制
void Camera::UpdateCameraPos()
{
Position += speedX * Right * 0.001f + speedY * Up * 0.001f + speedZ * Forward * 0.001f;
}
5.析构函数 ~Camera()
//析构函数空实现,但一定要有,否则不能实例化
Camera::~Camera()
{
}
实例化方式为:
Camera camera(glm::vec3(0, 0, 3.0f), glm::radians(0.0f), glm::radians(-90.0f), glm::vec3(0, 1.0f, 0));
这样就能够通过鼠标和按键来控制人物的移动和朝向。