百度地图SDK为开发者开放了OpenGL绘制接口,以帮助开发者在地图上实现灵活的样式绘制,丰富地图的显示效果和使用体验。
自V4.2.0起,百度地图SDK支持OpenGLES 2.0,请开发者调用OnMapDrawFrameCallback接口的onMapDrawFrame(MapStatus drawingMapStatus)方法来进行绘制,在地图渲染每一帧的过程中,以及每次需要重绘地图时(如添加覆盖物),该接口都会被调用。
自V4.2.0起,旧版的onMapDrawFrame(GL10 gl, MapStatus drawingMapStatus)方法废弃。
下面代码以在地图上绘制3D立方体为例,介绍如何使用OpenGL绘制接口。
定义3D立方体着色器类
private class CubeShader {int mVertex;int mMvpMatrix;int mColor;int mProgram;public CubeShader() {}String vertexShader = "precision highp float;\n" +" attribute vec3 mVertex;//顶点数组,三维坐标\n" +" attribute vec4 mColor;//颜色数组,三维坐标\n" +" uniform mat4 mMvpMatrix;//mvp矩阵\n" +" varying vec4 color;//\n" +" void main(){\n" +" gl_Position = mMvpMatrix * vec4(mVertex, 1.0);\n" +" color = mColor;\n" +" }";String fragmentShader = "//有颜色 没有纹理\n" +" precision highp float;\n" +" varying vec4 color;//\n" +" void main(){\n" +" gl_FragColor = color;\n" +" }";public void init() {int vertexLocation = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);GLES20.glShaderSource(vertexLocation, vertexShader);GLES20.glCompileShader(vertexLocation);int fragmentLocation = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);GLES20.glShaderSource(fragmentLocation, fragmentShader);GLES20.glCompileShader(fragmentLocation);mProgram = GLES20.glCreateProgram();GLES20.glAttachShader(mProgram, vertexLocation);GLES20.glAttachShader(mProgram, fragmentLocation);GLES20.glLinkProgram(mProgram);mVertex = GLES20.glGetAttribLocation(mProgram, "mVertex");mMvpMatrix = GLES20.glGetUniformLocation(mProgram,"mMvpMatrix");mColor = GLES20.glGetAttribLocation(mProgram,"mColor");}}
准备立方体数据并初始化
1、声明所需数据及属性
// 3D立方体顶点绘制顺序列表private short[] mDrawIndices = {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};// 3D立方体8个顶点颜色值private float[] mVertexColors = {1f, 1f, 0f, 1f,0f, 1f, 1f, 1f,1f, 0f, 1f, 1f,0f, 0f, 0f, 1f,1f, 1f, 1f, 1f,1f, 0f, 0f, 1f,0f, 1f, 0f, 1f,0f, 0f, 1f, 1f};// 立方体顶点坐标Bufferprivate FloatBuffer mVertextBuffer;// 顶点绘制顺序Bufferprivate ShortBuffer mIndexBuffer;// 立方体顶点颜色Bufferprivate FloatBuffer mColorBuffer;// 3D立方体着色器private CubeShader mCubeShader;
2、初始化数据
private void initCubeModelData(float width, float height, float depth) {// 对标墨卡托坐标width = width * 10000 / 2;height = height * 10000 / 2;depth = depth * 10000 / 2;// 立方体8个顶点坐标float[] vertices = {-width, -height, -0,width, -height, -0,width, height, -0,-width, height, -0,-width, -height, depth,width, -height, depth,width, height, depth,-width, height, depth,};mVertextBuffer = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();mVertextBuffer.put(vertices).position(0);// 立方体顶点绘制顺序BufferByteBuffer byteBuffer = ByteBuffer.allocateDirect(mDrawIndices.length * 4);byteBuffer.order(ByteOrder.nativeOrder());mIndexBuffer = byteBuffer.asShortBuffer();mIndexBuffer.put(mDrawIndices);mIndexBuffer.position(0);// 立方体顶点颜色BufferByteBuffer byteBuffer1 = ByteBuffer.allocateDirect(mVertexColors.length * 4);byteBuffer1.order(ByteOrder.nativeOrder());mColorBuffer = byteBuffer1.asFloatBuffer();mColorBuffer.put(mVertexColors);mColorBuffer.position(0);}
调用OnMapDrawFrameCallback接口绘制
1、创建OnMapDrawFrameCallback实例
BaiduMap.OnMapDrawFrameCallback callback = new BaiduMap.OnMapDrawFrameCallback() {//废弃@Overridepublic void onMapDrawFrame(GL10 gl, MapStatus drawingMapStatus) {}@Overridepublic void onMapDrawFrame(MapStatus drawingMapStatus) {if (null == mBaiduMap.getProjection()) {return;}drawFrameFor3DCube(drawingMapStatus, 0.2f, 0.2f, 0.3f);}};
2、设置OnMapDrawFrameCallback接口
mBaiduMap.setOnMapDrawFrameCallback(callback);
3、绘制方法
/*** 绘制3D立方体* @param drawingMapStatus*/private void drawCube(MapStatus drawingMapStatus) {if (null == mCubeShader || null == drawingMapStatus) {return;}// Step1 初始化数据float[] mvpMatrix = new float[16];Matrix.setIdentityM(mvpMatrix, 0);// 获取投影矩阵float[] projectMatrix = mBaiduMap.getProjectionMatrix();// 获取视图矩阵float[] viewMatrix = mBaiduMap.getViewMatrix();Matrix.multiplyMM(mvpMatrix,0, projectMatrix,0, viewMatrix,0);// 绑定地图移动PointF p1f = mBaiduMap.getProjection().toOpenGLLocation(latlng1, drawingMapStatus);Matrix.translateM(mvpMatrix, 0 , p1f.x, p1f.y, 0);// 设置缩放比例int scale = 1;Matrix.scaleM(mvpMatrix, 0 , scale, scale, scale);// Step2 开始绘制设置GLES20.glUseProgram(mCubeShader.mProgram);GLES20.glEnable(GLES20.GL_DEPTH_TEST);// 顶点指针GLES20.glEnableVertexAttribArray(mCubeShader.mVertex);GLES20.glVertexAttribPointer(mCubeShader.mVertex, 3, GLES20.GL_FLOAT, false, 0, mVertextBuffer);// 颜色指针GLES20.glEnableVertexAttribArray(mCubeShader.mColor);GLES20.glVertexAttribPointer(mCubeShader.mColor, 4, GLES20.GL_FLOAT,false, 0, mColorBuffer);GLES20.glUniformMatrix4fv(mCubeShader.mMvpMatrix, 1, false, mvpMatrix, 0);// 开始画GLES20.glDrawElements(GLES20.GL_TRIANGLES, mDrawIndices.length, GLES20.GL_UNSIGNED_SHORT, mIndexBuffer);GLES20.glDisableVertexAttribArray(mCubeShader.mVertex);GLES20.glDisable(GLES20.GL_DEPTH_TEST);}
效果如图:
上一篇
下一篇
本篇文章对您是否有帮助?