Hi,
When I have an array of uniform variables like:
uniform vec3 positions[20];
I can modify all of them at once by querying the location of positions[0] and doing something like
glUniform3fv(positionsArrayUnif, 20, positionsArray);
Now, I can kind of do the same thing with uniform buffer objects.
layout(std140) uniform UniformBlock
{
vec3 positions[20];
};
Now let’s say I’ve successfully made the association between that block and an a uniform buffer object via a uniform buffer binding point. How would I change that entire array in the UBO efficiently? I could try something like this:
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(array_of_vec3s), array_of_vec3s);
(glm is a library that imitates GLSL types for C++, at least that’s what I think it does.)
But this seems rather unsafe. Maybe it’s OK if I use the “std140” layout for the uniform block, but would there be any way to do this if I used the “packed” layout? Sorry if I’m being incorrect or ambiguous. I don’t know if it’s just me, but OpenGL’s structure and terminology is very confusing.
Edit: Specifically, I mean, if I use the “packed” layout, would it be possible to efficiently change the entire array, without having to query the location of each element?
Edit 2: I may have solved my problem, but I guess I’ll leave this up here for other people’s reference and if anyone else has other considerations, as I don’t feel completely sure if I can really trust this specification to work across all implementations.
From the OpenGL wiki:
Uniform arrays in a buffer are stored sequentially. But they are not guaranteed to be tightly packed. Therefore, for any array uniforms in a block, you must query a stride value with GL_UNIFORM_ARRAY_STRIDE. This stride is the byte distance from the beginning of one element to the beginning of the next.
Edit 3: Anyways, according to the 3.2 core specification, if you use “std140”, array_of_vec3s should have a vec4 of memory for each element, so it’s like 3 floats of data and a sizeof(float) of padding per element.