我的顶点着色器是,
uniform Block1{ vec4 offset_x1; vec4 offset_x2;}block1;
out float value;
in vec4 position;
void main()
{
value = block1.offset_x1.x + block1.offset_x2.x;
gl_Position = position;
}
我用来传递值的代码是:
GLfloat color_values[8];// contains valid values
glGenBuffers(1,&buffer_object);
glBindBuffer(GL_UNIFORM_BUFFER,buffer_object);
glBufferData(GL_UNIFORM_BUFFER,sizeof(color_values),color_values,GL_STATIC_DRAW);
glUniformBlockBinding(psId,blockIndex,0);
glBindBufferRange(GL_UNIFORM_BUFFER,0,buffer_object,0,16);
glBindBufferRange(GL_UNIFORM_BUFFER,0,buffer_object,16,16);
我期待的是,为每个vec4制服传递16个字节。我得到偏移= 16,大小= 16的GL_INVALID_VALUE错误。 我对偏移值感到困惑。 Spec说它对应于“buffer_object”。
答案 0 :(得分:8)
绑定时,UBO有alignment restriction个。任何glBindBufferRange/Base
的偏移量必须是GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
的倍数。这种对齐可以是任何东西,所以你必须在构建统一缓冲区数组之前查询它。这意味着您不能直接在编译时C ++逻辑中执行此操作;它必须是运行时逻辑。
说到在运行时查询事物,你的代码在很多其他方面都被严重破坏了。您没有为统一块定义布局限定符;因此,使用默认值:shared
。并且你不能使用`共享*布局而没有querying the layout of each block's members from OpenGL. Ever 。
如果你已经完成了一个查询,你很快就会发现你的统一块的大小至少是 32字节,而不是16.并且因为你只在你的范围内提供了16个字节,所以未定义的行为(包括程序终止的可能性)结果。
如果您希望能够定义完全映射到统一块定义的C / C ++对象,则需要使用std140
布局并遵循C中std140
布局的规则/ C ++对象。