Issue with glBindBufferRange() OpenGL 3.1

Issue with glBindBufferRange() OpenGL 3.1

My vertex shader is ,

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

The code I am using to pass values is :

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);

Here what I am expecting is, to pass 16 bytes for each vec4 uniform. I get GL_INVALID_VALUE error for offset=16 , size = 16. I am confused with offset value. Spec says it is corresponding to "buffer_object".

 

1 Answer

There is an alignment restriction for UBOs when binding. Any glBindBufferRange/Base's offset must be a multiple of GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. This alignment could be anything, so you have to query it before building your array of uniform buffers. That means you can't do it directly in compile-time C++ logic; it has to be runtime logic.

Speaking of querying things at runtime, your code is horribly broken in many other ways. You did not define a layout qualifier for your uniform block; therefore, the default is used: shared. And you cannot use `shared* layout without querying the layout of each block's members from OpenGL. Ever.

If you had done a query, you would have quickly discovered that your uniform block is at least 32 bytes in size, not 16. And since you only provided 16 bytes in your range, undefined behavior (which includes the possibility of program termination) results.

If you want to be able to define C/C++ objects that map exactly to the uniform block definition, you need to use std140 layout and follow the rules of std140's layout in your C/C++ object.

Nicol Bolas

378k5353 gold badges633633 silver badges829829 bronze badges

  • Thanks a lot for the answer ! I wasn't aware about GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. I had already queried my Uniform Block for its size (32 bytes), but I thought by specifying 16 bytes I could supply data for the second "vec4" component of Uniform Block, which I presume is wrong. I think I should treat the second "vec4" component as an individual uniform. Just to add information , if layout is not std140 then offset has to be a multiple of GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT. Consequently the bound buffer also has to be a multiple of GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT in size . – maverick9888 Oct 25 '12 at 10:17

  • Cont. - Consequently the bound buffer also has to be a multiple of GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT in size provided we are using a single buffer object to supply data to multiple uniform blocks. – maverick9888 Oct 25 '12 at 10:20

  • "if layout is not std140 then offset has to be a multiple of GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT." No; the offset always must be a multiple of that. std140 layout just means you don't have to query the buffer's size or the offset of any individual uniforms, because you can compute them directly. The buffer can be whatever size you want, but when you bind a range, the offset must be a multiple of that alignment. – Nicol Bolas Oct 25 '12 at 16:59

  • Still a bit confused. Lets say my shader contains 2 uniform blocks: uniform Block1{ vec4 offset_x1; }block1; uniform Block2{ vec4 offset_x3; vec4 offset_x4;}block2; And I want to supply data to both of them using a single buffer object. What will be my glBindBufferRange() call in that case ? Assume I am using std140 layout

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值