OpenGL ES 之attribute
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;
}
vPosition就是顶点数据,这个数据需要应用程序从外部传入,下面介绍如何将应用程序的顶点数据传递给我vPosition。
01
获取attribute句柄
在Android中获取句柄Kotlin代码如下:
val loc = GLES20.glGetAttribLocation(programHandle, attrName)
programHandle是program的句柄,attrName是attribute的名称。
02
定义顶点数据
在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
}
03
设置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地址:https://www.khronos.org/registry/OpenGL-Refpages/es2.0/ ,参数说明如下:
- 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
attribute参数的数据并不是一个内存的索引,而是定义了去哪个内存区域取数据,在GPU中attribute存放在一块固定区域,GPU计算的时候去buffer处取数据,结构如下图:
应用程序将数据传递给GPU后,这些数据保存在GPU的一块内存中,上面定义的顶点数据结构如下图:
顶点数据的结构别不是都这样,数据结构取决于你定义的顶点数据。
- WordPress 路径相关函数总结(四):路径相关常量
- .net和java互操作
- WordPress 路径相关函数总结(三):插件路径相关函数
- 修改WordPress 搜索结果页面url 形式,安全有保障
- C# Enum设计和使用的相关技巧
- 小程序如何利用更低成本获得高流量?
- 使用System.Net.Mail通过gmail发送电子邮件
- 删除 WordPress 导航菜单的多余 CSS 选择器(id或class)
- es6 对象的扩展
- 自定义WordPress 标签云小工具相关参数
- 检查.NET程序平台目标(Platform Target)工具CorFlags
- 哪些行业最适合抢驻小程序?
- WordPress 一键关闭/禁止页面评论功能
- 在一个.net sln中包含多个project,project引用同一个dll导致的错误
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法