OpenGL学习:坐标变换(1)-模型变换(model transformation)
来源:互联网 发布:nginx http2 不用TLS 编辑:程序博客网 时间:2024/05/29 19:41
本节开始学习OpenGL中的坐标处理。OpenGL中的坐标处理过程包括模型变换、视变换、投影变换、视口变换等内容,这个主题的内容有些多,因此分节学习,本节主要学习模型变换。本节示例代码均可在https://github.com/wangdingqiao/noteForOpenGL/tree/master/modelTransformation下载。
坐标处理的全局过程
OpenGL中的坐标处理包括模型变换、视变换、投影变换、视口变换等内容,具体过程如下图1所示:
今天我们学习第一个阶段——模型变换。
为什么需要模型变换
我们在OpenGL中通过定义一组顶点来定义一个模型,或者通过其他3D建模软件事先建好模型然后导入到OpenGL中。顶点属性定义了模型。如果我们要在一个场景中不同位置显示同一个模型怎么办? 如果我们要以不同的比例、不同角度显示同一个模型又怎么办 ?
如果继续以类似的顶点属性数据定义同一个模型,调整它满足上述需求的话,不仅浪费显卡内存,而且这个调整的工作量也很大,因此效率很低。更好地解决方法是,我们定义的模型根据需要可以执行放大、缩小等操作来不同比例显示,可以通过平移来放在不同位置,可以通过旋转来按不同角度显示。这种方式就是执行模型变换。
模型变换通过对模型执行平移(translation)、缩放(scale)、旋转(rotation)、镜像(reflection)、错切(shear)等操作,来调整模型的过程。通过模型变换,我们可以按照合理方式指定场景中物体的位置等信息。
平移变换
平移就是将物体从一个位置
本节的模型变换在OpenGL程序中,可以使用GLM数学库实现。例如平移变换实现如下:
- 1
- 2
- 1
- 2
上述表示平移向量为(-0.5,0.0,0.0),得到一个平移矩阵存储到model中。
在程序中我们绘制了4个矩形,通过平移将其放在不同位置,效果如下图所示:
在上图示例中,我们使用不同的着色器还绘制了坐标轴,坐标轴通过箭头和轴线绘制。在xoy坐标系中,第一个象限为原图,第二个象限为平移(-0.5,0.0,0.0)后的矩形,第三象限为平移(-0.8,-0.8,0.0)后的矩形,第四个象限为平移(0.0,-0.5,0.0)后的矩形。
注意 通过上面坐标处理的全局过程图1可以看到,实际顶点输出还需要经过视变换、投影变换过程等处理,本节主要讨论模型变换,因此我们在代码中,不考虑视变换和投影变换,使用默认的视变换和投影变换,即这两个变换保持为单位矩阵。默认的方式就是我们一直在使用的正交投影方式。变换矩阵在着色器中使用uniform变量传递,在c++程序中使用glm::mat4与之对应。对uniform变量不熟悉的话,可以回过头去看2D纹理部分的使用方法。
设置默认视变换和投影变换矩阵的代码如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
绘制四个矩形的代码为:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
这里绘制矩形使用的顶点属性数据,以及纹理使用方法,可以参考之前将2D纹理映射的内容。
本节绘制矩形的顶点着色器中都使用代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
本节绘制矩形的片元着色器中都使用代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
代码中使用坐标vec2(TextCoord.s, 1.0 -TextCoord.t)表示将纹理的y轴翻转,避免纹理倒立显示。
对于4x4仿射变换矩阵,可以表示平移(仿射变换)、缩放、旋转等线性变换,其中矩阵的形式为:
记住这一点,对于矩阵形式理解会比较清楚。
缩放变换
缩放可以沿着三个坐标轴的方向独立进行,当缩放参数一致时是均匀缩放,否则是非均匀缩放。对于以原点为中心的缩放来讲,根据坐标和变换的数学基础,一节所得到的结论:线性变换矩阵为变换后基向量组成。缩放因子为
上图中,第一象限为原图,第二象限为均匀缩放0.5倍,然后平移(-0.25, 0.0,0.0)后的结果;第三象限为均匀缩放2.0倍,然后平移(-1.0, -1.0,0.0)后的结果;第四象限为缩放(2.0,0.5,1.0)后,平移(0.0,-0.25,0.0)后的结果。例如第四象限使用的代码为:注意 设一个方向的缩放因子为
执行缩放变换,效果如下图所示:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这里需要注意几点:
(1) 模型变换进行的顺序与结果是相关的。在向量和矩阵一节已经讲过,矩阵乘法不满足交换律,即
(2) 上述第四个象限矩形,先进行缩放,然后平移到第四象限,这个过程表示为
(3)上述代码中,要按照先缩放后平移来完成模型变换,代码书写的顺序和我们变换的顺序是相反的,主要原因是:
- 1
- 2
- 3
- 1
- 2
- 3
这个代码等价于:
- 1
- 2
- 3
- 1
- 2
- 3
也就是说glm::scale是对单位矩阵进行缩放,然后左乘平移矩阵。这一点尤其要注意。
旋转变换
对于以原点为中心的旋转来讲,旋转矩阵可以这样来推导。以下面的绕+z轴的旋转角度
这样经过旋转以后,原来的+x轴对应的基向量
对于绕y轴,x轴的旋转同理可得到旋转矩阵如下:
不动点与旋转和缩放
对于旋转和缩放来说,我们上面得出的矩阵,都是针对物体以原点为中心进行的旋转和缩放,这种中心点称为不动点
对于缩放的缩放中心也有类似处理。
执行旋转变换,效果如下图所示:
其中,第一象限为原图,第二象限为绕+z轴旋转90度;第三象限为以中心点(0.25,0.25,0.0)旋转,平移(-0.5,-0.5,0.0)到第三象限的结果;第四象限为绕着右下角(0.5,0.0,0.0)旋转,平移(0.0, -0.5,0.0)到第四象限的结果。例如第三象限的绘制代码为:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
注意上面代码中,为了实现绕着矩形中心(0.25,0.25,0.0)旋转,先要平移至原点,然后旋转,最后平移至中心;为了实现平移至第三象限,实行平移变换(-0.5,-0.5,0.0)。
镜像变换
镜像变换,就是反射成像的概念,它是缩放变换的一个特例,当缩放因子
上面图中,第一象限为原图,第二象限为关于y轴的镜像,即点
可以看出这个矩阵,就是上面的缩放矩阵,当缩放因子为(-1.0,1.0,1.0)时的矩阵。因此实现时代码为:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
上图中,第三象限为以xy轴同时反射形成,缩放因子为(-1.0,-1.0,1.0);第四象限为以x轴进行反射,缩放因子为(1.0, -1.0, 1.0)。
应用变换的顺序问题
前面提到过由于矩阵乘法不满足交换律,即
最后说明
上面讨论的模型变换部分涉及到了平移、缩放、旋转和镜像变换,在实际中多半是这些变换的组合,一般地执行变换顺序为缩放–》旋转—》平移。在实行模型变换时,要注意变换的顺序和代码中书写的顺序相反。同时对于缩放和旋转变换,要注意不动点不在原点时的处理方法。对于绕任意方向的旋转,需要推导一个新的旋转矩阵,这个内容会放在数学相关的小节介绍
from:http://blog.csdn.net/wangdingqiaoit/article/details/51531002
- OpenGL学习:坐标变换(1)-模型变换(model transformation)
- OpenGL学习脚印: 模型变换(model transformation)
- OpenGL学习脚印: 模型变换(model transformation)
- OpenGL学习:坐标变换(2)-视变换(view transformation)
- OpenGL学习脚印: 坐标变换过程(vertex transformation)
- OpenGL坐标变换过程(vertex transformation)
- OpenGL学习脚印: 视变换(view transformation)
- OpenGL学习脚印: 视变换(view transformation)
- OpenGL 坐标变换(1)
- OpenGL学习:坐标变换(3)-坐标变换总结
- 【GPU编程】《The Cg Tutorial》学习之坐标变换(Transformation) .
- OpenGl学习之坐标变换(上)
- OpenGl学习之坐标变换(下)
- OpenGL学习(三):坐标变换
- OpenGL坐标变换详解
- OpenGL坐标变换详解
- openGL坐标变换
- OpenGL坐标变换复习
- Centos7 yum安装MongoDB
- 邮件权限的开通以及java后台代码
- axios 全攻略之基本介绍与使用(GET 与 POST)
- ArrayList初见
- Linux-IIC驱动(2)-Linux下IIC子系统的介绍
- OpenGL学习:坐标变换(1)-模型变换(model transformation)
- Linux下Tomcat的搭建以及开机自启动设置
- 保护你的网站免受这七大常见黑客攻击
- document.cookie在IE下不支持时,用sessionStorage配合解决
- [LWIP学习]--netconn结构体及其接口分析
- 机器学习笔记week4(Andrew NG)
- 你为什么跳槽?
- 矩形覆盖
- linux命令嵌套实例(五)