使用uvec3 []的统一缓冲区

时间:2016-03-21 18:46:47

标签: 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, 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)

1 个答案:

答案 0 :(得分:4)

uvec3的对齐方式为16个字节,因此您必须添加填充。请参阅OpenGL 4.5规范,第7.6.22节:

  

如果该成员是一个三分量向量,其组件消耗 N 基本机器单位,则基本对齐为4

以下是它的外观:

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,
};