我正在编写一个应用程序,
为此,我需要在管道和小部件上下文中共享这些纹理:
方法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管道
// [...] 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);
}
也不起作用,产生与方法1相同的错误,但我没有找到更多错误。
方法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();
}
这确实有效,但是这是一个不需要的解决方案,因为它不允许在管道初始化之后创建此类小部件
我要问的问题:
答案 0 :(得分:1)
为您解答:
是否需要添加特定的指令来分配共享资源 在共享的上下文中?
否。
上下文共享线程安全吗?例如我可以使用共享资源吗 不在乎互斥?
上下文共享不是线程安全的。共享是对OpenGL对象名称空间的整合。
但我怀疑这些答案根本无法帮助您。我将继续观察。您的错误很奇怪,因为GL_INVALID_OPERATION
仅在glBindTexture
的一种情况下生成:
如果先前创建了纹理,则会生成GL_INVALID_OPERATION 目标与 target 的目标不匹配。
这表示存在名称为textureHandle
的纹理,但没有目标GL_TEXTURE_2D
的纹理。也许纹理目标实际上是GL_TEXTURE_2D_MULTISAMPLE
?
当然,由于某种原因,共享可能无法正常工作。应该使用几乎所有图形调试器在每个上下文中列出对象,才能轻松找到它。在其中一个创建,然后查看是否在另一个弹出。