OpenGL ES之attribute

作者: 老孟程序员 | 来源:发表于2020-01-21 21:55 被阅读0次

attribute是GLSL中特殊的变量类型,用于从“外部”到顶点着色器的通信,只能用于Vertex Shader(顶点着色器),不能用于其他Shader中,attribute 通常用来存储位置坐标、法向量、纹理坐标和颜色等,定义如下:

attribute vec4 vPosition;

OpenGL 标准化组织规定OpenGL ES 2.0 至少支持8个attribute,OpenGL ES 3.0至少支持16个attribute,注意这里是至少,也可以多于8个,通过代码获取支持attribute的最大个数,Kotlin代码如下:

var count = IntArray(1)
GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_ATTRIBS, count, 0)
Log.d("OpenGL ES", "attribute支持的最大数量:${count[0]}")

下面是一个非常简单的Vertex Shader:

attribute vec4 vPosition;
void main() {
    gl_Position = vPosition;
}

\color{#c64935}{获取attribute句柄}

vPosition就是顶点数据,这个数据需要应用程序从外部传入,下面介绍如何将应用程序的顶点数据传递给我vPosition。
在Android中获取句柄Kotlin代码如下:

val loc = GLES20.glGetAttribLocation(programHandle, attrName)

programHandle是program的句柄,attrName是attribute的名称。

\color{#c64935}{定义顶点数据}

在Android中通常情况下顶点数据的类型是FloatBuffer,定义了3个顶点的Kotlin代码如下:

var vertexBuffer = array2Buffer(
            floatArrayOf(
                0.0f, 0.5f, 0.0f, // top
                -0.5f, -0.5f, 0.0f, // bottom left
                0.5f, -0.5f, 0.0f  // bottom right
            )
        )

    fun array2Buffer(array: FloatArray): FloatBuffer {
        val bb = ByteBuffer.allocateDirect(array.size * 4)
        bb.order(ByteOrder.nativeOrder())
        var buffer = bb.asFloatBuffer()
        buffer.put(array)
        buffer.position(0)
        return buffer
    }

\color{#c64935}{设置attribute数据}

设置顶点数据,即将顶点数据从CPU传递到GPU,Kotlin代码如下:

    fun setAttributePointer(location: Int, buffers: FloatBuffer, pointSize: Int) {
        buffers.position(0)
        GLES20.glEnableVertexAttribArray(location)
        GLES20.glVertexAttribPointer(location, pointSize, GLES20.GL_FLOAT, false, 0, buffers)
    }

这里定义了一个通用的方法,方法说明如下:

  • GLES20.glEnableVertexAttribArray(location)

激活当前attribute,location就是第一步中获取的vPosition的句柄,

  • GLES20.glVertexAttribPointer

设置attribute属性如何从buffers中获取数据。点击进入官方API介绍
参数说明如下:

  • location:attribute属性的句柄,对于本应用程序是指第一步中获取的vPosition的句柄。
  • pointSize:每一个attribute顶点数据的个数,返回看下第二步中定义顶点数据的数组,每个顶点由3个float组成,代表x,y,z,也可以由2个float代表一个顶点(x,y),对于本应用程序值是3。
  • type(第三个参数):顶点数据的类型,对于本应用程序是float,值是GLES20.GL_FLOAT。
  • normalized(第四个参数):是否归一化,将不是float的类型转为float,比如short转float,Android正常情况下不需要归一化,所以设置false。
  • stride(第五个参数):两个连续顶点之间的偏移量,对于本应用程序来说,顶点之间是连续的,设置为0。
  • buffer:顶点buffer

attribute参数的数据并不是一个内存的索引,而是定义了去哪个内存区域取数据,在GPU中attribute存放在一块固定区域,GPU计算的时候去buffer处取数据,结构如下图:


应用程序将数据传递给GPU后,这些数据保存在GPU的一块内存中,上面定义的顶点数据结构如下图:


顶点数据的结构别不是都这样,数据结构取决于你定义的顶点数据。

\color{#c64935}{更多相关内容:}

相关文章

网友评论

    本文标题:OpenGL ES之attribute

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