美文网首页OpenGLOpenGL ES图形处理Android OpenGL ES 应用开发
Android OpenGL ES 3.基础图形、多边形的绘制

Android OpenGL ES 3.基础图形、多边形的绘制

作者: Benhero | 来源:发表于2018-09-14 16:12 被阅读12次

    基础图形绘制

    之前讲解过,OpenGL ES中,只提供了3种基本图形:点、线、三角形。而其他我们熟知的图形,都是基于这3种基本图形处理拼接合成的。那么本章节我们先从OpenGL中给我们提供的3种基础图形讲起,再介绍下其他图形的绘制。

    基础图形绘制API

    /**
     * 使用顶点数据绘制图形
     */
     GLES20.glDrawArrays(int mode, int first, int count);
    

    基本上,很多场景下我们都使用这个方法来进行图形的绘制,这个方法通过调用GLES20.glVertexAttribPointer传递进去的顶点数据来绘制目标图形。相关参数作用如下

    • mode:绘制模式,控制绘制点、线段、三角形以及其具体的连接方式
    • first:从顶点数据读取数据的起点位置(以点作为单位,而非向量)
    • count:绘制的顶点数(以点作为单位,而非向量)

    废话说明:以点作为单位,而非向量,也就是说无论顶点数组是用x、y两个向量来标识,或者是用x、y、z、w来标识,最终都是以一个点的距离来控制绘制。主要原因是这里是传递给GL层的,而GL层的坐标是vec4的,和我们从java层传进去的无关,毕竟没传递的是有默认值的。

    当前我们有个案例,按顺序有A、B、C、D、E、F一共6个点。
    而mode的具体参数值如下:

    参数 类型 作用 案例图形
    GL_POINTS 绘制独立的点 A、B、C、D、E、F
    GL_LINES 线段 每2个点构成一条线段 AB、CD、EF
    GL_LINE_LOOP 线段 按顺序将所有的点连接起来,包括首位相连 AB、BC、CD、DE、EF、FA
    GL_LINE_STRIP 线段 按顺序将所有的点连接起来,不包括首位相连 AB、BC、CD、ED、EF
    GL_TRIANGLES 三角形 每3个点构成一个三角形 ABC、DEF
    GL_TRIANGLE_STRIP 三角形 相邻3个点构成一个三角形,不包括首位两个点 ABC、BCD、CDE、DEF
    GL_TRIANGLE_FAN 三角形 第一个点和之后所有相邻的2个点构成一个三角形 ABC、ACD、ADE、AEF

    案例图示

    GL_POINTS
    GL_LINES
    GL_LINES
    GL_LINE_LOOP
    GL_LINE_LOOP.gif
    GL_LINE_STRIP
    GL_LINE_STRIP.gif
    GL_TRIANGLES
    GL_TRIANGLES.gif
    GL_TRIANGLE_STRIP
    GL_TRIANGLE_STRIP.gif
    GL_TRIANGLE_FAN
    GL_TRIANGLE_FAN.gif

    多边形绘制

    实心的多边形我们可以通过三角形拼接而成来实现,非实心的则可以通过线段拼接实现。具体效果如下图,黄色部分为实心多边形,红线为非实心多边形。当边数足够多的时候,多边形便接近于圆形。


    polygon

    关键代码实现如下:

    /**
     * 多边形的顶点数,即边数
     */
    private int mPolygonVertexCount = 3;
    /**
     * 绘制所需要的顶点数
     */
    private float[] mPointData;
    /**
     * 多边形顶点与中心点的距离
     */
    private static final float RADIUS = 0.5f;
    
    private void updateVertexData() {
        // 边数+中心点+闭合点;一个点包含x、y两个向量
        mPointData = new float[(mPolygonVertexCount + 2) * 2];
        // 组成多边形的每个三角形的中心点角的弧度
        float radian = (float) (2 * Math.PI / mPolygonVertexCount);
        // 中心点
        mPointData[0] = 0f;
        mPointData[1] = 0f;
        // 多边形的顶点数据
        for (int i = 0; i < mPolygonVertexCount; i++) {
            mPointData[2 * i + 2] = (float) (RADIUS * Math.cos(radian * i));
            mPointData[2 * i + 1 + 2] = (float) (RADIUS * Math.sin(radian * i));
        }
        // 闭合点:与多边形的第一个顶点重叠
        mPointData[mPolygonVertexCount * 2 + 2] = (float) (RADIUS * Math.cos(0));
        mPointData[mPolygonVertexCount * 2 + 3] = (float) (RADIUS * Math.sin(0));
    
        mVertexData = ByteBufferUtil.createFloatBuffer(mPointData);
        mVertexData.position(0);
        GLES20.glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GLES20.GL_FLOAT,
                false, 0, mVertexData);
    }
    
    private void drawShape() {
        GLES20.glUniform4f(uColorLocation, 1.0f, 1.0f, 0.0f, 1.0f);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, mPolygonVertexCount + 2);
    }    
    

    思考与推论

    上面的示例图中,在onDrawFrame里,同时绘制了点、线、三角形,也就是多次调用glDrawArrays,并且绘制出来了。
    我们暂时定义glDrawArrays是进行一次图元组装,也就是绘制一个图层,那么一次onDrawFrame只绘制一帧,而这一帧可以绘制多种图元,多个图层。
    也就是:一次只绘制一帧,但是一帧可以绘制多个图层。

    参考

    Android OpenGL ES学习资料所列举的博客、资料。

    GitHub代码工程

    本系列课程所有相关代码请参考我的GitHub项目GLStudio

    课程目录

    本系列课程目录详见 简书 - Android OpenGL ES教程规划

    相关文章

      网友评论

        本文标题:Android OpenGL ES 3.基础图形、多边形的绘制

        本文链接:https://www.haomeiwen.com/subject/cibogftx.html