1

Is it guaranteed that if a uniform block is declared the same in multiple shader programs, say

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

Will it have the same block index returned by glGetUniformBlockIndex(program, "Matrices")?

If the answer is yes, then I'm able to query the index of the block once and use it for all the shader programs that contain that block, right?

Second question: will ProjectionMatrix, CameraMatrix, ModelMatrix, always have the same layout order in memory, respectively? I'm asking this because the tutorial I read uses the next functions

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

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

3
  • Can you link the tutorial you're following here? Commented Nov 12, 2015 at 10:02
  • It's actually a book. OpenGL 4.0 Shading Language Cookbook Commented Nov 12, 2015 at 10:07
  • Nice, I've the first edition of the book, the author does a good job. Commented Nov 12, 2015 at 10:59

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Specifying layout(std140) will do the trick then, right? (at least for three mat4's like the example above). One more question: 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?
About my first question: I know that uniform blocks are designed for sharing uniforms in multiple programs, but they never say that the same uniform block will be assigned the same index in different programs. (by the way, did you change your answer? Yesterday you said the opposite!)
You definitely answered my questions, however, it seems like a certain uniform block always has the same index when using different shader programs. I opened a new question for this. Thanks! link.
Sure, the whole point of having a function glGetUniformBlockIndex(program, name) shows that the UBO's index would change between programs. Thanks for the link.
The way I do it is when I create the Uniform Buffer Object I set it a binding index, then I never have to check its index again, because in each shader I have layout (binding = 2, std140) uniform perObjBuffer {// Your data here//} Surely this works and it never changes index.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.