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.setAngle(
                    mRenderer.getAngle() +
                    ((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) {
    ...
    float[] scratch = new float[16];

    // 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
    // Note that the mMVPMatrix factor *must be first* in order
    // for the matrix multiplication product to be correct.
    Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);

    // Draw triangle
    mTriangle.draw(scratch);
}
</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>
