相关主题:OpenGL变换,OpenGL投影矩阵,四元数
下载:matrix.zip, matrix_rowmajor.zip
OpenGL为渲染管线准备了4种不同类型的矩阵(GL_MODELVIEW,GL_PROJECTION, GL_TEXTURE and GL_COLOR)并且为这些矩阵提供了变换的操作:glLoadIdentity(),glTranslatef(),glRotatef(),glScalef(),glMultMatrixf(),glFrustum()和glOrtho().
这些内置的矩阵和操作对于开发简单的OpenGL应用程序非常有用并且非常有利于理解矩阵变换。但是当你的应用程序变的复杂的时候,最好是自己为所有需要移动的对象实现你自己的矩阵和操作。除此之外,你也不可以在可编程的管线(GLSL),像OpenGL v3.0+, OpenGL ES v2.0+ 和 WebGL v1.0+中使用这些内置的矩阵和操作。你必须实现你自己的矩阵并且将矩阵中的数据传递到着色器中。
这篇文章提供了一种使用C++编写的独立,通用的的4*4矩阵类Matrix4,并且描述了如果将这个类集成到OpenGL应用程序中。这个类只依赖于定义在Vectors.h中的Vector3和Vector4。这些向量类也包含在 matrix.zip中。
Matrix4类包含一个16个浮点型元素的数组来存储4*4的矩阵,它有3个构造函数来实例化这个Matrix4类的对象。
以行为主的Matrix4
OpenGL中使用的以列为主的矩阵
注意这个Matrix4类使用以行为主的标记次序而不是像OpenGL那样使用以列为主的标记次序。然儿,以行为主的次序和以列为主的次序只是两种不同的将多维数组中的数据存储的一维数组中的方式,这对矩阵的算法和矩阵的操作结果是没有影响的。
缺省的构造函数(没有参数)将会创建一个单位矩阵。其他两个构造函数接受16个参数或者包含16个参数的数组。你也可以使用复制构造或赋值操作符(=)来初始化一个Matrix4类的实例。
顺便说一下,复制构造和赋值操作符(=)会由C++编译器自动生成。
下面是一个使用不同方式构造Matrix4对象的例子。首先,需要在使用Matrix4类的文件中包含Matrices.h头文件。
Setters
Matrix4类提供set()函数来设置所有的16个元素。
你也可以使用setRow()和setColumn()函数一次来设置一行或一列的值,setRow()和setColumn()函数的第一个参数是一个基于0的索引,第二个参数是指向数组的指针。
单位矩阵
Matrix4类有一个特殊的setter,identify()函数用来生成一个单位矩阵
Getters
Matrix4::get()方法返回一个指向拥有16个元素的数组。getTranspose()返回转置后的矩阵元素。它专门用来将矩阵中的数据传递到OpenGL中,更多详细的细节参考例子。
访问单个元素
矩阵中的单个元素可以通过[]操作符来访问:
打印Matrix4
Matrix4也提供了一个便利的打印输出函数std::cout<<来方便调试:
Matrix4类提供了两个矩阵之间的基本算法。
加法和减法
你可以将两个矩阵相加和相减
乘法
你可以将两个矩阵相乘,也有与3维和4维向量相乘以便使用矩阵将向量进行变换。注意矩阵相乘不满足交换律。
比较
Matrix4类提供了比较操作符来比较两个矩阵中的所有元素:
OpenGL有几个变换函数:glTranslatef(),glRotatef()和glScalef()。Matrix4也提供了几个相同的函数来进行矩阵变换:translate(),rotate()andscale()。除此之外,Matrix4还提供了invert()函数计算矩阵的转置矩阵。
Matrix4::translate(x,y,z)
平移矩阵
translate()函数产生经过(x,y,z)变换后的矩阵。首先,它创建一个变换矩阵MT,然后乘以当前矩阵来产生最终的矩阵:
注意这个函数等价于OpenGL中的glTranslatef(),但是OpenGL使用后乘而不是前乘:,如果你执行多个变换,结果将会不一样因为矩阵相乘不满足交换律。
Matrix4::rotate(angle,x,y,z)
旋转矩阵
rotate()可以被用来通过指定一个轴(x,y,z)和绕轴旋转的角度来旋转三维模型。这个函数生成一个旋转矩阵MR,然后乘以当前矩阵生成一个最终经过旋转变换后的矩阵:
它等价于glRotatef(),但是OpenGL使用后乘操作来生成最终的变换后的矩阵:
rotate()可以用来绕任意的轴旋转。Matrix4类提供了额外的3个函数绕指定轴旋转rotateX(),rotateY(),rotateZ()。
Matrix4::scale(x,y,z)
缩放矩阵
scale()在每一个轴上产生一个不均等的缩放效果的矩阵:。
注意:OpenGL中glScalef()执行后乘操作:。
Matrix4类也提供了均等的缩放函数。
Matrix::invert()
invert()函数计算当前矩阵的反转矩阵,这个反转矩阵主要用来将法向量从物体坐标系变换到人眼坐标系中。法向量和顶点的变换不一样。法向量变换是使用GL_MODELVIEW的反转乘以法向量:详细的细节参考这儿。
如果矩阵只是欧式变换(旋转和平移),或者放射变换(旋转,平移,缩放,裁剪),反转矩阵的计算会很简单。Matrix4::invert()将会为你决定何时的反转方式,但是如果你明确地调用了一个反转函数:invertEuclidean(),invertAffine(),invertProjective()o或invertGeneral()。请阅读 Matrices.cpp中的详细细节。
下载源文件和二进制文件:matrix.zip
这个例子显示了怎么将Matrix4类集成到OpenGL程序中。GL_MODELVIEW联合和视图矩阵和模型矩阵,但是我们将它们分开并传递两个矩阵给OpenGL的模型视图矩阵。
等价的OpenGL实现如下:
模型视图矩阵的反转用来将法向量从物体坐标系变换到人眼坐标系中。在可编程的渲染管线中,你需要将它传递给GLSL着色器。
这个例子显示了如何创建投影矩阵,等价于glFrustum()和glOrtho()。更多细节查看source codes。
-
顶
- 0
-
踩