I want to be able to render to an X Window given just its id.
In this case I have a window created in python by gtk.
I can get the window ID of a gtk.Drawable
and pass it into my C python module, but can I then make OpenGL calls render to it?
I am aware of gtkglext, but would rather not use it if possible.
Update 1:
Ok, so (rather obviously now that I see it) You just do an XCreateWindow
with a parent of the Window id that you get from gtk.window.xid
, using the correct flags for an opengl window, and hey presto.
The only problem is I can't get it to work if there are not multiple widgets in the window, otherwise it seems that the xid represents a window that covers the entire toplevel window. Not sure how to rectify this.
Update 2: It turns out that if you have a gl window that is the same size as the toplevel then the toplevel window will not get expose events until the gl window has its buffers swapped. You just have to keep swapping the buffers and things wil be fine.
Update 3:
To answer @babele's comment:
This page in the python gtk docs say how to make a gtk window from an existing xid. After that you just have to remeber to keep calling glXSwapBuffers for that window (if it is an opengl buffered window, otherwise it should just work when you use window_foreign_new).
So the process goes:
One bit that really threw me is that if W2 covers the whole of W1 then W1 won't receive events until W2's buffers get swapped. This is particularly confusing if W1 is a top-level window as it can be that nothing appears on your screen at all (the window is there but it looks like whatever is behind it until it gets painted to, which won't happen until it gets an expose event).
Also note that you'll have to manually manage the resizing of W2 by connecting to the gtk resize events. You can do this by connecting to this signal, then calling this function in the handler and passing the results to your c/c++ module where you can resize W2 appropriately. Its a good idea to request a minimum size.
You don't need to create a new window, you pass an existing window to glXMakeCurrent().
In your current setup you'd need to:
However, this is doing it backwards, forcing OpenGL to use the visual used for CreateWindow. This often works because the default visual has sane GLX properties, but a correct application will glXChooseVisual with desired GLX properties, then use that visual to create the window.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With