I was browsing this page on how to use Uniform Buffer Objects in openGL and saw the following struct:
struct shader_data_t
{
float camera_position[4];
float light_position[4];
float light_diffuse[4];
} shader_data;
being buffered into an openGL Uniform Buffer Object using
GLuint ubo = 0;
glGenBuffers(1, &ubo);
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, sizeof(shader_data), &shader_data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
and being used in the shader as
...
layout (std140) uniform shader_data
{
vec4 camera_position;
vec4 light_position;
vec4 light_diffuse;
};
...
However, I don't understand how openGl knows how to map the data in the struct to the uniforms when glBufferData converts the struct pointer and a void pointer, which should make openGL unaware of the memory layout of the struct. c++ struct layout is implementation defined, and while the author and other users of UBOs manually pad their c++ structures with dummy variables to match the standardized std140 layout in the shader, what prevents the c++ compiler from adding more padding and breaking the layout? is there a strong guarantee in the c++ standard that more padding will not be inserted or is this a "practically portable" deal?