Opengl 使用uvec3[]的统一缓冲液
我有以下统一缓冲区:Opengl 使用uvec3[]的统一缓冲液,opengl,glsl,Opengl,Glsl,我有以下统一缓冲区: 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,
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
s都包含零
为什么会发生这种情况?如何正确初始化这样一个统一的缓冲区?
(C/C++,glew,glfw)A
uvec3
具有16个字节的对齐方式,因此必须添加填充。请参见OpenGL 4.5规范第7.6.22节:
如果成员为三分量向量,且分量消耗N个基本机器单元,则基本对齐为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,
};
这是您不应该在统一/存储块中使用任何类型的vec3的一个原因。这样写是否有效(似乎有效):
\define EDGE\u ID\u to\u DIRECTION\u SIZE(12*3)const GLuvec3 edgeIdToDirection\u constBuffer[12]={/*0*/GLuvec3{0,1,0},/*1*/GLuvec3{1,0,0}代码>与结构GLuvec3{GLuint x,y,z;}
@nicolabolas:我不相信vec3
是错误的,只要你知道填充。。。如果您使用vec4
,您可能会想知道第四个组件应该用于什么,然后您必须记住它实际上只是一个vec3
@maja:上次我检查时,没有GLuvec3
这样的类型。@DietrichEpp我自己创建了一个包含3个GLuint值的结构,这明显导致了相同的填充。