I believe Uniform Buffers/Blocks has been the hardest thing to grasp in OpenGL. Hopefully this will be my final issue regarding this.

I have created a uniform buffer that contain data of Light objects. Where Light is a structure containing ambient, diffuse, etc. When I have added all my lights with glBufferSubData then I can either call glBindBufferBase to bind the entire buffer to a binding-point, or glBindBufferRangeto bind different Lights to different binding-points.

I can get the latter one to work. For example, If I have added 3 lights, in my program I can do like this to point the uniform-block-array to correct offset in the buffer.

// First parameter: binding-point, second: uniform block name
program->UniformBlockBinding(1, "UBLight[0]");
program->UniformBlockBinding(2, "UBLight[1]");
program->UniformBlockBinding(3, "UBLight[2]");

// Fragment shader code
layout(std140) uniform UBLight
    vec3 PositionOrDirection;
    vec3 Diffuse;
    vec3 Specular;
    int Type;
} lights[3];

But what I want to do is just to map the entire uniform buffer to one binding-point, and still be able to use these 3 lights in the shader, that is lights[3]. I've tried to do like this without success:

glBindBufferBase(GL_UNIFORM_BUFFER, 1, id);

program->UniformBlockBinding(1, "UBLight");

It works for the first light, but if I try to use the 2nd or the 3rd light in the shader my model gets black.

Is it possible to solve this in some way, or do I have to bind each Light to a different binding point?


Code showing UniformBlockBinding:

void Program::UniformBlockBinding(GLuint uniformBlockBinding, GLchar *name)
    GLuint index = glGetUniformBlockIndex(program, name);

    if (index != GL_INVALID_INDEX)
        glUniformBlockBinding(program, index, uniformBlockBinding);
        printf("Error: the uniform block \"%s\" doesn't exist in program\n", name);
  • \$\begingroup\$ Can you show the code behind program->UniformBlockBinding()? I would expect the second way to work (map your CPU-side array of light data to a single uniform "UBLight"). Not sure how "UBLight[1]" gets parsed? \$\endgroup\$ – david van brink Jan 7 '15 at 5:41
  • \$\begingroup\$ Yes, check update #1 above. The second way works, it is the first way I don't get to work. That is, only use one binding-point, but still use an array in the shader. \$\endgroup\$ – Unresolved External Jan 7 '15 at 11:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.