Matrix OpenGL ES2.0 Modelview矩阵2D

Matrix OpenGL ES2.0 Modelview矩阵2D,matrix,camera,opengl-es-2.0,model-view,opengl-es-1.1,Matrix,Camera,Opengl Es 2.0,Model View,Opengl Es 1.1,从OpenGL ES1.1迁移到2.0以用于2D目的(正交),我在弄清楚如何应用变换(矩阵乘法顺序)时遇到了一些困难。我只需要在Z轴上旋转,在X轴和Y轴上缩放,这两个轴的值总是相同的,所以这将大大简化事情。 我目前的方法(ES1.1)工作得非常完美,它有一个虚拟摄像机,与对象位于相同的绝对坐标空间中 在每帧开始时,我首先调用 glRotatef(angle, 0.0f, 0.0f, 1.0f); glScalef(zoom, zoom, 0.0f); glTranslat

从OpenGL ES1.1迁移到2.0以用于2D目的(正交),我在弄清楚如何应用变换(矩阵乘法顺序)时遇到了一些困难。我只需要在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
对于对象,它看起来是这样的(忽略纹理和图形调用)

我试图在ES2.0中实现同样的功能,但所有矩阵操作都必须手动执行

从中我发现多重作用的正确顺序应该是((比例*旋转)*平移)

接下来,我提出了一个单一的矩阵公式,将所有这些结合起来,因为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;
不管相机矩阵本身的顺序如何,我认为这是不对的(我尝试了多种方法,没有一种是正确的)。我认为所有摄影机和对象modelview变换都必须编译成单个modelview矩阵(每个矩阵乘以最后一个矩阵,从摄影机变换开始,然后是对象,但显然是按特定顺序)。 这种操作顺序让我感到困惑,特别是因为它与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中的等效操作将是(所有操作的顺序相同):

要向其添加投影矩阵,只需将其附加到左侧:

mvpMatrix = proj * modelViewMatrix;
要变换顶点,请在右侧将其相乘:

transformed = mvpMatrix * in_vert;

在glPushMatrix、GLTRANSTALEF、glScalef、glRotatef、GLPOPMARRIX之后,您将得到被推到堆栈中的矩阵。所以它什么也没做


但无论如何,如果您希望矩阵以这种顺序(GLTRANSTALEF、glScalef、GLROTATIEF)重新生成xforms,您需要以相同的顺序进行乘法(平移*缩放)*旋转

我注意到您在平移*缩放周围加了括号,但这可能有点误导,因为它们肯定不是必需的。(AB)*C与A*相同(BC)与ABC相同。对不起,我应该说得更清楚,我省略了这里的绘图调用以减少混乱,但我在弹出矩阵之前绘制每个对象(或精灵)。谢谢,这篇文章真的让我开始了!
mvpMatrix = proj * modelViewMatrix;
transformed = mvpMatrix * in_vert;