统一变量
[layout (location = 0)] uniform float f = 1.0f;
若设置layout
,则不需要使用glGetUniformLocation
来获取统一变量的位置
使用glUniform*
传递值,glUniformMatrix*()
设置矩阵统一变量。
glUseProgram(myShader);
glUniform1f(0,45.2f);//0为location = 0的数据位置
glUniform4fv(iColorLocation , 1, vColor);
glUniformMatrixfv(proj_location, 1, GL_FALSE, proj_matrix);
一致区块
为了降低glUniform*的调用成本,更容易在不同应用程序之间共享一系列统一变量。
这种功能称为统一变量缓冲对象。
uniform Block{
...data
}block1;
数据布局
标准布局std140
标准布局的布局方式与c、c++的结构体的布局方式相同。在传递数据时,使用相同结构的结构体整体传递即可。
align限定符可用于整个区块以强制所有成员对齐到指定边界。如下,bar的偏移量为8,符合vec2的偏移规则,但align设置为16,则bar强制对齐边界为16的倍数,故,offset = 8会被
layout(std140, align = 16) uniform Block
{
layout (offset = 32) vec4 foo;
layout (offset = 8) vec2 bar;
layout (offset = 48) vec3 baz;
}
报错:offset只能递增,不能随机设置
修改如下
layout(std140,align = 16) uniform manuallyLaidOutBlock
{
layout (offset = 8) vec2 bar;
layout (offset = 32) vec4 foo;
layout (offset = 48) vec3 baz;
}myBlock;
获取一致区块的信息
const GLchar* unifromName = "manuallyLaidOutBlock.bar";
GLuint uniformindex = -1;
glGetUniformIndices(nanosuitShader.ID, 1, &unifromName, &uniformindex);//获取bar的索引
GLint uniformOffset = -1;
glGetActiveUniformsiv(nanosuitShader.ID,1,&uniformindex,GL_UNIFORM_OFFSET,&uniformOffset);//siv---系统信息显示
cout << uniformOffset << " " << endl;
uniformOffset
保存了manuallyLaidOutBlock.bar
的偏移量,输入如下:
进一步说明了align = 16
的作用。
共享布局shared
利用shared
布局,可以使缓存中的数据根据OpenGL确定的最佳运行性能和最佳着色器访问进行布局。但必须获取区块信息。
通过glGetActiveUniformsiv()
查询的统一变量参数类型,可查看书P84
页。
之后便可在内存构建一致区块,然后使用glBufferSubData()
将其加载到缓存或glMapBufferRange()
获取内存指针,并直接将数据组装到该内存。
统一变量绑定
方法一
程序中每一个一致区块都有一个分配了编译程序的索引。
获取程序中一致区块的索引,可以调用:
GLuint glGetUniformBlockIndex(GLuint program, const GLchar * uniformBlockName);
为一致区块赋予绑定点,调用:
void glUniformBlockBinding( GLuint program,
GLuint uniformBlockIndex,//要赋予绑定点的一致区块索引
GLuint uniformBlockBinding);//一致区块绑定点的索引
可使用glGetintegerv()
获取绑定点数量上限,glGetintegerv()
其他功能见P86
页。
OpenGL保证一致区块至少为64K,至少可以在一个程序中引用14个区块。
方法二
直接在着色器中设置binding
layout(std140, align = 16, binding = 2) uniform manuallyLaidOutBlock
{
layout (offset = 8) vec2 bar;
layout (offset = 32) vec4 foo;
layout (offset = 48) vec3 baz;
}myBlock;
将缓存绑定到绑定点
glBindBufferBase(GL_UNIFORM_BUFFER,index,buffer);
GL_UNIFORM_BUFFER
指定绑定点为统一变量。
index
绑定点的索引
buffer
想要绑定的缓存对象的名称