3

I am trying to send rendering information for an instancing rendering using shader buffer objects. My current problem is that I have 2 shader buffer objects, one which works just fine, and another that is not quite working.

The idea is to render squared faces at different positions in the screen. For this, I create a vector of glm::vec3 that represent the position of each face, put all of them in an std::vector and use them as the data for the Shader buffer object.

In other words I am creating the data as follows:

face_positions.push_back(vec3(0,0,0));
visible_faces.push_back(Left);

face_positions.push_back(vec3(0,-10,0));
visible_faces.push_back(Front);

face_positions.push_back(vec3(0,0,0));
visible_faces.push_back(Back);

Then updating the buffers as follows:

glBindBuffer(GL_SHADER_STORAGE_BUFFER, cube_rendering_VBOs[3]);
glBufferData(GL_SHADER_STORAGE_BUFFER, visible_faces.size()*sizeof(Face), visible_faces.data(), GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, cube_rendering_VBOs[3]);

glBindBuffer(GL_SHADER_STORAGE_BUFFER, cube_rendering_VBOs[4]);
glBufferData(GL_SHADER_STORAGE_BUFFER, face_positions.size()*sizeof(vec3), face_positions.data(), GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, cube_rendering_VBOs[4]);

And finally rendering by doing:

glDrawElementsInstanced(GL_TRIANGLES, MESH->indices->size(), GL_UNSIGNED_INT, (void*)0, visible_faces.size());

Obviously there is more code associated with passing the actual mesh geometry used for the instanced rendering and enabling the correct layouts in the vertex shader, but I cannot put my enire code base here and I have more throuroughly tested those, so I beleive the mistake is in how I am passing or reading the shader buffer objects.

The behaviour is, if you look at the lines:

face_positions.push_back(vec3(0,0,0));
visible_faces.push_back(Left);

face_positions.push_back(vec3(0,-10,0));
visible_faces.push_back(Front);

face_positions.push_back(vec3(0,0,0));
visible_faces.push_back(Back);

The face_positions() should be the poisitions of the faces.

However what I have noticed is, the first 3 floats (i.e face_positions[0]) work just as expected. Then one value is skipped (i.e face_positions[1].x) and the next values read are the next 3 (i.e face_positions[1].y face_positions[1].z face_positions[2].x) then once again one value is skipped, and it starts reading the next value (i.e face_positions[2].z).

So it seems somewhere something is padding the array with 0's to make everything 4 bytes aligned.

Does anyone have any idea of where to start looking?

Makogan
  • 1,706
  • 12
  • 28

1 Answers1

7

Does anyone ahve[sic] any idea of where to start looking

You fell victim to one of the classic blunders. Never use a vec3 in a UBO or SSBO.

While vec3s take up 12 bytes, they always have the alignment requirements of a vec4. Yes, even under std430 layout, they always have vec4 alignment. So if you have an array of vec3s in a U/SSBO, what you really have is an array of vec4s where one of the elements doesn't get used.

Nicol Bolas
  • 9,762
  • 18
  • 25