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
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}.
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(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}
This code populates a projection matrix, {@code mProjectionMatrix} 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.
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(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
// Draw shape
mTriangle.draw(mMVPMatrix);
}
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");
// Pass the projection and view transformation to the shader
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
...
}
Once you have correctly calculated 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.