Android OpenGL ES 四.基础图形、多边形的绘制(转载补充)

基础图形绘制

之前讲解过,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

案例图示

image
GL_LINES
image
GL_LINE_LOOP
image
GL_LINE_STRIP
image
GL_TRIANGLES
image
GL_TRIANGLE_STRIP
image
GL_TRIANGLE_FAN
image

多边形绘制

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

33019-b88c09bdab9b877c[1].gif

关键代码实现如下:

/**
 * 多边形的顶点数,即边数
 */
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教程规划

作者:Benhero
链接:https://www.jianshu.com/p/eb11a8346cf6
来源:
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(Android OpenGL ES 四.基础图形、多边形的绘制(转载补充))