缩放、旋转、平移 w。 openGl ES 2.0 中的矩阵

Posted

技术标签:

【中文标题】缩放、旋转、平移 w。 openGl ES 2.0 中的矩阵【英文标题】:Scale, rotate, translate w. matrices in openGl ES 2.0 【发布时间】:2014-09-29 13:30:14 【问题描述】:

我正在使用 OpenGL ES 2.0 并尝试使用一些方法来构建我的对象类来旋转/平移/缩放它们。

我只是在 0,0,0 中设置我的对象,然后将其移动到屏幕上的所需位置。以下是我单独移动它的方法。之后我运行 buildObjectModelMatrix 将所有矩阵传递到一个 objectMatrix 中,这样我就可以获取顶点并将它们与我的 modelMatrix/objectMatrix 相乘,然后再渲染它。

我认为是对的,我必须按这个顺序乘我的矩阵:

[缩放]x[旋转]x[平移]

->

[临时]x[翻译]

->

[对象矩阵]

我找到了一些文献。也许我会在几分钟内得到它,如果我愿意,我会更新它。

Beginning android 3D

http://gamedev.stackexchange.com

  setIdentityM(scaleMatrix, 0);
  setIdentityM(translateMatrix, 0);
  setIdentityM(rotateMatrix, 0);
public void translate(float x, float y, float z) 
    translateM(translateMatrix, 0, x, y, z);
    buildObjectModelMatrix();


public void rotate(float angle, float x, float y, float z) 
    rotateM(rotateMatrix, 0, angle, x, y, z);
    buildObjectModelMatrix();


public void scale(float x, float y,float z) 
    scaleM(scaleMatrix, 0, x, y, z);
    buildObjectModelMatrix();


private void buildObjectModelMatrix() 
    multiplyMM(tempM, 0, scaleMatrix, 0, rotateMatrix, 0);
    multiplyMM(objectMatrix, 0, tempM, 0, translateMatrix, 0);

已解决: 整个事情的问题是,如果你在翻译之前进行缩放,你翻译的距离就会有所不同!乘以矩阵的正确代码应该是(如果我错了,请纠正我)

    private void buildObjectModelMatrix() 
    multiplyMM(tempM, 0, translateMatrix, 0, rotateMatrix, 0);
    multiplyMM(objectMatrix, 0, tempM, 0, scaleMatrix, 0);

您首先平移和旋转。之后,您可以缩放对象。

用多个对象测试...所以我希望这会有所帮助:)

【问题讨论】:

【参考方案1】:

您知道这是大多数人在开始处理矩阵运算时最常见的问题。矩阵乘法的工作原理就像您从对象的第一人称视图中获取一些命令一样:例如,如果您从 (0,0,0) 开始面向正 X 轴,而 up 将是正 Y 轴,那么平移 (a,0,0) 将意味着“前进”,翻译(0,0,a) 表示“向左”,旋转(a, 0, 1, 0) 表示“左转”...

因此,如果在您的情况下,您按3 单位缩放,按90 度旋转,然后按(2,0,0) 平移,那么您首先将自己放大3,然后转动90 度,这样你现在正面临Z 仍然很大。然后你前进2在你自己的坐标系中测量的单位,这意味着你实际上会去(0,0,2*3)。所以你最终会在(0,0,6) 看向积极的Z 轴。

我相信这种方式是能够想象在处理此类操作时会发生什么的最佳方式。如果矩阵运算顺序出现错误,可能会挽救您的生命。

您应该知道,虽然这种矩阵操作在开始 3D 场景时是正常的,但您应该尽快尝试转向更好的系统。我最常用的是拥有一个包含 3 个向量的对象结构/类:positionforwardup(这很像使用 glLookAt,但不完全相同)。因此,当拥有这 3 个向量时,您可以使用三角函数或矩阵工具通过将向量与矩阵相乘而不是矩阵与矩阵相乘来简单地设置特定位置或旋转。或者您可以在内部(第一人称)使用它们,例如“前进”将作为position = position + position*forward*scale 完成,左转将围绕up 向量旋转forward 向量。无论如何,我希望能理解如何操纵这 3 个向量以获得所需的效果......所以你需要做的是从这 3 个向量重建矩阵需要生成另一个向量right,它是 @987654344 的叉积@ 和 forward 则模型矩阵包括:

right.x,    right.y,    right.z, .0
up.x,       up.y,       up.z, .0
forward.x,  forward.y,  forward.z,  .0
position.x, position.y, position.z, 1.0

请注意,行列顺序可能会根据您使用的内容而改变。

我希望这能让你更好地理解......

【讨论】:

以上是关于缩放、旋转、平移 w。 openGl ES 2.0 中的矩阵的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL中旋转平移缩放等变换的顺序对模型的影响

如何使用现代 OpenGL 的 GLM 或 JOML 矩阵正确转换(平移、旋转、缩放)对象

Android OpenGLES2.0——OpenGL中的平移旋转缩放

OpenGL ES平移矩阵和旋转矩阵的左乘与右乘效果

[opengl] 画一个可移动的自行车 二维几何变换(平移旋转缩放)

如何在 Android 中将 OpenCV 旋转和平移矢量与 OpenGL ES 一起使用?