iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >轻松实现Android3D效果通俗易懂
  • 423
分享到

轻松实现Android3D效果通俗易懂

2024-04-02 19:04:59 423人浏览 独家记忆
摘要

目录一、先看看聊天(需求)二、实现效果三、实现1.通过getSystemService获得SensORManager实例对象2.通过SensorManager实例对象获得想要的传感器

文章最后将会贴出源码(照顾新手附加注释)

一、先看看聊天(需求)

请添加图片描述

二、实现效果

请添加图片描述

三、实现

前五步传感器内容。

1.通过getSystemService获得SensorManager实例对象


mSensorManager = (SensorManager)context.getSystemService(SENSOR_SERVICE);

2.通过SensorManager实例对象获得想要的传感器对象:参数决定获取哪个传感器


 mRotationVectorSensor = mSensorManager.getDefaultSensor(
                Sensor.TYPE_ROTATION_VECTOR);

3.在获得焦点时注册传感器并让本类实现SensorEventListener接口


 mSensorManager.reGISterListener(this, mRotationVectorSensor, 10000);
  • 第一个参数:SensorEventListener接口的实例对象
  • 第二个参数:需要注册的传感器实例
  • 第三个参数:传感器获取传感器事件event值频率:

SensorManager.SENSOR_DELAY_FASTEST = 0:对应0微秒的更新间隔,最快,1微秒 = 1 % 1000000秒
SensorManager.SENSOR_DELAY_GAME = 1:对应20000微秒的更新间隔,游戏中常用
SensorManager.SENSOR_DELAY_UI = 2:对应60000微秒的更新间隔
SensorManager.SENSOR_DELAY_NORMAL = 3:对应200000微秒的更新间隔
键入自定义的int值x时:对应x微秒的更新间隔

4.必须重写的两个方法

onAccuracyChanged和onSensorChanged

onSensorChanged: 传感器事件值改变时的回调接口:执行此方法的频率与注册传感器时的频率有关.

onAccuracyChanged:传感器精度发生改变的回调接口

5.在失去焦点时注销传感器(为Activity提供调用)


    public void stop() {
        mSensorManager.unregisterListener(this);
    }

6.draw方法中的方发详解

本案例(opengl坐标系中采用的是3维坐标)

  • glEnable:启用服务器端GL功能。
  • glFrontFace:定义多边形的正面和背面。多边形正面的方向。GL_CW和GL_CCW被允许,初始值为GL_CCW。
  • glShadeModel:选择恒定或光滑着色模式。GL图元可以采用恒定或者光滑着色模式,默认值为光滑着色模式。当图元进行光栅化的时候,将引起插入顶点颜色计算,不同颜色将被均匀分布到各个像素片段。允许的值有GL_FLAT 和GL_SMOOTH,初始值为GL_SMOOTH。
  • glVertexPointer:定义一个顶点坐标矩阵。(后续源码中会贴上各个参数以及需要注意的地方)。
  • glColorPointer:定义一个颜色矩阵。size指明每个颜色的元素数量,必须为4。type指明每个颜色元素的数据类型,stride指明从一个颜色到下一个允许的顶点的字节增幅,并且属性值被挤入简单矩阵或存储在单独的矩阵中(简单矩阵存储可能在一些版本中更有效率)。
  • glDrawElements:由矩阵数据渲染图元

更多建议参考Android官方文档。

四、需求中的青黄色参数


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

五、源码

TdRenderer.java


public class TdRenderer implements GLSurfaceView.Renderer, SensorEventListener {
    //传感器
    private SensorManager mSensorManager;
    private Sensor mRotationVectorSensor;
    private Cube mCube;

    private final float[] mRotationMatrix = new float[16];

    public TdRenderer(Context context) {
        //第一步:通过getSystemService获得SensorManager实例对象
        mSensorManager = (SensorManager)context.getSystemService(SENSOR_SERVICE);
        //第二步:通过SensorManager实例对象获得想要的传感器对象:参数决定获取哪个传感器
        mRotationVectorSensor = mSensorManager.getDefaultSensor(
                Sensor.TYPE_ROTATION_VECTOR);

        mCube = new Cube();
        mRotationMatrix[ 0] = 1;
        mRotationMatrix[ 4] = 1;
        mRotationMatrix[ 8] = 1;
        mRotationMatrix[12] = 1;
    }
   // 第三步:在获得焦点时注册传感器并让本类实现SensorEventListener接口
    public void start() {
        
        mSensorManager.registerListener(this, mRotationVectorSensor, 10000);
    }
    //第四步:必须重写的两个方法:onAccuracyChanged,onSensorChanged
    //第五步:在失去焦点时注销传感器(为Activity提供调用)
    public void stop() {
        mSensorManager.unregisterListener(this);
    }
    //传感器事件值改变时的回调接口:执行此方法的频率与注册传感器时的频率有关
    public void onSensorChanged(SensorEvent event) {
        // 大部分传感器会返回三个轴方向x,y,x的event值
        //float x = event.values[0];
        //float y = event.values[1];
        //float z = event.values[2];
        if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
            SensorManager.getRotationMatrixFromVector(
                    mRotationMatrix , event.values);
        }
    }

    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        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) {
        gl.glDisable(GL10.GL_DITHER);
        //指定颜色缓冲区的清理值
        gl.glClearColor(1,1,1,1);
    }

    public class Cube {
        //opengl坐标系中采用的是3维坐标:
        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,  1,  1,  1,  1,  1,  1,  1,
                      1,  1,  0,  1,  1,  1,  1,  1,
                      1,  1,  1,  1,  0,  1,  1,  1,
                      1,  1,  1,  1,  1,  1,  0,  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功能。
            gl.glEnable(GL10.GL_CULL_FACE);
            //定义多边形的正面和背面。
            //参数:
            //mode——多边形正面的方向。GL_CW和GL_CCW被允许,初始值为GL_CCW。
            gl.glFrontFace(GL10.GL_CW);
            //选择恒定或光滑着色模式。
            //GL图元可以采用恒定或者光滑着色模式,默认值为光滑着色模式。当图元进行光栅化的时候,将引起插入顶点颜色计算,不同颜色将被均匀分布到各个像素片段。
            //参数:
            //mode——指明一个符号常量来代表要使用的着色技术。允许的值有GL_FLAT 和GL_SMOOTH,初始值为GL_SMOOTH。
            gl.glShadeModel(GL10.GL_SMOOTH);
            //定义一个顶点坐标矩阵。
            //参数:
            //
            //size——每个顶点的坐标维数,必须是2, 3或者4,初始值是4。
            //
            //type——指明每个顶点坐标的数据类型,允许的符号常量有GL_BYTE, GL_SHORT, GL_FIXED和GL_FLOAT,初始值为GL_FLOAT。
            //
            //stride——指明连续顶点间的位偏移,如果为0,顶点被认为是紧密压入矩阵,初始值为0。
            //
            //pointer——指明顶点坐标的缓冲区,如果为null,则没有设置缓冲区。
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
            //定义一个颜色矩阵。
            //size指明每个颜色的元素数量,必须为4。type指明每个颜色元素的数据类型,stride指明从一个颜色到下一个允许的顶点的字节增幅,并且属性值被挤入简单矩阵或存储在单独的矩阵中(简单矩阵存储可能在一些版本中更有效率)。
            gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
            //由矩阵数据渲染图元
            //可以事先指明独立的顶点、法线、颜色和纹理坐标矩阵并且可以通过调用glDrawElements方法来使用它们创建序列图元。
            gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
        }
    }
    //传感器精度发生改变的回调接口
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        //在传感器精度发生改变时做些操作,accuracy为当前传感器精度
    }
}

ThreeDimensionsRotation,java(Activity记得注册)


public class ThreeDimensionsRotation extends Activity {
    private GLSurfaceView mGLSurfaceView;
    private TdRenderer tdRenderer;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tdRenderer=new TdRenderer(this);
        // 创建预览视图,并将其设置为Activity的内容
        mGLSurfaceView = new GLSurfaceView(this);
        mGLSurfaceView.setRenderer(tdRenderer);
        setContentView(mGLSurfaceView);
    }

    @Override
    protected void onResume() {
        super.onResume();
        tdRenderer.start();
        mGLSurfaceView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        tdRenderer.stop();
        mGLSurfaceView.onPause();
    }

}

到此这篇关于轻松实现Android3D效果通俗易懂的文章就介绍到这了,更多相关Android 3D效果内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 轻松实现Android3D效果通俗易懂

本文链接: https://www.lsjlt.com/news/133145.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 轻松实现Android3D效果通俗易懂
    目录一、先看看聊天(需求)二、实现效果三、实现1.通过getSystemService获得SensorManager实例对象2.通过SensorManager实例对象获得想要的传感器...
    99+
    2024-04-02
  • OAuth2.0详细介绍与实践(通俗易懂)
    一、OAuth2.0介绍 1.1 概述 OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码)...
    99+
    2023-09-16
    java
  • vue轻松实现水印效果
    前言: vue项目中使用水印效果,可指定容器 效果图: 1、不指定容器 2、指定容器 实现方法: 1、新建一个配置文件 watermark.js ,可放util,也可放别的地方 ...
    99+
    2024-04-02
  • Python切片与索引初学者指南:用通俗易懂的语言轻松理解复杂概念
    # % & > ! | ""/ | | | |\ ``` | ^`| | | |] |\...
    99+
    2024-02-08
    切片与索引
  • c语言指针用法及实际应用详解,通俗易懂超详细
    C语言的指针是一种非常重要的概念,它可以实现很多高级的编程技巧。本文将详细介绍C语言指针的用法及实际应用,并尽可能用通俗易懂的语言进...
    99+
    2023-09-09
    C语言
  • vue2实现简易时钟效果
    本文实例为大家分享了vue2实现简易时钟效果的具体代码,供大家参考,具体内容如下 1.vue2+纯css实现 预览效果: 2.代码如下: <template>     ...
    99+
    2024-04-02
  • iOS实现简易的抽屉效果
    本文实例为大家分享了iOS实现简易的抽屉效果的具体代码,供大家参考,具体内容如下 1.添加需要实现抽屉效果的三个视图,这里需要注意主视图需要放在最后添加 // 左边视图  ... /...
    99+
    2022-11-13
    iOS 抽屉
  • Vue实现简易跑马灯效果
    本文实例为大家分享了Vue实现跑马灯效果的具体代码,供大家参考,具体内容如下 一个简单的跑马灯效果,就是如下这种效果 Vue跑马灯效果: 1.分析 a.点击"加油&quo...
    99+
    2024-04-02
  • Windows10 双网卡配置,轻松实现内外互通
      1 背景         我平常需要连接外网查阅资料,聊天等,做实验时需要将写到的代码打包部署到内网服务器中,所以需要频繁地切换内外网,修改静态网络配置。很是苦恼。         2 方法         最近,我找到了几种解决办法。...
    99+
    2023-09-13
    网络 服务器 运维
  • Java多线程Future松获取异步任务结果轻松实现
    目录前言Runnable的局限性练手小Demo -- 回顾既往文章知识复习:优化为使用Runnable为异步而生的Future类图FutureTask详解构造函数生命周期核心方法如何...
    99+
    2023-05-15
    Java Future异步任务结果获取 Java Future多线程
  • JavaScript怎么实现网易云轮播效果
    这篇文章主要介绍“JavaScript怎么实现网易云轮播效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript怎么实现网易云轮播效果”文章能帮助大家解决问题。div宽度直接与浏览器界...
    99+
    2023-06-29
  • 基于three.js实现简易照片墙效果
    学习three.js的过程中,写的一个简易照片墙,可以使用鼠标滚轮上下浏览,采用的是移动相机的方式。 代码贴出来,供学习这一块的朋友们参考和指导:  <!DOCTYPE HTM...
    99+
    2024-04-02
  • Vue如何实现简易跑马灯效果
    本文小编为大家详细介绍“Vue如何实现简易跑马灯效果”,内容详细,步骤清晰,细节处理妥当,希望这篇“Vue如何实现简易跑马灯效果”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。Vue跑马灯效果:1.分析a.点击&q...
    99+
    2023-06-30
  • JavaScript模拟实现网易云轮播效果
    1、div宽度直接与浏览器界面宽度一致:width:100% 2、怎么让图片在一个绝对定位的盒子中垂直居中显示? 继续加绝对定位。然后改变top,和left的值 3、采用外置的js文...
    99+
    2024-04-02
  • 使用ViewPager2实现简易轮播图效果
    本文实例为大家分享了使用ViewPager2实现轮播图效果的具体代码,供大家参考,具体内容如下 0.实现效果 1.添加依赖 dependencies {     ...     i...
    99+
    2024-04-02
  • HTML5 画布标签的绘制技巧大揭秘:轻松实现图形效果
    一、画布标签基本绘制 基本图形绘制 画布标签提供了多种基本图形绘制方法,包括矩形、圆形、线条、弧线、多边形等。通过设置这些图形的属性,如位置、大小、颜色、填充色等,可以实现简单的图形绘制。 演示代码: <canvas id="...
    99+
    2024-02-25
    HTML5 画布标签 绘制技巧 图形效果
  • 解密 JavaScript 跨域问题:轻松实现跨域通信
    跨域问题成因 跨域问题是指浏览器出于安全考虑,限制了不同域之间的脚本访问。当一个脚本试图访问另一个域上的资源时,就会触发跨域问题。跨域问题通常表现为以下几种情况: AJAX 请求被阻止 WebSocket 连接无法建立 脚本无法访...
    99+
    2024-02-23
    跨域 CORS JSONP WebSocket postMessage
  • HTML无序列表实战演练:手把手教你,轻松实现各种列表效果
    无序列表是 HTML 中用于创建列表元素的元素,它是一种无序列表,列表项之间没有严格的顺序。无序列表可以用于创建各种不同的内容,如购物清单、任务清单,或是一些段落。在本文中,我们将通过一些生动有趣的范例,向您展示如何使用 HTML 创建无...
    99+
    2024-02-14
    HTML 无序列表 / HTML 代码 / 演示范例 / 网页设计 / 网页内容优化
  • Java ActiveMQ:轻松实现分布式系统的异步通信
    ActiveMQ是Apache出品的一款开源消息中间件,它使用Java语言开发,具有可靠的消息传递、异步通信和集群支持等特点。ActiveMQ能够在不同的应用之间进行数据交换,并且支持多种消息协议,如JMS、AMQP和MQTT等。 1....
    99+
    2024-02-08
    ActiveMQ Java 分布式系统 异步通信
  • Flutter通过Container实现时间轴效果
    目录时间轴是前端UI经常用到的效果,先看下效果图:实现 一、借助 Container 中 decoration 属性,设置左侧的 border,可以实现时间轴高度随着 item 变化...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作