16

When do I use the STD140 for uniform blocks in OpenGL?

Although I am not a 100% sure, I believe there is an alternative to it which can achieve the same thing, called "Shared".

Is it just preference for the coder? Or are there reasons to use one over the other?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dan Webster
  • 1,185
  • 1
  • 12
  • 27
  • If you know [what `std140` layout is](http://www.opengl.org/wiki/Interface_Block_%28GLSL%29#Memory_layout), then you should already know why you would or would not want to use it. So, are you asking what `std140` layout is? – Nicol Bolas Apr 29 '13 at 03:47
  • @NicolBolas Nope, I know the difference is one you have to use query and one you have to pad. My question still stands. – Dan Webster Apr 29 '13 at 05:33
  • @NicolBolas: I see it in code I'm studying, and am glad to find this resource for helping to understand it. – Jack May 04 '17 at 22:46

2 Answers2

13

Uniform buffer objects are described in http://www.opengl.org/registry/specs/ARB/uniform_buffer_object.txt

The data storage for a uniform block can be declared to use one of three layouts in memory: packed, shared, or std140.

  1. packed uniform blocks have an implementation-dependent data layout for efficiency, and unused uniforms may be eliminated by the compiler to save space.

  2. shared uniform blocks, the default layout, have an implementation-dependent data layout for efficiency, but the layout will be uniquely determined by the structure of the block, allowing data storage to be shared across programs.

  3. std140 uniform blocks have a standard cross-platform cross-vendor layout. Unused uniforms will not be eliminated.

The std140 uniform block layout, which guarantees specific packing behavior and does not require the application to query for offsets and strides. In this case, the minimum size may still be queried, even though it is determined in advance based only on the uniform block declaration. The offset of each uniform in a uniform block can be derived from the definition of the uniform block by applying the set of rules described in the OpenGL specification.

Sergey K.
  • 24,894
  • 13
  • 106
  • 174
  • 4
    The std430 is also an alternative. – AzP Dec 01 '17 at 09:49
  • 5
    @AzP According to the OpenGL wiki, std430 *cannot* be used with uniform blocks. (https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Memory_layout) – Charlie Su Nov 16 '19 at 19:38
13

std140 is most useful when you have a uniform block that you update all at once, for example a collection of matrix and lighting values for rendering a scene. Declare the block with std140 in your shader(s), and you can replicate the memory layout in C with a struct. Instead of having to query and save the offsets for every individual value within the block from C, you can just glBufferData(GL_UNIFORM_BUFFER, sizeof(my_struct), &my_struct, with one call.

You do need to be a little careful with alignment in C, for instance, a vec3 will take up 4 floats, not 3, but it is still much easier IMHO.

Hugh Fisher
  • 2,321
  • 13
  • 8