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值的结构,这明显导致了相同的填充。