2

My (fragment) shader has a uniform array containing 12 structs:

struct LightSource
{
    vec3 position;
    vec4 color;
    float dist;
};
uniform LightSource lightSources[12];

In my program I have 12 buffer objects that each contain the data for one light source. (They need to be seperate buffers.)

How can I bind these buffers to their respective position inside the shader?

I'm not even sure how to retrieve the location of the array.

glGetUniformLocation(program,"lightSources");
glGetUniformLocation(program,"lightSources[0]");

These run without invoking an error, but the location is definitely wrong(4294967295). (The array is being used inside the shader, so I don't think it's being optimized out)

Silverlan
  • 2,783
  • 3
  • 31
  • 66
  • You are aware that `glGetUniformLocation` returns a signed number, right? That number is way too large for `GLint` (32-bit signed integer) to store. You are almost certainly misinterpreting the sign of that number. – Andon M. Coleman Dec 27 '13 at 18:37

1 Answers1

4

As glGetUniformLocation docs say:

name must be an active uniform variable name in program that is not a structure, an array of structures, or a subcomponent of a vector or a matrix.

...

Uniform variables that are structures or arrays of structures may be queried by calling glGetUniformLocation for each field within the structure.

So, you can only query one field at a time. Like this:

glGetUniformLocation(program,"lightSources[0].position")
glGetUniformLocation(program,"lightSources[0].color")
glGetUniformLocation(program,"lightSources[0].dist")

Hope it helps.

Edit:

You can make your life easier (at a cost of old hardware/drivers compatibility) by using Interface Blocks, Uniform Buffer Objects and glGetUniformBlockIndex. This will be more like DirectX constant buffers. Required hardware/drivers support for that: either OpenglGL 3.1 core or ARB_uniform_buffer_object extension.

Ivan Aksamentov - Drop
  • 12,860
  • 3
  • 34
  • 61
  • Yeah, I found this out a while ago and ended up using a string mangling loop to encapsulate having to manually set each uniform myself. – zero298 Dec 27 '13 at 16:35
  • So I assume I'll have to use glBindBufferRange on each buffer and set each field manually? I was hoping there was a more direct way of doing it, but I guess it'll have to do. – Silverlan Dec 27 '13 at 17:08
  • @Silverlan yes, each field manually. I've edited answer to add some info about how to make it easier. – Ivan Aksamentov - Drop Dec 27 '13 at 17:20