在Linux上与GLUT共享上下文

时间:2015-07-18 03:16:52

标签: linux multithreading opengl textures glut

在我目前的设置中,我有两个显示由两个GPU驱动。使用GLUT,我创建了两个窗口(每个显示一个),并通过在每个窗口的draw调用中调用glutSetWindow()从主线程渲染每个窗口。

绘制调用将Texture2D渲染为球体(使用gluSphere()),但每隔几秒就将Texture2D换成另一个图像。我已经设置了一个2 Texture2D的数组,所以我可以加载下一个图像,同时显示当前的Texture2D。只要一切都在主线程中运行,这种方法就可以正常工作。

问题是调用glTexImage2D()来加载下一个图像,挂起我的绘图调用,所以我需要在另一个线程上调用glTexImage2D()。在不同的线程上调用glTexImage2D()崩溃,因为看起来OpenGL上下文不是共享的。 GLUT似乎没有提供共享上下文的方法,但我应该能够通过glXGetCurrentContext()在Linux上获取上下文。

我的问题是,如果我通过此调用获取上下文,我该如何将其作为共享上下文?这甚至可以与GLUT一起使用吗?另一个选择是切换到不同的库来替换GLUT,就像GLFW一样,但在这种情况下,我会松开一些方便的功能,比如gluSphere()。如果不能与GLUT共享上下文,是否有任何建议?

1 个答案:

答案 0 :(得分:2)

在上下文创建时建立GLX上下文共享;与WGL不同,您不能将此分享视为事后的想法。由于GLUT没有上下文共享功能(FreeGLUT可能有一个,但我不确定),这不是直截了当的。

  

我有两个显示由两个GPU驱动。

除非这些GPU是SLi-ed或CrossFire-ed,否则您无法在它们之间建立上下文共享。

  

问题是调用glTexImage2D()来加载下一个图像,挂起我的绘图调用,所以我需要在另一个线程上调用glTexImage2D()。

如果图像大小相同,请使用glTexSubImage2D替换它。此外,图像数据可以使用像素缓冲区对象异步加载,使用的辅助线程甚至不需要OpenGL上下文!

概述步骤:

在OpenGL上下文线程中:

启动转移

  • glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID)
  • void *p = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
  • 信号转移线程
  • 继续正常的绘图操作

在传输广告中

关于开始转移的信号

  • 将数据复制到映射缓冲区
  • 发出信号OpenGL上下文线程

在OpenGL上下文线程中:

关于完成转移的信号

  • glUnmapBuffer
  • glTex[Sub]Image
  • sync = glFenceSync
  • 继续使用纹理
  • 绘图

关于绘图循环的进一步迭代

  • 使用sync使用超时0
  • glClientWaitSync进行投票
  • 如果等待同步返回信号切换到新纹理并删除旧纹理
  • 继续使用旧纹理绘图