1
votes

I'm trying to setup uniform blocks and got very confused about glUniformBlockBinding() and glBindBufferRange() The thing is that I'm trying to share single UBO buffer to multiple separable programs at once. think: glBindProgramPipeline() with glUniformBlockBinding(). I'm using OpenGL 4.5 Core profile features.

As an example have three shader stages, one vertex and two fragment for post processing:

//Vertex shader A:
#version 450 core
layout(std140) uniform Camera {
    mat4 Projection;
    mat4 Modelview;
};
const vec2 TexCoords[] = {
    { 0.f, 0.f },
    { 1.f, 0.f },
    { 1.f, 1.f },
    { 0.f, 1.f }};
out VertexData {
    smooth vec2 TexCoord;
} vs;
void main() {
    float xw = 400.0, yh = 300.0;
    vec2 vertices[] = {
        { -xw, -yh },
        { xw, -yh },
        { xw, yh },
        { -xw, yh }};
    vec4 vpos = vec4(vertices[gl_VertexID % 4], 0.0, 1.0);
    gl_Position = Projection * Modelview * vpos;
    vs.TexCoord = TexCoords[gl_VertexID % 4];
}

// Post processing Fragment shader skeleton:
#version 450 core
in VertexData {
    smooth vec2 TexCoord;
} fs;
layout(location=0) out vec4 FragData[2];
uniform sampler2D Texture[2];
layout(std140) uniform Effect {
    int FragIndex;
    int MaxWeights;
    float Weights[64];
    vec2 BlurXY;
};
void main() {
    FragData[FragIndex] = texture(Texture[1 - FragIndex], fs.TexCoord);
}

How do I setup above uniform blocks using only single UBO buffer?

1

1 Answers

3
votes

You can't. Or at least, not in the way that you mean.

You can in fact put all of the uniform data for these three shaders in the same buffer object. You have to make sure that the alignment for the start of each block's data matches the implementation-defined alignment requirements specified for UBOs (queried through GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT), but beyond that, you're fine.

However, there's no way to avoid calling glBindBufferRange between each shader's usage. Even if you set the block binding index for all of the blocks to the same index. Even if you're binding the same buffer each time. The reason being that you have to select a different range from the buffer, since the blocks are all different and are storing different data.