1
$\begingroup$

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?

$\endgroup$
  • 2
    $\begingroup$ Can you show your shader code—how are you declaring and using the SSBOs in the shader? $\endgroup$ – Nathan Reed Nov 2 '17 at 5:47
3
$\begingroup$

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.

$\endgroup$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.