opengl 教程(13) 摄像机坐标系

简介: 原帖地址:http://ogldev.atspace.co.uk/www/tutorial13/tutorial13.html       在前面的教程中,我们都是默认摄像机坐标在三维坐标的原点,本篇教程我们开始讨论把摄像机放在三维空间的任意位置,从而更方便的从不同视角观察物体。

原帖地址:http://ogldev.atspace.co.uk/www/tutorial13/tutorial13.html

      在前面的教程中,我们都是默认摄像机坐标在三维坐标的原点,本篇教程我们开始讨论把摄像机放在三维空间的任意位置,从而更方便的从不同视角观察物体。决定三维空间摄像机坐标系有三个因素,摄像机的在三维空间的位置,摄像机lookat的方向向量,摄像机的up方向向量,有了这三个值,我们就可以确定三维空间摄像机的位置和方位,从而推导出世界坐标系到摄像机坐标的转化矩阵。

具体推导见我转的另外一篇文章:http://www.cnblogs.com/mikewolf2002/archive/2012/11/25/2787636.html

主要代码变化:

 

建立一个矩阵类Matrix4f,用来管理所有的矩阵操作。

pipeline.h

struct {
Vector3f Pos;
Vector3f Target;
Vector3f Up;
} m_camera;

math3d.h

Vector3f Vector3f::Cross(const Vector3f& v) const
{
const float _x = y * v.z - z * v.y;
const float _y = z * v.x - x * v.z;
const float _z = x * v.y - y * v.x;
return Vector3f(_x, _y, _z);
}

向量类Vector3f增加了2个向量叉积的函数。

math3d.h

Vector3f& Vector3f::Normalize()
{
const float Length = sqrtf(x * x + y * y + z * z);
x /= Length;
y /= Length;
z /= Length;
return *this;
}

注意:右向量是根据叉积算出来的。

math3d.cpp

void Matrix4f::InitCameraTransform(const Vector3f& Target, const Vector3f& Up)
{
Vector3f N = Target;
N.Normalize();
Vector3f U = Up;
U.Normalize();
U = U.Cross(Target);
Vector3f V = N.Cross(U);
m[0][0] = U.x; m[0][1] = U.y; m[0][2] = U.z; m[0][3] = 0.0f;
m[1][0] = V.x; m[1][1] = V.y; m[1][2] = V.z; m[1][3] = 0.0f;
m[2][0] = N.x; m[2][1] = N.y; m[2][2] = N.z; m[2][3] = 0.0f;
m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f;
}

pipeline.cpp

 

const Matrix4f* Pipeline::GetTrans()
{
Matrix4f ScaleTrans, RotateTrans, TranslationTrans, CameraTranslationTrans, CameraRotateTrans, PersProjTrans;
ScaleTrans.InitScaleTransform(m_scale.x, m_scale.y, m_scale.z);
RotateTrans.InitRotateTransform(m_rotateInfo.x, m_rotateInfo.y, m_rotateInfo.z);
TranslationTrans.InitTranslationTransform(m_worldPos.x, m_worldPos.y, m_worldPos.z);
CameraTranslationTrans.InitTranslationTransform(-m_camera.Pos.x, -m_camera.Pos.y, -m_camera.Pos.z);
CameraRotateTrans.InitCameraTransform(m_camera.Target, m_camera.Up);
PersProjTrans.InitPersProjTransform(m_persProj.FOV, m_persProj.Width, m_persProj.Height, m_persProj.zNear, m_persProj.zFar);
m_transformation = PersProjTrans * CameraRotateTrans * CameraTranslationTrans * TranslationTrans * RotateTrans * ScaleTrans;
return &m_transformation;
}

      下面代码把摄像机从原点移动到(1.0,1.0,-3.0)的位置,摄像机对准位置(0.45f, 0.0f, 1.0f),摄像机的up方向是y轴正方向。

tutorial13.cpp

Vector3f CameraPos(1.0f, 1.0f, -3.0f);
Vector3f CameraTarget(0.45f, 0.0f, 1.0f);
Vector3f CameraUp(0.0f, 1.0f, 0.0f);
p.SetCamera(CameraPos, CameraTarget, CameraUp);

 

程序运行后界面如下:

image

相关文章
QT+OpenGL 摄像机
OpenGL本身没有摄像机的定义,但是我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种我们在移动的感觉。
182 0
OpenGL学习笔记(一):环境搭建、三维空间坐标系理解以及OpenGL的基本使用
OpenGL学习笔记(一):环境搭建、三维空间坐标系理解以及OpenGL的基本使用
OpenGL学习笔记(一):环境搭建、三维空间坐标系理解以及OpenGL的基本使用
openGL简明教程(一)---开始的开始,绘制一个三角形
openGL简明教程(一)---开始的开始,绘制一个三角形
260 0
下一篇
DataWorks