美文网首页
OpenGL之变换、矩阵堆栈

OpenGL之变换、矩阵堆栈

作者: K哥的贼船 | 来源:发表于2020-07-20 01:34 被阅读0次

    OpenGL中的变换

    变换 解释
    视图变换 指定观察者的位置
    模型变换 在场景中移动物体
    模型视图 描述视图/模型变换的二元性(2种看到模型转换的方式)
    投影 改变视景体大小和设置它的投影方式
    视口 伪变化,对窗口上最终输出进行缩放

    视图变换

    2个视角观察视觉坐标

    • 视图变换是应用到场景中的第一种变换,可以将观察者放在你希望的任何位置,并允许在任何方向上观察场景,确定场景中利于观察的位置。确定视图变换就像在场景中放置观察者并让它指向某一个方向。
    • 默认情况下,透视投影中的观察者位置处于原点(0,0,0),并沿着z轴负方向看向屏幕里面。
    • 从大局上考虑,在应用任何其他模型变换之前,必须先应用视图变换。这样做事由于,对于视觉坐标系而言,视图变换移动了当前的工作的坐标系,后续变换都会基于新调整的坐标系进行。

    模型变换

    模型变换:用于操纵模型与其中某特定变换。这些变换将对象移动到需要的位置,通过旋转、缩放、平移。


    模型变换
    模型变换组合

    对模型的组合变换顺序不一样,就会得到不同的结果,物体经过变换后的最终位置也不一样。其根本原因在于矩阵的叉乘不满足交换律。所以不能交换模型变换(平移、旋转)的前后顺序。
    如果对一个物体进行模型视图的变换,可以有多种方式。

    1. 观察者动,物体不动;
    2. 观察者不动,物体动;
    3. 观察者动,物体也动。

    其最终目的都是为了更好的观察物体。

    模型变换API

    转自style_月月

    投影变换

    来自CC老师

    投影方式有两种

    • 透视投影:屏幕上物体与实物的比例是 < 1:1的,且有远小近大的效果
      OpenGL中对应的设置API:
      void SetPerspective(float fFov, float fAspect, float fNear, float fFar)
    • 正投影:屏幕上物体与实物的比例是 = 1:1的,都是一样大的效果
      设置投影方式的API:
      void SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax)

    矩阵堆栈

    当我们观察物体变换场景时,需要设置一个几何的变换管道(GLGeometryTransform)来使用投影矩阵堆栈和模型视图矩阵堆栈。之后 变换管道通过GetModelViewProjectionMatrix()GetMatrix函数就可以获得矩阵堆栈顶部的值。给着色器的运行指定了一个几何图形变换4 * 4变换矩阵。
    其中用到的矩阵堆栈,在构造函数时允许指定堆栈的最大深度,默认的堆栈深度为64。这个矩阵堆在初始化时已经在堆栈中包含了单位矩阵。矩阵堆栈是用来保存物体变换的状态,在OpenGL的状态机里面,如果想要保证目标图形的变换不影响其他图形,需要一个矩阵去保存更改前的状态,在变换图形完成后恢复之前的状态。
    矩阵堆栈的使用API:

    图片转自style_月月

    矩阵堆栈中入栈、矩阵相乘、出栈的流程

    仿射变换
    矩阵堆栈中有与平移、旋转、缩放三个模型变换相对应的仿射变换,直接通过矩阵堆栈的API实现这3种变换,如下表所示

    仿射变换API 说明
    Void MatrixStack::Rotate(GLfloat angle,GLfloat x,GLfloat y, GLfloat z); 旋转;参数1 angle传递的是度数,⽽不是弧度
    Void MatrixStack::Translate(GLfloat x,GLfloat y, GLfloat z); 平移
    Void MatrixStack::Scale(GLfloat x,GLfloat y, GLfloat z); 缩放

    GLFrame(角色帧)
    用来表示物体及观察者所处的位置,有三个参数

    vOrigin:当前所处的位置,默认是(0,0,0),处于原点
    vForward:即将要去的位置,默认是(0,0,-1),朝向-z轴方向
    vUp:朝向哪,默认是(0,1,0),朝向+y轴方向

    GLFrame

    矩阵堆栈除了可以操作矩阵,也可以操作角色帧。

    • 将堆栈顶部压入任何矩阵
      void GLMatrixStack::LoadMatrix(GLFrame &frame);
    • 与堆栈栈顶相乘,将结果存储在堆栈栈顶
      void GLMatrixStack::MultMatrix(GLFrame &frame);
    • 将当前矩阵压栈
      void GLMatrixStack::PushMatrix(GLFrame &frame);

    照相机管理

    • GLFrame的函数,这个函数⽤来检索条件适合的观察者矩阵
      void GetCameraMatrix(M3DMatrix44f m,bool bRotationOnly = flase);

    相关文章

      网友评论

          本文标题:OpenGL之变换、矩阵堆栈

          本文链接:https://www.haomeiwen.com/subject/ezlrkktx.html