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 |
Administrator
|
Hi
Please provide a test case and tell me whether it is reproducible only under Windows 10.
Julien Gouesse | Personal blog | Website
|
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
|
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 |
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. |
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
|
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 |
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 |
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
|
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 |
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(); } }); } } |
Free forum by Nabble | Edit this page |