page.title=Applying Projection and Camera Views parent.title=Displaying Graphics with OpenGL ES parent.link=index.html trainingnavtop=true previous.title=Drawing Shapes previous.link=draw.html next.title=Applying Projection and Camera Views next.link=projection.html @jd:body

This lesson teaches you to

  1. Define a Projection
  2. Define a Camera View
  3. Apply Projection and Camera Transformations

You should also read

Download the sample

OpenGLES.zip

In the OpenGL ES environment, projection and camera views allow you to display drawn objects in a way that more closely resembles how you see physical objects with your eyes. This simulation of physical viewing is done with mathematical transformations of drawn object coordinates:

This lesson describes how to create a projection and camera view and apply it to shapes drawn in your {@link android.opengl.GLSurfaceView}.

Define a Projection

The data for a projection transformation is calculated in the {@link android.opengl.GLSurfaceView.Renderer#onSurfaceChanged onSurfaceChanged()} method of your {@link android.opengl.GLSurfaceView.Renderer} class. The following example code takes the height and width of the {@link android.opengl.GLSurfaceView} and uses it to populate a projection transformation {@link android.opengl.Matrix} using the {@link android.opengl.Matrix#frustumM Matrix.frustumM()} method:

@Override
public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);

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

This code populates a projection matrix, {@code mProjMatrix} which you can then combine with a camera view transformation in the {@link android.opengl.GLSurfaceView.Renderer#onDrawFrame onDrawFrame()} method, which is shown in the next section.

Note: Just applying a projection transformation to your drawing objects typically results in a very empty display. In general, you must also apply a camera view transformation in order for anything to show up on screen.

Define a Camera View

Complete the process of transforming your drawn objects by adding a camera view transformation as part of the drawing process. In the following example code, the camera view transformation is calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()} method and then combined with the previously calculated projection matrix. The combined transformation matrices are then passed to the drawn shape.

@Override
public void onDrawFrame(GL10 unused) {
    ...

    // Set the camera position (View matrix)
    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

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

    // Draw shape
    mTriangle.draw(mMVPMatrix);
}

Apply Projection and Camera Transformations

In order to use the combined projection and camera view transformation matrix shown in the previews sections, modify the {@code draw()} method of your graphic objects to accept the combined transformation matrix and apply it to the shape:

public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
    ...

    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
    ...
}

Once you have correctly calulated and applied the projection and camera view transformations, your graphic objects are drawn in correct proportions and should look like this:

Figure 1. Triangle drawn with a projection and camera view applied.

Now that you have an application that displays your shapes in correct proportions, it's time to add motion to your shapes.