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