QT如何在窗帘后面共享开放环境

How does Qt share OpenGL contexts behind the curtain?

本文关键字:共享 环境 QT      更新时间:2023-10-16

我正在编写一个应用程序:

  • 在具有私人opengl上下文&私人线程
  • 在小部件中绘制一些先前渲染的纹理

为了做到这一点,我需要在管道和小部件上下文上共享这些纹理:

方法1:共享所有上下文

int main (int argc, char *argv[])
{
     QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
     QApplication a(argc, argv);
     // [...] Create and initialize the pipeline (private context)
     // [...] Create a window with a widget that can display a texture (Qt creates a private context itself)
     // [...] Set the texture to display in the widget with one created and rendered in the pipeline
}

当我想绘制纹理时(在paintGL()回调中(时,glBindTexture产生GL_INVALID_OPERATION
图形调试器显示一个怪异的纹理,而不是我的:上下文共享似乎不起作用。

方法2:小部件具有一个自我创建的上下文,该上下文共享管道和qt One

// [...] Create and initialize the pipeline (private context)
// [...] Create a window with a widget that can display a texture (Qt creates a private context itself)
// widget's initializeGL() callback gets called
void initializeGL()
{
     initializeOpenGLFunctions();
     m_secondContext.setShareContext(QOpenGLContext::currentContext());
     m_secondContext.setShareContext(pipelineContext);
     m_secondContext.create();
}
// use the second context during paintEvents
void paintGL()
{
     auto contextBackup(QOpenGLContext::currentContext());
     auto surfaceBackup(contextBackup->surface());
     assert(m_secondContext->makeCurrent(surfaceBackup));
     // [...] draw texture
     contextBackup->makeCurrent(surfaceBackup);
}

也不起作用,产生与我未找到的其他方法相同的误差。

方法3:管道共享小部件上下文

// [...] Create a window with a widget that can display a texture (Qt creates a private context itself)
// [...] Create and initialize the pipeline with the widgets context set as shared 
//       before calling create on the new pipeline context
void initializePipeline()
{
     m_pipelineContext.setShareContext(widgetContext);
     m_pipelineContext.create();
}

这确实有效,但是它是一个不必要的解决方案,因为它不允许在管道初始化之后创建此类小部件

我问的问题:

  • 所有这些情况都应该给出相同的结果,发生了什么,我想念什么?
  • 是否需要在共享的上下文上添加特定的指令来分配共享资源?
  • 上下文共享线程安全吗?例如,我可以在不关心相互排斥的情况下使用共享资源吗?(编辑:使用一个没有解决任何问题(

回答您的问题:

是否需要添加特定的说明来分配共享资源 在共享的上下文中?

no。

上下文共享线程安全吗?例如,我可以使用共享资源 不关心相互排斥?

上下文共享不是线程安全的。共享是OpenGL对象名称空间的合并。

,但我怀疑这些答案根本没有帮助您。我会继续观察。您的错误很奇怪,因为GL_INVALID_OPERATION仅在glBindTexture的一种情况下生成:

gl_invalid_operation是先前创建的纹理如果 使用与 target 的目标。

表明有一个名称textureHandle的纹理,而不是目标GL_TEXTURE_2D。也许纹理目标实际上是GL_TEXTURE_2D_MULTISAMPLE

当然,无论出于何种原因,共享都可能不起作用。应该使用几乎所有图形调试器轻松找到这一点,以在每个上下文中列出对象。创建一个,看看它是否弹出另一个。