学习OpenGL ES for Android(三)

£神魔★判官ぃ 2023-06-20 10:59 228阅读 0赞

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

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

20191210135911870.png

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

绘制三角形的代码如下,

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

源码地址: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分别绘制三角形而组合成矩形。下面看下两种绘制矩形的方式的代码

  1. public class SquareRenderer extends BaseRenderer {
  2. private final float[] TriangleCoords = {
  3. -0.7f, 0.5f, 0.0f,
  4. -0.2f, 0.5f, 0.0f,
  5. -0.7f, -0.5f, 0.0f,
  6. -0.2f, -0.5f, 0.0f,
  7. 0.2f, 0.5f, 0.0f,
  8. 0.7f, 0.5f, 0.0f,
  9. 0.2f, -0.5f, 0.0f,
  10. 0.7f, -0.5f, 0.0f,
  11. };
  12. private short[] drawOrder = {
  13. 4, 5, 6, // 第一个三角形
  14. 5, 6, 7 // 第二个三角形
  15. };
  16. @Override
  17. public void onDrawFrame(GL10 gl) {
  18. super.onDrawFrame(gl);
  19. ....//省略部分代码
  20. // 设置颜色
  21. GLES20.glUniform4fv(colorHandle, 1, color, 0);
  22. // 绘制矩形
  23. GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
  24. ShortBuffer drawListBuffer = OpenGLUtil.createShortBuffer(drawOrder);
  25. // 绘制矩形
  26. GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
  27. GLES20.glDisableVertexAttribArray(positionHandle);
  28. }
  29. }

效果图如下

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2prbHdhbg_size_16_color_FFFFFF_t_70

改变三角形的颜色

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

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

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

  1. @Override
  2. public void onDrawFrame(GL10 gl) {
  3. super.onDrawFrame(gl);
  4. int shaderProgram = OpenGLUtil.createProgram(vertexShaderCode, fragmentShaderCode);
  5. GLES20.glUseProgram(shaderProgram);
  6. int positionHandle = GLES20.glGetAttribLocation(shaderProgram, "aPosition");
  7. int colorHandle = GLES20.glGetAttribLocation(shaderProgram, "aColor");
  8. FloatBuffer vertexBuffer = OpenGLUtil.createFloatBuffer(vertices);
  9. GLES20.glEnableVertexAttribArray(positionHandle);
  10. vertexBuffer.position(0);
  11. // 传入顶点坐标
  12. GLES20.glVertexAttribPointer(positionHandle, 3, GLES20.GL_FLOAT,
  13. false, (3 + 3) * 4, vertexBuffer);
  14. vertexBuffer.position(3);
  15. GLES20.glEnableVertexAttribArray(colorHandle);
  16. // 传入颜色
  17. GLES20.glVertexAttribPointer(colorHandle, 3, GLES20.GL_FLOAT,
  18. false, (3 + 3) * 4, vertexBuffer);
  19. GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertices.length / (3 + 3));
  20. GLES20.glDisableVertexAttribArray(positionHandle);
  21. GLES20.glDisableVertexAttribArray(colorHandle);
  22. }

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

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

发表评论

表情:
评论列表 (有 0 条评论,228人围观)

还没有评论,来说两句吧...

相关阅读

    相关 学习OpenGL ES for Android(七)

    上篇我们简单的学习了纹理的显示,这篇我们先把图片等比显示,然后使纹理和颜色叠加显示。 如果图片是正方形,直接使用缩放或投影即可,但是如果非正方形则需要计算图片的宽高比,然后和