QT如何在窗帘后面共享开放环境
How does Qt share OpenGL contexts behind the curtain?
我正在编写一个应用程序:
- 在具有私人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
?
当然,无论出于何种原因,共享都可能不起作用。应该使用几乎所有图形调试器轻松找到这一点,以在每个上下文中列出对象。创建一个,看看它是否弹出另一个。
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 在cuda线程之间共享大量常量数据
- 枚举环境变量的惯用C++14/C++17方法
- 如何从具有移动语义的类对象中生成共享指针
- 在c代码之间共享数据的最佳方式
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 将静态库链接到不带-fPIC的共享库中
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 为什么std::互斥需要很长的、非常不规则的时间来共享
- 使用Boost Interprocess创建托管共享内存需要很长时间
- 无法在Ubuntu上将共享库与Eclipse链接
- 从python调用openMP共享库时,未定义opnMP函数
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 为什么我的共享库中存在展开符号
- 跨语言共享环境变量
- QT如何在窗帘后面共享开放环境
- 如何分配套接字 ID 并且不共享C++中的环境变量
- 并发:用于多线程环境中共享变量的C++11内存模型
- 链接到32位环境中的32位共享对象文件会生成ELFCLASS64错误