创建后,我可以创建一个支持OpenGL的X11窗口吗?

时间:2010-02-11 22:09:24

标签: opengl x11

我希望能够只给出它的id来渲染到X Window。

在这种情况下,我有一个由gtk在python中创建的窗口。

我可以获取gtk.Drawable的窗口ID并将其传递给我的C python模块,但是我可以将OpenGL调用渲染到它吗?

我知道gtkglext,但如果可能的话,宁愿不使用它。

更新1:

好的,所以(很明显,现在我已经看到了)你只需要使用XCreateWindow的父ID获得gtk.window.xid,使用opengl窗口的正确标志,嘿presto。

唯一的问题是,如果窗口中没有多个小部件,我无法使其工作,否则似乎xid代表一个覆盖整个顶层窗口的窗口。不知道如何纠正这个问题。

更新2: 事实证明,如果你有一个与顶层大小相同的gl窗口,那么在gl窗口交换缓冲区之前,顶层窗口不会暴露事件。你只需要不断交换缓冲区就可以了。

更新3:

回答@ babele的评论:

python gtk文档中的

This page说明了如何从现有的xid创建一个gtk窗口。之后你只需要记住为那个窗口调用glXSwapBuffers(如果它是一个opengl缓冲窗口,否则它应该在你使用window_foreign_new时工作)。

所以过程如下:

  1. 创建一个包含OpenGL窗口的gtk小部件(DrawingArea是一个不错的选择 - 你不能使用例如标签,因为它没有自己的xid)
  2. 获取小部件的gtk.gdk.Window(docs
  3. 从gtk.gdk.Window获取xid(将此窗口称为W1)
  4. 将其传递给您的C / C ++代码
  5. 创建具有opengl功能的窗口(W2)作为W1的子项
  6. 将W2的xid传回python
  7. 使用window_foreign_new和W2的xid创建新的gtk.gdk.window对象
  8. 每次在W2 gtk上调用glXSwapBuffers时,应该能够做出反应来公开事件。
  9. 真正让我感到震惊的是,如果W2覆盖整个W1,那么在W2的缓冲区交换之前,W1将不会接收事件。如果W1是一个顶级窗口,这尤其令人困惑,因为它可能根本就没有任何东西出现在屏幕上(窗口就在那里,但它看起来就像它背后的任何东西,直到它被绘制,直到它才会发生得到曝光事件。)

    另请注意,您必须通过连接到gtk resize事件手动管理W2的大小调整。您可以通过连接到this signal,然后在处理程序中调用this function并将结果传递到c / c ++模块来执行此操作,您可以在其中适当地调整W2的大小。 request a minimum size是一个好主意。

1 个答案:

答案 0 :(得分:6)

您不需要创建新窗口,将现有窗口传递给glXMakeCurrent() 在您当前的设置中,您需要:

  1. XGetWindowAttributes()用于检索窗口是用
  2. 创建的视觉效果
  3. glXCreateContext()使用此视觉
  4. glXMakeCurrent()使用此上下文和窗口ID
  5. 然而,这是向后做的,迫使OpenGL使用CreateWindow使用的视觉效果。这通常有效,因为默认的视觉效果具有理智的GLX属性,但正确的应用程序将glXChooseVisual具有所需的GLX属性,然后使用该视觉创建窗口。