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主頁上https://github.com/slpslpslp,我渲染類寫了有幾個,有渲染立方體、渲染線、渲染圓環和球,詳細的Android使用opengles教程可以參照https://blog.csdn.net/column/details/apidemoopengl.html)
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(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中並沒有實際的路網。另外這是一年半以前的代碼了,代碼寫的也比較稚嫩,且現在已忘記很多。所以其中的細節我也沒法在這裏講解了,有興趣的可以下載下來進行擴展改進。