从另一个线程渲染到QWindow

时间:2014-03-21 20:06:20

标签: c++ multithreading qt opengl

我一直试图解决我的问题一段时间,到目前为止我还没有找到解决方案

我有一个QT应用程序,现在我需要添加一个QWindow来用opengl绘制。

我知道我需要调用QWidget :: createWindowContainer()来创建QWidget,我可以将其插入另一个小部件或主窗口。 现在,我已经在子类化的QWindow类中创建了一个上下文。当窗口暴露时,我这样做。然后我创建了另一个我的渲染类所在的线程,将QOpenGLContext传递给它,使其在那里保持最新状态,但无论我尝试什么,它都无法工作。

QWindow的子类我只是初始化上下文,仅此而已(我在构造函数中设置了表面类型):

void OpenGLWindow::initialize()
{
    if (!m_context) {
        m_context = new QOpenGLContext();
        m_context->setFormat(requestedFormat());
        m_context->create();
    }

    if(!isRunning) {
    thread = new ThreadHelper(m_context, this);
    thread->start();
    }
} 

然后是ThreadHelper:

ThreadHelper::ThreadHelper(QOpenGLContext *context, OpenGLWindow *window) : 
m_window(window),
m_context(context)
{
}


void ThreadHelper::run()
{
    m_context->makeCurrent(m_window);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    glClearColor(1.0, 0.0, 0.0, 0.5);

    // the rendering is done here, it's a loop, where I loop 
    // over classes and call the render method
}

void ThreadHelper::swapOpenGLBuffers(){
    m_context->swapBuffers(m_window);
}

它在m_context-> makeCurrent(m_window)行崩溃。

还尝试将上下文移动到另一个线程但没有成功,我收到一个运行时错误,表示它无法移动。

1 个答案:

答案 0 :(得分:1)

来自文档:

  

可以使用moveToThread()将QOpenGLContext移动到其他线程。   不要从与其中一个不同的线程调用makeCurrent()   QOpenGLContext对象所属的对象。上下文只能是最新的   在一个线程中,一次一个表面,一个线程只有   一次一个上下文当前。

所以你需要在启动线程之前调用m_context->moveToThread(thread)之类的东西。这可能对你不起作用,因为你试图在另一个线程中调用它。必须在当前拥有该对象的线程(即创建它的线程)中调用moveToThread