-1

I am trying to render multiple instances of a mesh, each with a different float offset. To do this I am passing a uniform float array to the shader, which will then be indexed with gl_InstanceID. But I am getting an InvalidOperation error and nothing is being rendered. The relevant lines of my vertex shader are as follows.

#version 150
uniform float offsets[16]; //Uniform array declaration.
// Other uniforms

void main () {
    // Other code to assign gl_Position.
    // ...
    // Assigning the value to the vertex colour for debugging purposes.
    col = vec3(offsets[gl_InstanceID]);
}

I am uploading the array offsets to the shader using GL.Uniform1(location, offsets.Length, offsets); After some experimenting, I've figured out the following:

  • using offsets[0] instead of offsets[gl_InstanceID] works and the meshes are rendered, but GL.GetActiveUniform shows that the array's size is 1, and GL.GetUniform only returns the first element of the array. The float[] functionally behaves like a float.
  • using a constant index of 1,2, or 3, GL.GetActiveUniform shows the array's size has increased to 2,3,or 4 respectively, but GL.GetUniform still only returns the first item and I get an InvalidOperation error and nothing rendered.
  • using a variable index (i.e. int i=0; and then offsets[i]), causes the uniform to have the desired size of 16, but still only contains the first element of the array I upload, and I get InvalidOperation + nothing rendered, even when i=0;

From what I can tell, the problem is being caused by GL.Uniform1 only uploading the first item regardless of what array I pass in. My understanding is that GL.Uniform1(int location, int count, float[] value) in OpenTK corresponds to the OpenGL function glUniform1fv, so could this be a bug with OpenTK or am I simply not doing it correctly?

2 Answers2

0

The initialization of the uniform variable with an array of floats with GL.Uniform1 works as expected (OpenTK 4.6.3):

uniform float offsets[16];
int offsetsLoc = GL.GetUniformLocation(program, "offsets");

GL.UseProgram(program);
var offsets = new float[16] { ... };
GL.Uniform1(offsetsLoc, offsets.Length, offsets);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
0

I had the same problem. Using the GL.Uniform2() function instead of the GL.Uniform1() function worked for me.

Wayne Birch
  • 645
  • 6
  • 18
Bgt
  • 1