我正在编写一个应用程序,其功能如下:
- 在具有私有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
的错误。
图形调试器显示的是奇怪的纹理,而不是我的纹理:上下文共享似乎没有起作用。
方法二:小部件拥有自己创建的上下文,该上下文共享了管线和 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();
}
这确实可以解决问题,但是这不是一个理想的解决方案,因为它不允许在管道初始化后创建此类小部件
我的问题:
- 这三种情况应该得到相同的结果,发生了什么事,我错过了什么?
- 在共享上下文中是否需要添加特定指令来分配共享资源?
- 上下文共享是线程安全的吗?例如,我可以使用共享资源而不关心互斥吗? (编辑:使用一个并没有解决任何问题)
glFlush
或glFinish
来“提交”上下文命令队列?因为您应该这样做。 - Andreas