How to work with matrices in OpenGL ES 2.0


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

matrix api

what is known: The order of matrix multiplication matters

and then the view matrix (eye coordinates) transformation and then the projection matrix transformation.


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

including the right behavior sometimes.

Pay real attention!!! Don't give the same matrix for both. they seem to get completely confused. Use different variables!!

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.

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.


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

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

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