2012-09-06 94 views
4

从OpenGL ES1.1移植到2.0用于2D目的(拼写),并且我在计算如何应用转换(矩阵乘法顺序)时遇到了一些问题。我只需要在Z轴上旋转,并且在X和Y上的比例总是相同的值,所以这应该显着简化事情。 我当前使用的方法(ES1.1)有一个虚拟相机,它位于与对象相同的绝对坐标空间中。OpenGL ES2.0模型视图矩阵2D

在每帧我先做相机的转换的开始通过调用

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我发现multiplaction的正确顺序应该是((秤*旋转)*翻译)

下面,我想出了将所有的这些单一基质配方,因为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; 

,我不认为这是正确的不分先后顺序的相机矩阵本身(我尝试了多种方式,没有一个正确地工作)。我相信所有的相机和对象模型视图变换必须被编译成单个模型视图矩阵(每个矩阵乘以最后一个,从相机变形开始,然后是对象,但显然是按照特定的顺序)。 这个操作顺序是我很困惑的,特别是因为它与ES1.1中正常工作的不匹配。

有人可以解释正确的顺序,以及为什么gl调用不同于实际的乘法?

+0

谢谢,这个帖子真让我开始! – dac2009

回答

5

如果这是在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; 
1

后glPushMatrix,的glTranslatef,glScalef,glRotatef,glPopMatrix你会得到你矩阵推到堆栈。所以它没有什么。

但无论如何,如果你想矩阵repoduces顺序执行的XForms(的glTranslatef,glScalef,glRotatef),你需要乘以相同的顺序(翻译*比例)*旋转

+0

我注意到你在翻译*范围内放了括号,但这可能有点误导,因为它们当然不是必需的。 (A * B)* C与A *相同(B * C)与A * B * C相同。 – Tim

+0

是的,它只是让顺序更清晰 – ChatCloud

+0

对不起,我应该更清楚了,我省略了我的绘图调用来减少混乱,但是我在绘制矩阵之前绘制每个对象(或精灵)。 – user1137704

相关问题