diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java index e8da8deff..5af84f7af 100644 --- a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java +++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.java @@ -16,9 +16,6 @@ package com.example.android.apis.graphics; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.opengles.GL10; - import android.app.Activity; import android.content.Context; import android.opengl.GLSurfaceView; @@ -27,6 +24,9 @@ import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + /** * Wrapper activity demonstrating the use of {@link GLSurfaceView}, a view * that uses OpenGL drawing into a dedicated surface. @@ -35,6 +35,9 @@ import android.view.MotionEvent; * + How to redraw in response to user input. */ public class TouchRotateActivity extends Activity { + + private GLSurfaceView mGLSurfaceView; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -63,125 +66,147 @@ public class TouchRotateActivity extends Activity { mGLSurfaceView.onPause(); } - private GLSurfaceView mGLSurfaceView; -} - -/** - * Implement a simple rotation control. - * - */ -class TouchSurfaceView extends GLSurfaceView { - - public TouchSurfaceView(Context context) { - super(context); - mRenderer = new CubeRenderer(); - setRenderer(mRenderer); - setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); - } - - @Override public boolean onTrackballEvent(MotionEvent e) { - mRenderer.mAngleX += e.getX() * TRACKBALL_SCALE_FACTOR; - mRenderer.mAngleY += e.getY() * TRACKBALL_SCALE_FACTOR; - requestRender(); - return true; - } - - @Override public boolean onTouchEvent(MotionEvent e) { - if (e.getActionMasked() == MotionEvent.ACTION_MOVE) { - updateAngles(e); - } - mPreviousX = e.getX(); - mPreviousY = e.getY(); - return true; - } - - private void updateAngles(MotionEvent e) { - float dx = e.getX() - mPreviousX; - float dy = e.getY() - mPreviousY; - if (dx != 0 && dy != 0) { - mRenderer.mAngleX += dx * TOUCH_SCALE_FACTOR; - mRenderer.mAngleY += dy * TOUCH_SCALE_FACTOR; - requestRender(); - } - } - /** - * Render a cube. + * Implement a simple rotation control. + * */ - private class CubeRenderer implements GLSurfaceView.Renderer { - public CubeRenderer() { - mCube = new Cube(); + private static class TouchSurfaceView extends GLSurfaceView { + + private static final float TOUCH_SCALE_FACTOR = 180.0f / 320; + private static final float TRACKBALL_SCALE_FACTOR = 36.0f; + private CubeRenderer mRenderer; + private float mPreviousX; + private float mPreviousY; + + TouchSurfaceView(Context context) { + super(context); + mRenderer = new CubeRenderer(); + setRenderer(mRenderer); + setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); } - public void onDrawFrame(GL10 gl) { - /* - * Usually, the first thing one might want to do is to clear - * the screen. The most efficient way of doing this is to use - * glClear(). - */ - - gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); - - /* - * Now we're ready to draw some 3D objects - */ - - gl.glMatrixMode(GL10.GL_MODELVIEW); - gl.glLoadIdentity(); - gl.glTranslatef(0, 0, -3.0f); - gl.glRotatef(mAngleX, 0, 1, 0); - gl.glRotatef(mAngleY, 1, 0, 0); - - gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); - gl.glEnableClientState(GL10.GL_COLOR_ARRAY); - - mCube.draw(gl); + @Override + public boolean onTrackballEvent(MotionEvent e) { + updateAngles(e.getX(), e.getY(), TRACKBALL_SCALE_FACTOR); + return true; } - public void onSurfaceChanged(GL10 gl, int width, int height) { - gl.glViewport(0, 0, width, height); - - /* - * Set our projection matrix. This doesn't have to be done - * each time we draw, but usually a new projection needs to - * be set when the viewport is resized. - */ - - float ratio = (float) width / height; - gl.glMatrixMode(GL10.GL_PROJECTION); - gl.glLoadIdentity(); - gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); + @Override + public boolean onTouchEvent(MotionEvent e) { + final int action = e.getActionMasked(); + if (action == MotionEvent.ACTION_MOVE) { + updateAngles(e.getX() - mPreviousX, e.getY() - mPreviousY, TOUCH_SCALE_FACTOR); + } else if (action == MotionEvent.ACTION_DOWN) { + if (e.isFromSource(InputDevice.SOURCE_MOUSE)) { + requestPointerCapture(); + } else { + releasePointerCapture(); + } + } + mPreviousX = e.getX(); + mPreviousY = e.getY(); + return true; } - public void onSurfaceCreated(GL10 gl, EGLConfig config) { - /* - * By default, OpenGL enables features that improve quality - * but reduce performance. One might want to tweak that - * especially on software renderer. - */ - gl.glDisable(GL10.GL_DITHER); - - /* - * Some one-time OpenGL initialization can be made here - * probably based on features of this particular context - */ - gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, - GL10.GL_FASTEST); - - - gl.glClearColor(1,1,1,1); - gl.glEnable(GL10.GL_CULL_FACE); - gl.glShadeModel(GL10.GL_SMOOTH); - gl.glEnable(GL10.GL_DEPTH_TEST); + @Override + public boolean onCapturedPointerEvent(MotionEvent e) { + if (e.getActionMasked() == MotionEvent.ACTION_DOWN) { + releasePointerCapture(); + } else { + updateAngles(e.getX(), e.getY(), TOUCH_SCALE_FACTOR); + } + return true; + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + // Release pointer capture on any key press. + releasePointerCapture(); + return super.onKeyDown(keyCode, event); + } + + private void updateAngles(float dx, float dy, float scaleFactor) { + if (dx != 0 && dy != 0) { + mRenderer.mAngleX += dx * scaleFactor; + mRenderer.mAngleY += dy * scaleFactor; + requestRender(); + } + } + + /** + * Render a cube. + */ + private static class CubeRenderer implements GLSurfaceView.Renderer { + CubeRenderer() { + mCube = new Cube(); + } + + @Override + public void onDrawFrame(GL10 gl) { + /* + * Usually, the first thing one might want to do is to clear + * the screen. The most efficient way of doing this is to use + * glClear(). + */ + + gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); + + /* + * Now we're ready to draw some 3D objects + */ + + gl.glMatrixMode(GL10.GL_MODELVIEW); + gl.glLoadIdentity(); + gl.glTranslatef(0, 0, -3.0f); + gl.glRotatef(mAngleX, 0, 1, 0); + gl.glRotatef(mAngleY, 1, 0, 0); + + gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); + gl.glEnableClientState(GL10.GL_COLOR_ARRAY); + + mCube.draw(gl); + } + + @Override + public void onSurfaceChanged(GL10 gl, int width, int height) { + gl.glViewport(0, 0, width, height); + + /* + * Set our projection matrix. This doesn't have to be done + * each time we draw, but usually a new projection needs to + * be set when the viewport is resized. + */ + + float ratio = (float) width / height; + gl.glMatrixMode(GL10.GL_PROJECTION); + gl.glLoadIdentity(); + gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); + } + + @Override + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + /* + * By default, OpenGL enables features that improve quality + * but reduce performance. One might want to tweak that + * especially on software renderer. + */ + gl.glDisable(GL10.GL_DITHER); + + /* + * Some one-time OpenGL initialization can be made here + * probably based on features of this particular context + */ + gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, + GL10.GL_FASTEST); + + gl.glClearColor(1, 1, 1, 1); + gl.glEnable(GL10.GL_CULL_FACE); + gl.glShadeModel(GL10.GL_SMOOTH); + gl.glEnable(GL10.GL_DEPTH_TEST); + } + private Cube mCube; + float mAngleX; + float mAngleY; } - private Cube mCube; - public float mAngleX; - public float mAngleY; } - - private final float TOUCH_SCALE_FACTOR = 180.0f / 320; - private final float TRACKBALL_SCALE_FACTOR = 36.0f; - private CubeRenderer mRenderer; - private float mPreviousX; - private float mPreviousY; }