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

问题描述:

我希望能够渲染到一个X窗口,只要它的ID。创建后,我可以创建一个X11窗口OpenGL吗?

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

我可以得到一个gtk.Drawable的窗口ID并将它传递到我的C python模块,但是我可以让OpenGL调用渲染它吗?

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

更新1:

好了,(而很明显,现在我看到它)你只是做一个XCreateWindow与窗口ID,你从gtk.window.xid得到家长,使用正确的标志为一个OpenGL窗户,嘿presto。

唯一的问题是,如果窗口中没有多个小部件,我不能让它工作,否则它看起来像是一个窗口,覆盖整个顶层窗口。不知道如何纠正这一点。

更新2: 事实证明,如果你有一个GL窗口的大小与顶层相同,则顶层窗口将不会公开事件,直至GL窗口有交换缓冲区。你只需要保持交换缓冲区,事情就会好起来。

更新3:

要回答@ babele的评论:

在Python This page GTK文档说如何从现有的XID做出GTK窗口。之后,你只需要记住继续为该窗口调用glXSwapBuffers(如果它是一个opengl缓冲窗口,否则它应该只在你使用window_foreign_new时才起作用)。

所以过程进行:

  1. 创建一个GTK控件将包含你的OpenGL窗口(DrawingArea是一个不错的选择 - 因为它不会有自己的XID你不能使用如标签)
  2. 获取widget的gtk.gdk.Window(docs
  3. 从gtk.gdk.Window获取XID(这个窗口W1)
  4. 它传给你的C/C++代码
  5. 创建opengl风能低(W2)为W1
  6. 的孩子
  7. 传递W2的XID回蟒蛇
  8. 使用window_foreign_new与W2的XID创建新gtk.gdk.window对象
  9. 每次调用上W2 GTK glXSwapBuffers时间应然后能够对暴露事件做出反应。

真正抛出我的一点是,如果W2覆盖整个W1,那么W1将不会接收事件,直到W2的缓冲区被交换。如果W1是顶层窗口,这一点尤其令人困惑,因为它可能是屏幕上没有任何东西出现(窗口在那里,但它看起来像它后面的任何东西,直到它被绘制为止,这不会发生在它之前)得到揭露事件)。

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

+0

“我已经找到一个办法让GTK来管理手动创建使用XCreateWindow窗口” ......请,你可以解释一点点怎么办?我正在寻找一些类似的片段,但我找不到任何东西..只是一个粗略的概述:) THX! – 2011-01-23 16:04:04

你并不需要创建一个新的窗口,你通过现有的窗口glXMakeCurrent()。
在当前设置你需要:

  1. XGetWindowAttributes使用这种视觉
  2. glXMakeCurrent()使用此上下文()来检索窗口与
  3. glXCreateContext创建视觉()和窗口ID

但是,这是做倒退,迫使OpenGL使用用于CreateWindow的视觉。这通常是有效的,因为默认视觉具有理智的GLX属性,但正确的应用程序将使用GLX属性的glXChooseVisual,然后使用该视觉创建窗口。

+0

XSetWindowAttributes如何将窗口的Visual更改为适当的OpenGL?这会起作用吗? – Loomchild 2017-02-03 12:56:15

+0

当然,我的意思是XChangeWindowAttributes。 – Loomchild 2017-02-03 13:36:22

+1

XChangeWindowAttributes无法更改窗口的Visual。您需要创建所需的视觉窗口。 – 2017-02-03 21:28:53