When I bind my buffers to attributes for my shaders, they seem to be getting flipped.
So, I've got a vertex shader:
precision highp float; uniform mat4 projection_matrix; uniform mat4 modelview_matrix; in vec3 in_position; in vec3 in_color; out vec3 ex_Color; void main(void) { gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1); ex_Color = in_color; }
and a fragment shader
precision highp float; in vec3 ex_Color; out vec4 out_frag_color; void main(void) { out_frag_color = vec4(ex_Color, 1.0); }
Nothing too complicated. There are two inputs: one for vertex locations, and one for colors. (As a newb, I didn't want to deal with textures or light yet.)
Now, in my client code, I put data into two arrays of vectors, positionVboData and colorVboData, and I create the VBOs...
GL.GenBuffers(1, out positionVboHandle); GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, new IntPtr(positionVboData.Length * Vector3.SizeInBytes), positionVboData, BufferUsageHint.StaticDraw); GL.GenBuffers(1, out colorVboHandle); GL.BindBuffer(BufferTarget.ArrayBuffer, colorVboHandle); GL.BufferData<Vector3>(BufferTarget.ArrayBuffer, new IntPtr(colorVboData.Length * Vector3.SizeInBytes), colorVboData, BufferUsageHint.StaticDraw);
and then, I would expect the following code to work to bind the vbos to the attributes for the shaders:
GL.EnableVertexAttribArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, positionVboHandle); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0); GL.BindAttribLocation(shaderProgramHandle, 0, "in_position"); GL.EnableVertexAttribArray(1); GL.BindBuffer(BufferTarget.ArrayBuffer, colorVboHandle); GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, true, Vector3.SizeInBytes, 0); GL.BindAttribLocation(shaderProgramHandle, 1, "in_color");
But, in fact I have to swap positionVboHandle and colorVboHandle in the last code sample and then it works perfectly. But that seems backwards to me. What am I missing?
Update
Something weird is going on. If I change the vertex shader to this:
precision highp float; uniform mat4 projection_matrix; uniform mat4 modelview_matrix; in vec3 in_position; in vec3 in_color; out vec3 ex_Color; void main(void) { gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1); //ex_Color = in_color; ex_Color = vec3(1.0, 1.0, 1.0); }"
And make no other changes (other than the fix suggested to move the program link after all the set up, it loads the correct attribute, the vertex positions, into in_position rather than into in_color.
So, with Mārtiņš Možeiko's help, I was able to figure this out. I was calling BindAttribLocation before LinkProgram correctly. However, I wasn't calling GL.CreateProgram() BEFORE I was binding any of the attribute locations.
GL.BindAttribLocation must be performed before GL.LinkProgram. Are you calling GL.LinkProgram after this code fragment?
EDIT: Answering to your Update - because you don't use in_color, then OpenGL simply ignores this input. And your vertex shader taks only in_position as input. Most likely it binds it in location 0. That's why your code works. You should bind locations before linking program as it is described in link above.