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


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

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值