出于 2D 目的(正交)从 OpenGL ES1.1 迁移到 2.0,我在弄清楚如何应用变换(矩阵乘法顺序)时遇到了一些麻烦。我只需要 Z 轴上的旋转,以及 X 和 Y 上的缩放,这始终是相同的值,所以这应该会大大简化事情。 我当前的方法(ES1.1)工作完美,有一个虚拟相机,位于与对象相同的绝对坐标空间中。
在每一帧的开始,我首先通过调用进行相机的变换
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glScalef(zoom, zoom, 0.0f);
glTranslatef(-pos.x, -pos.y, 0.0f); // negative position to shift everything back to the center of the view
对于对象,它看起来像这样(省略纹理和绘图调用)。
glPushMatrix(); // to preserve camera transform
glTranslatef(pos.x, pos.y, 0.0f);
glScalef(scale, scale, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
// drawing done here
glPopMatrix();
我试图在 ES2.0 中获得相同的功能,但所有矩阵运算都必须手动执行。
来自this link我发现乘法的正确顺序应该是 ((Scale * Rotation) * Translation)
接下来我想出了一个结合了所有这些的单一矩阵公式,因为 2D 更简单。 我还包括了一个正交投影矩阵。 对于测试着色器,我有这个:
attribute vec4 position;
attribute vec4 color;
varying vec4 colorVarying;
uniform vec2 translate;
uniform float rotate;
uniform float scale;
uniform vec4 camera; // x, y, z = angle, w = zoom
void main()
{
const float w = 3.2;
const float h = 4.8;
mat4 projection = mat4(1.0/w, 0.0, 0.0, 0.0,
0.0, 1.0/h, 0.0, 0.0,
0.0, 0.0, -1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
float s1 = scale * sin(rotate);
float s2 = scale * cos(rotate);
mat4 m = mat4(s2, s1, 0.0, 0.0,
-s1, s2, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
translate.x, translate.y, 0.0, 1.0);
gl_Position = projection * m * position;
colorVarying = color;
}
这对于每个自由度来说都像它应该的那样工作。 但是,我不知道如何合并相机。着色器中矩阵乘法的顺序与 gl 调用的顺序不匹配,因此我不确定如何将相机调用转换为乘法。 起初我还尝试计算相机的单独变换矩阵,并设置最终位置,如下所示:
gl_Position = projection * cam * m * position;
无论相机矩阵本身的顺序如何,我都不认为这是正确的(我尝试了多种方法,但没有一个正确)。我相信所有相机和对象模型 View 变换都必须编译成单个模型 View 矩阵(每个矩阵乘以最后一个矩阵,从相机变换开始,然后是对象,但显然按特定顺序)。 这种操作顺序是我感到困惑的地方,特别是因为它与 ES1.1 中正常工作的内容不匹配。
有人可以解释一下正确的顺序,以及为什么 gl 调用与实际的乘法不同吗?
最佳答案
如果这在 OpenGLES 1.1 中适合您
glRotatef(angle, 0.0f, 0.0f, 1.0f); //camera
glScalef(zoom, zoom, 0.0f); //camera
glTranslatef(-pos.x, -pos.y, 0.0f); //camera
glTranslatef(pos.x, pos.y, 0.0f); //model
glScalef(scale, scale, 0.0f); //model
glRotatef(angle, 0.0f, 0.0f, 1.0f); //model
那么 OpenGLES 2.0 中的等效操作将是(所有内容都按相同顺序):
modelViewMatrix = camRotate *
camScale *
camTranslate *
objTranslate *
objScale *
objRotate;
要向其中添加投影矩阵,只需将其附加到左侧即可:
mvpMatrix = proj * modelViewMatrix;
要变换顶点,请将其乘以右侧:
transformed = mvpMatrix * in_vert;
关于matrix - OpenGL ES2.0 模型 View 矩阵 2D,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12309192/