OpenGL进阶十(四)——UVN相机实现

提要

,,,3 d游戏中最基本的一个功能就是3 d漫游了,玩家可以通过键盘或者鼠标控制自己的视角。

,,,之前我们也学习过一个相关的函数,glLookAt,用来制定摄像机的位置,摄像机观察目标位置,还有摄像机的放置方式,我们可以通过不断地调用这个函数来实现3 d漫游,但更方便的是抽象出一个摄像机类,实现一些摄像机的方法。


UVN相机

UVN使用三个相互垂直的向量来表示相机的位置与朝向:

1)相机注视的向量N
2)相机的上方向向量V
3)相机的右方向向量U

如下图,是在世界坐标系下的UVN相机的向量表示:

 OpenGL进阶十(四)——UVN相机实现“> <br> </p> <p> <br> </p> <p>绿色轴为N,蓝色轴为V,红色轴为美国</p> <p>当要改变相机位置和朝向的时候,只需要将UVN矩阵和相应的变换矩阵相乘即可。</p> <p> <br> </p> <h3>代码实现</h3> <p>这里借助了一个第三方矩阵向量库——eigen.Ubuntu下的安装的过程非常简单,下载源码之后,解压,cd进目录:</p> <p> mkdir构建<br> cd build  <br> cmake . .<br> <br> sudo make install </p> <p> <br> </p> <p>写一个头文件:</p> <p>特征。h </p> <p> </p> <pre name==癱pp”>“代码”类的ifndef EIGEN_H # define EIGEN_H # include“eigen3/特征/Dense
放在工程目录下面,使用的时候包含进来就可以了。


看类声明:glcamera。h

“代码”类的ifndef GLCAMERA_H # define GLCAMERA_H # include“eigen.h"# include & lt; GL/glu.h># include & lt; iostream>使用名称空间特征;类GLCamera{公众:GLCamera ();GLCamera (const Vector3d&pos, const Vector3d&目标,const Vector3d&了);空白setModelViewMatrix ();空白setShape (viewAngle浮动,浮动方面,附近浮动,浮动远);空白幻灯片(du浮动,浮动dv,浮动dn);空白卷(浮动角);空白偏航(浮动角);空白间距(浮动角);浮动getDist ();私人:Vector3d m_pos;Vector3d m_target;Vector3d m_up;Vector3d u, v、n;};# endif//GLCAMERA_H 

setModelViewMatrix:加载将当前MV矩阵。

setShape:设置摄像机的视角。

辊、偏航,音高相当于绕N, V, U轴的旋转,如下图:

 OpenGL进阶十(四)——UVN相机实现“> <br> </p> <p> <br> </p> <p>下面是相机的实现:</p> <p> </p> <=按搿崩嗝? # include“glcamera.h"GLCamera: GLCamera () {} GLCamera:: GLCamera (const Vector3d, pos, const Vector3d,目标,const Vector3d,) {m_pos=pos;m_target=目标;m_up=;n=Vector3d (pos.x () -target.x (), pos.y () -target.y (), pos.z () -target.z ());u=Vector3d (up.cross (n)方式(),up.cross (n) .y (), up.cross (n)还是z ());v=Vector3d (n.cross (u)方式(),n.cross (u) .y (), n.cross (u)还是z ());n.normalize ();u.normalize ();v.normalize ();setModelViewMatrix ();}无效GLCamera: setModelViewMatrix(){双m [16];m [0]=u.x ();m [4]=u.y ();m [8]=u.z ();m [12]=-m_pos.dot (u);m [1]=v.x ();m [5]=v.y ();m [9]=v.z ();m [13]=-m_pos.dot (v);m [2]=n.x ();纽约州m [6]=();m [10]=n.z ();m [14]=-m_pos.dot (n);m [3]=0;m [7]=0;m [11]=0;m [15]=1.0;glMatrixMode (GL_MODELVIEW);glLoadMatrixd (m);//用M矩阵替换原视点矩阵}无效GLCamera:: setShape (viewAngle浮动,浮动方面,附近浮动,浮动远){glMatrixMode (GL_PROJECTION);glLoadIdentity ();//设置当前矩阵模式为投影矩阵并归一化gluPerspective (viewAngle方面,接近,远);//对投影矩阵进行透视变换}无效GLCamera::幻灯片(du浮动,浮动dv,浮动dn) {//std:: cout<& lt;“u.x:“& lt; & lt; u.x () & lt; & lt; std:: endl;m_pos (0)=m_pos (0) & # 43;杜* u.x () & # 43; dv * v.x () & # 43; dn * n.x ();m_pos (1)=m_pos (1) & # 43;杜* u.y () & # 43; dv * v.y () & # 43; dn *纽约();m_pos (2)=m_pos (2) & # 43;杜* u.z () & # 43; dv * v.z () & # 43; dn * n.z ();m_target (0)=m_target(0) & # 43;杜* u.x () & # 43; dv * v.x () & # 43; dn * n.x ();m_target (1)=m_target(0) & # 43;杜* u.y () & # 43; dv * v.y () & # 43; dn *纽约();m_target (2)=m_target(0) & # 43;杜* u.z () & # 43; dv * v.z () & # 43; dn * n.z ();setModelViewMatrix ();}无效GLCamera:卷(浮动角){浮动cs=cos(角* 3.14159265/180);浮动sn=罪(角* 3.14159265/180);Vector3d t (u);Vector3d年代(v);u.x ()=c * t.x () - sn * s.x ();u.y ()=c * t.y () - sn * s.y ();u.z ()=c * t.z () - sn * s.z ();sn * t.x v.x ()=() & # 43; c * s.x ();sn * t.y v.y ()=() & # 43; c * s.y ();sn * t.z v.z ()=() & # 43; c * s.z ();setModelViewMatrix ();//每次计算完坐标轴变化后调用此函数更新视点矩阵}无效GLCamera::音高(浮动角){浮动cs=cos(角* 3.14159265/180);浮动sn=罪(角* 3.14159265/180);Vector3d t (v);Vector3d年代(n);v.x ()=c * t.x () - sn * s.x ();v.y ()=c * t.y () - sn * s.y ();v.z ()=c * t.z () - sn * s.z ();sn * t.x n.x ()=() & # 43; c * s.x ();纽约()=sn * t.y () & # 43; c * s.y ();sn * t.z n.z ()=() & # 43; c * s.z ();setModelViewMatrix ();}无效GLCamera:偏航角度(浮点){浮动cs=cos(角* 3.14159265/180);浮动sn=罪(角* 3.14159265/180);Vector3d t (n);Vector3d年代(u);n.x ()=c * t.x () - sn * s.x ();纽约()=c * t.y () - sn * s.y ();n.z ()=c * t.z () - sn * s.z ();null

OpenGL进阶十(四)——UVN相机实现