OpenGL ES 系列

Android OpenGL ES 根底原理

动态色值

在说烘托形式之前,咱们来简略了解下动态色值的填充方法。

在OpenGL ES 根底原理中,咱们仅仅对极点做了简略的填充设置,现在咱们持续对片段着色器中的色彩做自界说。

Android OpenGL ES 渲染模式

这是现有的样式,色值在片段着色器中是一个写死的值,现在咱们需求将它变为动态设置的值,将这个两个三角形的色彩值设置为红、绿、蓝的混合色。也便是三角形的三个极点,分别设置红绿蓝,色彩再从极点向中心分散。

下面是实际操作

修正着色器源码

要动态设置色彩值,需求界说色彩变量

private const val VERTEX_SHADER_SOURCE =
    "attribute vec4 a_Position;\n" +
            "attribute vec4 a_Color;\n" +
            "varying vec4 v_Color;\n" +
            "void main() {\n" +
            "   v_Color = a_Color;\n" +
            "   gl_Position = a_Position;\n" +
            "}"
private const val FRAGMENT_SHADER_SOURCE =
    "precision mediump float;\n" +
            "varying vec4 v_Color;\n" +
            "void main() {\n" +
            "   gl_FragColor = v_Color;\n" +
            "}"

之前的a_Position不动,新增a_Color与v_Color变量,留意v_Color被varying声明,所以它能够传递到片段着色器中,最终再将它赋值给gl_FragColor

界说色彩数据源

private val mColorData = floatArrayOf(
    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 1.0f,
    1.0f, 0.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f, 1.0f
)
private const val COLOR_DIMENSION_SIZE = 4

分别为两个三角形的六个极点设置红绿蓝设置,色彩维度为4,不要忘了还有透明度。

加载色彩数据

这一点与极点数据的加载方法相同,关于GL程序来说他们仅仅不同的变量,而变量的数据填充方法都是共同的。了解这一点就简略多了,依照极点数据填充的方法来。

将色彩数据填充到Buffer中,并将索引方位移动到0方位。

// 加载色彩数据
val colorBuffer = ByteBuffer.allocateDirect(mColorData.size * Float.SIZE_BYTES)
    .order(ByteOrder.nativeOrder())
    .asFloatBuffer()
colorBuffer.put(mColorData)
colorBuffer.position(0)

持续获取a_Color在GL程序中的参数方位索引

// 获取对应color参数方位
val colorLocation = GLES20.glGetAttribLocation(programId, "a_Color")

随后激活

// 发动对应color参数方位
GLES20.glEnableVertexAttribArray(colorLocation)

最终填充

// 填充对应极点处color数据
GLES20.glVertexAttribPointer(colorLocation, COLOR_DIMENSION_SIZE, GLES20.GL_FLOAT, false, 0, colorBuffer)

再走一遍这些流程,了解起来信任简略了许多。

烘托部分就不多说了,这个没什么不同。

下面来看下运转的作用

Android OpenGL ES 渲染模式

达到预期,功德圆满。

烘托形式

// 烘托
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mVertexData.size / VERTEX_DIMENSION_SIZE)

GL_TRIANGLES是三角形烘托的一种方法,一共有三种。

GL_TRIANGLES

以每三个极点为三角形的方法进行烘托,极点不重复,即(v0,v1,v2)、(v3,v4,v5)等。

咱们目前用到的烘托方法都是这种,所以咱们界说6个极点,依照这种方法咱们就会制作出两个完全不穿插的三角形,由于它们的极点并没有交集。

GL_TRIANGLE_STRIP

选择制作三角形的极点不同,极点会重复使用,即(v0,v1,v2)、(v2,v1,v3)、(v2,v3,v4)、(v4,v3,v5)

简略的来看,便是它会复用之前的两个极点,但需求留意的是它的制作次序,并不是简略的直接依照直接的次序进行复用。

这里的次序逻辑是:

  1. 假如当时极点是偶数,则为(n-2,n-1,n)
  2. 假如当时极点是奇数,则为(n-1,n-2,n)

这种方法是为了保证制作的每个三角形的次序是共同的。

那么这种烘托形式的优点是什么呢?你会发现相同的极点数,通过这种方法制作出来的三角形个数比GL_TRIANGLES要多。

对应的咱们就能发现,假如制作相同的图形GL_TRIANGLE_STRIP所要加载的极点数会更少,这样在OpenGL制作的过程中占用的内存也就越低,所以也就更有用。

原理了解了,下面咱们将比如中的制作方法修正成GL_TRIANGLE_STRIP,看下作用是怎么样的。

Android OpenGL ES 渲染模式

GL_TRIANGLE_FAN

以扇形的方法进行,它会共用一个极点,环绕它进行扇形制作,(v0,v1,v2)、(v3,v0,v2)、(v4,v0,v3)、(v5,v0,v4)

这种方法很合适用来制作多边形,以任意一个极点为中心进行扇形制作。

咱们再将比如中的制作方法改成GL_TRIANGLE_FAN,看下作用怎么。

Android OpenGL ES 渲染模式

假如不太了解的可以自己动手画一画,原理并不难。

后面我会持续聊聊对纹路方面的了解,敬请期待。

源码地址:OpenGL ES

推荐

android_startup: 提供一种在应用发动时能够更加简略、高效的方法来初始化组件,优化发动速度。不只支撑Jetpack App Startup的悉数功用,还提供额外的同步与异步等候、线程操控与多进程支撑等功用。

AwesomeGithub: 根据Github的客户端,纯练习项目,支撑组件化开发,支撑账户密码与认证登陆。使用Kotlin言语进行开发,项目架构是根据JetPack&DataBinding的MVVM;项目中使用了Arouter、Retrofit、Coroutine、Glide、Dagger与Hilt等流行开源技能。

flutter_github: 根据Flutter的跨平台版本Github客户端,与AwesomeGithub相对应。

android-api-analysis: 结合具体的Demo来全面解析Android相关的知识点, 帮助读者能够更快的掌握与了解所阐述的关键。

daily_algorithm: 每日一算法,由浅入深,欢迎加入一同共勉。