OpenGL ES on iOS --- 统一变量(Uniform)和统一变量块(UBO)

OpenGL ES on iOS --- 统一变量(Uniform)和统一变量块(UBO),第1张

概述简介 Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。 首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。 第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。 单独统一变量 声 简介

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表示接受相应的指针类型(或者就是传入的是数组)。

gluniform1f(Glint locaation,GLfloat x) 表示 float类型
gluniform2f(Glint locaation,GLfloat x,GLfloat y) 表示 二位向量 分量类型为float
gluniform1fv(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)

原理

原理示意图.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)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1015724.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存