package com.tus.wtf; import java.awt.GraphicsConfigTemplate; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; import java.awt.image.SinglePixelPackedSampleModel; import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.PixelFormat; import javafx.scene.image.WritableImage; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; import javax.media.j3d.Alpha; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.GraphicsConfigTemplate3D; import javax.media.j3d.ImageComponent2D; import javax.media.j3d.RotationInterpolator; import javax.media.j3d.Screen3D; import javax.media.j3d.Transform3D; import javax.media.j3d.TransformGroup; import javax.vecmath.Point3d; import sun.awt.image.IntegerInterleavedRaster; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.universe.SimpleUniverse; public final class J3DTest extends Application { private static final int WIDTH = 1500; private static final int HEIGHT = 1000; private SimpleUniverse univ = null; private BranchGroup scene = null; public BranchGroup createSceneGraph() { // Create the root of the branch graph BranchGroup objRoot = new BranchGroup(); // Create the TransformGroup node and initialize it to the // identity. Enable the TRANSFORM_WRITE capability so that // our behavior code can modify it at run time. Add it to // the root of the subgraph. TransformGroup objTrans = new TransformGroup(); objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); objRoot.addChild(objTrans); // Create a simple Shape3D node; add it to the scene graph. objTrans.addChild(new ColorCube(0.4)); // Create a new Behavior object that will perform the // desired operation on the specified transform and add // it into the scene graph. Transform3D yAxis = new Transform3D(); Alpha rotationAlpha = new Alpha(-1, 4000); RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, objTrans, yAxis, 0.0f, (float) Math.PI * 2.0f); BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); rotator.setSchedulingBounds(bounds); objRoot.addChild(rotator); // Have Java 3D perform optimizations on this scene graph. objRoot.compile(); return objRoot; } private void createUniverse(final Canvas3D canvas) { // Create simple universe with view branch univ = new SimpleUniverse(canvas); // This will move the ViewPlatform back a bit so the // objects in the scene can be viewed. univ.getViewingPlatform().setNominalViewingTransform(); // Ensure at least 5 msec per frame (i.e., < 200Hz) univ.getViewer().getView().setMinimumFrameCycleTime(25); // 25=>40Hz // Create the content branch and add it to the universe scene = createSceneGraph(); univ.addBranchGraph(scene); } private static GraphicsConfigTemplate getTemplate() { final GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); template.setStereo(GraphicsConfigTemplate.UNNECESSARY); template.setDoubleBuffer(GraphicsConfigTemplate.UNNECESSARY); return template; } private static Canvas3D getCanvas(final GraphicsContext context, final WritableImage image, final int[] data) { final GraphicsConfiguration configuration = GraphicsEnvironment.getLocalGraphicsEnvironment() .getDefaultScreenDevice().getBestConfiguration(getTemplate()); final Canvas3D canvas = new Canvas3D(configuration, true) { public void postSwap() { System.out.println("postSwap"); image.getPixelWriter().setPixels(0, 0, J3DTest.WIDTH, J3DTest.HEIGHT, PixelFormat.getIntArgbPreInstance(), data, 0, J3DTest.WIDTH); Platform.runLater(new Runnable() { public void run() { context.drawImage(image, 0, 0); } }); } }; return canvas; } @Override public void start(final Stage stage) throws Exception { final WritableImage image = new WritableImage(J3DTest.WIDTH, J3DTest.HEIGHT); final Canvas canvas = new Canvas(J3DTest.WIDTH, J3DTest.HEIGHT); final AnchorPane pane = new AnchorPane(canvas); final Scene scene = new Scene(pane); final DataBufferInt buffer = new DataBufferInt(J3DTest.WIDTH * J3DTest.HEIGHT); final Canvas3D canvas3D = getCanvas(canvas.getGraphicsContext2D(), image, buffer.getData()); final Screen3D screen = canvas3D.getScreen3D(); screen.setSize(J3DTest.WIDTH, J3DTest.HEIGHT); screen.setPhysicalScreenWidth(J3DTest.WIDTH * 0.0254 / 90.0); screen.setPhysicalScreenHeight(J3DTest.HEIGHT * 0.0254 / 90.0); canvas3D.setOffScreenBuffer(new ImageComponent2D(ImageComponent2D.FORMAT_RGBA, /** * new BufferedImage(J3DTest.WIDTH, J3DTest.HEIGHT, * BufferedImage.TYPE_INT_ARGB))); **/ new BufferedImage(ColorModel.getRGBdefault(), new IntegerInterleavedRaster(new SinglePixelPackedSampleModel( DataBuffer.TYPE_INT, J3DTest.WIDTH, J3DTest.HEIGHT, J3DTest.WIDTH, new int[] { 16711680, 65280, 255, -16777216 }), buffer, new Point(0, 0)), true, null), true, true)); /** * new BufferedImage(ColorModel.getRGBdefault(), new Writable(), true, * null), true, true)); **/ createUniverse(canvas3D); // canvas3D.startRenderer(); // FAILS TO WORK! AnchorPane.setLeftAnchor(canvas, 0d); AnchorPane.setRightAnchor(canvas, 0d); AnchorPane.setTopAnchor(canvas, 0d); AnchorPane.setBottomAnchor(canvas, 0d); stage.setTitle("JavaFX3D"); stage.setScene(scene); stage.centerOnScreen(); stage.show(); new Thread(new Runnable() { public void run() { for (;;) { try { canvas3D.renderOffScreenBuffer(); Thread.sleep(25); } catch (final Exception e) { System.out.println("Ops, missed frame!"); } } } }).start(); } public static void main(final String... a) { launch(a); } }