如果一个统一块在多个着色器程序中声明相同,比如,是否可以保证
uniform Matrices
{
mat4 ProjectionMatrix;
mat4 CameraMatrix;
mat4 ModelMatrix;
};
它会有glGetUniformBlockIndex(program, "Matrices")
返回的相同块索引吗?
如果答案是肯定的,那么我可以查询块的索引一次,并将其用于包含该块的所有着色器程序,对吧?
第二个问题:ProjectionMatrix
、CameraMatrix
、ModelMatrix
在内存中是否总是分别具有相同的布局顺序?我之所以这么问,是因为我阅读的教程使用了的下一个功能
// Query for the offsets of each block variable
const GLchar *names[] = { "InnerColor", "OuterColor",
"RadiusInner", "RadiusOuter" };
GLuint indices[4];
glGetUniformIndices(programHandle, 4, names, indices);
GLint offset[4];
glGetActiveUniformsiv(programHandle, 4, indices,
GL_UNIFORM_OFFSET, offset);
我不确定是否真的需要,只要我知道制服区内的制服顺序。。?
ProjectionMatrix
、CameraMatrix
、ModelMatrix
在内存中是否总是分别具有相同的布局顺序?
没有。以下是标准规定(重点是我的):
如果pname是
UNIFORM_BLOCK_DATA_SIZE
,则实现-返回在uniformBlockIndex标识的统一块中保持所有活动统一所需的以基本机器为单位的依赖最小总缓冲区对象大小既不能保证也不能期望给定的实现将统一的值紧密地封装在缓冲区对象中std140
统一块布局是一个例外,它保证了特定的打包行为,并且不需要应用程序查询偏移和步进。我不确定是否真的需要,只要我知道制服区内的制服顺序。。?
因此,是的,作者在而不是中是正确的,假设布局是连续的,并做合理的事情(保证在所有实现中始终有效):获得统一索引并分别分配它们的值。
指定布局(std140)就可以了,对吧?
是的,通过使用统一缓冲区对象和std140
,可以避免每次查询位置和上传数据。但是,请确保您了解其对齐要求。ARB_uniform_buffer_object
的规范中详细介绍了这些信息。有关示例的详细处理,请参阅OpenTK关于使用std140布局规范的统一缓冲区对象(UBO)的文章。
是否可以保证,如果在多个着色器程序中声明一个统一块相同,那么它是否具有
glGetUniformBlockIndex(program, "Matrices")
返回的相同块索引?
没有。我已经搜索了OpenGL 3.3规范,它没有提供这样的保证。从标准的角度来看,统一块(默认块或命名块)与程序、周期相关联。规范中未规定程序之外的统一块的存在/关联。
因为不能保证统一块在不同的着色器程序中具有相同的索引,这意味着我每次切换程序时都需要调用
glBindBufferBase()
,对吧?
是的,有关示例,请参阅ARB_uniform_buffer_object
的规范。