LWJGL/JavaFX Integration

Here are my results from a laptop with a Nvidia Gefore 8400GS

All tests run with vsync turned off and MSAA x 1, Asynchronous PBO for both gives - No buffering runs at 30fps and double and triple buffer runs at 60fps. Similar results for the other options.

Is it possible you could also add a second JNLP to the download bundle with those JavaFX parameters that unlock its 60fps cap?

Also maybe adding another option demonstrating glReadPixels would be nice for performance comparison (and if set as default would allow demo to run on gfx cards which don’t support PBO’s properly as glReadPixels should work just about everywhere).

GTX 580 with MSAA x1.

No Buffering:

[tr][td]Texture V | Render >[/td][td]Asynchronous PBO[/td][td]ARB_copy_buffer[/td][/tr]
[tr][td]Asynchronous PBO[/td][td]480 FPS[/td][td]770-780 FPS[/td][/tr]
[tr][td]ARB_map_buffer_range[/td][td]480 FPS[/td][td]770-780 FPS[/td][/tr]

Double Buffering:

[tr][td]Texture V | Render >[/td][td]Asynchronous PBO[/td][td]ARB_copy_buffer[/td][/tr]
[tr][td]Asynchronous PBO[/td][td]590-595 FPS[/td][td]1080-1085 FPS[/td][/tr]
[tr][td]ARB_map_buffer_range[/td][td]590-595 FPS[/td][td]1080-1085 FPS[/td][/tr]

Triple Buffering: same numbers as Double Buffering.

Hello

I found this with google and tried it, and I have to say I really like it, because it works. But on my Intel card it is slow, but that video card sucks anyway. I think the performance could be better if you exploit the fact that GUI elements update rather seldom compared to the 3D Scene. So instead of moving the 3D Scene into an ImageView, you might render all GUI elements that have changed into an offscreen texture and draw thaw with LWJGL manualy. This might be done, if you can replace or modyfy the scene Renderer from JavaFX with one of your own.

I tried to do something similar with swing, but I miserably failed. I could copy the swing component to an OpenGL texture, that was no problem, but I was not able to do it on change events. Also all interacitivity was lost if I wanted to bring swing elements into the 3D space. I was not able to find a hook to replace the renderer or to replace the user input. If you can do this in javafx, I will like you very much :wink:

Hi Krux,

First of all the integration in this demo is 2-way; you have both JavaFX nodes rendered in a 3D scene and the 3D scene itself rendered as a JavaFX node. This is the worst possible scenario in terms of performance and probably unrealistic in a real application. If you only need JavaFX content in an LWJGL window that’s possible of course.

You’re correct that GUI elements don’t need to be redrawn as frequently. Again, I chose a WebView on purpose because I needed to test the most demanding node possible to see if this approach is viable. I do in fact use a texture to cache the JavaFX rendering, but in this demo it’s being updated whenever I detect a change in the HTML content or every 4 frames (at 60fps), for carets etc. In a real app you could reduce the update rate considerably.

JavaFX does have a fully working robot implementation, but it’s currently undocumented. You can use com.sun.glass.ui.Application.GetApplication().createRobot() to get an instance and start firing events. I’m afraid I can’t help you with transforming 3D scene coordinates to 2D node coordinates, that’s scene/engine specific, but it should be easy as long as you know the transformation matrix of the surface that contains the JavaFX texture.

thanks for the info, no problem with math here, but I am still not shure how to lock the mouse to do some first person stuff with mouse, keyboard and for those, who prefer it, even gamepad. I think I am going to explore your sourcecode a little bit more.

Ok, I have integrated your code into my project, and I really like it. The problem is, that my cpu usage is pretty high. I have an Itel Gpu and Linux, which gives me software javafx. But I have the impression, that my render Screen in rendered on the GPU, pulled back into main memory and merged with all the other JavaFx screens, and then pushed back into the game. My question is, if I had a better GPU with better drivers will my framebuffer remain on the GPU?

here an image if you care. The Button is JavaFx ;D

This is normal and a better GPU won’t eliminate the framebuffer read-back. The point of this demo is to enable integration with zero changes to JavaFX and to showcase what such an integration could be used for. The overhead you’re seeing is probably too much to use in production, especially on low-end hardware.

Possible changes to JavaFX that would make it more viable:

  • Better PixelReader/Writer API to allow for zero-copy read-back loops. This would reduce memory/CPU pressure, but won’t eliminate the read-back (+ upload).
  • Exposure of the internal GL context to enable GPU copies via WGL/GLX make_current_read or NV_copy_image.
  • Exposure of the internal GL context and also of any FBOs or textures used for JavaFX rendering. These could be used directly without any copies via context object sharing.

The last 2 would also require rendering synchronization APIs and a flag that forces OpenGL rendering, even on Windows.

Thanks for the info so far. But I think there can be done something with this overhead. Currently I have these ideas:

I could make the JavaFx pipeline optional. This means as long as my mouse is grabbed by Lwjgl I would render without framebuffer directly with Display.swapBuffers. But as soon as the mouse is released (by pressing Esc) my screen will render into a framebuffer once and the GUI will shows up. But I am not shure if this is as easy as it sounds, because this requires that the JavaFx window to turn into an LWJGL window and vice versa.

A different approach to reduce the render overhead would be to move textures only in one direction. So instead of rendering the scene into a framebuffer, the GUI could be rendered into a window sized rgba texture. Then I can merge the GUI texture with the scene rendering within my rendering loop. This could also benefit from the fact, that (as I’ve mentioned earlier) GUI updates are commonly less frequent than scene updates. This requires offscreen rendering with javafx and translation of LWJGL events into JavaFx events.

Maybe if you are still interested about it:

Maybe if you are still interested about it: