1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.apis.graphics; 18 19 import javax.microedition.khronos.egl.EGL10; 20 import javax.microedition.khronos.egl.EGLConfig; 21 import javax.microedition.khronos.opengles.GL10; 22 23 import android.app.Activity; 24 import android.content.Context; 25 import android.opengl.GLSurfaceView; 26 import android.os.Bundle; 27 import android.view.MotionEvent; 28 29 /** 30 * Wrapper activity demonstrating the use of {@link GLSurfaceView}, a view 31 * that uses OpenGL drawing into a dedicated surface. 32 * 33 * Shows: 34 * + How to redraw in response to user input. 35 */ 36 public class TouchRotateActivity extends Activity { 37 @Override onCreate(Bundle savedInstanceState)38 protected void onCreate(Bundle savedInstanceState) { 39 super.onCreate(savedInstanceState); 40 41 // Create our Preview view and set it as the content of our 42 // Activity 43 mGLSurfaceView = new TouchSurfaceView(this); 44 setContentView(mGLSurfaceView); 45 mGLSurfaceView.requestFocus(); 46 mGLSurfaceView.setFocusableInTouchMode(true); 47 } 48 49 @Override onResume()50 protected void onResume() { 51 // Ideally a game should implement onResume() and onPause() 52 // to take appropriate action when the activity looses focus 53 super.onResume(); 54 mGLSurfaceView.onResume(); 55 } 56 57 @Override onPause()58 protected void onPause() { 59 // Ideally a game should implement onResume() and onPause() 60 // to take appropriate action when the activity looses focus 61 super.onPause(); 62 mGLSurfaceView.onPause(); 63 } 64 65 private GLSurfaceView mGLSurfaceView; 66 } 67 68 /** 69 * Implement a simple rotation control. 70 * 71 */ 72 class TouchSurfaceView extends GLSurfaceView { 73 TouchSurfaceView(Context context)74 public TouchSurfaceView(Context context) { 75 super(context); 76 mRenderer = new CubeRenderer(); 77 setRenderer(mRenderer); 78 setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 79 } 80 onTrackballEvent(MotionEvent e)81 @Override public boolean onTrackballEvent(MotionEvent e) { 82 mRenderer.mAngleX += e.getX() * TRACKBALL_SCALE_FACTOR; 83 mRenderer.mAngleY += e.getY() * TRACKBALL_SCALE_FACTOR; 84 requestRender(); 85 return true; 86 } 87 onTouchEvent(MotionEvent e)88 @Override public boolean onTouchEvent(MotionEvent e) { 89 float x = e.getX(); 90 float y = e.getY(); 91 switch (e.getAction()) { 92 case MotionEvent.ACTION_MOVE: 93 float dx = x - mPreviousX; 94 float dy = y - mPreviousY; 95 mRenderer.mAngleX += dx * TOUCH_SCALE_FACTOR; 96 mRenderer.mAngleY += dy * TOUCH_SCALE_FACTOR; 97 requestRender(); 98 } 99 mPreviousX = x; 100 mPreviousY = y; 101 return true; 102 } 103 104 /** 105 * Render a cube. 106 */ 107 private class CubeRenderer implements GLSurfaceView.Renderer { CubeRenderer()108 public CubeRenderer() { 109 mCube = new Cube(); 110 } 111 onDrawFrame(GL10 gl)112 public void onDrawFrame(GL10 gl) { 113 /* 114 * Usually, the first thing one might want to do is to clear 115 * the screen. The most efficient way of doing this is to use 116 * glClear(). 117 */ 118 119 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 120 121 /* 122 * Now we're ready to draw some 3D objects 123 */ 124 125 gl.glMatrixMode(GL10.GL_MODELVIEW); 126 gl.glLoadIdentity(); 127 gl.glTranslatef(0, 0, -3.0f); 128 gl.glRotatef(mAngleX, 0, 1, 0); 129 gl.glRotatef(mAngleY, 1, 0, 0); 130 131 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 132 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); 133 134 mCube.draw(gl); 135 } 136 onSurfaceChanged(GL10 gl, int width, int height)137 public void onSurfaceChanged(GL10 gl, int width, int height) { 138 gl.glViewport(0, 0, width, height); 139 140 /* 141 * Set our projection matrix. This doesn't have to be done 142 * each time we draw, but usually a new projection needs to 143 * be set when the viewport is resized. 144 */ 145 146 float ratio = (float) width / height; 147 gl.glMatrixMode(GL10.GL_PROJECTION); 148 gl.glLoadIdentity(); 149 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); 150 } 151 onSurfaceCreated(GL10 gl, EGLConfig config)152 public void onSurfaceCreated(GL10 gl, EGLConfig config) { 153 /* 154 * By default, OpenGL enables features that improve quality 155 * but reduce performance. One might want to tweak that 156 * especially on software renderer. 157 */ 158 gl.glDisable(GL10.GL_DITHER); 159 160 /* 161 * Some one-time OpenGL initialization can be made here 162 * probably based on features of this particular context 163 */ 164 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, 165 GL10.GL_FASTEST); 166 167 168 gl.glClearColor(1,1,1,1); 169 gl.glEnable(GL10.GL_CULL_FACE); 170 gl.glShadeModel(GL10.GL_SMOOTH); 171 gl.glEnable(GL10.GL_DEPTH_TEST); 172 } 173 private Cube mCube; 174 public float mAngleX; 175 public float mAngleY; 176 } 177 178 private final float TOUCH_SCALE_FACTOR = 180.0f / 320; 179 private final float TRACKBALL_SCALE_FACTOR = 36.0f; 180 private CubeRenderer mRenderer; 181 private float mPreviousX; 182 private float mPreviousY; 183 } 184 185 186