Uniforms location


I have a glsl program containing an array of uniform like this:

struct ControlPoint
	vec4 position;	
	vec4 rotation;
	vec4 some_data;

uniform ControlPoint control_points[30];

On the cpu I have the exact same structure, and i was hoping that I would be able to do something like this

int base = glGetUniformLocationARB(m_program, "control_points[0].position");

glUniform4fvARB(base, 30 * 3, &m_control_points[0].position[0])

to initialize the entire array of uniforms. This doesn’t seem to work however.

Upon further investigation I discovered that

int index_0 = glGetUniformLocationARB(m_program, "control_points[0].position");
int index_1 = glGetUniformLocationARB(m_program, "control_points[0].rotation");
int index_2 = glGetUniformLocationARB(m_program, "control_points[0].some_data");

returns index_0 = 0, index_1 = 2 and index_2 = 1, i.e. the glsl compiler doesn’t respect the order of the members in my struct.

Is this to be expected? Is there any way to force the compiler to respect the order of the members in the struct?


Interesting. What OpenGL implementation is this?

Probably to be expected.
See issue 75 in the GLSL spec
75) Should uniforms and attributes which are initialized by the application allowed to be structs?
ADDED on September 25, 2002.
DISCUSSION: If we don’t allow this, the application has to pass all data via individual global
variables, and shader code must pack the data together in structs in order to use structs. This causes
ugly unnecessary shader code. On the other hand, initializing struct data should not involve a
complexification of the API.
Also, it seems broken to have structs in the language, but not have a way to initialize them from the
application. On the other hand, a complete solution for initializing structs seems beyond this release.
It’s also been noted that attributes can be matrices, but there is no API for initializing them.

  • Add entry points to initialize an attribute matrix. At bind time, a 4x4 matrix takes 4 consecutive
    locations, a 3x3 matrix takes 3 consecutive locations, and a 2x2 matrix takes 2 consecutive locations.
    Details of layout are hidden. If an implementation only needs one slot for a 2x2, it only has to use
    one slot, but the room is there for implementations that need two.
  • Don’t yet support arrays of attributes and structs of attributes.
  • Allow uniform struct and array of struct.
    * Support API initialization of struct members by specifying a string at GetUniformLocation time
    that selects the member to be initialized. E.g. “struct.member”, “struct[4].member”,
    “struct[2].member[2]” etc.

    * Don’t yet support struct-level initialization in the API, wait for future full solution that
    understands strides, alignments, padding, etc.

    CLOSED October 22, 2002.

I would probably just stick with

vec4 positionArray[30];
vec4 rotation[30];
vec4 some_data[30];

for now so that you can load the data in only 3 calls. (Yes I know, it makes your GLSL a bit more hacky looking)

Ok, thanks guys. For your information I’m using ForceWare 81.67 (probably a bit old) but judging from Relics answer, this isn’t something that’s going to be fixed any time soon.

For now I think I will just use a loop to initialize my struct variables.


This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.