opengl 和 d3d 中的手性和向量、矩阵的区别
1 、 d3d 中是用左手坐标系, opengl 是用右手坐标系;
左手和右手从坐标系看只是一个 z 轴的差别(要注意: opengl 和 d3d 对坐标轴的正向,都有约定, x 轴默认向右, y 轴默认向上,而 z 轴则由左手和右手判定之, d3d 的 z 轴正向朝屏幕里面,而 opengl 的 z 轴正向朝屏幕外面),但是实际上却是一个左右颠倒的世界,是不能用旋转和平移等变换来模拟的。这一点在用 3D 建模工具导出模型时要留意。
【类似的,引擎 ogre 使用右手,而引擎 irrlicht 使用左手 … 拜托你们采用统一的标准不好嘛 ~~~~ 】
2 、 d3d 中矩阵采用行主序, opengl 的矩阵采用列主序
注意:由于 C 语言的数组本来就是行主序的,所以在 opengl 中,刚开始时候有点不适应,不过向量和矩阵在数学上本来就经常以列来描述,所以在数学上是比较适应的。
在 opengl 中,矩阵: m = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} 乘以向量 v = {17,18, 19, 20} 应该这么理解:
M * v =
1 2 3 4 17
5 6 7 8 * 18
9 10 11 12 19
13 14 15 16 20
又:如果几个变换按次序相连:向量 v 先做变换 M1 ,再做变换 M2 ,再做变换 M3 ,表现在矩阵乘法上时候,却是: M3 * M2 * M1 * v ,所以我们总是看见 opengl 是这样得到综合矩阵的: Matrix = Mproj * Mmodelview
D3D 的矩阵是以行主序,所以向量和矩阵的乘积就是: v * M ,而且向量先做变换 M1 ,再做变换 M2 ,再做变换 M3 ,得到的式子是: v * M1 * M2 * M3 ,比较符合直觉。但是数学上的矩阵公式全部要先转置才能应用到 D3D 中
3 、第 1 点和第 2 点不同很容易让人产生一种错觉,就是左手坐标系肯定是用行主序来描述,而右手坐标系是用列主序来描述,这只是一中 opengl 和 d3d 给人的错觉,完全可以在右手坐标系中用行主序,也可以在左手坐标系中用列主序。
注:顺便埋怨几句 irrlicht 引擎,里面是用左手坐标系,而矩阵也是用行主序,但是却在矩阵乘积上要这样子写: WorldViewProject = Mpro * Mview * Mworld
搞得我查了半天,发现在引擎里面矩阵乘法上的实现写反了,但是却不知道为什么要写反,结果在官方论坛上找到了解释:
矩阵乘法的成员函数注释上这样说:
//! Add another matrix.
CMatrix4<T> operator+(const CMatrix4<T>& other) const;
//! Subtract another matrix.
CMatrix4<T> operator-(const CMatrix4<T>& other) const;
//! Multiply by another matrix.
CMatrix4<T> operator*(const CMatrix4<T>& other) const;
看见了没,加法和减法的注释都很干脆:加上另一个矩阵;减去另一个矩阵;唯独是乘法:是:被另一个矩阵所乘!!! ,这说明了用别人的代码先要看别人的注释;还有就是一个东西如果不遵从潜规则,给别人带来多么大的痛苦!【注:说到这里,还是不知道为什么要写反,但是人家注释清楚了,也算是说明了原因】