android / platform / frameworks / base / f2e3305 / . / docs / html / training / graphics / opengl / projection.jd

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 | |

<div id="tb-wrapper"> | |

<div id="tb"> | |

<h2>This lesson teaches you to</h2> | |

<ol> | |

<li><a href="#projection">Define a Projection</a></li> | |

<li><a href="#camera-view">Define a Camera View</a></li> | |

<li><a href="#transform">Apply Projection and Camera Transformations</a></li> | |

</ol> | |

<h2>You should also read</h2> | |

<ul> | |

<li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li> | |

</ul> | |

<div class="download-box"> | |

<a href="{@docRoot}shareables/training/OpenGLES.zip" | |

class="button">Download the sample</a> | |

<p class="filename">OpenGLES.zip</p> | |

</div> | |

</div> | |

</div> | |

<p>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:</p> | |

<ul> | |

<li><em>Projection</em> - This transformation adjusts the coordinates of drawn objects based on | |

the width and height of the {@link android.opengl.GLSurfaceView} where they are displayed. Without | |

this calculation, objects drawn by OpenGL ES are skewed by the unequal proportions of the view | |

window. A projection transformation typically only has to be calculated when the proportions of the | |

OpenGL view are established or changed in the {@link | |

android.opengl.GLSurfaceView.Renderer#onSurfaceChanged | |

onSurfaceChanged()} method of your renderer. For more information about OpenGL ES projections and | |

coordinate mapping, see <a | |

href="{@docRoot}guide/topics/graphics/opengl.html#coordinate-mapping">Mapping Coordinates for Drawn | |

Objects</a>.</li> | |

<li><em>Camera View</em> - This transformation adjusts the coordinates of drawn objects based on a | |

virtual camera position. It’s important to note that OpenGL ES does not define an actual camera | |

object, but instead provides utility methods that simulate a camera by transforming the display of | |

drawn objects. A camera view transformation might be calculated only once when you establish your | |

{@link android.opengl.GLSurfaceView}, or might change dynamically based on user actions or your | |

application’s function.</li> | |

</ul> | |

<p>This lesson describes how to create a projection and camera view and apply it to shapes drawn in | |

your {@link android.opengl.GLSurfaceView}.</p> | |

<h2 id="projection">Define a Projection</h2> | |

<p>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:</p> | |

<pre> | |

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

} | |

</pre> | |

<p>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.</p> | |

<p class="note"><strong>Note:</strong> 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.</p> | |

<h2 id="camera-view">Define a Camera View</h2> | |

<p>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.</p> | |

<pre> | |

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

} | |

</pre> | |

<h2 id="#transform">Apply Projection and Camera Transformations</h2> | |

<p>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:</p> | |

<pre> | |

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

... | |

} | |

</pre> | |

<p>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:</p> | |

<img src="{@docRoot}images/opengl/ogl-triangle-projected.png"> | |

<p class="img-caption"> | |

<strong>Figure 1.</strong> Triangle drawn with a projection and camera view applied.</p> | |

<p>Now that you have an application that displays your shapes in correct proportions, it's time to | |

add motion to your shapes.</p> |