本文是学习OpenGL过程中的一篇笔记。在学习过程中,主要参照了大名鼎鼎的

  • 《OpenGL Programming Guide》(中文名《OpenGL编程指南》,有些人还称之为OpenGL红宝书)
  • 《OpenGL SuperBible》(中文名《OpenGL超级宝典》,有些人还称之为OpenGL蓝宝书)

另外还有

  • 《3D Computer Graphics: A Mathematical Introduction with OpenGL》
  • 《Advanced Graphics Programming Using OpenGL Morgan Kaufmann Series in Computer Graphics and Geometric Modeling 》
  • 《3D Math Primer for graphics and game development》

等书籍。

1,应用程序传送给OpenGL的顶点位置坐标,法线向量坐标、纹理坐标以及光源坐标都是定义在对象坐标系中的。如果应用程序开启了基于对象坐标系的纹理生成,那么这些纹理坐标的生成是利用末经模型视图矩阵变换的顶点位置坐标生成的,所以这种情况下如果移动或者旋转物体,纹理将和物体一起移动或者旋转,实例请参考蓝宝书第9章的TEXGEN程序。

The vertices of a model are typically stored in object space, a coordinate system that is local to the particular model and used only by that model. The position and orientation of each model are often stored inworld space, a global coordinate system that ties all of the object spaces together. Before  an object can be rendered, its vertices must be transformed into  camera space (also called  eye space), the space in which the x and y axes are aligned to the display and the z axis is parallel to the viewing direction.

2,模型转换(Modeling Transformation):使用模型转换的目的是设置物体在场景中的位置(position)和方向(orientation)。通常,为了正确的在场景中放置每个物体,每个物体都需要一个不同的模型转换。如果要使物体产生运动效果,也需要在每帧更新时对物体使用不同的模型转换。

3,视觉转换(Viewing Transformation):使用视觉转换的目的是改变场景中所有物体的位置和方向,换句话说,就是改变观察的位置和方向。实例请参见下图:

视觉转换需要的信息是viewer’s (eye) position, the center of observation, and the normal (“vector” quantity) to the viewer’s head (as indicated by the orange arrow over the Blender camera in Figures。

4,使用glLight命令给定光源位置和方向时,在光源位置和方向被OpenGL存储之前会经过模型视图矩阵(ModelView Matrix)的变换。如果没有用glLight命令更新的话,这些位置和方向将一直被OpenGL在计算光照时使用。

5,在视觉坐标系中,物体光照效果发生作用,基于视觉坐标系的纹理坐标生成也是发生在视觉坐标系中的。默认情况下,视点(或者说成照相机)位于视觉坐标系原点,指向Z轴负方向,向上向量为(0,1,0),请参见下图。

由于视觉坐标系指向Z轴负方向,所以glFrustum(GLdouble left,GLdouble  right,GLdouble bottom,GLdouble  top,GLdouble  near,GLdouble  far)和gluPerspective(GLdouble fovy,GLdoubleaspect,GLdoublenear,GLdoublefar)中的near和far是在以Z轴负方向的情况下指定的。

可以直接使用gluLookAt来改变视点的位置和方向。注意,在OpenGL代码中,视觉转换一定要发生在模型转换之前,可以在绘图之前的任何时刻进行投影变换和视口变换。

如果使能光照的话,openGL会在视觉坐标系中使用视点位置,光源位置和法线向量来进行光照计算,从而修改物体顶点的颜色。为了便于理解,这里引用一个光照模型图,如下:

6,投影变换(Project Transformation):投影变换的一个显著特征是透视缩短,即物体如果离照相机的距离越远,则它看上去就越小。透视投影可以看成一个金字塔的平截头体。靠近观察点的物体看上去会更大一些,因为和远处的物体相比,他们占据了视景体中相对较大的区域。

投影变换其实是对对象进行变形处理,使得变形后的对象经正交投影后得到与原对象的理想投影后一样的视图(详细请参见:投影矩阵,深入探索透视投影变换)。

“透视”一词源自拉丁文“perspclre”,意为看透。为了将立体物体的图像转化到平面上以完成作画的过程,人们开始了关于透视的研究。最初研究透视是采取通过一块透明的平面去看景物的方法,将所见景物准确描画在这块平面上,即成该景物的透视图。随着研究的深入,人们将在平面画幅上根据一定原理,用线条来显示物体的空间位置、轮廓和投影的科学称为透视学。
       在多种透视方法中,最常用到的是线透法。线透法的基本原理,在于将物体的每一个点全部以连线的方式与观察视野,也就是我们的眼睛相连,然后再将一块平面置于这些线上,由线穿透平面所构成的投影来确定物体在画面中的形态。无论是现代西方美术、摄影还是图形渲染工业,一切与现代西方美术有关并以平面化展现立体物体形象为任务的领域,都要依赖线透法来实现最终的画面效果。

透视投影在图形学中非常重要,因为它是人类视觉系统的模型。为便于理解,我们以小孔成像来说明它的基本原理。请参见下图:

图中右边的茶壶经过小孔投影到左边的立方体中。其剖面图如下:

为了计算上的方便,我们将投影平面移到投影的前面,如下图:

这就是OpenGL使用的投影原理。

我们可以用glFrustum建立投影视景体,如下图:

此时,投影后所形成的最终图像将会显示在near平面上。投影矩阵的推导过程请参见《OpenGL Projection Matrix》。

注意:投影变换变换后的坐标系是右手坐标系,即点(0,0,1)比点(0,0,-1)距离观察者近。

7,透视除法(Perspective Division):通过透视除法,我们可以得到NDC(Normalized Device Coordinate)。规范化的原因是不想为每种类型的投影设计不同的投影矩阵,所以把所有的投影转换为具有默认视景体的正交投影。

通过投影变换和透视除法,我们得到NDC。这个过程可能难于理解,下面我们用计算机图形学中的一点透视来解释一下(详细请参见《三维变换及三维观察》)。我们考虑从NDC到视景体的变换,步骤如下:

设:视点(投影中心)在Z轴上(z=-d),投影面在XOY上,一点透视的步骤:

①平移三维形体到(l、m、n)

②确定d的值,透视变换

③向XOY作正投影变换

8,Normalized Device Coordinate System (NDCS) is the coordinate system in which the entire screen of the device corresponds to a unit cube, so all points in this cube are within the range [1, 1, 1] to [-1, -1, -1] for x, y, and z。

注意:NDC坐标系是左手坐标系,即点(0,0,-1)比点(0,0,1)距离观察者近。

可以通过在启用深度测试(GL_DEPTH_TEST)后,使用glDepthRangef(1, 0) 来将左手坐标系变成右手坐标系。

9,窗口变换矩阵(Viewport Transformation):在NDC视景体中的每一个点(x,y,z),其x,y,z取值范围都在区间[-1,1]内。它的x和y坐标映射到一个以(Vx,Vy)为起点,宽为w,高为h,中心点为(Vx+w/2, Vy+y/2)的窗口(Viewport)中。z坐标默认映射到范围[0,1]中,也可改变它,使它映射到[Dn,Df]中,这样深度范围d=Df-Dn,并且它的中心点是(Dn+Df)/2。这样,实现从NDC到窗口坐标转换的窗口变换矩阵是:

下面是2张效果示例图:

10,关于红宝书中3.2节视图和模型转换中提到的局部移动坐标系可以参考《3D Math Primer for graphics and game development》3.5节Coordinate Space Transformations进行理解。

OpenGL笔记之矩阵变换(Matrix Transformation)相关推荐

  1. OpenGL学习笔记:矩阵变换

    文章目录 缩放 glm矩阵表示 glm缩放矩阵实现 位移 齐次坐标 glm位移矩阵实现 旋转 沿x轴旋转 沿y轴旋转 沿z轴旋转 沿任意轴旋转 glm旋转矩阵实现 矩阵的组合 glm矩阵组合使用 接上 ...

  2. opengl笔记——OpenGL好资料备忘

    Plane Equation 注:面可理解为:连接面上的点与原点,投影相同(为:a*x1+b*x2+c*x3) OpenGL Matrix Class (C++) Overview OpenGL fi ...

  3. OPenGL笔记--创建三维图形(立方体)

    文章目录 一.前置知识 二.运行效果 三.具体代码 一.前置知识 通过之前的学习,我们已经知道了如何创建多边形,立方体实际就是多边形围起来的三维图形,例如: 椎体是4个三角形围起来的三维图形: 正方体 ...

  4. OPenGL笔记--创建一个3D场景

    文章目录 一.前言 二.效果展示 三.详细流程 3.1.World.txt文件规则 3.2.加载World.txt 3.3.绘制场景 3.4.交互 四.详细代码 五.举一反三 一.前言 通过前面的学习 ...

  5. 乱弹OpenGL中的矩阵变换

    在前面的日志(Shadow Volume 阴影锥技术之探Ⅲ )中,自己稍微提及了NEHE的"3D矩阵求逆"方法之高,并谈了谈自己的一点拙略理解.呵呵,然后,既然如此,一不做二不休, ...

  6. 乱弹OpenGL中的矩阵变换(上)

    在前面的日志(Shadow Volume 阴影锥技术之探Ⅲ )中,自己稍微提及了NEHE的"3D矩阵求逆"方法之高,并谈了谈自己的一点拙略理解.呵呵,然后,既然如此,一不做二不休, ...

  7. Opengl ES之矩阵变换

    前言 说到矩阵变换,我们第一时间想到的就是大学时代的线性代数这些复杂的东西,突然有了一种令人从入门到放弃的念头,不慌,作为了一个应用层的CV工程师, 在实际应用中线性代数哪些复杂的计算根本不用我们自己 ...

  8. 浅谈矩阵变换——Matrix

    矩阵变换在图形学上经常用到.基本的常用矩阵变换操作包括平移.缩放.旋转.斜切. 每种变换都对应一个变换矩阵,通过矩阵乘法,可以把多个变换矩阵相乘得到复合变换矩阵. 矩阵乘法不支持交换律,因此不同的变换 ...

  9. 论文笔记:Hankel Matrix Factorization for Tagged Time Series to Recover Missing Values during Blackouts

    ICDE 2019 0 摘要 在执行时间序列分析时,恢复时间序列中的缺失值至关重要.而本文研究的blackouts问题,即在一定时期内丢失所有数据,是最紧迫和最具挑战性的问题之一.现有的时间序列缺失值 ...

最新文章

  1. LoaderManager使用具体解释(三)---实现Loaders
  2. Iconfont使用手册
  3. UA OPTI544 量子光学14 量子电动力学基础
  4. 亡羊补课2019-12-19
  5. 微信小程序支付java视频_【原创】微信小程序支付(普通模式,公众号支付同适用)java后台案例...
  6. 光纤收发器的原理及应用_光纤收发器的几种常规应用
  7. JavaFX游戏(四连环)
  8. unity3d学习笔记(一)-在一个GameObject上进行多个AudioSource的控制
  9. 快速行进算法(fast_marching_kroon)的matlab代码
  10. FreeImage编译及遇到问题解决
  11. 用Java山寨一款Flash游戏
  12. 一图看清美国最具前景的50家人工智能公司
  13. 学生用计算机怎么玩俄罗斯方块,计算机专业项目二 俄罗斯方块
  14. 【R语言实验】基于R语言的时间序列平稳性检验
  15. strcmp( )函数
  16. Maven配置阿里云HTTPS镜像地址
  17. 作为一名计算机学院普通的大学生如何提高兴趣敲代码?谈谈我的感受,欢迎交流
  18. linux网卡恢复默认配置,Linux网卡的配置
  19. Vue项目启动出现的问题及解决方法
  20. 宗海图cad_AutoCAD技术在海域使用论证宗海图绘制中的应用

热门文章

  1. Python学习(文件操作)
  2. 泛微oa明细表添加按钮_泛微OA 新增能:表单建模详解.doc
  3. 湖人总冠军,快来抢注NBA球队球星的.fans域名
  4. Vulnhub靶机Five86-2渗透笔记
  5. 游戏——TextOut函数
  6. SSH1和SSH2区别
  7. 进程间通信————共享内存
  8. 小组赛-卡希尔替补建奇功 澳大利亚3-1力克日本
  9. Linux 必学的 100+ 常用命令,你都会用吗?
  10. 【学习SLAM】ORB_SLAM2 双目测试(1)