浏览器版本低!无法浏览完整内容,建议升级或更换浏览器。
OpenGL绘制(绘制3D模型)

百度地图SDK为开发者开放了OpenGL绘制接口,以帮助开发者在地图上实现灵活的样式绘制,丰富地图的显示效果和使用体验。

自V4.2.0起,百度地图SDK支持OpenGLES 2.0,请开发者调用OnMapDrawFrameCallback接口的onMapDrawFrame(MapStatus drawingMapStatus)方法来进行绘制,在地图渲染每一帧的过程中,以及每次需要重绘地图时(如添加覆盖物),该接口都会被调用。

自V4.2.0起,旧版的onMapDrawFrame(GL10 gl, MapStatus drawingMapStatus)方法废弃。

绘制3D立方体

下面代码以在地图上绘制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
};

// 立方体顶点坐标Buffer
private FloatBuffer mVertextBuffer;
// 顶点绘制顺序Buffer
private ShortBuffer mIndexBuffer;
// 立方体顶点颜色Buffer
private 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);

    // 立方体顶点绘制顺序Buffer
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(mDrawIndices.length * 4);
    byteBuffer.order(ByteOrder.nativeOrder());
    mIndexBuffer = byteBuffer.asShortBuffer();
    mIndexBuffer.put(mDrawIndices);
    mIndexBuffer.position(0);

    // 立方体顶点颜色Buffer
    ByteBuffer 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() {
    //废弃
    @Override
    public void onMapDrawFrame(GL10 gl, MapStatus drawingMapStatus) {
        
    }
    @Override
    public 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);
}

效果如图:

opengl.png

  • 文档根本没法用

  • 文档水平很差

  • 文档水平一般

  • 文档不错

  • 文档写的很好

如发现文档错误,或对此文档有更好的建议,请在下方反馈。问题咨询请前往反馈平台提交工单咨询。

提交反馈

拖动标注工具

添加矩形标注

添加箭头标注

完成

取消