2

两个问题:

  1. 我正在使用不同着色器的大型 VBO 中渲染元素。在 GLSL 1.2 中,如果我是正确的,我必须使用它,因为它是 OSX 上的最新版本不支持统一位置,我认为这意味着您的属性的位置是编译器决定的任何位置。有没有办法解决?例如,当我的 VBO 使用交错 (x,y,z,nx,ny,nz,texU,texV) 时,我需要多个着色器才能每次都在同一个地方访问这些属性。然而,我发现编译器给了它们不同的位置,导致该位置成为法线,依此类推。我需要它们的位置与我的 VBO 属性位置一致。

  2. 我刚刚完成了我的第一个 GLSL 渲染,看起来就像我忘记启用深度测试一样,各种多边形相互叠加。我启用了深度测试:

    glEnable(GL_DEPTH_TEST);
    

    问题仍然存在。是否有不同的方法可以使用着色器启用它们?我以为深度缓冲区会解决这个问题?

    问题 2 已解决。原来是一个 SFML 问题,我需要在创建窗口时指定 OpenGL 设置。

4

2 回答 2

2

属性位置指定在 3 个位置之一,从最高优先级到最低优先级:

  1. 通过使用 GLSL 3.30(或更好)或 ARB_explicit_attrib_location 扩展语法layout(location = #),其中#是属性索引。因此,如果我有一个名为 的输入position,我会给它索引 3,如下所示:

    layout(location = 3) in vec4 position;
    

    这是我首选的处理方法。Explicit_attrib_location 可用于几乎所有仍受支持的硬件(不是英特尔)。

  2. 通过 显式关联glBindVertexAttrib。在链接程序之前调用此函数。要做到以上几点,我们会这样做:

    GLuint program = glCreateProgram();
    glAttachShader(program, some_shader);
    glBindVertexAttrib(program, 3, "position");
    glLinkProgram(program);
    

    您可以设置多个属性。实际上,您可以将多个属性名称设置为同一个索引。这样做的想法是能够自动设置一堆映射并让 OpenGL 找出哪个与实际的着色器代码一起使用。因此,您可以将“位置”和“轴”映射到索引 3,只要您不将着色器放入具有这两个输入的系统中,就可以了。

    请注意,您还可以设置不存在的属性。您可以给“正常”一个未在着色器中指定的属性。那很好;链接器只关心实际存在的属性。因此,您可以为此类事情建立一个复杂的约定,并在链接之前运行每个程序:

    void AttribConvention(GLuint prog)
    {
      glBindVertexAttrib(program, 0, "position");
      glBindVertexAttrib(program, 1, "color");
      glBindVertexAttrib(program, 2, "normal");
      glBindVertexAttrib(program, 3, "tangent");
      glBindVertexAttrib(program, 4, "bitangent");
      glBindVertexAttrib(program, 5, "texCoord");
    }
    
    GLuint program = glCreateProgram();
    glAttachShader(program, some_shader);
    AttribConvention(program);
    glLinkProgram(program);
    

    即使一个特定的着色器没有所有这些属性,它仍然可以工作。

  3. 让OpenGL分配它。如果您没有以其他方式之一为属性分配属性索引,则 GLSL 链接器将为您分配它。您可以使用glGetAttribLocation.

    我真的不建议这样做,因为 OpenGL 会任意分配索引。因此,每个使用命名属性的着色器都position可能在不同的索引中具有位置。我不认为这是一个好主意。因此,如果您不能在着色器中显式设置它,那么至少在链接之前在您的 OpenGL 代码中显式设置它。这样,您可以对属性索引 0 的含义、索引 1 的含义等有一个约定。

于 2012-07-29T20:48:23.183 回答
1

在 OpenGL 3.3+ 上,您有 VAO,当您使用它们时,您确实将 VBO 绑定到它,并且您可以按自定义顺序定义属性:http ://www.opengl.org/sdk/docs/man3/xhtml/glEnableVertexAttribArray.xml (记住属性必须是连续的)

可以在 XNA 上找到一个很好/简单的实现:VertexDeclaration,您可能还想查看所有 Vertex* 类型。

关于让 v3 与 SFML 一起工作的一些提示: http ://en.sfml-dev.org/forums/index.php?topic=6314.0

关于如何创建和使用 VAO 的示例:http ://www.opentk.com/files/issues/HelloGL3.cs

(这是 C# 但我想你会明白的)

更新 :

在 v2.1 上,您也拥有它http://www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml,尽管您无法创建 VAO。可以实现几乎相同的功能,但您每次都必须绑定属性,因为它将位于固定管道上。

于 2012-07-29T01:35:53.440 回答