Canvas3D disappears when resizing JComponets on Windows10

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Canvas3D disappears when resizing JComponets on Windows10

ThomasR
Hi All,

Resizing a JFrame alone, or a JPlitPane,  frequently causes the Canvas3D to disappear - only
an empty grey component is visible. I'm using the most recent Java3D1.6 and most recent version
of jogl (2.3.2) with Java8.

I tried to use some older versions of my software which uses Java7 with older versions of Java3d1.6
and jogl and the problem remains. It's as if the Canvas3D doesn't get an event to paint itself when
the JFrame is resized. No exeptions or core dumps occur afaik.

Interesting that if a mouse event most of the time will wake up the Canvas3d and it reappears.
A request to render something new in the display will also bring the Canvas back and everything works
as expected.

When the component is grey, NetBeans shows that all threads are "running" including all of the J3D threads.

Tom
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

gouessej
Administrator
Hi

Please provide a test case and tell me whether it is reproducible only under Windows 10.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

gouessej
Administrator
In reply to this post by ThomasR
Hi

I'm currently building Sweet Home 3D with Java3D 1.7.0-pre1 and JOGL 2.3.2, I'll give it a try under Windows 10. If it works, you'll have to look for the culprit in your own source code rather than in Java3D. JOGL 2.3.2 works correctly under Windows 10 and the other scenegraph APIs based on it too (especially JogAmp's Ardor3D Continuation, LibGDX, JMonkeyEngine, ...).
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

ThomasR
Hi,

Here is slightly modified test case I grabbed from this list. It exhibits the problem. In fact,
the Canvas3D is not visible on the initial setVisible. I believe the graphics is a GEForce 700
series and I installed the latest drivers from Nvidia, though it's a new system anyway.
I've not had any problems on other Windows machines XP and 7.

Java3DSimpleTest.java

Tom
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

philjord
Tom,
I can't tell you the exact cause but I can tell you how to work around the issue.

It appears to have been around since 2002
https://www.mail-archive.com/java3d-interest@java.sun.com/msg18026.html

The issue is that the renderer decides not to update the Canvas3D in the name of efficiency. However something else comes in and clears the Canvas3D to grey in a race condition with the Renderer, so you get the crazy sometimes grey output.

The work around is to always have at least 1 non passive behavior in the scene graph

Like this:




import java.awt.Frame;
import java.util.Enumeration;

import javax.media.j3d.Behavior;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.WakeupCondition;
import javax.media.j3d.WakeupOnElapsedFrames;
import javax.swing.SwingUtilities;
import javax.vecmath.Point3d;

import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class Java3DSimpleTest
{
        public static void createAndShowGUI()
        {
                BranchGroup root = new BranchGroup();
                root.addChild(new ColorCube(0.5f));
                root.addChild(go);
                Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration()) {
                        public void postSwap()
                        {
                                System.out.println("swap called");
                        }
                };

                SimpleUniverse universe = new SimpleUniverse(canvas);
                universe.getViewingPlatform().setNominalViewingTransform();
                universe.addBranchGraph(root);

                Frame frame = new Frame("Java3DSimpleTest");
                frame.add(canvas);
                frame.setSize(400, 400);
                frame.setVisible(true);
        }

        public static void main(String[] args)
        {
                SwingUtilities.invokeLater(new Runnable() {
                        public void run()
                        {
                                createAndShowGUI();
                        }
                });
        }

        private static GoBehavior go = new GoBehavior();

        private static class GoBehavior extends Behavior
        {
                private WakeupCondition FPSCriterion = new WakeupOnElapsedFrames(0, false);

                public GoBehavior()
                {
                        setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0), Double.POSITIVE_INFINITY));
                        setEnable(true);
                }

                public void initialize()
                {
                        wakeupOn(FPSCriterion);
                }

                @SuppressWarnings("rawtypes")
                public void processStimulus(Enumeration criteria)
                {

                        wakeupOn(FPSCriterion);
                }
        }

}


Notice if you comment out the line
 root.addChild(go);

then the console no longer fills with swap called.

Sorry I don't don't the actual cause and a decent way around whatever is painting the grey.
Phil.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

gouessej
Administrator
Thank you for the example.

Reminder: If you use Java3D 1.7.0-pre1, you have to replace "javax.media.j3d" and "com.sun.j3d" by "org.jogamp.java3d".
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

ThomasR
In reply to this post by gouessej
Hi Julien,

Did you have the same problem with this test code on Windows10?

Do you have any ideas or intuition on how application code can cause a problem like this? Where would we
need to be digging to fix this problem? I assume it's not a jogl issue since there's no core dump.

Tom
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

ThomasR
In reply to this post by philjord
Hi Phil,

Your workaround seems to work with this very simple example. Thank you very much. This
example also provides some valuable insight. Have you noticed any significant degradation
of performance with this Behavior?

Tom
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

gouessej
Administrator
In reply to this post by ThomasR
Sorry for the delay, I still have to give it a try under Windows 10... I'd like to determine whether your problem has something to do with a particular hardware but according to the hint given by Phil, it is probably reproducible in other contexts even without Windows 10 :s
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

ThomasR
Hi Phil, Julien,

Using a non-passive WakeupOnElapsedFrames almost started my MacBook on fire! It works, but
hits the CPU hard. Do you think enabling this Behavior for short intervals around a Frame
creation and resize might work?

Tom
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

philjord
Tom,
Sorry my answer was just an old work around I happened to recal.

Good news I've just stumbled across the real answer that I put in place many years ago also.

Early in your main (first line) add

System.setProperty("sun.awt.noerasebackground", "true");


Just as I was removing System.setProperty("jogl.disable.opengles", "true"); from my main call I found that call next to it, and it suddenly came back to me.


When you add that simple behavior Java3d will go as fast as it can, and send instructions to the GPU very quickly, so they will both thrash. The behavior itself does nothing so takes effectively zero time, not slowing anything down.

In almost all cases you'll want to add a line like this after you create your canvas3d and add it to a Universe:
canvas.getView().setMinimumFrameCycleTime(20);



This will set the maximum frame rate to 50, and allow the CPU and GPU to relax a bit. Feel free to set it to anything that seems right.


Of course things may be different on the Mac regarding the property.

Phil.


import java.awt.Frame;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.swing.SwingUtilities;

import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.SimpleUniverse;

public class Java3DSimpleTest
{
        public static void createAndShowGUI()
        {
                BranchGroup root = new BranchGroup();
                root.addChild(new ColorCube(0.5f));
                Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration());

                SimpleUniverse universe = new SimpleUniverse(canvas);
                universe.getViewingPlatform().setNominalViewingTransform();
                universe.addBranchGraph(root);
               
                ////////////////////////////
                canvas.getView().setMinimumFrameCycleTime(20);
               
                Frame frame = new Frame("Java3DSimpleTest");
                frame.add(canvas);
                frame.setSize(400, 400);
                frame.setVisible(true);
               
        }

        public static void main(String[] args)
        {
                ///////////////////////////
                System.setProperty("sun.awt.noerasebackground", "true");
               
                SwingUtilities.invokeLater(new Runnable() {
                        public void run()
                        {
                                createAndShowGUI();
                        }
                });
        }
}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Canvas3D disappears when resizing JComponets on Windows10

ThomasR
Thanks Phil! This is looking to be a good solution.
Loading...