Login  Register

Re: Java 3D crash or flickering

Posted by philjord on Oct 25, 2016; 1:21am
URL: https://forum.jogamp.org/Java-3D-crash-or-flickering-tp4035074p4037362.html

Ok Team, progress, but it's not perfect.

I have discovered that the property
-Dsun.java2d.noddraw=true
Is involved in this problem.

When I set this to false, I cannot get this problem to reproduce anywhere.
Not in the IDE running the 3D_Viewer Plugin, not in the IDE running ImageJ nor Fiji.

and when I export a Fiji jar file with
System.setProperty("sun.java2d.noddraw", "false");
in the main() method everything works every time.

I've looked at the world from Java3D's perspective and the only difference I can find is that the device from
awtConfig.getAWTGraphicsConfiguration().getDevice()
is
sun.java2d.d3d.D3DGraphicsDevice when things work (that is the prop = false)
and
sun.awt.Win32GraphicsDevice when things break (prop = true)

which tells me almost nothing.

I can't work out how system properties are set when using the exe, so someone from the ImageJ side would need to confirm a totally unaltered release with just that property set to false fixes this issue.

Then if this is confirmed, the need for the property to be true, like here:
http://imagej.1557.x6.nabble.com/FFT-of-color-images-td4354255.html
Will make for an interesting decision.


Now for something slightly weird, I've cut this down to a minimal test case.
I created a new project, added the Fiji release java3d-core, java3d-utils and vecmath jars, then made these the two classes below.
And I absolutely cannot see what the difference is, but I get a perfectly working HelloUniverse frame and a broken "ImageJ 3D Viewer" frame.

So if anyone else wants to try and see if they get the same madness that would help.

package _testcase;

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.scijava.java3d.BranchGroup;
import org.scijava.java3d.Canvas3D;
import org.scijava.java3d.utils.universe.SimpleUniverse;

public class ImageJ3DViewerTestCase {

        public static SimpleUniverse univ;

        public static void main(final String[] args) {
                System.setProperty("sun.java2d.noddraw", "true");
                //System.setProperty("sun.java2d.noddraw", "false");
               
                //Works every time!///////////////////////////////////
                HelloUniverse hu = new HelloUniverse();
                hu.setVisible(true);
               
               
                //Only works iwth noddraw = false//////////////////////////////////////////////////////
                Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
                univ = new SimpleUniverse(c);

                univ.getViewingPlatform().setNominalViewingTransform();
                univ.getViewer().getView().setMinimumFrameCycleTime(5);

                BranchGroup scene = HelloUniverse.createSceneGraph();
                univ.addBranchGraph(scene);

                JFrame win = new JFrame("ImageJ 3D Viewer");

                JPanel drawingPanel = new JPanel();
                drawingPanel.setLayout(new BorderLayout());
                drawingPanel.setPreferredSize(new Dimension(250, 250));
                win.getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER);
                drawingPanel.add(c, java.awt.BorderLayout.CENTER);

                win.pack();
                win.setVisible(true);

        }

}


 package _testcase;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;

import javax.swing.JPanel;
import javax.swing.WindowConstants;

import org.scijava.java3d.Alpha;
import org.scijava.java3d.BoundingSphere;
import org.scijava.java3d.BranchGroup;
import org.scijava.java3d.Canvas3D;
import org.scijava.java3d.RotationInterpolator;
import org.scijava.java3d.Transform3D;
import org.scijava.java3d.TransformGroup;
import org.scijava.java3d.utils.geometry.ColorCube;
import org.scijava.java3d.utils.universe.SimpleUniverse;
import org.scijava.vecmath.Point3d;

public class HelloUniverse extends javax.swing.JFrame {
        private JPanel drawingPanel;
        private SimpleUniverse univ = null;
        private BranchGroup scene = null;

        public HelloUniverse() {
                initComponents();
                Canvas3D c = createUniverse();
                drawingPanel.add(c, java.awt.BorderLayout.CENTER);
                scene = createSceneGraph();
                univ.addBranchGraph(scene);
        }

        private void initComponents() {
                drawingPanel = new JPanel();
                setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                setTitle("HelloUniverse");
                drawingPanel.setLayout(new BorderLayout());
                drawingPanel.setPreferredSize(new Dimension(250, 250));
                getContentPane().add(drawingPanel, BorderLayout.CENTER);
                pack();
        }

        private Canvas3D createUniverse() {
                GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
                Canvas3D c = new Canvas3D(config);
                univ = new SimpleUniverse(c);
                univ.getViewingPlatform().setNominalViewingTransform();
                univ.getViewer().getView().setMinimumFrameCycleTime(5);
                return c;
        }

        public static BranchGroup createSceneGraph() {
                BranchGroup objRoot = new BranchGroup();
                TransformGroup objTrans = new TransformGroup();
                objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
                objRoot.addChild(objTrans);
                objTrans.addChild(new ColorCube(0.4));
                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);
                objRoot.compile();
                return objRoot;
        }

}