利用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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
表示我来过!
[***.240.166.169]2024年03月23日 15时02分16秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
c语言 无错 但只运行一半,求哈夫曼编码时程序运行到一半就终止了,编译无错...
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
es审计日志_elasticsearch 事务日志translog
2019-04-21
dw1510_超低温种子储存柜
2019-04-21
docker 查看容器磁盘大小_查看 docker 容器使用的资源
2019-04-21
python consul服务发现_Prometheus+Consul服务自动发现监控
2019-04-21
excel提取不规则字段_利用excel服务器来实现3级或者更多级的层级关联
2019-04-21