QGLBuffer VBO 实现

Posted

技术标签:

【中文标题】QGLBuffer VBO 实现【英文标题】:QGLBuffer VBO implementation 【发布时间】:2013-06-23 11:57:14 【问题描述】:

我想在我的绘图 GPU 中传输顶点和颜色变量。不幸的是,它无法在程序运行时呈现。 定义如下:

QVector<QVector3D> vertices;
float* colors;

QGLBuffer* m_bufferData;
QGLBuffer* m_colorData;
float* m_color;

这就是我在initializeGL()中所做的,因为顶点是构建一次并永远使用的,我不分配和映射它。但是,代码中颜色会定期变化,所以我在代码中将颜色映射到了 m_color。

void PlanPositionIndicator::QtVBO()

     m_bufferData = new QGLBuffer(QGLBuffer::VertexBuffer);
    m_bufferData->create();
    m_bufferData->bind();
    m_bufferData->setUsagePattern(QGLBuffer::DynamicDraw); //staticDraw
    m_bufferData->allocate(8*6*sizeof(float)* ANGLE_COUNT*RANGE_COUNT);
    m_bufferData->release();
    //m_data = (QVector<QVector3D>*)m_bufferData->map (QGLBuffer::ReadWrite);

    m_colorData = new QGLBuffer(QGLBuffer::VertexBuffer);//static
    m_colorData->create();
    m_colorData->bind();
    m_colorData->setUsagePattern(QGLBuffer::DynamicDraw);
    m_colorData->allocate(6*sizeof(float)* ANGLE_COUNT*RANGE_COUNT);

    if(m_colorData->isCreated())
    
        qDebug() << "buffer created";
    
    m_color = (float*)m_colorData->map(QGLBuffer::ReadWrite);
    m_colorData->unmap();
    m_colorData->release();

到目前为止一切顺利,接下来,在paintGL()中,在设置矩阵和绑定着色器程序之后,我调用渲染函数来渲染我的绘图,如下所示:

    glEnableClientState( GL_VERTEX_ARRAY);
    glEnableClientState( GL_COLOR_ARRAY);

    if (m_bufferData->bind ()) 

        m_bufferData->write(0,vertices.constData(),sizeof(vertices));
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer( 3, GL_FLOAT, 0, &vertices);

        if(m_colorData->bind())
        
            shaderProgram->setAttributeArray("vertex", vertices.constData());
            shaderProgram->enableAttributeArray("vertex");
            shaderProgram->setAttributeArray("color", GL_FLOAT,colors,1);
            shaderProgram->enableAttributeArray("color");

            glEnable    (GL_BLEND);
            glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glDrawArrays(GL_TRIANGLES, 0, vertices.size());
//        
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_COLOR_ARRAY);

        m_bufferData->release();
        m_colorData->release();
    

最后,我尝试更改颜色数组的值。首先,我使用 map() 和 unmap() 完成了它,但它给了我分段错误。接下来,我使用了 write(),它运行良好,但没有渲染任何东西。

      float* m_color = (float*)glBuffer->map(QGLBuffer::ReadWrite);
    m_color[k++] = rnd;
    m_color[k++] = rnd;
    m_color[k++] = rnd;
    m_color[k++] = rnd;
    m_color[k++] = rnd;
    m_color[k++] = rnd;
    glBuffer->unmap ();

有什么建议吗?

【问题讨论】:

解决了segmentation fault,但是在程序运行的时候还是没有效果。 【参考方案1】:
m_colorData->release();
m_color = (float*)m_colorData->map(QGLBuffer::ReadWrite);

这个序列对我来说很可疑——你被允许映射然后解除绑定,但你确定你可以做相反的事情吗? Qt 在这里不会做任何诡计——它会为GL_ARRAY_BUFFER​ 绑定点直接调用glMapBuffer,而那里没有绑定缓冲区(请参阅here)。

此外,当您的m_colorData 缓冲区被映射时,you are not allowed 可以通过 OpenGL 调用对其进行任何操作(这当然包括使用它进行渲染)。

【讨论】:

我是 Qt QGLBuffer 的新手,有没有 QT 经验的人请指导我的问题。 这与 QGLBuffer 无关——这是一个 OpenGL 问题。首先交换这两行。此外,不要在绘制时保持 m_colorData 映射。仅在必要时映射,然后取消映射。 那么请用您当前版本的代码修改您的帖子。

以上是关于QGLBuffer VBO 实现的主要内容,如果未能解决你的问题,请参考以下文章

[转]OpenGL 通过VBO实现顶点数组绘制顶点

如何在 Qt 中使用顶点缓冲区对象渲染地形?

尝试使用 VBO 时出错“必须禁用数组 vertex_buffer_object 才能调用此方法”

VBO绑定的OpenGL顺序

VBO 不使用 UV 坐标

配置 VAO 以处理具有多个网格的 VBO