OSDN Git Service

docs: Fix notification api guide issues (7461154, 12765600)
[android-x86/frameworks-base.git] / docs / html / training / graphics / opengl / projection.jd
1 page.title=Applying Projection and Camera Views
2 parent.title=Displaying Graphics with OpenGL ES
3 parent.link=index.html
4
5 trainingnavtop=true
6 previous.title=Drawing Shapes
7 previous.link=draw.html
8 next.title=Applying Projection and Camera Views
9 next.link=projection.html
10
11 @jd:body
12
13 <div id="tb-wrapper">
14 <div id="tb">
15
16 <h2>This lesson teaches you to</h2>
17 <ol>
18   <li><a href="#projection">Define a Projection</a></li>
19   <li><a href="#camera-view">Define a Camera View</a></li>
20   <li><a href="#transform">Apply Projection and Camera Transformations</a></li>
21 </ol>
22
23 <h2>You should also read</h2>
24 <ul>
25   <li><a href="{@docRoot}guide/topics/graphics/opengl.html">OpenGL</a></li>
26 </ul>
27
28 <div class="download-box">
29  <a href="{@docRoot}shareables/training/OpenGLES.zip"
30 class="button">Download the sample</a>
31  <p class="filename">OpenGLES.zip</p>
32 </div>
33
34 </div>
35 </div>
36
37 <p>In the OpenGL ES environment, projection and camera views allow you to display drawn objects in a
38 way that more closely resembles how you see physical objects with your eyes. This simulation of
39 physical viewing is done with mathematical transformations of drawn object coordinates:</p>
40
41 <ul>
42   <li><em>Projection</em> - This transformation adjusts the coordinates of drawn objects based on
43 the width and height of the {@link android.opengl.GLSurfaceView} where they are displayed. Without
44 this calculation, objects drawn by OpenGL ES are skewed by the unequal proportions of the view
45 window. A projection transformation typically only has to be calculated when the proportions of the
46 OpenGL view are established or changed in the {@link
47 android.opengl.GLSurfaceView.Renderer#onSurfaceChanged
48 onSurfaceChanged()} method of your renderer. For more information about OpenGL ES projections and
49 coordinate mapping, see <a
50 href="{@docRoot}guide/topics/graphics/opengl.html#coordinate-mapping">Mapping Coordinates for Drawn
51 Objects</a>.</li>
52   <li><em>Camera View</em> - This transformation adjusts the coordinates of drawn objects based on a
53 virtual camera position. It’s important to note that OpenGL ES does not define an actual camera
54 object, but instead provides utility methods that simulate a camera by transforming the display of
55 drawn objects. A camera view transformation might be calculated only once when you establish your
56 {@link android.opengl.GLSurfaceView}, or might change dynamically based on user actions or your
57 application’s function.</li>
58 </ul>
59
60 <p>This lesson describes how to create a projection and camera view and apply it to shapes drawn in
61 your {@link android.opengl.GLSurfaceView}.</p>
62
63
64 <h2 id="projection">Define a Projection</h2>
65
66 <p>The data for a projection transformation is calculated in the {@link
67 android.opengl.GLSurfaceView.Renderer#onSurfaceChanged onSurfaceChanged()}
68 method of your {@link android.opengl.GLSurfaceView.Renderer} class. The following example code
69 takes the height and width of the {@link android.opengl.GLSurfaceView} and uses it to populate a
70 projection transformation {@link android.opengl.Matrix} using the {@link
71 android.opengl.Matrix#frustumM Matrix.frustumM()} method:</p>
72
73 <pre>
74 &#64;Override
75 public void onSurfaceChanged(GL10 unused, int width, int height) {
76     GLES20.glViewport(0, 0, width, height);
77
78     float ratio = (float) width / height;
79
80     // this projection matrix is applied to object coordinates
81     // in the onDrawFrame() method
82     Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
83 }
84 </pre>
85
86 <p>This code populates a projection matrix, {@code mProjectionMatrix} which you can then combine
87 with a camera view transformation in the {@link android.opengl.GLSurfaceView.Renderer#onDrawFrame
88 onDrawFrame()} method, which is shown in the next section.</p>
89
90 <p class="note"><strong>Note:</strong> Just applying a projection transformation to your
91 drawing objects typically results in a very empty display. In general, you must also apply a camera
92 view transformation in order for anything to show up on screen.</p>
93
94
95 <h2 id="camera-view">Define a Camera View</h2>
96
97 <p>Complete the process of transforming your drawn objects by adding a camera view transformation as
98 part of the drawing process. In the following example code, the camera view transformation is
99 calculated using the {@link android.opengl.Matrix#setLookAtM Matrix.setLookAtM()} method and then
100 combined with the previously calculated projection matrix. The combined transformation matrices
101 are then passed to the drawn shape.</p>
102
103 <pre>
104 &#64;Override
105 public void onDrawFrame(GL10 unused) {
106     ...
107     // Set the camera position (View matrix)
108     Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
109
110     // Calculate the projection and view transformation
111     Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
112
113     // Draw shape
114     mTriangle.draw(mMVPMatrix);
115 }
116 </pre>
117
118
119 <h2 id="#transform">Apply Projection and Camera Transformations</h2>
120
121 <p>In order to use the combined projection and camera view transformation matrix shown in the
122 previews sections, modify the {@code draw()} method of your graphic objects to accept the combined
123 transformation matrix and apply it to the shape:</p>
124
125 <pre>
126 public void draw(float[] mvpMatrix) { // pass in the calculated transformation matrix
127     ...
128
129     // get handle to shape's transformation matrix
130     mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
131
132     // Pass the projection and view transformation to the shader
133     GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
134
135     // Draw the triangle
136     GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
137     ...
138 }
139 </pre>
140
141 <p>Once you have correctly calculated and applied the projection and camera view transformations,
142 your graphic objects are drawn in correct proportions and should look like this:</p>
143
144
145 <img src="{@docRoot}images/opengl/ogl-triangle-projected.png">
146 <p class="img-caption">
147 <strong>Figure 1.</strong> Triangle drawn with a projection and camera view applied.</p>
148
149
150 <p>Now that you have an application that displays your shapes in correct proportions, it's time to
151 add motion to your shapes.</p>