GLSL-GLSL 1.2中的统一位置和着色器中的深度测试

GLSL - Uniform locations in GLSL 1.2 and depth testing in shaders

本文关键字:深度测试 GLSL-GLSL 位置      更新时间:2023-10-16

两个问题:

  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设置。

属性位置按优先级从高到低的顺序指定在三个位置之一:

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

    layout(location = 3) in vec4 position;
    

    这是我处理这个问题的首选方法。Explicit_attrib_location在几乎所有仍受支持的硬件上都可用(不是Intel)。

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

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

    可以设置多个属性。实际上,您可以将多个属性名称设置为同一索引。这样做的目的是能够自动设置一组映射,并让OpenGL确定哪一个映射适用于实际的着色器代码。所以你可以将"位置"answers"轴"映射到索引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获取属性post链接。

    我真的不建议这样做,因为OpenGL会任意地分配索引。因此,每个使用名为position的属性的着色器都可能在不同的索引中具有该位置。我认为这不是个好主意。因此,如果不能在着色器中明确设置它,那么在链接之前,至少要在OpenGL代码中明确设置。这样,您就可以有一个关于属性索引0的含义、索引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。可以实现几乎相同的功能,但每次都必须绑定属性,因为它将在固定管道上。