I am following an OpenGL tutorial, and in it, what is being done to pass the mesh data to the video card is basically the following:
#include <GL/glew.h>
#include <glm/glm.hpp>
struct Vertex {
...
private:
glm::vec3 pos;
glm::vec2 texCoord;
glm::vec3 normal;
};
Mesh::Mesh(Vertex * vertices, unsigned int numVertices) {
...
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(vertices[0]), vertices, GL_STATIC_DRAW);
...
}
However, I feel this could cause problems because of the assumption that the vertices will be laid out perfectly. Or is it guaranteed that the Vertex fields will be placed without padding and in that order? Also, I don't know what the layouts or sizes of the glm::vec* types are.
Am I right to suspect that this could cause problems?
What should be done instead?
What can affect the layout of a struct?
There is nothing wrong with this approach, provided you specify the correct attribute pointers, e.g:
glVertexAttribPointer( ..., 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, pos));
glVertexAttribPointer( ..., 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, texCoord));
glVertexAttribPointer( ..., 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, normal));
both sizeof
and offsetof
will take into account any padding which might occur.
If you want more control about the actual layout, you can also of course work with #pragma pack
, which isn't part of any C/C++ standard but understood by all major compilers. In practice, no real-world compiler on a platform where an OpenGL implementation exists will add any padding for your original struct layout, so it is probably a moot point.
Also, I don't know what the layouts or sizes of the
glm::vec*
types are.
The GLM vectors and matrices are tightly packed arrays of the respective base type, in particular float[N]
for glm::vecN
.