假设我有一个蓝色的3D盒子(顶部是红色的)。
我所期望的是看到红色面朝向屏幕并沿着屏幕伸展(沿着模型的Y轴)。
但是我看到的是: 红色面朝向屏幕(正如预期的那样)。 但拉伸发生在视图空间的Y轴上(而不是模型)。
我知道如果我沿着Z轴设置比例,那么我将得到正确的结果。 但我的困惑是,我认为在Y轴上放大,然后旋转框,会给我正确的结果。
我缺少什么?
答案 0 :(得分:20)
OpenGL在所谓的column major
order中读取其矩阵。结果是每个后续操作都是它之前所有操作的预乘,而不是后乘。因此,每次后续调用OpenGL操作(glScale,glTranslate,glRotate)都是影响对象的 第一个 事物,它进入你如何编写它的逆序。
因此,您需要更改乘法顺序:
glRotatef(90, 0, 1, 0); // Notice how this is the first operation ...
// ... but will be applied after
glScalef(1, 10, 1); // This will be applied first, but is the last operation
// Zany, right?
说实话,当你编写程序和使用计算机必须以相反的顺序指定事物时,感觉不太直观。但是图形众神决定了他们希望OpenGL的矩阵堆栈如何表现(与HLSL,GLSL和其他系统一起:请参阅上面关于列主要排序的链接)。
答案 1 :(得分:-1)
如果你有一个表示像这样的4x4矩阵的数组:
float mat[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
然后将其加载到OpenGL矩阵中,OpenGL将前4个浮点数作为矩阵的第一列,第二个浮点数作为第二列,第三个浮点数作为矩阵的第3列等,等
因此,每4个浮点数,OpenGL就会看到另一个列。这称为Column-Major订单。 它将数据存储在列中。如果你必须转置一个列主矩阵,它最终会成为一个行主矩阵,反之亦然。
因为你有一个列主矩阵,你还需要使用列向量,这意味着你的乘法顺序是: M * v 。
为了证明这一点,请使用带有2x1列向量的简单2x2矩阵,乘以 M * v 。设K =转置(M),r =行向量(1x2)。
然后 M * v = r * K
最重要的是,一旦在代码中使用了列或行主要表示法,就必须坚持下去。