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)

1
  • 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. Commented Dec 27, 2013 at 18:37

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

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.
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 yes, each field manually. I've edited answer to add some info about how to make it easier.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.