How to work with matrices in OpenGL ES 2.0
satya - Mon Aug 06 2012 13:34:07 GMT-0400 (Eastern Daylight Time)
Here is how you arrive at a model-view-projection matrix
protected void setupMatrices()
{
Matrix.setIdentityM(mMMatrix, 0);
//world coordinates
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
//Project it: screen coordinates
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
}
satya - Tue Aug 07 2012 10:03:01 GMT-0400 (Eastern Daylight Time)
what is known: The order of matrix multiplication matters
what is known: The order of matrix multiplication matters
satya - Tue Aug 07 2012 10:03:49 GMT-0400 (Eastern Daylight Time)
Make sure you apply the model coordinate transformation first
and then the view matrix (eye coordinates) transformation and then the projection matrix transformation.
satya - Tue Aug 07 2012 10:04:41 GMT-0400 (Eastern Daylight Time)
Here is the right order example
private void initializeMatrices()
{
Matrix.setIdentityM(mTranslateMatrix, 0);
}
public void trnslate(float x, float y, float z)
{
Matrix.translateM(this.mTranslateMatrix,0,this.mTranslateMatrix,0,x,y,z);
}
public void rotate(float angle, float x, float y, float z)
{
Matrix.rotateM(this.mTranslateMatrix,0,this.mTranslateMatrix,0,angle,x,y,z);
//Matrix.rotateM(this.mRotationMatrix,0,x,y,z);
}
protected void setupMatrices()
{
Matrix.setIdentityM(mMMatrix, 0);
//translate model coordinates
Matrix.multiplyMM(mMVPMatrix, 0, this.mTranslateMatrix, 0, mMMatrix, 0);
//world coordinates: viewmatrix * model matrix
Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMVPMatrix, 0);
//Project it: screen coordinates
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
}
satya - Tue Aug 07 2012 10:05:46 GMT-0400 (Eastern Daylight Time)
You will get weird results if you apply the eye coordinate transformation first
including the right behavior sometimes.
satya - Tue Aug 07 2012 16:27:36 GMT-0400 (Eastern Daylight Time)
Bummer...source and target matrices for rotateM(Target, Source...)
Pay real attention!!! Don't give the same matrix for both. they seem to get completely confused. Use different variables!!
satya - Fri Aug 10 2012 15:15:58 GMT-0400 (Eastern Daylight Time)
May be not, don't take my word for it...
I was reading the opengl super bible yesterday and saw the recommendation that one should use eye coordinate transformation first, followed by the concatenated model transformations next.
umm...not entirely sure why, but it seem to work as well!!
Nope!! My intuition was right
Do the model transformations first and then do the eye coordinates next yielding a joint MV (Model View) Matrix. Perhaps the book is right as well if the focus had been when to apply the projection matrix which clearly comes after the eye coordinates.
satya - Fri Aug 10 2012 15:22:08 GMT-0400 (Eastern Daylight Time)
Transformation in OpenGL applies to a single 'POINT'
It will come as a surprise to you in opengl if you are doing it the first time. we may see things as 3 dimensional objects such as cubes and spheres.
however realize all of the matrix transformations ACT on a SINGLE POINT. Each point is individually transformed and it has no memory of its adjacent vertices!! Ha! It is right before my eyes but I refuse to abandon my "whole" object view of the world.
why is this important?
it is so when you apply a series of transformations such as translate, rotate, scale etc. You may think that you are concatenating these transformations through matrix multiplication.
whats wrong with that?
well in your mind you are only thinking of starting object and the ending object. So you tend to give your coordinates at those two distinct points in time. There lies the problem.
After each transformation the point that is transformed is at a different location. Now the new transformation applies to this NEW point not to the OLD my friend.
satya - Sat Aug 11 2012 13:37:32 GMT-0400 (Eastern Daylight Time)
Here is the right way to multiply the matrices
protected void setupMatrices()
{
Matrix.setIdentityM(mMMatrix, 0);
//translate the model combo next
Matrix.multiplyMM(mMVPMatrix, 0, this.mCurrentModelMatrix, 0, mMMatrix, 0);
//translate eye coordinates first
Matrix.multiplyMM(mMVPMatrix, 0, this.mVMatrix, 0, mMVPMatrix, 0);
//Project it: screen coordinates
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
}
satya - Sat Aug 11 2012 13:37:56 GMT-0400 (Eastern Daylight Time)
Here is the wrong way to do it
protected void setupMatrices1()
{
Matrix.setIdentityM(mMMatrix, 0);
//translate eye coordinates first
Matrix.multiplyMM(mMVPMatrix, 0, this.mVMatrix, 0, mMMatrix, 0);
//translate the model combo next
Matrix.multiplyMM(mMVPMatrix, 0, this.mCurrentModelMatrix, 0, mMVPMatrix, 0);
//Project it: screen coordinates
Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
}
satya - Sat Aug 11 2012 13:41:46 GMT-0400 (Eastern Daylight Time)
Key driver code
protected void draw(GL10 gl, int positionHandle)
{
GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT, false,
0, mFVertexBuffer);
checkGlError("glVertexAttribPointer maPosition");
//mFVertexBuffer.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
GLES20.glEnableVertexAttribArray(positionHandle);
checkGlError("glEnableVertexAttribArray maPositionHandle");
long time = SystemClock.uptimeMillis() % 4000L;
//Break time into 4000 parts
//each part is .090 so that in 4000 parts it will be 360
float angle = 0.090f * ((int) time);
this.initializeMatrices();
//Center the cube
this.trnslate(0,0,-1);
//Rotate it around y axis
this.rotate(angle, 0,-1,0);
//Decenter it to where ever you want
this.trnslate(0,-2,2);
this.setupMatrices();
int vertexCount = mTriangleVerticesData.length/3;
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
checkGlError("glDrawArrays");
}