0
votes

I am developing a library for Qt that extends it's OpenGL functionality to support modern OpenGL (3+) features like texture buffers, image load-store textures, shader storage buffers, atomic counter buffers, etc.. In order to fully support features like transform feedback, I allow users to bind a buffer object to different targets at different times (regardless of what data they allocated the buffer with). Consider the following scenario where I use transform feedback to advance vertex data ONCE, and then bind it to a separate program for rendering (used for the rest of the application run time) :

// I attach a (previously allocated) buffer to the transform feedback target so that I 
// can capture data advanced in a shader program. 
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, someBufferID);

// Then I execute the shader program...

// and release the buffer from the transform feedback target.
glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);

// Then, I bind the same buffer containing data advanced via transform feedback 
// to the array buffer target for use in a separate shader program.
glBindBuffer(GL_ARRAY_BUFFER, someBufferID);

// Then, I render something using this buffer as the data source for a vertex attrib.

// After, I release this buffer from the array buffer target.
glBindBuffer(GL_ARRAY_BUFFER, 0);

In this scenario, being able to bind a buffer object to multiple targets is useful. However, I am uncertain if there are situations in which this capability would cause problems given the OpenGL specification. Essentially, should I allow a single buffer object to be bound to multiple targets or force a target (like the standard Qt buffer wrappers) during instantiation?

Edit: I have found that there is a problem mixing creation/binding targets with TEXTURE objects as the OpenGL documentation for glBindTexture states:

GL_INVALID_OPERATION is generated if texture was previously created with a target that doesn't match that of target.

However, the documentation for glBindBuffer states no such problem.

1
Buffers are just blocks of data, in contrast to textures, which have a ton of structure (dimensions, format, mipmap levels, configured state). So it makes sense that a buffer can be used for any purpose. - Ben Voigt
That's what I was thinking, but I thought I'd make sure there were no potential hazards. (Perhaps due to different vendor implementations, possible quirks of certain targets, etc..) - Sir Digby Chicken Caesar

1 Answers

1
votes

Well, there can always be faulty drivers (and if you don't have "green" hardware nothing can be guaranteed, anyway). But rest assured that it is perfectly legal to bind buffers to any target you want, disregarding the target they were created with.

There might be certain subtleties, like certain targets need to be used in an indexed way using glBindBufferRange/Base (like uniform buffers or transform feedback buffers). But enforcing a buffer to be used with a single target only, like Qt does, is too rigid to be useful in modern OpenGL, as your very common example already shows. Maybe a good compromise would be to use an either per-class (like Qt does) or per-buffer default target (which will be sufficient in most simple situations, when the buffer is always used with a single target, and can be used for class-internal binding operations if neccessary), but provide the option to bind it to something else.