QT之OpenGL摄像机

1. 概述

OpenGL本身没有摄像机(Camera)的概念,但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机,产生一种我们在移动的感觉。

当我们讨论摄像机/观察空间(Camera/View Space)的时候,是在讨论以摄像机的视角作为场景原点时场景中所有的顶点坐标:观察矩阵把所有的世界坐标变换为相对于摄像机位置与方向的观察坐标。
在这里插入图片描述
正z轴是指向屏幕外,如果我们希望摄像机向后移动,我们就沿着z轴的正方向移动

1.1 摄像机创建

因此OpenGL想达到摄像机的效果,就要首先需要创建一个摄像机坐标系,用来表示摄像机本身,步骤如下:

  1. 指定Camera的位置QVector3D(0.0f,0.0f,3.0f)

  2. 指定摄像机指向的方向,现在让摄像机朝向原点(0.0f,0.0f,0.0f)
    此时摄像机的方向向量(Direction Vector)应当是(0.0f,0.0f,0.0f) - (0.0f,0.0f,3.0f) ,即方向向量指向Z轴的负方向,
    但我们希望它指向摄像机的Z轴正方向,因此使用方向向量(Direction Vector)表示指向摄像机Z轴正方向的向量(0.0f,0.0f,3.0f) - (0.0f,0.0f,0.0f)

    auto directionVector = QVector3D(0.0f,0.0f,3.0f)-QVector3D(0.0f,0.0f,0.0f);
    
  3. 至此我们有了一个摄像机的方向,接下来处理X
    使用右向量(Right Vector),代表摄像机空间的X轴的正方向,为了得到一个垂直于Z轴的X轴,首先顶一个上向量(Up Vector)Y(0.0f, 1.0f, 0.0f),最后将Y轴与Z进行叉乘得出X

    auto upVector = QVector3D(0.0f, 1.0f, 0.0f);
    auto rightVector = QVector3D::crossProduct(upVector, directionVector);
    
  4. 最后需要一个垂直于XZ平面的Y轴,此时将X轴与Z轴叉乘即可得出垂直于XZ平面的Y

    auto resultUpVector =QVector3D::crossProduct(directionVector, rightVector)
    
  5. 使用摄像机向量创建LookAt矩阵

    使用矩阵的好处之一是如果使用3个相互垂直(或非线性)的轴定义了一个坐标空间,可以用这3个轴外加一个平移向量来创建一个矩阵,并且可以用这个矩阵乘以任何向量来将其变换到那个坐标空间。这正是LookAt矩阵所做的,LookAt矩阵如下:
    在这里插入图片描述
    其中R是右向量,U是上向量,D是方向向量P是摄像机位置向量。注意,位置向量是相反的,因为我们最终希望把世界平移到与我们自身移动的相反方向。把这个LookAt矩阵作为观察矩阵可以很高效地把所有世界坐标变换到刚刚定义的观察空间。

    前四步我们算出了,方向向量,右向量与向上向量,但定义的值只有一个摄像机位置摄像机方向向量及一个向上的向量,而lookAt()函数同样需要这三个参数,此函数就会进行以上四步的 运算。

    void lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up)
    

2. 旋转(欧拉角)

欧拉角(Euler Angle)是可以表示3D空间中任何旋转的3个值,由莱昂哈德·欧拉(Leonhard Euler)在18世纪提出。一共有3种欧拉角:俯仰角(Pitch)、偏航角(Yaw)和滚转角(Roll),下面的图片展示了它们的含义:

在这里插入图片描述

  • 俯仰角(pitch):是描述我们如何往上或往下看的角,其绕X轴旋转,在旋转时YZ坐标将被改变

  • 偏航角(yaw):表示我们往左和往右看的程度,其绕Y轴旋转,在旋转时XZ坐标将被改变

  • 滚转角(roll):代表我们如何翻滚摄像机,通常在太空飞船的摄像机中使用。其
    Z轴旋转,在旋转时XY坐标将被改变

用欧拉角描述物体的旋转时会存在一个问题——万向死锁有关欧拉角及万向死锁的解释请看这个视频,这里简要概括如下:

  1. 旋转的顺序不同,最终的姿态也会不同(这里以 pitch -> yaw -> roll顺序表述)
  2. 欧拉角描述的是一个旋转变换,而不是旋转过程。即在给定三个角度的情况下,从初始姿态旋转变换到最终姿态,仅此而已
  3. 将最不可能旋转90°的旋转角(尽可能避免),放置在中间,即yaw -> pitch -> roll的旋转顺序

3. demo示例

在这里插入图片描述

  1. WASD进行移动
  2. 滚轮进行缩放
  3. 鼠标按下时移动鼠标图形也发生转动

camera demo 代码

4. 参考

OpenGL摄像机

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值