关于统一缓冲对象的问题

时间:2015-11-12 09:59:53

标签: opengl shader opengl-4

如果在多个着色器程序中声明统一块相同,请确保

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

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

1 个答案:

答案 0 :(得分:1)

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

No. Here's what the standard states (emphasis mine):

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..?

So, yes, the author is right in not assuming the layout is contiguous and does what's sensible (guaranteed to work always in all implementations): gets the uniform indices and assigns their values respectively.

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

Yes, you can avoid querying the location and uploading data every time by making use of both uniform buffer objects and std140. However, make sure you understand its alignment requirements. This information is detailed in 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")?

No. I've searched the OpenGL 3.3 specification which gives no such guarantees. From the standard's viewpoint, uniform blocks (default or named) are associated to a program, period. No existence/association of uniform blocks beyond a program is made in the specification.

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?

Yes, see ARB_uniform_buffer_object's specification for an example.