Just create a buffer with the right size (GetUniformBufferSizeEXT), then attach it to your uniform with UniformBufferEXT. Otherwise it’s a lot like a regular uniform. You can use the buffer API (BufferSubData and friends) or the Uniform* flavors to update stuff.
There’s no way to determine whether a uniform is bindable at runtime with the API (although I think calling GetUniformBufferSize generates an error if it’s not).
What I’m worried about is if these variables are in sequence in the memory or not.
What if I want to have 2 pairs of BO for 1 shader? 1 BO where values are not updated as often and another BO that is very dynamic. Or must I have a BO for the entire shader.
What if I want to have 2 pairs of BO for 1 shader? 1 BO where values are not updated as often and another BO that is very dynamic. Or must I have a BO for the entire shader.
Each bindable uniform variable must have its own buffer object. Note that “glUniformBufferEXT” does not take an offset into a buffer object. So it is assumed to be the entire buffer object.
So to make the best use of bindable uniforms, you must use structs as I showed.
BTW, as I read over the bindable_uniform extension, it’s really clear that this is a terrible extension. It is poorly specified and doesn’t even go far enough to actually tell you how structs (for example) are laid out in memory, which makes using the extension in any real manner basically useless.
The problems are:
a) glGetUniformLocation only returns locations for uniforms that are actually used by the program. In order to circumvent this, I have to write a pseudo-shader which is accessing all struct members, just to force the compiler to tell me their offsets in the buffer.
b) the whole approach somehow implies that the result is specific to “program”, which is clearly not.
That’s a good reason for a default packing rule to be spec’d. You need to know something about the buffers you’re binding, anyway, as they’re not really discoverable in their entirety through shader reflection, or what there is of it. If you have a packing rule and a buffer size, that’s all you really need to know.
For now on NV hw, if you pack vec4s, it’s all gravy.
the whole approach somehow implies that the result is specific to “program”, which is clearly not.
No. The poorly-written spec does state that the layout for structs/arrays of bindable uniforms is the same for all programs that use that uniform specified in the same way. All you need is one program to get it started.
glGetUniformLocation(“ProjectionModelviewMatrix”) returns 1
glGetUniformLocation(“MaterialDiffuse0”) returns 0
glGetUniformLocation(“TexMatrix0_a”) returns -1
glGetUniformLocation(“TexMatrix0_b”) returns -1
I guess these last 2 got optimized out.
If I call glGetUniformOffsetEXT(“MaterialDiffuse0”) it returns 0
glGetUniformOffsetEXT(“ProjectionModelviewMatrix”) it returns -1
Yes, I use the uniform location of course when I call glGetUniformOffsetEXT.