I defined these two structs in glsl:
struct Triangle{
vec3[3] vertices;
vec3 norm;
vec3 color;
mat4 model;
};
struct Sphere{
vec3 centre;
float radius;
vec3 color;
mat4 model;
};
correspondingly,I defined these two structs in client like this:
struct Triangle {
glm::vec3 vertices[3];
glm::vec3 norm;
glm::vec3 color;
glm::mat4 model;
};
struct Sphere {
glm::vec3 centre;
float radius;
glm::vec3 color;
glm::mat4 model;
};
Now, I want to pass my data to glsl through buffer object:
layout(binding = 0, std430) buffer Triangles{
Triangle[] triangles;
};
layout(binding = 1,std430) buffer Spheres{
Sphere[] spheres;
};
but I don't know clearly how to do it with regard to alignment. I calculate the space and paddding in this way:
- for Triangle, the members of it can be splitted like this:
struct Triangle{
vec3[3] vertices; // because it's an array, so vec3 will not be rounded up to vec4, so it is 3 * 4 = 12 bytes,starts at 0
vec3 norm; //4 * 4 = 16,starts at 12*3=36. (4*4 not 3*4 because norm is not a member of an array)
vec3 color; // 4 * 4 = 16, starts at 36+16=52
vec4[4] mat; // 4 * 4 = 16,starts at 52+16=68
};// whole size is 68+64 = 132, ignoring end padding.
the max size member's size is 16, so each triangle in an array should start at 16x position, and a 16x9 - 132 = 12 bytes will be added to the end of each of them. And for Sphere, it is similar. After mapping the buffer's address to pointer p (Triangle*), I can pass my data to glsl through this way:
for(int i=0;i<triangle_count;i++){
memcpy(p,triangles + i,144);//triangles[n]
p++;
}
C/C++ has layout rules for members of a struct, but as Pods for glm::vec3, glm::mat4 are both float, so there will be no padding between members in Triangle storage, so that why I can copy a whole triangle to p instead of doing it member by member. I don'w know whether my analysis is correct. I just share my understanding here and hope some one can point out my errors and other readers can gain something from my analysis.