
OpenTK and WPF interoperation
Posted Wednesday, 9 September, 2009 - 15:28 by the Fiddler| Project: | The Open Toolkit library |
| Version: | 0.9.9-2b |
| Component: | Code |
| Category: | support request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | in progress (review) |
Right now, it is possible to create an OpenTK.GLControl and host it in a WPF using a WindowsFormsHost.
The question is: can we create an OpenGL context directly on a WPF window and do away with the host control?
The attached solution creates a WPF solution, obtains its handle and creates a GraphicsContext. This works without errors, however OpenGL rendering results in artifacts. The msdn entry for the OnRender method, notes that:
The rendering instructions for this element are not used directly when this method is invoked, and are instead preserved for later asynchronous use by layout and drawing.
This explains why the rendering artifacts appear: OpenGL tries to render to the window directly and does not participate into WPF composition.
One *could* use offscreen OpenGL rendering, perform a readback and present the results into the WPF window, but this is inefficient. It would be nice to find a better solution or confirm that it cannot be done.
Any ideas?
| Attachment | Size |
|---|---|
| OpenTKWPF.zip | 1.81 MB |


Comments
#1
A related discussion on the msdn forums indicates that:
I don't know why, but overriding OnRender does not work when the class is Window or derives from Window. That's the only reason I can think of that this method wouldn't work.
Most commonly, only classes the derive from FrameworkElement override OnRender. Most applications use pre-existing classes that derive from FrameworkElement rather than making their own.
Maybe overriding from FrameworkElement would yield better results?
Edit: same question on stackoverflow.
#2
This post outlines a potential solution that is trivial to adopt to OpenTK: Managed DirectX Interop with WPF.
They still use a WindowsFormsHost to host the DirectX control but render a transparent overlay on top it. This way, they can receive input events and host WPF controls on top of the WindowsFormsHost without introducing airspace issues. Quite nice!
#3
Hi,
Here is a solution to have a 100% WPF control drawing OpenGL.
I'm still working on ...
It is currently based on Tao, but currently we only have to got a solution... after we can convert it to OpenTk.
Performance
I think that there are several ways to improve it , it sounds that not creating a WGL context, but draw into a FBO (http://www.opentk.com/doc/graphics/frame-buffer-objects)
I have no experience with FBO and do not know to have a "MakeCurrent" method based on this... I hope you will find some time to help me.
If you can help me to avoid to create a WindowsForm control and draw only in memory ?
Issues
When I use the SimpleOpenGLControl (Tao) or the OpenTk GLControl.... in the WindowsHostForm I got some refreshing problems.
Here I got the same problem...
#4
#5
Hi,
I have a new version...
The difference is that we create a BitmapSource at startup and then we use glReadPixel to put the image directly in the image.
Like this we avoid one copy.
But I have a question, it sounds that glReadPixel do not always read the "right" buffer or that maybe it read a previous image.
Is it possible ?
Thanks
#6
if you are using framebuffer for offline rendering (render to texture then glReadPixels to memory bitmap); it is most likely to utilize pixel buffer objects(PBO) with double buffering. for detailed info: PBO
#7
Yes, it is possible. Make sure you call
SwapBuffersorGL.Finish()just before you callGL.ReadPixels.#8
Thanks,
But why calling SwapBuffer ? It sounds that we have 2 buffers... it will be better if we can always play with one buffer...
Is there a way to force glReadPixel to read on the "drawing" buffer ?
The second buffer is the WPF image... so we also avoid the flickering effect.
#9
You can use
GL.ReadBuffer()to instructGL.ReadPixels()to read from the backbuffer.You can also request a single-buffered context (use a
GraphicsContextconstructor that takes a "buffers" argument), but note that this is not supported very well on modern operating systems (Aero might turn off, for example).#10
Thanks
I use glReadBuffer and glReadPixels but doesn't see any performance improvement .
When I use GL_AUX0 it doesn't work !! I got no image !