1 /* 2 * Copyright (C) 2007 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.os; 18 19 import java.nio.ByteBuffer; 20 import java.nio.ByteOrder; 21 import java.nio.FloatBuffer; 22 import javax.microedition.khronos.egl.EGLConfig; 23 import javax.microedition.khronos.opengles.GL10; 24 import android.app.Activity; 25 import android.hardware.Sensor; 26 import android.hardware.SensorEvent; 27 import android.hardware.SensorEventListener; 28 import android.hardware.SensorManager; 29 import android.opengl.GLSurfaceView; 30 import android.os.Bundle; 31 32 /** 33 * Wrapper activity demonstrating the use of the new 34 * {@link SensorEvent#values rotation vector sensor} 35 * ({@link Sensor#TYPE_ROTATION_VECTOR TYPE_ROTATION_VECTOR}). 36 * 37 * @see Sensor 38 * @see SensorEvent 39 * @see SensorManager 40 * 41 */ 42 public class RotationVectorDemo extends Activity { 43 private GLSurfaceView mGLSurfaceView; 44 private SensorManager mSensorManager; 45 private MyRenderer mRenderer; 46 47 @Override onCreate(Bundle savedInstanceState)48 protected void onCreate(Bundle savedInstanceState) { 49 super.onCreate(savedInstanceState); 50 51 // Get an instance of the SensorManager 52 mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE); 53 54 // Create our Preview view and set it as the content of our 55 // Activity 56 mRenderer = new MyRenderer(); 57 mGLSurfaceView = new GLSurfaceView(this); 58 mGLSurfaceView.setRenderer(mRenderer); 59 setContentView(mGLSurfaceView); 60 } 61 62 @Override onResume()63 protected void onResume() { 64 // Ideally a game should implement onResume() and onPause() 65 // to take appropriate action when the activity looses focus 66 super.onResume(); 67 mRenderer.start(); 68 mGLSurfaceView.onResume(); 69 } 70 71 @Override onPause()72 protected void onPause() { 73 // Ideally a game should implement onResume() and onPause() 74 // to take appropriate action when the activity looses focus 75 super.onPause(); 76 mRenderer.stop(); 77 mGLSurfaceView.onPause(); 78 } 79 80 81 class MyRenderer implements GLSurfaceView.Renderer, SensorEventListener { 82 private Cube mCube; 83 private Sensor mRotationVectorSensor; 84 private final float[] mRotationMatrix = new float[16]; 85 MyRenderer()86 public MyRenderer() { 87 // find the rotation-vector sensor 88 mRotationVectorSensor = mSensorManager.getDefaultSensor( 89 Sensor.TYPE_ROTATION_VECTOR); 90 91 mCube = new Cube(); 92 // initialize the rotation matrix to identity 93 mRotationMatrix[ 0] = 1; 94 mRotationMatrix[ 4] = 1; 95 mRotationMatrix[ 8] = 1; 96 mRotationMatrix[12] = 1; 97 } 98 start()99 public void start() { 100 // enable our sensor when the activity is resumed, ask for 101 // 10 ms updates. 102 mSensorManager.registerListener(this, mRotationVectorSensor, 10000); 103 } 104 stop()105 public void stop() { 106 // make sure to turn our sensor off when the activity is paused 107 mSensorManager.unregisterListener(this); 108 } 109 onSensorChanged(SensorEvent event)110 public void onSensorChanged(SensorEvent event) { 111 // we received a sensor event. it is a good practice to check 112 // that we received the proper event 113 if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { 114 // convert the rotation-vector to a 4x4 matrix. the matrix 115 // is interpreted by Open GL as the inverse of the 116 // rotation-vector, which is what we want. 117 SensorManager.getRotationMatrixFromVector( 118 mRotationMatrix , event.values); 119 } 120 } 121 onDrawFrame(GL10 gl)122 public void onDrawFrame(GL10 gl) { 123 // clear screen 124 gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 125 126 // set-up modelview matrix 127 gl.glMatrixMode(GL10.GL_MODELVIEW); 128 gl.glLoadIdentity(); 129 gl.glTranslatef(0, 0, -3.0f); 130 gl.glMultMatrixf(mRotationMatrix, 0); 131 132 // draw our object 133 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 134 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); 135 136 mCube.draw(gl); 137 } 138 onSurfaceChanged(GL10 gl, int width, int height)139 public void onSurfaceChanged(GL10 gl, int width, int height) { 140 // set view-port 141 gl.glViewport(0, 0, width, height); 142 // set projection matrix 143 float ratio = (float) width / height; 144 gl.glMatrixMode(GL10.GL_PROJECTION); 145 gl.glLoadIdentity(); 146 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); 147 } 148 onSurfaceCreated(GL10 gl, EGLConfig config)149 public void onSurfaceCreated(GL10 gl, EGLConfig config) { 150 // dither is enabled by default, we don't need it 151 gl.glDisable(GL10.GL_DITHER); 152 // clear screen in white 153 gl.glClearColor(1,1,1,1); 154 } 155 156 class Cube { 157 // initialize our cube 158 private FloatBuffer mVertexBuffer; 159 private FloatBuffer mColorBuffer; 160 private ByteBuffer mIndexBuffer; 161 Cube()162 public Cube() { 163 final float vertices[] = { 164 -1, -1, -1, 1, -1, -1, 165 1, 1, -1, -1, 1, -1, 166 -1, -1, 1, 1, -1, 1, 167 1, 1, 1, -1, 1, 1, 168 }; 169 170 final float colors[] = { 171 0, 0, 0, 1, 1, 0, 0, 1, 172 1, 1, 0, 1, 0, 1, 0, 1, 173 0, 0, 1, 1, 1, 0, 1, 1, 174 1, 1, 1, 1, 0, 1, 1, 1, 175 }; 176 177 final byte indices[] = { 178 0, 4, 5, 0, 5, 1, 179 1, 5, 6, 1, 6, 2, 180 2, 6, 7, 2, 7, 3, 181 3, 7, 4, 3, 4, 0, 182 4, 7, 6, 4, 6, 5, 183 3, 0, 1, 3, 1, 2 184 }; 185 186 ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); 187 vbb.order(ByteOrder.nativeOrder()); 188 mVertexBuffer = vbb.asFloatBuffer(); 189 mVertexBuffer.put(vertices); 190 mVertexBuffer.position(0); 191 192 ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4); 193 cbb.order(ByteOrder.nativeOrder()); 194 mColorBuffer = cbb.asFloatBuffer(); 195 mColorBuffer.put(colors); 196 mColorBuffer.position(0); 197 198 mIndexBuffer = ByteBuffer.allocateDirect(indices.length); 199 mIndexBuffer.put(indices); 200 mIndexBuffer.position(0); 201 } 202 draw(GL10 gl)203 public void draw(GL10 gl) { 204 gl.glEnable(GL10.GL_CULL_FACE); 205 gl.glFrontFace(GL10.GL_CW); 206 gl.glShadeModel(GL10.GL_SMOOTH); 207 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer); 208 gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer); 209 gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer); 210 } 211 } 212 onAccuracyChanged(Sensor sensor, int accuracy)213 public void onAccuracyChanged(Sensor sensor, int accuracy) { 214 } 215 } 216 } 217