我认为这是不可能的,但我用我的软件看到它.我已经构建了一个包装器对象来管理我的缓冲区对象(我正在使用共享上下文,所以我不能使用VAO),并且VBO方面的工作正常,直到我开始用IBO测试它(glDrawElements(),我' m使用纯OpenGL 3+环境).
以下是向我的对象添加缓冲区的代码(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;
}
Run Code Online (Sandbox Code Playgroud)
并且此函数返回的缓冲区名称很好,直到此代码调用它:
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 );
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,索引数组和顶点数组名称都是相同的!setVertexPointer()实际上并不调用glVertexAttribPointer(),它只是将它的参数存储在POD类中 - 因此在两个addBuffers()命令之间不进行OpenGL调用.顶点调用是"正确的",因为它比前一个glGenBuffers()结果高一个,但从addBuffers()的角度来看,调用之间应该没有区别.
是否存在glGenBuffers可能返回已使用的缓冲区名称的情况!?
谢谢!
更新
为了确保线程不是一个因素,我在glGenBuffers()块周围包装了一个静态互斥.
QMutexLocker locker( &mutex_ ); // mutex_ is a QMutex static class member.
uint* adds = new uint[numBuffers];
glGenBuffers( numBuffers, adds );
locker.unlock();
Run Code Online (Sandbox Code Playgroud)
但它绝对没有效果......
感谢Ilian Dinev在OpenGL.org论坛上指出这个愚蠢的错误.我在堆栈上创建了我的Buffer对象,并且方便地让它的析构函数调用glDeleteBuffers().神奇的设计.