Uniform是一种从cpu中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。
单独统一变量 声明首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。
第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。
uniform vec3 color
//获取指定统一变量的locationint vertexcolorLocation = glGetUniformlocation(_program,"test");//为vec3 的统一变量 赋值gluniform3f(vertexcolorLocation,0.0f,1.0f,0.0f);
赋值函数是根据 统一变量类型的不同而调整的.其中函数名中包含数字(1、2、3、4)表示接受这个数字个用于更改uniform变量的值,i表示32位整形,f表示32位浮点型,ub表示8位无符号byte,ui表示32位无符号整形,v表示接受相应的指针类型(或者就是传入的是数组)。
UBO
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(Uniform Buffer Object)是用来存储着色语言中Uniform类型变量的缓冲区对象,使用UBO可以让uniform变量在不同的着色语言程序中实现共用,也可以在着色语言程序中实现uniform类型变量的设置与更新。
提到UBO就必须要提到着色语言GLSL中的Uniform Blocks,它将众多的Uniform类型的变量集中在一起进行统一的管理,对于需要大量Uniform类型变量的程序可以显著地提高性能。(有点像全局版的VBO)
原理 原理示意图.png在显存中创建缓存对象(Buffer),在buffer中存储统一变量数据,将Buffer与 指定的point绑定,将统一变量缓冲区的索引 和 point绑定. 这样通过point 将变量 和 缓存 连接.
设置UBO//统一变量块layout (std140) uniform colorBlock{ vec4 cc;};
gluint blockID,bufferID; Glint blocksize; Glint point = 1; // 统一变量数据 GLfloat blockData[] = { 1.0f,1.0f }; //获取统一变量块索引 blockID = glGetUniformBlockIndex(_program,"colorBlock"); //获取统一变量块大小 glGetActiveUniformBlockiv(_program,blockID,GL_UNIFORM_BLOCK_DATA_SIZE,&blocksize); //将变量索引 和 point 绑定 gluniformBlockBinding(_program,point); //创建与绑定缓冲区 glGenBuffers(1,&bufferID); glBindBuffer(GL_UNIFORM_BUFFER,bufferID); //向缓冲区中赋值 glBufferData(GL_UNIFORM_BUFFER,blocksize,blockData,GL_DYNAMIC_DRAW); //将UBO 和 point 绑定 glBindBufferBase(GL_UNIFORM_BUFFER,point,bufferID);修改UBO
GLfloat uploadData[] = { 0.0f,1.0f }; // 绑定当然统一变量块的 buffer glBindBuffer(GL_UNIFORM_BUFFER,bufferID); //获取统一变量块 中 指定变量的 偏移量 const GLchar *names[] = {"cc"}; gluint indices[1]; glGetUniformIndices(_program,1,names,indices); Glint offset[1]; glGetActiveUniformsiv(_program,indices,GL_UNIFORM_OFFSET,offset); glBufferSubData(GL_UNIFORM_BUFFER,offset[0],uploadData);函数补充
1,glGetUniformIndices (gluint program,GLsizei uniformCount,const GLchar* const *uniformnames,gluint* uniformIndices)
该函数用于获取统一变量块中 变量们的索引 参数:
program 程序对象
uniformCount 变量名称数组的元素数量
uniformnames 变量名称数组
uniformIndices 用于接受变量索引的数组
2,glGetActiveUniformsiv (gluint program,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(标准统一变量块布局)限定符的内存分配情况:
std140布局.png 总结以上是内存溢出为你收集整理的OpenGL ES on iOS --- 统一变量(Uniform)和统一变量块(UBO)全部内容,希望文章能够帮你解决OpenGL ES on iOS --- 统一变量(Uniform)和统一变量块(UBO)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)