顶点属性缓冲区绑定到错误的属性

时间:2012-07-20 02:58:35

标签: c# opengl glsl opentk

当我将缓冲区绑定到着色器的属性时,它们似乎被翻转了。

所以,我有一个顶点着色器:

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;
}

和片段着色器

precision highp float;

in vec3 ex_Color;

out vec4 out_frag_color;

void main(void)
{
  out_frag_color = vec4(ex_Color, 1.0);
}

没有什么太复杂的。有两个输入:一个用于顶点位置,一个用于颜色。 (作为一个新手,我不想处理纹理或光。)

现在,在我的客户端代码中,我将数据放入两个向量数组中,即positionVboData和colorVboData,我创建了VBO ......

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);

然后,我会期望以下代码将vbos绑定到着色器的属性:

    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");

但是,实际上我必须在最后一个代码示例中交换positionVboHandle和colorVboHandle,然后它才能完美运行。但这对我来说似乎是倒退。我错过了什么?


更新

奇怪的事情正在发生。如果我将顶点着色器更改为:

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);
}"

并且不做任何其他更改(除了建议在所有设置之后移动程序链接的修复,它将正确的属性,顶点位置加载到in_position而不是in_color。

2 个答案:

答案 0 :(得分:4)

必须在GL.LinkProgram之前执行

GL.BindAttribLocation。您是否在此代码片段后调用GL.LinkProgram?

编辑: 回答你的更新 - 因为你没有使用in_color,那么OpenGL只是忽略了这个输入。并且您的顶点着色器仅将in_position作为输入。最有可能的是它将它绑定在位置0.这就是你的代码工作的原因。您应该在链接程序之前绑定位置,如上面的链接所述。

答案 1 :(得分:0)

所以,在MārtiņšMožeiko的帮助下,我能够弄清楚这一点。我正确地在LinkProgram之前调用了BindAttribLocation。但是,在绑定任何属性位置之前,我没有调用GL.CreateProgram()。