Monday, March 30, 2009

3D and JavaFX

I had a chance to watch recently "Monsters vs. Aliens", in IMAX 3D format. The movie was a brilliant piece of art, as most DreamWorks creations, and 3D added quite an edge to it. I left the theater under impression that 2D projectors will be replaced with 3D ones soon.

According to WSJ, "Hollywood plans to release as many as 45 3D films over the next two and a half to three years". "This weekend makes me confident that this is the beginning of the era, not just a passing fad," said DreamWorks CEO Jeffrey Katzenberg, referring to 3D. "This film certainly established a beachhead, and there are many more 3D films coming from talented and important filmmakers."

Spoiled by fun and ubiquity of 3D, the movie goers will demand 3D technology on the computer screens as well, at least in a form of 3D objects on a flat screen. What JavaFX can do to address this upcoming market?

JavaFX 1.1 API does not support 3D. Rumor is that later this year it will--Java3D is available (see a cool sample), and the task requires just a simple matter of integration. However, JavaFX has never been alien to the 3D, as shows this 2-years old Chris Oliver' demo. It was also refreshing to find out about German company InteractiveMesh (blogged by Jim Weaver), owned by August Lammersdorf and pushing JavaFX 3D to the new level .


The company page provides samples of JavaFX 1.1 apps and applets with 3D rendering, along with source and library download. (I'm sure, NetBeans users would appreciate NetBeans project, so, perhaps, August can oblige us in the future).


Thanks to InteractiveMesh, we can look under the hood of this beautiful implementation:

  • Java 3D renders off-screen into a lightweight component which is added via a resizable JavaFX SwingComponent to JavaFX Scene
  • The Java 3D rendering loop runs in parallel to the JavaFX painting loop with a minimal synchronized overlap. It is implemented as Java class FXCanvas3D, derived from JCanvas3D and available under the BSD license, and Java interface FXCanvas3DRepainter.
  • A Double Off-screen Buffer and a controlling Lock with two Conditions were introduced to ensure that the threads of both loops access the common image data deadlock-free. These two buffers are: BufferedImage which Java 3D is rendering into and a BufferedImage which JavaFX is drawing. Both images have an identical format type. Only for the period of time when integer values are copied from the first into the second image, the loops interrupt their regular tasks controlled by one of the two Lock's Condition. The other Condition guarantees that during resizing of the FXCanvas3D panel the Java 3D renderer thread isn't blocked.
  • The web page samples provide an implementation of the corresponding SwingComponent named as FXCanvas3DComp. This JavaFX class has the interface FXCanvas3DRepainter implemented and allows a FXCanvas3D object to call 'repaintFXCanvas3D()' from its 'postSwap()' method. The repaint request is handled by a FX.deferAction() - an equivalent to SwingUtilities.invokeLater() - and is executed on the EDT. The assigned function calls first 'copyOffScreenBuffer()' while the Java 3D renderer thread is waiting, and then calls 'repaint()' on the FXCanvas3D object. This completes the cycle of 3D off-screen rendering and image drawing.
  • The duration of one cycle on a multi-core system can be estimated as ( max(Java 3D loop, JavaFX loop) + image copying + thread handling ) ms. The cost of the extra BufferedImage in comparison to JCanvas3D is about ( image.width x image.height x 4 ) bytes of CPU memory.
  • Initiating the Java 3D engine, the 3D scene, and the FXCanvas3D object asynchronously is implemented with 'async operation' (see James Clarke' post), and is reliable and effective
Will InteractiveMesh' work help Sun JavaFX team to speed up the release of JavaFX 3D API? The time will tell. For now, the first generation of JavaFX "Monsters vs. Aliens" games may be implemented in 2D.

2 comments:

  1. "Java/Swing vs. JavaFX"

    Unfortunately, you won't find the wording 'JavaFX and 3D' neither in the JavaFX 1.1 FAQ nor in one of the JavaOne 2009 sessions. So, I'm deadly curious if and when we will see Monsters and Aliens animated and rendered by pure script coding on the JavaFX stage.

    Thanks for your detailed description of the FXCanvas3D API. When using Java 3D you will not be binded to a specific GUI framework. Currently it supports Swing(heavyweight/lightweight), Eclipse/SWT(heavyweight) and JavaFX(lightweight). Its fork JUniversal3D, on which InteractiveMesh is working, will be fully independent.

    Anatoli, have you already started your own first 3D sample?

    August Lammersdorf, InteractiveMesh

    ReplyDelete
  2. @August Lammersdorf

    Thank you for your comment.

    Hopefully, we will hear more about 'JavaFX and 3D' at JavaOne.
    My experiments with 3D are on a short list.
    Will be happy to see more of your great apps.

    ReplyDelete