OpenGL如何区分VAO中的绑定点和使用glBindBufferBase定义的绑定点?

时间:2018-06-12 00:13:07

标签: c++ opengl glsl shader

我正在编写一个使用OpenGL> = 4.3的粒子模拟,并遇到了一个问题" (或者说缺少一个),这让我感到困惑 对于计算着色器部分,我使用各种 GL_SHADER_STORAGE_BUFFERs ,它们通过 glBindBufferBase()绑定到绑定点。
其中一个 GL_SHADER_STORAGE_BUFFERs 也用于顶点着色器,以提供渲染所需的法线。 计算和顶点着色器GLSL中的绑定(下面称为着色器1)如下所示:

OpenGL部分:

glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, normals_ssbo);

GLSL部分:

...
layout(std430, binding = 1) buffer normals_ssbo
{
    vec4 normals[];
};
...

有趣的是,在一个单独的着色器程序中,使用不同的顶点着色器(下面称为着色器2),绑定点1(重新)使用如下:
GLSL:

layout(location = 1) in vec4 Normal;

但在这种情况下,法线来自不同的缓冲区对象,并且使用VAO完成绑定,如下所示:
OpenGL的:

glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);

如您所见,绑定点和数据布局(两者都是vec4)是相同的,但实际缓冲区对象不同。

现在问我的问题:
为什么着色器2的VAO是在设置着色器1(使用 glBindBufferBase 进行绑定)之后创建和使用的,接缝覆盖(?)绑定点,但着色器1仍记得SSBO绑定并且在使用之前不再调用 glBindBufferBase 就能正常工作? OpenGL如何知道这两个缓冲区对象中的哪一个应该使用绑定点(在两种情况下都是1)?通过VAO和 glBindBufferBase 创建的绑定点是完全独立的吗?如果是这种情况,为什么会这样工作:

layout(std430, binding = 1) buffer normals_ssbo
{
    vec4 normals[];
};
layout(location = 1) in vec4 Normal;

1 个答案:

答案 0 :(得分:2)

  

通过VAO和glBindBufferBase创建的绑定点是完全独立的吗?

是的,他们是。这就是为什么他们由两个不同的功能设置的原因。

  

如果是这样的话,为什么这样的事情不起作用:

有两种可能性。您在渲染方面错误地实现了它,或者您的驱动程序有错误。如果没有看到您的实际代码,哪些是无法确定的。