I use a buffer to which I pass my C structures
struct Node {
Node(int size, glm::ivec3 position);
bool isEmpty();
int getSubIndex(const glm::ivec3& vec);
void divide(std::vector<Node> &nodes);
void setColor(glm::vec4 color);
int getSubNodeIndex(const glm::ivec3& vec);
int getSubNodeIndex(int subIndex);
glm::ivec4 position;
glm::vec4 color;
int halfSize;
int sub;
int leaf;
};
In the shader it looks like this
struct Node {
vec4 position;
vec4 color;
int data[3];
};
layout(std430, binding=4) readonly buffer Octree_data {
Node nodes[];
};
In the process of calculations, I find out that in all elements of the array (except for the first element) there are incorrect data (most likely displaced) in what could I make a mistake?
CodePudding user response:
The std430
required alignment for your Node
structure is 16-bytes. This is because it contains a 16-byte-aligned type (vec4
and ivec4
). Therefore, every array element in the Node
array will have to start at a 16-byte boundary. So the array stride for nodes
will have to be 48.
The C alignment of your Node
structure is probably 4 bytes. This is because nothing in C 's layout for your Node
structure requires higher alignment. GLM's 4-element vector types are 4-byte aligned (or rather, they're float
aligned, which is almost always 4 bytes). This means that the sizeof(Node)
will be 44 bytes, as will the array stride.
If you want your C struct to match the GLSL required layout, you need to align it properly:
struct Node {
Node(int size, glm::ivec3 position);
bool isEmpty();
int getSubIndex(const glm::ivec3& vec);
void divide(std::vector<Node> &nodes);
void setColor(glm::vec4 color);
int getSubNodeIndex(const glm::ivec3& vec);
int getSubNodeIndex(int subIndex);
alignas(16) glm::ivec4 position;
alignas(16) glm::vec4 color;
int halfSize;
int sub;
int leaf;
};