5

As a beginner to android and openGL 2.0 es, I'm testing simple things and see how it goes.

I downloaded the sample at http://developer.android.com/training/graphics/opengl/touch.html .

I changed the code to check if I could animate a rotation of the camera around the (0,0,0) point, the center of the square.

So i did this:

public void onDrawFrame(GL10 unused) {
    // Draw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    // Set the camera position (View matrix)
    long time = SystemClock.uptimeMillis() % 4000L;
    float angle = ((float) (2*Math.PI)/ (float) 4000) * ((int) time);
    Matrix.setLookAtM(mVMatrix, 0, (float) (3*Math.sin(angle)), 0, (float) (3.0f*Math.cos(angle)),     0 ,0, 0,     0f, 1.0f, 0.0f);

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

    // Draw square
    mSquare.draw(mMVPMatrix);
}

I expected the camera to look always to the center of the square (the (0,0,0) point) but that's not what happens. The camera is indeed rotating around the square but the square does not stay in the center of the screen.. instead it is moving along the X axis...: enter image description here enter image description here

I also expected that if we gave the eyeX and eyeY the same values as centerX and centerY,like this:

Matrix.setLookAtM(mVMatrix, 0, 1, 1, -3,     1 ,1, 0,     0f, 1.0f, 0.0f);

the square would keep it's shape (I mean, your field of vision would be dragged but along a plane which would be paralel to the square), but that's also not what happens:

enter image description here

This is my projection matrix:

float ratio = (float) width / height;

// this projection matrix is applied to object coordinates
// in the onDrawFrame() method
Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 2, 7);

What is going on here?

jmacedo
  • 773
  • 1
  • 13
  • 24

1 Answers1

10

Looking at the source code to the example you downloaded, I can see why you're having that problem, it has to do with the order of the matrix multiplication.

Typically in OpenGL source you see matrices set up such that

transformed vertex = projMatrix * viewMatrix * modelMatrix * input vertex

However in the source example program that you downloaded, their shader is setup like this:

" gl_Position = vPosition * uMVPMatrix;"

With the position on the other side of the matrix. You can work with OpenGL in this way, but it requires that you reverse the lhs/rhs of your matrix multiplications.

Long story short, in your case, you should change your shader to read:

" gl_Position = uMVPMatrix * vPosition;"

and then I believe you will get the expected behavior.

Tim
  • 35,413
  • 11
  • 95
  • 121
  • Yes, it works like this,but now the rotation is "broken" with the green triangle (you know, the one they have in the tutorial).I've seen your new question,I'll make sure to keep an eye on it. When I was studying for my CG classes, I've done a Matlab mini 3d renderer and I used to know these transformations kinda well. But now, I'm kinda rusty.This is confusing because there are lots of ways to do this..Change the order of multiplications,transpose matrices, etc..And I'm not familiar with the helper functions enough to break through this at the moment.btw,is there a print matrix funct avaiable? – jmacedo Aug 12 '12 at 23:49
  • 1
    @joxnas : `Arrays.toString(matrix)` – Tim Aug 13 '12 at 02:34
  • As for the rotation which doesn't work now, any clue? They have: `Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);` The triangle rotates weirdly around the z axis, although it appears to be ok if i set the projection matrix to `Matrix.frustumM(mProjMatrix, 0, -1, 1, -1, 1, 2, 7);` instead of `Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 2, 7)`, getting of course the screen skewness. I tried swapping the rotation matrix with MVPMatrix in the multiplication, but didn't get any good results. – jmacedo Aug 13 '12 at 03:26
  • 1
    I believe it should be mvpMatrix * mRotationMatrix, but you're not supposed to use the same matrix as the input and output to that function, you need to use a temporary matrix. [Android.opengl.Matrix](http://developer.android.com/reference/android/opengl/Matrix.html) " The same float array may be passed for result, lhs, and/or rhs. **However, the result element values are undefined if the result elements overlap either the lhs or rhs elements.**" If that doesn't help then post your entire code. – Tim Aug 13 '12 at 03:27
  • 1
    Yeh, that works: `Matrix.setRotateM(mRotationMatrix, 0, angle, 0.0f, 0.0f, -1.0f);Matrix.multiplyMM(mMVPMatrix, 0, dupMatrix(mMVPMatrix), 0, mRotationMatrix, 0);` Thanks for the help! (I'm kinda shocked thought... The tutorial uses the same matrix for input and output...) – jmacedo Aug 13 '12 at 03:46