【发布时间】:2011-04-29 19:39:12
【问题描述】:
我认为这是不可能的,但我在我的软件中看到了这一点。我已经构建了一个包装器对象来管理我的缓冲区对象(我正在使用共享上下文,所以我不能使用 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;
}
并且这个函数返回的缓冲区名称是正常的,直到它被这段代码调用:
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 );
}
由于某种原因,索引数组和顶点数组名称都相同! 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();
但它完全没有效果......
【问题讨论】:
-
你有没有机会在线程环境中?
-
可能,这一切都在基于 Qt 的 GUI 中运行,该 GUI 对各个部分进行了线程化。这当然有道理,我会做更多的测试。
-
根据更新,我对 glGenBuffers() 块进行了互斥,但无济于事。我想知道 glGenBuffers 是否可以被绕过我的线程保护的其他 OpenGL 函数隐式调用?
-
似乎只有 glBindBuffers() 可以隐式调用 glGenBuffers(),但是在我的代码中,只有我的 GL 包装器对象直接调用此函数,并且它只使用 glGenBuffers() 提供的地址。这让我快疯了……