利用OpenGL ES、手机传感器、相机和调用百度语音包服务,实现AR+语音播报导航功能(导航功能为模拟,Android)
发布日期:2022-02-01 16:54:12 浏览次数:39 分类:技术文章

本文共 6111 字,大约阅读时间需要 20 分钟。

Demo展示:

几个重要模块

GLSurfaceView:

1.首先需要自定义类实现GlsurfaceView.Renderer接口

public abstract class AbstractMyRender implements GLSurfaceView.Renderer {    public float ratio;//    围绕X轴旋转的角度    public float xrotate = 0f;//    围绕Y轴旋转的角度    public float yrotate = 0f;//    围绕Z轴旋转的角度    public float zrotate = 0f;    /*            这是第一步     */    @Override    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {//        清屏色        gl10.glClearColor(0f,0f,0f,1f);//        启用顶点缓冲区数组        gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);    }    /*            这是第二步     */    @Override    public void onSurfaceChanged(GL10 gl10, int i, int i1) {//设置视口        gl10.glViewport(0,0,i,i1);        ratio = (float)i/(float)i1;//      投影矩阵        gl10.glMatrixMode(GL10.GL_PROJECTION);//      加载单位矩阵        gl10.glLoadIdentity();//      设置平截头体        gl10.glFrustumf(-ratio,ratio,-1,1,3f,7f);    }    /*            这是第三步     */    public  abstract void onDrawFrame(GL10 gl10);}

2.定义子类继承自定义类并复写其中的方法(可以绘制不同的图案),例如绘制颜色立方体可以定义子类MyColorCubeRenderer

public class MyColorCubeRenderer extends AbstractMyRender {    @Override    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {//        清屏色        gl10.glColor4f(0,0,0,1f);//        启动顶点缓冲区数组        gl10.glEnableClientState(GL10.GL_VERTEX_ARRAY);//        颜色缓冲区        gl10.glEnableClientState(GL10.GL_COLOR_ARRAY);//        启用深度测试        gl10.glEnable(GL10.GL_DEPTH_TEST);    }    @Override    public void onSurfaceChanged(GL10 gl10, int i, int i1) {//        设置视口        gl10.glViewport(0,0,i,i1);        ratio = (float)i/(float)i1;//        投影矩阵        gl10.glMatrixMode(GL10.GL_PROJECTION);//        加载单位矩阵        gl10.glLoadIdentity();//        设置平截头体        gl10.glFrustumf(-ratio,ratio,-1f,1f,3f,7f);    }    @Override    public void onDrawFrame(GL10 gl10) {        gl10.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);        gl10.glColor4f(1f,0f,0f,1f);//        模型视图矩阵        gl10.glMatrixMode(GL10.GL_MODELVIEW);        gl10.glLoadIdentity();        GLU.gluLookAt(gl10,0,0,5,0,0,0,0,1,0);        gl10.glRotatef(xrotate,1,0,0);        gl10.glRotatef(yrotate,0,1,0);        gl10.glRotatef(zrotate,0,0,1);        float r = 0.4f;//        定义点坐标        float[] coords = {//                前面四个点坐标,分别是左上,左下,右上,右下                -r,r,r,                -r,-r,r,                r,r,r,                r,-r,r,//                后面四个点坐标                -r,r,-r,                -r,-r,-r,                r,r,-r,                r,-r,-r        };//        定义顶点索引位置        byte[] indices = {                0,1,2,2,1,3,//front                4,5,6,6,5,7,//back                0,1,4,4,1,5,//left                2,3,6,6,3,7,//right                4,0,2,4,2,6,//top                5,1,3,5,3,7//bottom        };//        定义颜色        float[] colors = {                0f,1f,1f,1f,//青色                0,1,0,1,                1,1,1,1,//白色                1,1,0,1,//黄色                0,0,1,1,//4                0,0,0,1,//5                1,0,1,1,//6                1,0,0,1//7        };        gl10.glColorPointer(4,GL10.GL_FLOAT,0, BufferUtil.arr2ByteBuffer(colors));        gl10.glVertexPointer(3,GL10.GL_FLOAT,0,BufferUtil.arr2ByteBuffer(coords));//        使用顶点索引方式绘制        gl10.glDrawElements(GL10.GL_TRIANGLES,indices.length, GL10.GL_UNSIGNED_BYTE,BufferUtil.arr2ByteBuffer(indices));//        使用顶点数组索引方式绘制//        gl10.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,coords.length/3);    }}

在本例中使用的MultiArrow类渲染的图案。(详细代码我会放置于我的github主页上,我渲染类写了有几个,有渲染立方体、渲染线、渲染圆环和球,详细的Android使用opengles教程可以参照)

Camera(相机已被Google弃用,可选择替代)

1.相机预览功能函数

private void startPreview() {        camera = Camera.open();        try {            camera.setPreviewDisplay(cameraPreview.getHolder());            camera.setDisplayOrientation(90);        } catch (IOException e) {            e.printStackTrace();        }    }

2.相机预览回调函数

private Camera camera;private SurfaceHolder.Callback cameraPreviewcallback = new SurfaceHolder.Callback() {        @Override        public void surfaceCreated(SurfaceHolder surfaceHolder) {            startPreview();            Log.i(TAG, "surfaceCreated" + Thread.currentThread().getName());        }        @Override        public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {            Log.i(TAG, "surfaceChanged");            camera.startPreview();        }        @Override        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {            Log.i(TAG, "surfaceDestoryed");            if (camera != null) {                camera.stopPreview();                camera.release();//释放相机资源                camera = null;            }        }    };

3.设置相机预览SurfaceView

cameraPreview = new SurfaceView(this);        cameraPreview.getHolder().addCallback(cameraPreviewcallback);        cameraPreview.getHolder().setFormat(PixelFormat.TRANSPARENT);

SensorManager

1.开启传感器服务

SensorManager sensorManager;sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

2.在方向传感器(TYPE_OPIENTATION,已被弃用,可以选择替代)变化的同时,请求渲染

@Override    public void onSensorChanged(SensorEvent sensorEvent) {        int sensorType = sensorEvent.sensor.getType();        switch (sensorType) {            case Sensor.TYPE_ORIENTATION://                获取绕三轴的角度                float degreeZ = sensorEvent.values[0];                float degreeX = sensorEvent.values[1];                float degreeY = sensorEvent.values[2];                render.xrotate = degreeX;                render.zrotate = degreeZ;//                render.yrotate = degreeY;                glSurfaceView.requestRender();    //请求渲染,和脏渲染配合使用                break;        }    }    @Override    public void onAccuracyChanged(Sensor sensor, int i) {    }

SpeechSynthesizerListener

百度语音合成接口Api(),下载Android SDK,申请获得APP_ID,API_KEY,SECRET_KEY,填入即可直接使用

private static final String APP_ID = "YOUR_APP_ID";    private static final String API_KEY = "YOUR API_KEY";    private static final String SECRET_KEY = "YOUR SECRET_KEY";

后记:

           这个demo是我当初为了做AR导航做的一个小项目,是自己模拟的一段导航路径,主要是实现打开摄像头将路径进行渲染,通过方向传感器,在手机摆动时而保持导航路径绝对方向不变,在本demo中并没有实际的路网。另外这是一年半以前的代码了,代码写的也比较稚嫩,且现在已忘记很多。所以其中的细节我也没法在这里讲解了,有兴趣的可以下载下来进行扩展改进。

转载地址:https://blog.csdn.net/slphahaha/article/details/81171023 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:据说 Go 面试官都是他的读者?
下一篇:选择合适的 Go 字符串拼接方式

发表评论

最新留言

表示我来过!
[***.240.166.169]2024年03月23日 15时02分16秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

s2-045 php exp,S2-045-EXP.py --Struts2任意代码执行漏洞 (S2-045,CVE-2017-5638) 2019-04-21
linux sdk 窗口句柄,Venus: 针对Linux平台上,对常用的系统API进行面向对象的封装SDK。... 2019-04-21
c语言程序设计 科学出版社习题答案,C语言程序设计(科学出版社)第4章 课后习题参考答案.doc... 2019-04-21
c语言 无错 但只运行一半,求哈夫曼编码时程序运行到一半就终止了,编译无错... 2019-04-21
deepin linux 2014安装,2014.2版本的Deepin虚拟机安装浅谈(就是深度Linux) 2019-04-21
android 限速工具,Android下载器之限速篇 2019-04-21
html刷新ajax实现原理,AJAX的原理—如何做到异步和局部刷新 2019-04-21
html中列表菜单加文字请选择,html中下拉菜单 2019-04-21
读书郎平板中android,读书郎学生平板电脑怎么用 使用方法详解【图文】 2019-04-21
html5 调用摄像头 支持IE,JS调用本地摄像头拍照(兼容各大浏览器及IE8+) 2019-04-21
rust和gta5哪个吃配置_盘点4款Steam“自由度”很高的游戏,GTA5众所周知,目前最热门... 2019-04-21
es审计日志_elasticsearch 事务日志translog 2019-04-21
dw1510_超低温种子储存柜 2019-04-21
python用opencv计算汽车间距_计算机视觉:利用OpenCV和Python进行车辆计数详细步调... 2019-04-21
文件未找到mathpage.wll_解决MathPage.wll文件找不到的问题(找了好久的良心之作)... 2019-04-21
docker 查看容器磁盘大小_查看 docker 容器使用的资源 2019-04-21
python consul服务发现_Prometheus+Consul服务自动发现监控 2019-04-21
excel提取不规则字段_利用excel服务器来实现3级或者更多级的层级关联 2019-04-21
@autowired注解的作用_只因多看了一眼提示,又一次刷新了@Autowired注释的认知 2019-04-21
ab753变频器参数怎么拷贝到面板_变频器不知道如何上手,厂家教你如何三点搞定设置变频器参数... 2019-04-21