【问题标题】:QOpenGLWidget just works correctly in the first paintQOpenGLWidget 在第一次绘制中正常工作
【发布时间】:2017-03-08 09:09:56
【问题描述】:

我开发了一个简单的点云数据查看器(仅供学习),我正在使用 Qt 库。我的第一个实现使用了 QOpenGLWindow 但现在我想使用 QOpenGLWidget 来使用它,例如动态库。

关于 QOpenGLWidget,它只在第一次“绘画”中工作(在我创建小部件时调用 PaintGL),并且在连续的 paintGL() 调用中没有任何反应。 QOpenGLWindow中没有出现这个问题,完美运行。

我的 PaintGL() 使用我的类的下一个方法绘制:

void AEOpenGLViewer::renderGL() {
    // Clear
    glClear(GL_COLOR_BUFFER_BIT);

    shader_program->bind();

    shader_program->setUniformValue(u_worldToCamera, camera.toMatrix());
    shader_program->setUniformValue(u_cameraToView, projection);
    {
        for (size_t globjects_index = 0; globjects_index < objects.size(); ++globjects_index) {
            objects.at(globjects_index).vao->bind();
            shader_program->setUniformValue(u_modelToWorld, objects.at(globjects_index).transform.toMatrix());

            glDrawArrays(objects.at(globjects_index).primitive_type, 0, objects.at(globjects_index).vertices.size());
            objects.at(globjects_index).vao->release();
        }
    }
    shader_program->release();
}

其中“objects”是在我的应用程序中定义 OpenGL 对象的本地结构的 std::vector:

typedef struct {
    QOpenGLBuffer *vbo;
    QOpenGLVertexArrayObject *vao;
    GLenum primitive_type;
    std::vector<Vertex> vertices;
    Transform3D transform;
} GLObject;

使用输入事件(KeyPressEvent、MouseMoveEvent..)调用插槽“update()”只是为了减少 GPU 负载。

如果有人感兴趣,vbo分配如下:

void AEOpenGLViewer::prepareObjectInGPU(GLObject globject) {
    shader_program->bind();
    {
        // Create Buffer (Do not release until VAO is created) (vbo)
        globject.vbo->create();
        globject.vbo->bind();
        globject.vbo->setUsagePattern(QOpenGLBuffer::StaticDraw);
        globject.vbo->allocate(globject.vertices.data(), globject.vertices.size() * sizeof(Vertex));

        // Create Vertex Array Object (vao)
        globject.vao->create();
        globject.vao->bind();

        shader_program->enableAttributeArray(0);
        shader_program->enableAttributeArray(1);
        shader_program->setAttributeBuffer(0, GL_FLOAT, Vertex::positionOffset(), Vertex::PositionTupleSize, Vertex::stride());
        shader_program->setAttributeBuffer(1, GL_FLOAT, Vertex::colorOffset(), Vertex::ColorTupleSize, Vertex::stride());

        // Release (unbind) all
        globject.vbo->release();
        globject.vao->release();
    }
    shader_program->release();
}

【问题讨论】:

    标签: c++ qt opengl


    【解决方案1】:

    问题解决了,这是因为我必须在GPU中分配对象的过程中使相应的上下文成为当前的(我的prepareObjectInGPU()方法)。所以,问题解决如下:

    void AEOpenGLViewer::prepareObjectInGPU(GLObject globject) {
        makeCurrent();
        shader_program->bind();
        {
            ...
        }
        shader_program->release();
        doneCurrent();
    }
    

    在 QOpenGLWindow 中,这不是必需的,但我建议将其作为良好做法。请记住,在 PaintGL() 期间不必调用 makeCurrent(),因为它会在调用 paintGL() 之前自动调用。

    但是,如果有人想回答我,那么欢迎您。

    谢谢!

    【讨论】:

      猜你喜欢
      • 2014-05-02
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-24
      • 2015-12-25
      相关资源
      最近更新 更多