学习OpenGL ES for Android(三)

上篇我们看到绘制点和线,在平面上,点和线组成了面,我们先看绘制三角形。

glDrawArrays的mode参数除了点和线,还有三角,是这三个:GL_TRIANGLE,GL_TRIANGLE_STRIP和GL_TRIANGLE_FAN。他们的绘制规则如下图所示,

GL_TRIANGLE:每三个顶点绘制为三角形,如果不足三个则不绘制,绘制的三角形个数是:顶点数/3
GL_TRIANGLE_STRIP:相邻的三个顶点就绘制为三角形,绘制的三角形个数为:顶点数-2
GL_TRIANGLE_FAN:绘制扇形,第一个顶点和其他两个相邻的顶点绘制三角形,绘制的三角形个数为:顶点数-2

绘制三角形的代码如下,

    @Override
    public void onDrawFrame(GL10 gl) {
        super.onDrawFrame(gl);
        ....//省略了前面的代码
        // 设置颜色
        GLES20.glUniform4fv(colorHandle, 1, color, 0);
        // 画三角:每间隔三个顶点结合为一个三角
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
        // 画三角:每相邻的三个顶点为一个三角
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 3, 6);
        // 画三角扇形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_FAN, 9, 6);
        GLES20.glDisableVertexAttribArray(positionHandle);
    }

源码地址:https://github.com/jklwan/OpenGLProject/blob/master/sample/src/main/java/com/chends/opengl/view/window/TriangleView.java

绘制矩形

和桌面不同的是,OpenGL ES没有绘制多边形的功能,绘制多边形可以使用三角形组合而成。

这里提一下glDrawElements( int mode, int count, int type, java.nio.Buffer indices),参数mode和glDrawArrays的相同;参数count是索引数组的总数;type是索引的数量;indices是索引集合;用glDrawElements绘制一个矩形可以定义四个顶点,然后定义索引数组{0,1,2,0,2,3}表示012和123分别绘制三角形而组合成矩形。下面看下两种绘制矩形的方式的代码

public class SquareRenderer extends BaseRenderer {

    private final float[] TriangleCoords = {
            -0.7f, 0.5f, 0.0f,
            -0.2f, 0.5f, 0.0f,
            -0.7f, -0.5f, 0.0f,
            -0.2f, -0.5f, 0.0f,

            0.2f, 0.5f, 0.0f,
            0.7f, 0.5f, 0.0f,
            0.2f, -0.5f, 0.0f,
            0.7f, -0.5f, 0.0f,
    };

    private short[] drawOrder = {
            4, 5, 6, // 第一个三角形
            5, 6, 7 // 第二个三角形
    };

    @Override
    public void onDrawFrame(GL10 gl) {
        super.onDrawFrame(gl);
        ....//省略部分代码
        // 设置颜色
        GLES20.glUniform4fv(colorHandle, 1, color, 0);
        // 绘制矩形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
        ShortBuffer drawListBuffer = OpenGLUtil.createShortBuffer(drawOrder);
        // 绘制矩形
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
        GLES20.glDisableVertexAttribArray(positionHandle);
    }
}

效果图如下

改变三角形的颜色

改变顶点的颜色,需要修改顶点着色器代码,设置颜色参数以便传入,片段着色器中使用传入的颜色进行绘制,代码分别如下

        vertexShaderCode =
                "attribute vec3 aPosition;" +
                        "attribute vec3 aColor;" + // 颜色变量的属性位置值为 1
                        "varying vec3 ourColor;" +
                        "void main() {" +
                        "  gl_Position = vec4(aPosition, 1.0);" +
                        "   ourColor = aColor;" +  // 将ourColor设置为我们从顶点数据那里得到的输入颜色
                        "}";
        fragmentShaderCode =
                "precision mediump float;" +
                        "varying vec3 ourColor;" +
                        "void main() {" +
                        "  gl_FragColor = vec4(ourColor, 1.0);" +
                        "}"; // 动态改变颜色

我们同样使用glGetAttribLocation获取aColor变量的索引,然后传入我们的颜色值。绘制的代码如下

    @Override
    public void onDrawFrame(GL10 gl) {
        super.onDrawFrame(gl);
        int shaderProgram = OpenGLUtil.createProgram(vertexShaderCode, fragmentShaderCode);
        GLES20.glUseProgram(shaderProgram);
        int positionHandle = GLES20.glGetAttribLocation(shaderProgram, "aPosition");
        int colorHandle = GLES20.glGetAttribLocation(shaderProgram, "aColor");
        FloatBuffer vertexBuffer = OpenGLUtil.createFloatBuffer(vertices);
        GLES20.glEnableVertexAttribArray(positionHandle);
        vertexBuffer.position(0);
        // 传入顶点坐标
        GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT,
                false, (3 + 3) * 4, vertexBuffer);

        vertexBuffer.position(3);
        GLES20.glEnableVertexAttribArray(colorHandle);
        // 传入颜色
        GLES20.glVertexAttribPointer(colorHandle, 3, GLES20.GL_FLOAT,
                false, (3 + 3) * 4, vertexBuffer);
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertices.length / (3 + 3));

        GLES20.glDisableVertexAttribArray(positionHandle);
        GLES20.glDisableVertexAttribArray(colorHandle);
    }

源码地址https://github.com/jklwan/OpenGLProject/blob/master/sample/src/main/java/com/chends/opengl/view/window/TriangleColorView.java

此篇文章我们学习了矩形的绘制和顶点颜色的变化,下一篇我们将要学习图形的变换。

发布了53 篇原创文章 · 获赞 17 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/jklwan/article/details/103474326