Demo展示:
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主页上https://github.com/slpslpslp,我渲染类写了有几个,有渲染立方体、渲染线、渲染圆环和球,详细的Android使用opengles教程可以参照https://blog.csdn.net/column/details/apidemoopengl.html)
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);
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) {
}
百度语音合成接口Api(http://ai.baidu.com/docs#/TTS-Android-SDK/top),下载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中并没有实际的路网。另外这是一年半以前的代码了,代码写的也比较稚嫩,且现在已忘记很多。所以其中的细节我也没法在这里讲解了,有兴趣的可以下载下来进行扩展改进。