简介
Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。
首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。
第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。
单独统一变量
声明
uniform vec3 color
赋值
1 | //获取指定统一变量的location |
赋值函数是根据 统一变量类型的不同而调整的.其中函数名中包含数字(1、2、3、4)表示接受这个数字个用于更改uniform变量的值,i表示32位整形,f表示32位浮点型,ub表示8位无符号byte,ui表示32位无符号整形,v表示接受相应的指针类型(或者就是传入的是数组)。
glUniform1f(GLint locaation,GLFloat x)
表示 float类型glUniform2f(GLint locaation,GLFloat x,GLFloat y)
表示 二位向量 分量类型为floatglUniform1fv(GLint locaation,GLSize count,const GLfloat* value)
float类型指针glUniformMatrix4x3(Glint location,GLsizei count,GLboolean transpose,const GLfloat* value)
表示为 4x3矩阵. 参数: transpose 表示是否采用 行优先顺序(GL_TRUE)
UBO
UBO(Uniform Buffer Object)是用来存储着色语言中Uniform类型变量的缓冲区对象,使用UBO可以让uniform变量在不同的着色语言程序中实现共用,也可以在着色语言程序中实现uniform类型变量的设置与更新。
提到UBO就必须要提到着色语言GLSL中的Uniform Blocks,它将众多的Uniform类型的变量集中在一起进行统一的管理,对于需要大量Uniform类型变量的程序可以显著地提高性能。(有点像全局版的VBO)
原理
在显存中创建缓存对象(Buffer),在buffer中存储统一变量数据, 将Buffer与 指定的point绑定, 将统一变量缓冲区的索引 和 point绑定. 这样通过point 将变量 和 缓存 连接.
设置UBO
1 | //统一变量块 |
1 | GLuint blockid,bufferid; |
修改UBO
1 | GLfloat uploadData[] = { |
函数补充
1, glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* const *uniformNames, GLuint* uniformIndices)
该函数用于获取统一变量块中 变量们的索引 参数:
program 程序对象
uniformCount 变量名称数组的元素数量
uniformNames 变量名称数组
uniformIndices 用于接受变量索引的数组
2,glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params)
该函数用于 通过变量索引 查询变量信息. 参数:
program 程序对象
uniformCount 变量数量
uniformIndices 变量索引数组
pname 表示要查询变量的那个属性 GL_UNIFORM_OFFSET(变量偏移量) GL_UNIFORM_SIZE(变量大小) GL_UNIFORM_NAME_LENGTH(变量名长度) GL_UNIFORM_TYPE(变量类型)….
params 接受查询结果的数组
注意
着色语言编译优化
如果你声明了一个uniform却在GLSL代码中没用过,编译器会静默移除这个变量,导致最后编译出的版本中并不会包含它.
UBO限定符
在UBO中,针对不同的限定符 还存在不同的字节补齐的情况.所以获取偏移量,大小最好还是通过查询进行,避免自己计算出现错误.
这是 std140(标准统一变量块布局)限定符的内存分配情况:
其他的限定符 在我学了之后会补上~