OpenGL ES Android Matrix Transformations

本秂侑毒 提交于 2019-11-28 07:02:57
escalator

I´ve been working with the example from the Android Training, the following approach finally works for me. (Based on Android Training > Displaying Graphics with OpenGL ES > Adding Motion)

  1. Use the correct vertex shader:

    private final String vertexShaderCode =
    // This matrix member variable provides a hook to manipulate
    // the coordinates of the objects that use this vertex shader
    "uniform mat4 uMVPMatrix;" +
    "attribute vec4 vPosition;" +
    "void main() {" +
    // the matrix must be included as a modifier of gl_Position
    "  gl_Position = uMVPMatrix * vPosition;" +
    "}";
    
  2. In the renderer class:

    public class MyGL20Renderer implements GLSurfaceView.Renderer {
    [...]
    // create a model matrix for the triangle
    private final float[] mModelMatrix = new float[16];
    // create a temporary matrix for calculation purposes,
    // to avoid the same matrix on the right and left side of multiplyMM later
    // see https://stackoverflow.com/questions/13480043/opengl-es-android-matrix-transformations#comment18443759_13480364
    private float[] mTempMatrix = new float[16];
    [...]
    
  3. Apply transformations in onDrawFrame, start with translation:

    public void onDrawFrame(GL10 unused) {
    [...]
    Matrix.setIdentityM(mModelMatrix, 0); // initialize to identity matrix
    Matrix.translateM(mModelMatrix, 0, -0.5f, 0, 0); // translation to the left
    
  4. Then rotation:

    // Create a rotation transformation for the triangle
    long time = SystemClock.uptimeMillis() % 4000L;
    float mAngle = 0.090f * ((int) time);
    Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);
    
  5. Combine rotation and translation, avoid using mModelMatrix

    "as the same matrix on the right and left side of multiplyMM" (see 2)

    // Combine Rotation and Translation matrices 
    mTempMatrix = mModelMatrix.clone();
    Matrix.multiplyMM(mModelMatrix, 0, mTempMatrix, 0, mRotationMatrix, 0);
    
  6. Combine the model matrix with the projection and camera view; again avoid using mModelMatrix

    "as the same matrix on the right and left side of multiplyMM" (see 2)

    // Combine the model matrix with the projection and camera view
    mTempMatrix = mMVPMatrix.clone();
    Matrix.multiplyMM(mMVPMatrix, 0, mTempMatrix, 0, mModelMatrix, 0);
    
  7. Draw the shape

    // Draw shape
    mTriangle.draw(mMVPMatrix);
    

Thank you all, for all the useful input I could draw from this thread.

If you want to see movement, you should update mTriangle.mAngle each frame (preferably as a function of time to combat speed differences or delays caused by other processes...).

Note that Matrix.setIdentityM(mModelMatrix, 0); restores all the accumulated rotations and translations to "zero" or actually to Identity Matrix... The same convention applies btw to all set functions. To accumulate all the transformations, one has to

  • setIdentity(model);
  • translate(trans); // to get the origin of rotation
  • rotate(rotmatrix); // to accumulate the rotation
  • translate(t2); // to translate again to some better position...

Also one should keep the values of object translation vector [ox,oy,oz] between each call and feed them to Matrix.translateM(mModelMatrix, ox, oy, oz, 0);

Typically one concatenates all 'translate, rotate, scale', etc. matrices as early as possible and cache them per object, or hierarchically per a complex container having multiple objects and having a bounding box, so that multiple objects can be culled when on behind the camera (or generally outside the viewing frustum).

Also typically one keeps a moving camera in one matrix and per frame multiplies it with the projection matrix.

You can start with something like:

float Time = System.currentTimeMillis() * 0.01f;  // 10 radians / second == fast!
Matrix.translateM(mModelMatrix, Math.sin(Time)*2.0f, 0, 1f, 0);
...

As Tim noticed, there is no projection matrix involved, meaning that all z-values behave in this code exactly, even though changing x & y values would make a difference.

I'd be tempted to say, that MVP matrix would mean multiplying in order M * V * P = (M*V) * P = M * (V*P).

Note that you're not applying your projection matrix to the triangle you're drawing, that could cause problems.

Should probably be:

Matrix.multiplyMM(mMVMatrix, 0, mVMatrix, 0, mModelMatrix, 0);  
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVMatrix, 0); 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!