OpenGL - 调用索引= 1的glBindBufferBase中断渲染(Pitch black)

时间:2014-02-01 13:04:57

标签: opengl buffer fragment-shader

我的着色器中有一系列统一块,其定义如下:

layout (std140) uniform LightSourceBlock
{
    int shadowMapID;
    int type;
    vec3 position;
    vec4 color;

    float dist;

    vec3 direction;
    float cutoffOuter;
    float cutoffInner;
    float attenuation;
} LightSources[12];

为了能够将我的缓冲区对象绑定到每个LightSource,我将每个制服绑定到一个统一的块索引:

for(unsigned int i=0;i<12;i++)
    glUniformBlockBinding(program,locLightSourceBlock[i],i); // locLightSourceBlock contains the locations of each element in LightSources[]

渲染时,我使用以下命令将缓冲区绑定到相应的索引:

glBindBufferBase(GL_UNIFORM_BUFFER,i,buffer);

这个工作正常,只要我只将一个缓冲区绑定到绑定索引0.只要有更多,一切都是黑色(即使使用完全不同的着色器的东西)。 (glGetError返回没有错误)

如果我将块索引范围从0-11更改为2-13(跳过索引1),则一切正常。我想如果我使用索引1,我会覆盖一些东西,但我的着色器中没有任何其他统一块,而且我在代码中的任何其他地方都没有使用glUniformBlockBinding或glBindBufferBase,所以我不确定。

可能导致此类行为的原因是什么?索引1是为某些东西保留的吗?

1 个答案:

答案 0 :(得分:0)

1)不要使用多个块。使用一个数组块。像这样:

struct Light{
  ...
}
layout(std430, binding=0) uniform lightBuffer{
 Light lights[42];
}

跳过glUniformBlockBinding并且只将glBindBufferBase转换为着色器中指定的索引

2)阅读std140,std430的对齐。简而言之,缓冲变量是对齐的,因此它们不会跨越128位边界。所以在你的情况下,位置将从字节16(而不是8)开始。这导致CPU / GPU侧访问不匹配。 (重新排序变量或添加填充)