PDA

View Full Version : glGenBuffers returning non-unique names.



cbamber85
04-30-2011, 04:58 AM
I thought that this was impossible but I'm seeing it with my software. I have built a wrapper object to manage my buffer objects (I am working with shared contexts so I can't use VAOs), and the VBO side of things was working fine until I starting testing it with IBOs (glDrawElements(), I'm using a OpenGL Core 3+ environment).

Here is the code for adding a buffer to my object (Sy_GLObject):


QList< uint > Sy_GLObject::addBuffers( uint numBuffers, GLenum target, GLenum numericType, GLenum usage )
{
uint* adds = new uint[numBuffers];
glGenBuffers( numBuffers, adds );

QList< uint > l;
for ( uint i = 0; i < numBuffers; ++i ) {
Buffer buffer( target, adds[i], 0, numericType, usage );
buffers_ << buffer;

l << i;
}
delete[] adds;

Sy_GL::checkError();
return l;
}

And the buffer names returned by this function are fine, until it is called by this code:


void Sy_BVH::initialiseGLObject()
{
Sy_application::getMainWindow()->getActiveProject()->getModelContext()->makeCurrent();

GLuint vLoc = Sy_settings::get( "shader/flat/vertexLoc" ).toUInt();
drawBBs_ = Sy_GLObject::createObject();

// Add vertex array.
drawBBs_->addBuffers( 1 );
drawBBs_->buffers()[0].setVertexPointer( vLoc );

// Add indices array.
drawBBs_->addBuffers( 1, GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT );
}

For some reason the indices array and vertex array names are both the same! setVertexPointer() does not actually call glVertexAttribPointer(), it just stores the parameters for it in a POD class - so no OpenGL calls are made between the two addBuffers() commands. The vertex call is 'correct' as it is one higher than the previous glGenBuffers() result, but from addBuffers() point of view there should be no difference between the calls.

To make sure threading was not a factor, I wrapped a static mutex around the glGenBuffers() block (and every other OpenGL call).


QMutexLocker locker( &amp;mutex_ ); // mutex_ is a QMutex static class member.
uint* adds = new uint[numBuffers];
glGenBuffers( numBuffers, adds );
locker.unlock();

But it had absolutely no effect... Are there circumstances where glGenBuffers can possibly return the name of a buffer already in use!?

Thanks!

Ilian Dinev
04-30-2011, 06:07 AM
this line:
Buffer buffer( target, adds[i], 0, numericType, usage );

it creates the C++ Buffer object on the stack, and its destructor gets called soonish. Do you happen to be calling glDeleteBuffers in that destructor?

cbamber85
04-30-2011, 06:34 AM
I shouldn't be allowed near a computer - I'm too dangerous.

Thank you, that was exactly what was happening! It's a miracle it worked most of the time...