سؤال

Migrating from OpenGL ES1.1 to 2.0 for 2D purposes (orthographic), and I'm having a little trouble figuring out how apply transformations (matrix multiplication order). I only need rotation on the Z-axis, and scaling on X and Y which is the always the same value, so this should simplify things significantly. My current method (ES1.1) which works perfect has a virtual camera, located in the same absolute coordinate space as objects.

At the beginning of each frame I first do the camera's transforms by calling

    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

For objects, it looks like this (omitting the texture and drawing calls).

   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();

I'm trying to get this same functionaly in ES2.0, but all the matrix operations have to be performed manually.

From this link I found that the proper order of multiplaction should be ((Scale * Rotation) * Translation)

Following that I came up with a single matrix formula that combines all of those, since 2D is much simpler. I also have included an orthographic projection matrix. For a test shader I have this:

   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;
  }

Which works just like it's supposed to for every degree of freedom. However, I cannot figure out how to incorporate the camera. The order of multiplication of the matrices in the shader does not match the order of the gl calls, so I'm not sure how to convert my camera calls into multiplication. At first I was also trying to calculate a seperate tranformation matrix for the camera, and set the final position like this:

    gl_Position = projection * cam * m * position;

Which I don't think is right regardless of the order for the camera matrix itself (I tried multiple ways, none worked right). I believe all the camera and object modelview transforms must be compiled into a single modelview matrix (each matrix multiplied by the last, starting with camera tranforms, then object, but obviously in a specific order). This order of operations is what I'm confused about, espcially since it doesn't match up with what was working properly in ES1.1.

Could someone explain the proper order, and why the gl calls are different than the actual multiplication?

هل كانت مفيدة؟

المحلول

If this is working for you in 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

Then the equivalent operation in OpenGLES 2.0 would be (everything in the same order):

modelViewMatrix = camRotate * 
                  camScale * 
                  camTranslate * 
                  objTranslate * 
                  objScale * 
                  objRotate;

To add a projection matrix to that, just append it on the left:

mvpMatrix = proj * modelViewMatrix;

To transform the vertex, multiply it on the right:

transformed = mvpMatrix * in_vert;

نصائح أخرى

After glPushMatrix, glTranslatef, glScalef, glRotatef, glPopMatrix you'll get matrix you pushed to stack. So it does pretty nothing.

But anyway if you want matrix that repoduces xforms performed in this order (glTranslatef, glScalef, glRotatef) you need multiply in the same order (translation * scale) * rotation

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top