关于统一缓冲对象的问题

Questions about uniform buffer objects

是否保证如果一个统一块在多个着色器程序中声明相同,比如说

uniform Matrices
{
    mat4 ProjectionMatrix;
    mat4 CameraMatrix;
    mat4 ModelMatrix;
};

是否会与 glGetUniformBlockIndex(program, "Matrices") 返回相同的块索引?

如果答案是肯定的,那么我可以查询一次块的索引并将其用于包含该块的所有着色器程序,对吗?

第二个问题:ProjectionMatrixCameraMatrixModelMatrix在内存中的布局顺序会不会总是一样?我问这个是因为我阅读的教程使用了下一个函数

// 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);

而且我不确定这是否真的需要,只要我知道制服区内的制服顺序..?

will ProjectionMatrix, CameraMatrix, ModelMatrix, always have the same layout order in memory, respectively?

没有。以下是标准规定(强调我的):

If pname is UNIFORM_BLOCK_DATA_SIZE, then the implementation- dependent minimum total buffer object size, in basic machine units, required to hold all active uniforms in the uniform block identified by uniformBlockIndex is returned. It is neither guaranteed nor expected that a given implementation will arrange uniform values as tightly packed in a buffer object. The exception to this is the std140 uniform block layout, which guarantees specific packing behavior and does not require the application to query for offsets and strides.

I'm not sure if that's really needed, as long as I know the uniforms order inside the uniform block..?

所以,是的,作者是正确的 而不是 假设布局是连续的并且做了明智的事情(保证在所有实现中始终工作):获取统一索引并分配他们的价值分别。

Specifying layout(std140) will do the trick then, right?

是的,同时使用uniform buffer objects和std140可以避免每次查询位置和上传数据。但是,请确保您了解其对齐要求。此信息在 ARB_uniform_buffer_object's specification. For an elaborate treatment with examples see OpenTK's article on Uniform Buffer Objects (UBO) using the std140 layout specification.

中有详细说明

Is it guaranteed that if a uniform block is declared the same in multiple shader programs, will it have the same block index returned by glGetUniformBlockIndex(program, "Matrices")?

没有。我搜索了没有提供此类保证的 OpenGL 3.3 规范。从标准的角度来看,统一块(默认或命名)与程序、句点相关联。规范中没有existence/association超出程序的统一块。

Because there is no guarantee that uniform blocks will have the same index in different shader program, that means I need to call glBindBufferBase() everytime I switch programs, right?

是的,参见 ARB_uniform_buffer_object 的规范示例。