Loading Data into Unform Struct Array

I’ve implemented geometry instacing and are trying to load instance data into vertex uniforms as efficient as possible.

Each vertex contains an index pointing to the instance that it belongs to, and the vertex shader reconstruct the vertex position etc using instance specific data specified in an array of instance data.

The instance specific data looks like:

uniform struct instanceData[64] {
  vec3 offset;
  vec3 size;
  // etc
};

I have a corresponding structure in my C++ program, but how do I load data into this array? It seems that I’m only able to load data into each struct attribute separately using glUniform3fv - but this requires splitting the struct on the client side (As there is no stride parameter in glUniform3fv).

Is there something I’m missing, or is it really not possible to load data into a struct using a single glCall, or even a single glCall for each attribute in the struct without splitting the struct on the client side?

So far I’ve insured that each instance data attribute is a vec3, and loaded the data using a single glUniform3fv call - but I’m hoping that there is a better way which let’s me keep my struct.

This extension should make things easier… unfortunately its only available on the newest hardware (e.g. GeForce 8800 series). Note that Longs Peak will use buffer object for all uniform storage (effectively emulating this feature on older hardware).

I’ve seen this extension, but I was hoping for something that would work with vanilla GLSL. Moreover, I’m not sure that you’re able to get the location of the first element in the struct, i.e. a call to glGetUniformLocation (shaderProgram, “instanceData”) in my example is valid…

I’m afraid with vanilla GLSL you can’t load a struct with a single call.

Overmind, this was also the conclusion that I came to. But I can’t belive that I cannot populate the array with a call for each member variable without splitting the struct on the client side - surely, I must be missing something?!

Originally posted by Niels Husted Kjaer:
But I can’t belive that I cannot populate the array with a call for each member variable without splitting the struct on the client side - surely, I must be missing something?!
Unfortunately this is not supported. The only array that can be populated in single call is array of basic types. This is detailed in issue 32 of shader objects extension.

If you wish to upload more values at once, you will probably need to rewrite the structure to something like:

uniform struct instanceData {
  vec3 offset[64];
  vec3 size[64];
};

or

uniform vec3 instanceData[ 128 ] ;

#define get_instance_pos( index ) instanceData[ int( int( index ) * 2 ) ]
#define get_instance_size( index ) instanceData[ int( int( index ) * 2 + 1 ) ]

Thanks Komat, I missed the issues section. I guess I’ll keep my current setup and use a flat vec3 array for all members variables of the structure.