How to set a uniform struct in GLSL 4.6

Viewed 319

I have a group of related variables in a struct, each struct member is of basic type. I declared a uniform of that struct type, and want to use foo.a, foo.b, etc in my shader.

struct Foo {
    vec3 a;
    vec4 b;
    bool c;
    mat3 d;
    uint e;
};

layout(location = 1001) uniform Foo foo;

The documentation says that foo takes up 5 uniform locations, so I assume I can simply set the uniform value like this?

unsigned int e = 1;
glUniform1i(1005, e);  // e corresponds to uniform location 1005
// do sth with foo.e

My question is, do I have to query uniform locations explicitly here? Do I need to worry about memory layout and padding issues? My purpose of using a struct is to group these variables in a much cleaner way, but I don't want to query uniform locations explicitly.

I know it's easier to use a uniform buffer object with std140 layout if the variables are global to all shader programs. However, since UBOs are very precious in OpenGL, I don't want to waste it here, I'd rather keep UBOs for lighting inputs. Is it possible to just use a raw uniform struct? (By precious I mean the number of UBOs available is relatively small compared to loose uniforms, graphics cards usually only support up to 15 or 16 UBOs)

1 Answers

For structures the uniform locations are sequential and ascending. See 4.4.3. Uniform Variable Layout Qualifiers:

Locations can be assigned to default-block uniform arrays and structures. The first inner-most scalar, vector or matrix member or element takes the specified location and the compiler assigns the next inner-most member or element the next incremental location value.

Related