ApiDemos学习知识点之os-RotationVector(14)

时间:2022-01-18 09:26:26

public class RotationVectorDemo extends Activity {
private GLSurfaceView mGLSurfaceView;
private SensorManager mSensorManager;
private MyRenderer mRenderer;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);


//获取SensorManager的实例
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);


// 创建我们的预览视图并将其设置为我们的内容活动页面
mRenderer = new MyRenderer();
mGLSurfaceView = new GLSurfaceView(this);
mGLSurfaceView.setRenderer(mRenderer);
setContentView(mGLSurfaceView);
}


@Override
protected void onResume() {
// 理想情况下,游戏应该实现onResume()和onPause()在活动发生时采取适当的行动
super.onResume();
mRenderer.start();
mGLSurfaceView.onResume();
}


@Override
protected void onPause() {
// Ideally a game should implement onResume() and onPause()
// to take appropriate action when the activity looses focus
super.onPause();
mRenderer.stop();
mGLSurfaceView.onPause();
}




class MyRenderer implements GLSurfaceView.Renderer, SensorEventListener {
private Cube mCube;
private Sensor mRotationVectorSensor;
private final float[] mRotationMatrix = new float[16];


public MyRenderer() {
//找到旋转矢量传感器
mRotationVectorSensor = mSensorManager.getDefaultSensor(
Sensor.TYPE_ROTATION_VECTOR);


mCube = new Cube();
// 将旋转矩阵初始化为恒等式
mRotationMatrix[ 0] = 1;
mRotationMatrix[ 4] = 1;
mRotationMatrix[ 8] = 1;
mRotationMatrix[12] = 1;
}


public void start() {
// 激活我们的传感器当活动恢复时,请求10 ms更新。

mSensorManager.registerListener(this, mRotationVectorSensor, 10000);
}


public void stop() {
// 当活动暂停时,请确保将传感器关闭
mSensorManager.unregisterListener(this);
}


public void onSensorChanged(SensorEvent event) {
// /我们收到了一个传感器事件。检查我们是否收到了适当的活动是一个很好的做法
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
// 将旋转矢量转换为4x4矩阵。这个矩阵被打开的GL解释为旋转矢量的倒数,这就是我们想要的。
SensorManager.getRotationMatrixFromVector(
mRotationMatrix , event.values);
}
}


public void onDrawFrame(GL10 gl) {
// 清除屏幕
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);


// 设置modelview矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
gl.glMultMatrixf(mRotationMatrix, 0);


// 画出我们的目标
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);


mCube.draw(gl);
}


public void onSurfaceChanged(GL10 gl, int width, int height) {
// 设置视图端口
gl.glViewport(0, 0, width, height);
//设置投影矩阵
float ratio = (float) width / height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}


public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// dither是默认启用的,我们不需要它
gl.glDisable(GL10.GL_DITHER);
// 清除屏幕
gl.glClearColor(1,1,1,1);
}


class Cube {
// 初始化我们多维数据集
private FloatBuffer mVertexBuffer;
private FloatBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;


public Cube() {
final float vertices[] = {
-1, -1, -1, 1, -1, -1,
1, 1, -1, -1, 1, -1,
-1, -1, 1, 1, -1, 1,
1, 1, 1, -1, 1, 1,
};


final float colors[] = {
0, 0, 0, 1, 1, 0, 0, 1,
1, 1, 0, 1, 0, 1, 0, 1,
0, 0, 1, 1, 1, 0, 1, 1,
1, 1, 1, 1, 0, 1, 1, 1,
};


final byte indices[] = {
0, 4, 5, 0, 5, 1,
1, 5, 6, 1, 6, 2,
2, 6, 7, 2, 7, 3,
3, 7, 4, 3, 4, 0,
4, 7, 6, 4, 6, 5,
3, 0, 1, 3, 1, 2
};


ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asFloatBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);


ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer = cbb.asFloatBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);


mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
mIndexBuffer.put(indices);
mIndexBuffer.position(0);
}


public void draw(GL10 gl) {
gl.glEnable(GL10.GL_CULL_FACE);
gl.glFrontFace(GL10.GL_CW);
gl.glShadeModel(GL10.GL_SMOOTH);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
}
}


public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}

GLSurfaceView是一个视图,继承至SurfaceView,它内嵌的surface专门负责OpenGL渲染。

        GLSurfaceView提供了下列特性:                 1> 管理一个surface,这个surface就是一块特殊的内存,能直接排版到android的视图view上。                 2> 管理一个EGL display,它能让opengl把内容渲染到上述的surface上。                 3> 用户自定义渲染器(render)。                 4> 让渲染器在独立的线程里运作,和UI线程分离。                 5> 支持按需渲染(on-demand)和连续渲染(continuous)。                 6> 一些可选工具,如调试。          使用GLSurfaceView         通常会继承GLSurfaceView,并重载一些和用户输入事件有关的方法。如果你不需要重载事件方法,GLSurfaceView也可以直接使用, 你可以使用set方法来为该类提供自定义的行为。例如,GLSurfaceView的渲染被委托给渲染器在独立的渲染线程里进行,这一点和普通视图不一 样,setRenderer(Renderer)设置渲染器。          初始化GLSurfaceView         初始化过程其实仅需要你使用setRenderer(Renderer)设置一个渲染器(render)。当然,你也可以修改GLSurfaceView一些默认配置。             * setDebugFlags(int)             * setEGLConfigChooser(boolean)             * setEGLConfigChooser(EGLConfigChooser)             * setEGLConfigChooser(int, int, int, int, int, int)             * setGLWrapper(GLWrapper) 

SensorManager 传感器

一般流程:

Sensor编程的一般步骤

1.取得SensorManager

SensorManager sm (SensorManager)getSystemService(SENSOR_SERVICE);

2.实现接口SensorEventListener

public void onAccuracyChanged(Sensor sensor, int accuracy) {}

public void onSensorChanged(SnesorEvent event) {}

3.取得某种Sensor对象

List<Sensor> sensors sm.getSensorList(Sensor.TYPE_TEMPERATURE);

4.注册SensorListener

sm.regesterListener(SensorEventListener listener, Sensor sensor, int rate);

其中第三个参数是延迟时间的精密度。

表格 2感应检测Sensor的延迟时间

参数

延迟时间

SensorManager.SENSOR_DELAY_FASTEST

0ms

SensorManager.SENSOR_DELAY_GAME

20ms

SensorManager.SENSOR_DELAY_UI

60ms

SensorManager.SENSOR_DELAY_NORMAL

200ms

5.取消注册SensorManager

sm.unregisterListener(SensorEventListener listener);


Cube对象。

 

需要用到两张图片:第一张是立方体顶点顺序和位置图,第二张是三角面示例图。

ApiDemos学习知识点之os-RotationVector(14)

 

 

ApiDemos学习知识点之os-RotationVector(14)

 

 

[java] view plain copy
  1. package com.example.android.apis.graphics;  
  2. import java.nio.ByteBuffer;  
  3. import java.nio.ByteOrder;  
  4. import java.nio.IntBuffer;  
  5. import javax.microedition.khronos.opengles.GL10;  
  6. /** 
  7.  * A vertex shaded cube. 
  8.  */  
  9. class Cube  
  10. {  
  11.     public Cube()  
  12.     {  
  13.         int one = 0x10000;  
  14.           
  15.         //每一个顶点都是由x/y/z三个坐标表示的。对于一个立方体,有八个顶点。  
  16.         //每个顶点的位置是先下到上,在每一层是由里到外逆时针方向标识  
  17.         int vertices[] = {  
  18.                 -one, -one, -one,  
  19.                 one, -one, -one,  
  20.                 one,  one, -one,  
  21.                 -one,  one, -one,  
  22.                 -one, -one,  one,  
  23.                 one, -one,  one,  
  24.                 one,  one,  one,  
  25.                 -one,  one,  one,  
  26.         };  
  27.         //每个顶点的颜色由四个数字表示:RED/GREEN/BLUE/ALPHA,最后一个透明度是可选的  
  28.         int colors[] = {  
  29.                 0,    0,    0,  one,  
  30.                 one,    0,    0,  one,  
  31.                 one,  one,    0,  one,  
  32.                 0,  one,    0,  one,  
  33.                 0,    0,  one,  one,  
  34.                 one,    0,  one,  one,  
  35.                 one,  one,  one,  one,  
  36.                 0,  one,  one,  one,  
  37.         };  
  38.         //这里有点复杂,每个数字对应于正方体中的每个特定的点。比如0代表立方体原点,就是立方体下面一层中最后面的那个点。  
  39.         //那么0,4,5对应的就是立方体侧面上的一个三角,每个面都有两个三角组成。  
  40.         //这样,整个立方体有六个面,就有12个三角面了。  
  41.         //注意:点的排列顺序对于显示效果有很大的影响。比如:0,4,5和0,5,4就不一样。  
  42.         //之所以会这样的原因是因为,调用了gl.glFrontFace(gl.GL_CW).  
  43.         //这样我们需要以顺时针的顺序来指定可视的三角面。  
  44.         byte indices[] = {  
  45.                 045,    051,  
  46.                 156,    162,  
  47.                 267,    273,  
  48.                 374,    340,  
  49.                 476,    465,  
  50.                 301,    312  
  51.         };  
  52.         //这里使用ByteBuffer来做缓冲处理。必须通过ByteBuffer.allocateDirect()方法来实例化ByteBuffer对象  
  53.         //这些buffer必须放到本地堆栈中,以使垃圾回收器不能移除它们  
  54.         //这些缓冲将作为参数传入到gl*Pointer()方法中  
  55.         //对于不同原数据类型的Buffers需要将byte设置成对应的顺序  
  56.         //int类型的是每个点式四个字节。  
  57.         ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);  
  58.         vbb.order(ByteOrder.nativeOrder());  
  59.         mVertexBuffer = vbb.asIntBuffer();  
  60.         mVertexBuffer.put(vertices);  
  61.         mVertexBuffer.position(0);  
  62.         ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);  
  63.         cbb.order(ByteOrder.nativeOrder());  
  64.         mColorBuffer = cbb.asIntBuffer();  
  65.         mColorBuffer.put(colors);  
  66.         mColorBuffer.position(0);  
  67.         mIndexBuffer = ByteBuffer.allocateDirect(indices.length);  
  68.         mIndexBuffer.put(indices);  
  69.         mIndexBuffer.position(0);  
  70.     }  
  71.     //让Cube来绘制自己,传入GL10g  
  72.     //GL10里包含很多绘制3D图刑的接口  
  73.     public void draw(GL10 gl)  
  74.     {  
  75.         gl.glFrontFace(gl.GL_CW);  
  76.         gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);  
  77.         gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);  
  78.         gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);  
  79.     }  
  80.     private IntBuffer   mVertexBuffer;  
  81.     private IntBuffer   mColorBuffer;  
  82.     private ByteBuffer  mIndexBuffer;  
  83. }