GLSL-GLSL 1.2中的统一位置和着色器中的深度测试
GLSL - Uniform locations in GLSL 1.2 and depth testing in shaders
两个问题:
-
我正在使用不同的着色器渲染大型VBO中的元素。如果我是正确的,我必须使用GLSL 1.2,因为它是OSX上最新的版本,不支持统一的位置,我认为这意味着属性的位置是编译器决定的。有办法解决这个问题吗?例如,当我的VBO使用交错(x,y,z,nx,ny,nz,texU,texV)时,我需要多个着色器才能每次在同一位置访问这些属性。然而,我发现编译器给了它们不同的位置,导致位置成为法线,等等。我需要它们的位置与我的VBO属性位置一致。
-
我刚刚完成了我的第一个GLSL渲染,看起来就像我忘记了启用深度测试,在一个又一个的上面渲染各种多边形。我启用了深度测试:
glEnable(GL_DEPTH_TEST);
问题依然存在。是否有其他方法可以使用着色器启用它们?我以为深度缓冲区解决了这个问题?
问题2已解决。结果是一个SFML问题,我需要在创建窗口时指定OpenGL设置。
属性位置按优先级从高到低的顺序指定在三个位置之一:
-
通过使用GLSL 3.30(或更好)或ARB_explicit_attrib_location扩展语法
layout(location = #)
,其中#
是属性索引。因此,如果我有一个名为position
的输入,我会给它索引3,如下所示:layout(location = 3) in vec4 position;
这是我处理这个问题的首选方法。Explicit_attrib_location在几乎所有仍受支持的硬件上都可用(不是Intel)。
-
通过
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);
即使某个特定着色器没有所有这些属性,它仍然可以工作。
-
让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。可以实现几乎相同的功能,但每次都必须绑定属性,因为它将在固定管道上。
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- OpenGL在启用深度测试时不会丢弃我的碎片
- Opengl 3.1 GLSL 140 在 C++ 年输出白色在片段着色器中
- 在不使用统一的情况下将纹理传递给 GLSL 着色器?
- 在细胞中产生噪声 - CPP 和 GLSL
- 这个SSDO演示的GLSL版本要求是自我冲突的吗
- 在 Ubuntu 18.04 上编译 GLSL 着色器时"不支持 GLSL 3.30"?
- 使用自定义深度测试的深度打击解决方案
- 深度测试根本不起作用
- OpenGL 深度测试不起作用
- 深度检查OpenGL(GLSL)
- GLSL-GLSL 1.2中的统一位置和着色器中的深度测试
- C++ 和 directx11 深度测试 不适用于少数对象场景
- 启用深度测试时出现 GL 错误 1280
- 使用深度纹理OpenGL/GLSL的深度遮挡(3.3/330)
- 将OpenGL深度测试应用于轨道球体
- 在OpenGL中,我如何在两个深度缓冲区之间进行深度测试
- 在OpenGL中启用深度测试后,我的整个屏幕是空白的(恢复为清晰的颜色)-为什么
- GLSL玻璃效果加上深度剥落
- 无法在 QWIndow (Qt5) 中使用 OpenGL 启用深度测试