1

enter image description here

Problem

There should not be gaps between those white lines. Those lines are composed of squares (eventually I won't be generating just another giant square; this is for debugging). For some reason when I send data through my Uniform Buffer Object (example below), I am getting gaps. It's almost as if it's skipping every other y value. There are actually two squares on each location instead of there being one at (y) and one at (y + 1).

Code Snippets

Generating data pointer array

blockData = new glm::vec2[24*24];
for (int x = 0; x < 24; x++) {
    for (int y = 0; y < 24; y++) {
        int i = x * 24 + y;
        blockData[i] = glm::vec2(x, y);
    }
}

In the rendering class

glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(glm::vec2) * blocksActive, blockData);
glBindBufferRange(GL_UNIFORM_BUFFER, uniBlockData, ubo, 0, sizeof(glm::vec2) * blocksActive);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

glBindVertexArray(vao);
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0, blocksActive);
glBindVertexArray(0);

Vertex Shader (GLSL)

layout (std140) uniform blockData {
    vec2 blockDataPosition[5184];
};

Testing

  • When I change blockData[i] = glm::vec2(x, y); to blockData[i] = glm::vec2(y, x); (switching y and x), the gaps move to the x-axis.
  • I have tried switching the x and the y in the for loop, but it does not affect it. This issue is somehow linked to the y variable.
  • What does affect it is if I switch the x and y around in int i = x * 24 + y;
  • Setting the vec2 to (x, x) results in a correctly placed diagonal.
  • Setting the vec2 to (y, y) results in an oddly placed diagonal (below)
  • Before switching to a UBO, I was just using a uniform in the shader and it worked fine. That is why I believe it has something to do with my sending of data through the UBO. enter image description here
2
  • Can you actually include the relevant part of the GLSL shader? Sounds a bit like an alignment issue in your UBO. Commented Nov 12, 2014 at 9:26
  • Thank you for the suggestion, I forgot to include it. I understand that with std140, a vec3 takes the same amount of space as a vec4, but I am using a vec2 so I'm not sure what could be going on. Commented Nov 12, 2014 at 21:00

1 Answer 1

4

Well so what is happening is most likely an alignment issue. Using std140, you must align for 4 floats. However, without seeing all of your code, its not going to be possible for me to be completely certain how you are buffering your data. What I can suggest, however, is to query your block offsets using glGetActiveUniformsiv, and then align your objects based on that. So a typical example would be this :

    char* bufferNames[] = [generate the values with a for loop, this should be pretty easy with string and sprintf e.g "blockData.blockDataPosition[0]" to "block.Data.blockDataPosition[5184]"];

    GLuint uniformBlockIndex = glGetUniformBlockIndex(yourprogram, "block name");

    GLuint uniformIndices[number of names in bufferNames];

    glGetUniformIndices(yourprogram, the number of names in bufferNames, bufferNames, indices);

    GLint uniformOffsets[the number of names in bufferNames];

    glGetActiveUniformsiv(yourprogram, 1, &uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets);

The offsets will tell you everything you need to know. They are the number of offset in bytes for every name. And you can use a for loop to fill each offset, or just print it out to see how everything is aligned. This should not be done in a loop, but once for initialization and such. Tell me if you have any questions or you need a more specific example.

Sign up to request clarification or add additional context in comments.

3 Comments

Is this different than variable alignment (i.e. vec2 requires 2 floats of padding, vec3 and vec4 require 4)?
@badcc No, it does not do anything to the alignment itself, that is designated by the std140, packed or shared. However, this does allow you to see how everything is aligned in a block, and you can fill your buffer based on that, or simply read it to see if the layout you requested is what you are getting. This is one of the ways to use faster layout specifications like packed, and still guarantee proper behavior across different vendors. For your case, this is more for debugging, and to see whether the uniform layout you requested is being properly presented.
I have determined that my buffer (with 4 elements; so vec4 * 4; but I'm only using the x and the y. The vec4 is for padding.) is size 64. The data I am sending in (sizeof(glm::vec2) * 4) is 32. I just changed the vec2 in my shader to a vec4. What else do I need to change in order to get this to work? EDIT: Instead of sending in a vec2 through C++, I changed it to send a vec4. Now it works! Thank you for the help :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.