第七课,OpenGL之摄像机类

类参数

private:
	glm::vec3 cameraPosi;
	glm::vec3 cameraFocus;
	glm::vec3 cameraUp;
	glm::vec3 dirZ;//正向
	glm::vec3 dirX;//右向
	glm::vec3 dirY;//上方

定义cameraPosi,cameraFocus,及cameraUp可以确定摄像机的初始位置。
dirX,Y,Z分别表示摄像机的三个坐标方向。

类函数声明

基本函数

	//构造函数
	camera();
	//向视角前后移动
	void moveForBackward(float meters);
	//向视角左右移动
	void moveLRward(float meters);
	//向视角上下移动
	void moveUpDownward(float meters);
	//以交点为中心对摄像机位置进行旋转
	void rotateCamera(float xRotate, float yRotate);
	//获取lookat矩阵
	glm::mat4 getViewMetrix();

类函数实现

#include "camera.h"
camera::camera() :cameraPosi{ 0.0f,0.0f,0.3f }, cameraFocus{ 0.0f,0.0f,0.0f },
					cameraUp{ 0.0f,0.1f,0.0f }
{
	dirZ = glm::normalize(cameraPosi - cameraFocus);
	dirX = glm::normalize(glm::cross(dirZ, cameraUp));
	dirY = glm::normalize(glm::cross(dirZ, dirX));
}

void camera::moveForBackward(float meters)
{
	if (glm::distance(cameraPosi, cameraFocus) >= 0.3f) {
		cameraPosi += meters * dirZ;
	}
	else {
		cameraPosi = dirZ * 0.3f + cameraFocus;
	}
}

void camera::moveLRward(float meters)
{
	cameraPosi  -= meters * dirX;//meters为正时,向左移动。
	cameraFocus -= meters * dirX;
}

void camera::moveUpDownward(float meters)
{
	cameraPosi += meters * dirY;
	cameraFocus += meters * dirY;
}

void camera::rotateCamera(float xRotate, float yRotate)
{
	glm::vec4 cameraPosi4v = glm::vec4(cameraPosi, 1.0f);
	glm::vec4 dirY4v = glm::vec4(dirY, 1.0f);
	
	glm::mat4 rotateMetrix = glm::mat4(1.0f);
	rotateMetrix = glm::rotate(rotateMetrix, glm::radians(xRotate), -dirY);
	cameraPosi4v = rotateMetrix * cameraPosi4v;

	rotateMetrix = glm::mat4(1.0f);
	rotateMetrix = glm::rotate(rotateMetrix, glm::radians(yRotate), -dirX);
	cameraPosi4v = rotateMetrix * cameraPosi4v;
	dirY4v = rotateMetrix * dirY4v;

	dirY = glm::vec3(dirY4v.x, dirY4v.y, dirY4v.z);
	cameraPosi = glm::vec3(cameraPosi4v.x, cameraPosi4v.y, cameraPosi4v.z);
	resetDirXYZ();
	
}

glm::mat4 camera::getViewMetrix()
{
	return glm::lookAt(cameraPosi,cameraFocus,dirY);
}

void camera::resetDirXYZ()
{
	dirY = glm::normalize(dirY);
	dirZ = glm::normalize(cameraPosi - cameraFocus);
	dirX = glm::normalize(glm::cross(dirZ, dirY));
}


  1. camera::camera():通过默认数据对dirXYZ进行初始化。

  2. void camera::moveForBackward(float meters)。向前向后不改变焦点,且只能放大到一定程度。移动方向为dirZ轴。

  3. void camera::moveLRward(float meters)。移动方向为X轴。

  4. void camera::moveUpDownward(float meters)。移动方向为Y轴。

  5. void camera::rotateCamera(float xRotate, float yRotate)。
    对摄像机进行旋转会改变改变摄像机的方向轴。
    通过将摄像机的三维坐标变化为齐次方程,再通过旋转矩阵修改,最后再转化为三维坐标。

    沿摄像机Y轴为轴旋转只需计算摄像机位置,dirY轴方向不变,其他轴也可对应的计算出来。
    但沿摄像机X轴旋转还需改变dirY轴方向,及需对dirY也做相同的旋转。

    重点:最后不要忘了对摄像机的方向轴重设。及调用 resetDirXYZ() 。

void camera::resetDirXYZ()
{
	dirY = glm::normalize(dirY);
	dirZ = glm::normalize(cameraPosi - cameraFocus);
	dirX = glm::normalize(glm::cross(dirZ, dirY));
}
  1. glm::mat4 camera::getViewMetrix()。通过get函数得到ViewMetrix,可以很好的提高摄像机移动效率,在获取VIew时才计算lookat函数。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elsa的迷弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值