1

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

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

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 中。

4

2 回答 2

4

GL.BindAttribLocation必须在 GL.LinkProgram 之前执行。你在这个代码片段之后调用 GL.LinkProgram 吗?

编辑:回答您的更新 - 因为您不使用 in_color,所以 OpenGL 会简单地忽略此输入。并且您的顶点着色器仅将 in_position 作为输入。很可能它将它绑定在位置 0。这就是您的代码有效的原因。您应该在链接程序之前绑定位置,如上面链接中所述。

于 2012-07-20T03:12:43.193 回答
0

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

于 2012-07-22T17:09:18.593 回答