zoukankan      html  css  js  c++  java
  • 【OpenGL】学习笔记#3

    唉,虽然学会了,但是懒得做笔记呀。俗话说好记性不如烂笔头,防止遗忘我还是记一记吧。

    一、矩阵

    众所周知,三弟3D图形学中很重要的就是线性代数,我们进行各种变换的时候就要用到神奇的矩阵。

    (不禁想吐槽一句,这个神奇的东西到底是怎么想出来的。。)

    相信矩阵乘法大家都了解,下面讲几种特殊的矩阵。

    1.平移矩阵(Translate Matrix)

    在讲矩阵之前,先说一个东西:齐次坐标。

    为了区分矢量和标量,我们用第四维w来表示,v(x,y,z,w) ,则w=1 => v是空间中的位置,w=0 => v是向量。

    那么我们想要在x轴上移动位置v(10,10,10,1),那么相应的平移矩阵就是

    1 ,0 ,0 ,10

    0 ,1 ,0 ,0

    0 ,0 ,1 ,0

    0 ,0 ,0 ,1

    将它乘上我们的v,根据矩阵乘法得到v'(20,10,10,1),显然是正确的。

    如果v是(-1,0,0,0)呢?(代表x轴负方向),根据计算得到(-1,0,0,0),显然是正确的,因为移动方向没有意义,帅呆了!

    定义一个平移矩阵:

    glm::mat4 myMatrix = glm::translate(glm::mat4(), glm::vec3(10.0f, 0.0f, 0.0f));

    把位置和矩阵相乘:

    glm::vec4 myVector(10.0f, 10.0f, 10.0f, 0.0f);
    glm::vec4 transformedVector = myMatrix * myVector; // guess the result

    相乘的代码是一样的,下文不表。

    2.单位矩阵(The Identity Matrix)

    1 ,0 ,0 ,0

    0 ,1 ,0 ,0

    0 ,0 ,1 ,0

    0 ,0 ,0 ,1

    它就相当于1,任何数乘上1不会改变,单位矩阵乘上单位矩阵也是一样。

    代码:

    glm::mat4 myIdentityMatrix = glm::mat4(1.0f);

    3.缩放矩阵(Scaling matrices)

    x ,0 ,0 ,0

    0 ,y ,0 ,0

    0 ,0 ,z ,0

    0 ,0 ,0 ,1

    xyz就是缩放的倍数,多么优美的矩阵。

    代码:

    glm::mat4 myScalingMatrix = glm::scale(2.0f, 2.0f ,2.0f);

    4.旋转矩阵(Rotation matrices)

    很复杂的东西,贴代码:

    // RotationAngle is in radians
    x = RotationAxis.x * sin(RotationAngle / 2)
    y = RotationAxis.y * sin(RotationAngle / 2)
    z = RotationAxis.z * sin(RotationAngle / 2)
    w = cos(RotationAngle / 2)

    代码:

    glm::vec3 myRotationAxis( ??, ??, ??);
    glm::rotate( angle_in_degrees, myRotationAxis );

    这里不涉及到矩阵,OpenGL已经封装好了。(如此贴心!)

    介绍完了矩阵们,接下来要用到他们变换我们的3D世界了。

    变换大致是这样的流程:

    模型坐标系--×模型矩阵-->世界坐标系--×相机矩阵-->相机坐标系--×透视矩阵-->屏幕坐标系

    模型坐标系和世界坐标系:假定(0,0,0,1)是模型的中心点,将它乘上一个平移矩阵,此时它的位置就不是(0,0,0,1),而是另一个位置,此时它就处于世界坐标系。(细品)

    相机坐标系:把相机往一个位置移动似乎不好解决(仔细想,因为所有的变换都是为了让物体在屏幕上以一个真实的方式呈现,我们不择手段),所以我们移动世界,把一切顶点移动,幸运的是OpenGL已经为我们实现了!

    屏幕坐标系:通过透视变换,我们把3D变成了2D(画家:我恨数学!)!具体实现比较复杂,不细说,但是原理也是通过乘上一个透视变换的矩阵,这个矩阵OpenGL也为我们提供了!(欢呼!)

    下面是代码实现:

    模型矩阵:(我们把它放到世界原点,所以就用单位矩阵作为模型矩阵)

    glm::mat4 Model      = glm::mat4(1.0f);

    相机矩阵:(使用lookAt函数)

    glm::mat4 View       = glm::lookAt(
                                    glm::vec3(4,3,-3), // Camera is at (4,3,-3), in World Space
                                    glm::vec3(0,0,0), // and looks at the origin
                                    glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
                               );

    第一个参数是相机位置(世界坐标系),第二个是相机观察的位置,第三个是向上的方向(用于计算一个交叉积,一定要填对喔!)。

    透视矩阵:

    glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.0f);

    第一个参数代表Fov,视角大小,第二个代表屏幕宽高比,第三个代表近裁剪面(近于这个值的物体将被裁剪,不显示),第四个代表远裁剪面(远于这个值的物体将被裁剪,不显示)。

    最后,把这三个矩阵相乘,即可得到顶点们的变换了。

    glm::mat4 MVP        = Projection * View * Model;

    注意顺序!

  • 相关阅读:
    jtopo
    转载model2
    转载model
    Vue -- 后台系统布局导航栏
    Vue -- iview表格 axiso调用接口数据
    Vue -- 视频&&下载 组件
    Vue -- echarts 折线图demo
    Vue -- axios封装
    Vue -- 验证码
    01 & 02 & 03笔记
  • 原文地址:https://www.cnblogs.com/dudujerry/p/13542357.html
Copyright © 2011-2022 走看看