glBindBufferRange()问题OpenGL 3.1

mav*_*888 5 opengl glsl opengl-3

我的顶点着色器是,

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;
}
Run Code Online (Sandbox Code Playgroud)

我用来传递值的代码是:

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);
Run Code Online (Sandbox Code Playgroud)

我期待的是,为每个vec4制服传递16个字节.对于offset = 16,size = 16,我得到GL_INVALID_VALUE错误.我对偏移值感到困惑.Spec说它对应于"buffer_object".

Nic*_*las 8

绑定时,UBO 有一个对齐限制.任何glBindBufferRange/Base偏移都必须是倍数GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT.这种对齐可以是任何东西,因此您必须在构建统一缓冲区数组之前查询它.这意味着您不能直接在编译时C++逻辑中执行此操作; 它必须是运行时逻辑.

说到在运行时查询事物,您的代码在很多其他方面都被严重破坏.您没有为统一块定义布局限定符; 因此,使用默认值:shared.而且,如果从OpenGL 查询每个块成员的布局, 就不能使用`shared*layout .曾经.

如果你已经完成了一个查询,你会很快发现你的统一块大小至少是32个字节,而不是16个.由于你只在你的范围内提供了16个字节,所以未定义的行为(包括程序终止的可能性)结果.

如果您希望能够定义完全映射到统一块定义的C/C++对象,则需要使用std140布局并遵循std140C/C++对象中的布局规则.