summaryrefslogtreecommitdiffstats
path: root/docs/html/training/graphics/opengl/touch.jd
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/training/graphics/opengl/touch.jd')
-rw-r--r--docs/html/training/graphics/opengl/touch.jd145
1 files changed, 145 insertions, 0 deletions
diff --git a/docs/html/training/graphics/opengl/touch.jd b/docs/html/training/graphics/opengl/touch.jd
new file mode 100644
index 0000000..c058a59
--- /dev/null
+++ b/docs/html/training/graphics/opengl/touch.jd
@@ -0,0 +1,145 @@
+page.title= Responding to Touch Events
+parent.title=Displaying Graphics with OpenGL ES
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Adding Motion
+previous.link=motion.html
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<h2>This lesson teaches you to</h2>
+<ol>
+ <li><a href="#listener">Setup a Touch Listener</a></li>
+ <li><a href="#angle">Expose the Rotation Angle</a></li>
+ <li><a href="#rotate">Apply Rotation</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="http://developer.android.com/shareables/training/OpenGLES.zip"
+class="button">Download the sample</a>
+ <p class="filename">OpenGLES.zip</p>
+</div>
+
+</div>
+</div>
+
+<p>Making objects move according to a preset program like the rotating triangle is useful for
+getting some attention, but what if you want to have users interact with your OpenGL ES graphics?
+The key to making your OpenGL ES application touch interactive is expanding your implementation of
+{@link android.opengl.GLSurfaceView} to override the {@link
+android.opengl.GLSurfaceView#onTouchEvent onTouchEvent()} to listen for touch events.</p>
+
+<p>This lesson shows you how to listen for touch events to let users rotate an OpenGL ES object.</p>
+
+
+<h2 id="listener">Setup a Touch Listener</h2>
+
+<p>In order to make your OpenGL ES application respond to touch events, you must implement the
+{@link android.opengl.GLSurfaceView#onTouchEvent onTouchEvent()} method in your
+{@link android.opengl.GLSurfaceView} class. The example implementation below shows how to listen for
+{@link android.view.MotionEvent#ACTION_MOVE MotionEvent.ACTION_MOVE} events and translate them to
+an angle of rotation for a shape.</p>
+
+<pre>
+&#64;Override
+public boolean onTouchEvent(MotionEvent e) {
+ // MotionEvent reports input details from the touch screen
+ // and other input controls. In this case, you are only
+ // interested in events where the touch position changed.
+
+ float x = e.getX();
+ float y = e.getY();
+
+ switch (e.getAction()) {
+ case MotionEvent.ACTION_MOVE:
+
+ float dx = x - mPreviousX;
+ float dy = y - mPreviousY;
+
+ // reverse direction of rotation above the mid-line
+ if (y &gt; getHeight() / 2) {
+ dx = dx * -1 ;
+ }
+
+ // reverse direction of rotation to left of the mid-line
+ if (x &lt; getWidth() / 2) {
+ dy = dy * -1 ;
+ }
+
+ mRenderer.mAngle += (dx + dy) * TOUCH_SCALE_FACTOR; // = 180.0f / 320
+ requestRender();
+ }
+
+ mPreviousX = x;
+ mPreviousY = y;
+ return true;
+}
+</pre>
+
+<p>Notice that after calculating the rotation angle, this method calls {@link
+android.opengl.GLSurfaceView#requestRender requestRender()} to tell the
+renderer that it is time to render the frame. This approach is the most efficient in this example
+because the frame does not need to be redrawn unless there is a change in the rotation. However, it
+does not have any impact on efficiency unless you also request that the renderer only redraw when
+the data changes using the {@link android.opengl.GLSurfaceView#setRenderMode setRenderMode()}
+method, so make sure this line is uncommented in the renderer:</p>
+
+<pre>
+public MyGLSurfaceView(Context context) {
+ ...
+ // Render the view only when there is a change in the drawing data
+ <strong>setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);</strong>
+}
+</pre>
+
+<h2 id="angle">Expose the Rotation Angle</h2>
+
+<p>The example code above requires that you expose the rotation angle through your renderer by
+adding a public member. Since the renderer code is running on a separate thread from the main user
+interface thread of your application, you must declare this public variable as {@code volatile}.
+Here is the code to do that:</p>
+
+<pre>
+public class MyGLRenderer implements GLSurfaceView.Renderer {
+ ...
+ public volatile float mAngle;
+</pre>
+
+
+<h2 id="rotate">Apply Rotation</h2>
+
+<p>To apply the rotation generated by touch input, comment out the code that generates an angle and
+add {@code mAngle}, which contains the touch input generated angle:</p>
+
+<pre>
+public void onDrawFrame(GL10 gl) {
+ ...
+ // Create a rotation for the triangle
+ // long time = SystemClock.uptimeMillis() % 4000L;
+ // float angle = 0.090f * ((int) time);
+ <strong>Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, -1.0f);</strong>
+
+ // Combine the rotation matrix with the projection and camera view
+ Matrix.multiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);
+
+ // Draw triangle
+ mTriangle.draw(mMVPMatrix);
+}
+</pre>
+
+<p>When you have completed the steps described above, run the program and drag your finger over the
+screen to rotate the triangle:</p>
+
+<img src="{@docRoot}images/opengl/ogl-triangle-touch.png">
+<p class="img-caption">
+<strong>Figure 1.</strong> Triangle being rotated with touch input (circle shows touch
+location).</p>