本机将主要实现相机类.
Camera.h:
#ifndef _CAMERA_H_
#define _CAMERA_H_
#include "Angel.h"
class Camera
{
public:
Camera();
~Camera();
mat4 lookAt(const vec4& eye, const vec4& at, const vec4& up);
mat4 ortho(const GLfloat left, const GLfloat right,
const GLfloat bottom, const GLfloat top,
const GLfloat zNear, const GLfloat zFar);
mat4 perspective(const GLfloat fovy, const GLfloat aspect,
const GLfloat zNear, const GLfloat zFar);
mat4 frustum(const GLfloat left, const GLfloat right,
const GLfloat bottom, const GLfloat top,
const GLfloat zNear, const GLfloat zFar);
// 每次更改相机参数后更新一下相关的数值
void updateCamera();
// 处理相机的键盘操作
void keyboard(unsigned char key, int x, int y);
// 模视矩阵
mat4 viewMatrix;
mat4 projMatrix;
// 相机位置参数
float radius = 4.0;
float rotateAngle = 0.0;
float upAngle = 0.0;
vec4 eye;
vec4 at;
vec4 up;
// 投影参数
#undef near
#undef far
float near = 0.1;
float far = 100.0;
// 透视投影参数
float fov = 45.0;
float aspect = 1.0;
// 正交投影参数
float scale = 1.5;
};
#endif
Camera.cpp:
#include "Camera.h"
# include <math.h>
Camera::Camera() { updateCamera(); };
Camera::~Camera() {};
mat4 Camera::lookAt(const vec4& eye, const vec4& at, const vec4& up)
{
// 相机观察矩阵的计算
vec4 vpn = eye - at;
vec4 n = normalize(vpn);
vec4 u = normalize(cross(up, n));
vec4 v = normalize(cross(n, u));
vec4 l1 = vec4(u.x, u.y, u.z, -eye.x * u.x - eye.y * u.y - eye.z * u.z);
vec4 l2 = vec4(v.x, v.y, v.z, -eye.x * v.x - eye.y * v.y - eye.z * v.z);
vec4 l3 = vec4(n.x, n.y, n.z, -eye.x * n.x - eye.y * n.y - eye.z * n.z);
vec4 l4 = vec4(0, 0, 0, 1);
mat4 c;
c = mat4(
l1, l2, l3, l4
);
return c;
}
mat4 Camera::ortho(const GLfloat left, const GLfloat right,
const GLfloat bottom, const GLfloat top,
const GLfloat zNear, const GLfloat zFar)
{
// 正交投影矩阵的计算
mat4 c;
vec4 l1 = vec4(2/(right-left), 0, 0, -(right + left)/(right-left));
vec4 l2 = vec4(0, 2/(top-bottom), 0, -(top + bottom)/(top-bottom));
vec4 l3 = vec4(0, 0, -2/(zFar-zNear), -(zFar+zNear)/(zFar-zNear));
vec4 l4 = vec4(0, 0, 0, 1);
c = mat4(
l1, l2, l3, l4
);
return c;
}
mat4 Camera::perspective(const GLfloat fovy, const GLfloat aspect,
const GLfloat zNear, const GLfloat zFar)
{
// 透视投影矩阵的计算
mat4 c;
GLfloat top = zNear * tan(fovy/2/180*M_PI);
GLfloat right = top * aspect;
vec4 l1 = vec4(zNear/right, 0, 0, 0);
vec4 l2 = vec4(0, zNear/top, 0, 0);
vec4 l3 = vec4(0,0, -(zFar+zNear)/(zFar-zNear), (-2*zFar*zNear)/(zFar-zNear));
vec4 l4 = vec4(0,0,-1,0);
c = mat4(
l1, l2, l3, l4
);
return c;
}
mat4 Camera::frustum(const GLfloat left, const GLfloat right,
const GLfloat bottom, const GLfloat top,
const GLfloat zNear, const GLfloat zFar)
{
// 任意视锥体矩阵
mat4 c;
vec4 l1 = vec4(2.0 * zNear / (right - left), 0, (right + left) / (right - left), 0);
vec4 l2 = vec4(0, 2.0 * zNear / (top - bottom), (top + bottom) / (top - bottom), 0);
vec4 l3 = vec4(0, 0, -(zFar + zNear) / (zFar - zNear), -2.0 * zFar * zNear / (zFar - zNear));
vec4 l4 = vec4(0, 0, -1, 0);
c = mat4(l1, l2, l3, l4);
return c;
}
void Camera::updateCamera()
{
// 设置相机位置和方向
float eyex = 0; // 根据rotateAngle和upAngle设置x
float eyey = 0; // 根据upAngle设置y
float eyez = radius; // 根据rotateAngle和upAngle设置z
eyex = radius * cos(upAngle * M_PI / 180) * sin(rotateAngle * M_PI / 180);
eyey = radius * sin(upAngle * M_PI / 180);
eyez = radius * cos(upAngle * M_PI / 180) * cos(rotateAngle * M_PI / 180);
eye = vec4(eyex, eyey, eyez, 1.0);
at = vec4(0.0, 0.0, 0.0, 1.0);
up = vec4(0.0, 1.0, 0.0, 0.0);
}
void Camera::keyboard(unsigned char key, int x, int y)
{
// 键盘事件处理
switch (key)
{
// 通过按键改变相机和投影的参数
case 'x':
rotateAngle += 5.0;
break;
case 'X':
rotateAngle -= 5.0;
break;
case 'y':
upAngle += 5.0;
if (upAngle > 180)
upAngle = 180;
break;
case 'Y':
upAngle -= 5.0;
if (upAngle < -180)
upAngle = -180;
break;
case 'r':
radius += 0.1;
break;
case 'R':
radius -= 0.1;
break;
case 'f':
fov += 5.0;
break;
case 'F':
fov -= 5.0;
break;
case 'a':
aspect += 0.1;
break;
case 'A':
aspect -= 0.1;
break;
case 's':
scale += 0.1;
break;
case 'S':
scale -= 0.1;
break;
// 空格键初始化所有参数
case ' ':
radius = 4.0;
rotateAngle = 0.0;
upAngle = 0.0;
fov = 45.0;
aspect = 1.0;
scale = 1.5;
break;
}
}