【问题标题】:glGenBuffers returning non-unique namesglGenBuffers 返回非唯一名称
【发布时间】:2011-04-29 19:39:12
【问题描述】:

我认为这是不可能的,但我在我的软件中看到了这一点。我已经构建了一个包装器对象来管理我的缓冲区对象(我正在使用共享上下文,所以我不能使用 VAO),并且 VBO 方面工作正常,直到我开始使用 IBO 测试它(glDrawElements(),我' m 使用纯 OpenGL 3+ 环境)。

以下是向我的对象 (Sy_GLOb​​ject) 添加缓冲区的代码:

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() 提供的地址。这让我快疯了……

标签: c++ opengl buffer


【解决方案1】:

感谢 OpenGL.org 论坛上的 Ilian Diev 指出了这个愚蠢的错误。我在堆栈上创建了我的 Buffer 对象,并方便地调用了它的析构函数 glDeleteBuffers()。很棒的设计。

【讨论】:

  • 谢谢,我已经为类似的事情苦苦挣扎了几个星期,这篇文章让我在我的 glDeleteBuffers 上设置了断点,发现我在做同样的事情
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多