glUniform index arithmetic

We have a discussion at the WebGL mailing list about uniform locations. The OpenGL ES 2.0 specification says that glGetUniformLocation returns an index to a uniform location. Also glGetAttribLocation returns an index to an attribute location.

Now the WebGL team claims that glGetUniformLocation doesn’t return an index but its actually a handle to only one element of an uniform array. For glGetAttribLocation they claim it is an index and you can’t do arithmetic to get random access to an element of an array. As a result of this they box the uniform location, and return an object instead of an integer for glGetUniformLocation.

Lets say I have the following uniform array in the shader:

uniform vec4 elements[MAXIMUM_ELEMENTS];

Then I would like to have random access to update a single array element.

GLint location = glGetUniformLocation(program, “elements”);

// update an element at an arbitrary position m
glUniform4fv(location + m, 1, element);

This is the way it is done in several NVIDIA example sources.
The WebGL team claims that some implementations of glGetUniformLocation(program, “elements[1]”) return 1 while others return 4. Thats why according to the WebGL team updating an array element should be done as follows:

char name[16];
sprintf(name, “elements[%d]”, m);

GLint location = glGetUniformLocation(program, name);

// update an element at an arbitrary position m
glUniform4fv(location, 1, element);

In my opinion it would be valid to update an array element with the following code:

GLint location = glGetUniformLocation(program, “elements[0]”);
GLint size = glGetUniformLocation(program, “elements[1]”) - location;

// update an element at an arbitrary position m
glUniform4fv(location + m * size, 1, element);

These are my questions:
Is a uniform location a handle or a index?
Are you allowed to compute the index of an array element?
Are the NVIDIA code samples using bad coding?

Best regards,

  1. A handle.
  2. It probably works, but the spec doesn’t make any guarantees.
  3. Yes.