c++ - OpenGL/GLSL - 统一 block 数据值不正确

标签 c++ opengl glsl shader

我的着色器有一个统一的 block :

layout (std140) uniform LightSourceBlock
{
    vec3 test;
    vec3 color;
} LightSources;

这个 block 的数据应该来自一个像这样创建的缓冲区对象:

GLuint buffer;
glGenBuffers(1,&buffer);

GLfloat data[6] = {
    0,0,0,
    0,0,1
};
glBindBuffer(GL_UNIFORM_BUFFER,buffer);
glBufferData(GL_UNIFORM_BUFFER,sizeof(data),&data[0],GL_DYNAMIC_DRAW);

缓冲区在渲染前链接到统一 block :

unsigned int locLightSourceBlock = glGetUniformBlockIndex(program,"LightSourceBlock");
glUniformBlockBinding(program,locLightSourceBlock,8);
glBindBufferBase(GL_UNIFORM_BUFFER,8,buffer);

根据我的理解,这应该是将着色器中 block 内的“颜色”设置为 (0,0,1),但我得到的值是 (0,1,0)。

如果我从 block 中删除“测试”变量并且只将三个 float (0,0,1) 绑定(bind)到着色器,它会按预期工作。

这是怎么回事?

最佳答案

因为您确实为您的 UBO 指定了 layout (std140),所以您必须遵守此处定义的对齐规则。该布局首先在 OpenGL 3.2 core spec 中指定(在核心中) ,“标准统一 block 布局”小节中的第 2.11.4 节“统一变量”:

  1. If the member is a scalar consuming N basic machine units, the base alignment is N.
  2. If the member is a two- or four-component vector with components consuming N basic machine units, the base alignment is 2N or 4N, respectively.
  3. If the member is a three-component vector with components consuming N basic machine units, the base alignment is 4N.
  4. If the member is an array of scalars or vectors, the base alignment and array stride are set to match the base alignment of a single array element, according to rules (1), (2), and (3), and rounded up to the base alignment of a vec4. The array may have padding at the end; the base offset of the member following the array is rounded up to the next multiple of the base alignment.
  5. If the member is a column-major matrix with C columns and R rows, the matrix is stored identically to an array of C column vectors with R components each, according to rule (4).
  6. If the member is an array of S column-major matrices with C columns and R rows, the matrix is stored identically to a row of S C column vectors with R components each, according to rule (4).
  7. If the member is a row-major matrix with C columns and R rows, the matrix is stored identically to an array of R row vectors with C components each, according to rule (4).
  8. If the member is an array of S row-major matrices with C columns and R rows, the matrix is stored identically to a row of S R row vectors with C components each, according to rule (4).
  9. If the member is a structure, the base alignment of the structure is N, where N is the largest base alignment value of any of its members, and rounded up to the base alignment of a vec4. The individual members of this substructure are then assigned offsets by applying this set of rules recursively, where the base offset of the first member of the sub-structure is equal to the aligned offset of the structure. The structure may have padding at the end; the base offset of the member following the sub-structure is rounded up to the next multiple of the base alignment of the structure.
  10. If the member is an array of S structures, the S elements of the array are laid out in order, according to rule (9).

对于您的情况,第 3 点适用。因此,您需要在第二个 vector 开始之前填充另一个 float 。

关于c++ - OpenGL/GLSL - 统一 block 数据值不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20807797/

相关文章:

c++ - 使用统一初始化语法从函数返回元组

c++ - 在保留类名的同时弃用类模板的正确程序是什么?

c++ - 关于内存地址的问题

c++ - 我会因单例过度而感到过度杀伤力吗?

c++ - OpenGL 在绘制一个网格时绑定(bind)多个纹理

opengl - 在 OpenGL 中设置统一

c++ - 字符串文字不能有外部链接是否有原因?

c++ - 是否可以在不退出 OpenGL 矩阵的情况下使用 glColor3f 更改颜色?

c++ - OpenGL 纹理坐标无效

c++ - OpenGL 着色器 : uniform variables count incorrect