使用 uvec3[] 的统一缓冲区
Use uniform buffer of uvec3[]
我有以下统一缓冲区:
uniform EDGE_ID_TO_START_POS{
uint[12*3] pos;
} edgeIdToStartPos;
写入此缓冲区工作正常:
#define EDGE_ID_TO_START_POS_SIZE (12*3)
const uint32_t edgeIdToStartPos_constBuffer[EDGE_ID_TO_START_POS_SIZE] = {
/* 0*/ 0, 0, 0, /* 1*/ 0, 1, 0, /* 2*/ 1, 0, 0, /* 3*/ 0, 0, 0,
/* 4*/ 0, 0, 1, /* 5*/ 0, 1, 1, /* 6*/ 1, 0, 1, /* 7*/ 0, 0, 1,
/* 8*/ 0, 0, 0, /* 9*/ 0, 1, 0, /*10*/ 1, 1, 0, /*11*/ 1, 0, 0
};
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, EDGE_ID_TO_START_POS_SIZE * sizeof(uint32_t), edgeIdToStartPos_constBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
现在我想将统一缓冲区更改为以下结构:
uniform EDGE_ID_TO_START_POS{
uvec3[12] pos;
} edgeIdToStartPos;
这种结构更有意义,也更容易使用。并且它应该具有与以前版本相同的内存布局(?)。
但是,从该结构读取时,只有向量 0..3 包含数据。所有索引为 4 或更高的 uvec
都包含零。
为什么会发生这种情况,如何正确初始化这样一个统一缓冲区?
(C/C++, glew, glfw)
一个uvec3
有一个16字节的对齐,所以你必须添加填充。请参阅 OpenGL 4.5 规范,第 7.6.22 节:
If the member is a three-component vector with components consuming N basic machine units, the base alignment is 4N.
这是它的样子:
static const int EDGE_ID_TO_START_POS_SIZE = 12 * 4;
const uint32_t edgeIdToStartPos_constBuffer[EDGE_ID_TO_START_POS_SIZE] = {
/* 0*/ 0, 0, 0, 0, /* 1*/ 0, 1, 0, 0, /* 2*/ 1, 0, 0, 0, /* 3*/ 0, 0, 0, 0,
/* 4*/ 0, 0, 1, 0, /* 5*/ 0, 1, 1, 0, /* 6*/ 1, 0, 1, 0, /* 7*/ 0, 0, 1, 0,
/* 8*/ 0, 0, 0, 0, /* 9*/ 0, 1, 0, 0, /*10*/ 1, 1, 0, 0, /*11*/ 1, 0, 0, 0,
};
我有以下统一缓冲区:
uniform EDGE_ID_TO_START_POS{
uint[12*3] pos;
} edgeIdToStartPos;
写入此缓冲区工作正常:
#define EDGE_ID_TO_START_POS_SIZE (12*3)
const uint32_t edgeIdToStartPos_constBuffer[EDGE_ID_TO_START_POS_SIZE] = {
/* 0*/ 0, 0, 0, /* 1*/ 0, 1, 0, /* 2*/ 1, 0, 0, /* 3*/ 0, 0, 0,
/* 4*/ 0, 0, 1, /* 5*/ 0, 1, 1, /* 6*/ 1, 0, 1, /* 7*/ 0, 0, 1,
/* 8*/ 0, 0, 0, /* 9*/ 0, 1, 0, /*10*/ 1, 1, 0, /*11*/ 1, 0, 0
};
glBindBuffer(GL_UNIFORM_BUFFER, ubo);
glBufferData(GL_UNIFORM_BUFFER, EDGE_ID_TO_START_POS_SIZE * sizeof(uint32_t), edgeIdToStartPos_constBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
现在我想将统一缓冲区更改为以下结构:
uniform EDGE_ID_TO_START_POS{
uvec3[12] pos;
} edgeIdToStartPos;
这种结构更有意义,也更容易使用。并且它应该具有与以前版本相同的内存布局(?)。
但是,从该结构读取时,只有向量 0..3 包含数据。所有索引为 4 或更高的 uvec
都包含零。
为什么会发生这种情况,如何正确初始化这样一个统一缓冲区? (C/C++, glew, glfw)
一个uvec3
有一个16字节的对齐,所以你必须添加填充。请参阅 OpenGL 4.5 规范,第 7.6.22 节:
If the member is a three-component vector with components consuming N basic machine units, the base alignment is 4N.
这是它的样子:
static const int EDGE_ID_TO_START_POS_SIZE = 12 * 4;
const uint32_t edgeIdToStartPos_constBuffer[EDGE_ID_TO_START_POS_SIZE] = {
/* 0*/ 0, 0, 0, 0, /* 1*/ 0, 1, 0, 0, /* 2*/ 1, 0, 0, 0, /* 3*/ 0, 0, 0, 0,
/* 4*/ 0, 0, 1, 0, /* 5*/ 0, 1, 1, 0, /* 6*/ 1, 0, 1, 0, /* 7*/ 0, 0, 1, 0,
/* 8*/ 0, 0, 0, 0, /* 9*/ 0, 1, 0, 0, /*10*/ 1, 1, 0, 0, /*11*/ 1, 0, 0, 0,
};