Search code examples
c++openglglsl

OpenGL use uniform buffer as an array


I found out that I can use uniform buffers to store multiple variables like this

#version 330 core
layout (location = 0) in vec3 aPos;

layout (std140) uniform Matrices
{
    mat4 projection;
    mat4 view;
};

uniform mat4 model;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}  

and treat this data like any other buffer


unsigned int uboMatrices
glGenBuffers(1, &uboMatrices);
  
glBindBuffer(GL_UNIFORM_BUFFER, uboMatrices);
glBufferData(GL_UNIFORM_BUFFER, 2 * sizeof(glm::mat4), NULL, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
  
glBindBufferRange(GL_UNIFORM_BUFFER, 0, uboMatrices, 0, 2 * sizeof(glm::mat4));

However, I can't seem to find any examples that would allow me to treat such a buffer like an array. Essentially I would like to achieve a global random-access buffer like this

#version 330 core
layout (location = 0) in vec3 aPos;

layout (what here?) uniform float[] globalBuffer;

uniform mat4 model;

void main()
{
    ...
}  

The long term plan is to later produce this array with OpenCL


Solution

  • uniform float[] globalBuffer; is not a uniform buffer. It is just an array of uniforms. You must set the uniforms with glUniform1fv.

    A Uniform block would be:

    layout (std140) uniform Foo 
    { 
        float[] globalBuffer; 
    }
    

    Unfortunately, in this case each array element would be aligned to the size of vec4. See OpenGL 4.6 API Core Profile Specification; 7.6.2.2 Standard Uniform Block Layout:

    1. If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element, according to rules (1), (2), and (3), and rounded up to the base alignment of a vec4.

    I recommend to use a Shader Storage Buffer Object

    layout (std430) buffer Foo
    {
        float[] globalBuffer; 
    };
    

    OpenGL 4.6 API Core Profile Specification; 7.6.2.2 Standard Uniform Block Layout:

    Shader storage blocks (see section 7.8) also support the std140 layout qualifier, as well as a std430 qualifier not supported for uniform blocks. When using the std430 storage layout, shader storage blocks will be laid out in buffer storage identically to uniform and shader storage blocks using the std140 layout, except that the base alignment and stride of arrays of scalars and vectors in rule 4 and of structures in rule 9 are not rounded up a multiple of the base alignment of a vec4.