From : jdverret@tx.rr.com
Hello everyone. First, congratulations to the team on your very fast port for Java3D to use jogl! I'm very impressed with the much improved performance over Java3d 1.5.1 However, I cannot seem to get true stereo working with Java3D (see example code StereoTestJava3D.java) However, it works just fine using the jogl. (see example code StereoTestJogl.java) The symptom when I try StereoTestJava3D is that I get this message when trying "Stereo is not support, you should only see the left red cone." (and BTW, I don't see the red nor the green cone) I'm running Linux Fedora 15 and have the latest nvidia drivers. Thanks in advance. ------------------------------------------------- //StereoTestJava3D import java.util.*; import com.sun.j3d.utils.geometry.*; import com.sun.j3d.utils.universe.*; import javax.media.j3d.*; import javax.vecmath.*; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; /** * Pure immediate mode stereo example program for stereo. In pure * immediate mode, the renderer must be stopped on the Canvas being * rendered into. In our example, this is done immediately after the * canvas is created. A separate thread is started up to do the * immediate mode rendering. */ public class StereoTestJava3D extends javax.swing.JFrame implements Runnable { private SimpleUniverse univ = null; private BranchGroup scene = null; // Set this to true when the graphics card use shared z buffer // in stereo mode. public static String defaultSharedStereoZbuffer = Boolean.TRUE.toString(); private boolean sharedStereoZbuffer; private boolean stereoSupport; private Canvas3D canvas; private GraphicsContext3D gc; private Shape3D leftConeBody, rightConeBody; private Shape3D leftConeCap, rightConeCap; private Transform3D cmt = new Transform3D(); private Vector3f leftTrans, rightTrans; // One rotation (2*PI radians) every 6 seconds private Alpha rotAlpha = new Alpha(-1, 6000); private double angle; // Compute data which is common for both // left and right eye void computeSharedData() { // Compute angle of rotation based on alpha value angle = rotAlpha.value() * 2.0*Math.PI; cmt.rotY(angle); } // Render the geometry in right eye void renderLeft() { cmt.setTranslation(leftTrans); gc.setModelTransform(cmt); if (sharedStereoZbuffer) { // Graphics card shared same z buffer in stereo mode, // in this case we have to explicitly clearing both // frame buffers. gc.clear(); } gc.draw(leftConeBody); gc.draw(leftConeCap); } // Render the geometry for right eye void renderRight() { cmt.setTranslation(rightTrans); gc.setModelTransform(cmt); if (sharedStereoZbuffer) { // Graphics card shared same z buffer in stereo mode, // in this case we have to explicitly clearing both // frame buffers. gc.clear(); } gc.draw(rightConeBody); gc.draw(rightConeCap); } // // Run method for our immediate mode rendering thread. // public void run() { // Set up Graphics context gc = canvas.getGraphicsContext3D(); // We always need to set this for PureImmediate // stereo mode gc.setBufferOverride(true); Color3f lightColor = new Color3f(1, 1, 1); Vector3f lightDir = new Vector3f(0, 0, -1); DirectionalLight light = new DirectionalLight(lightColor, lightDir); gc.addLight(light); Appearance redApp = new Appearance(); Appearance greenApp = new Appearance(); Color3f ambientColor = new Color3f(0, 0, 0); Color3f emissiveColor = new Color3f(0, 0, 0); Color3f diffuseColor = new Color3f(1, 0, 0); Color3f specularColor = new Color3f(1, 1, 1); redApp.setMaterial(new Material(ambientColor, emissiveColor, diffuseColor, specularColor, 5)); diffuseColor = new Color3f(0, 1, 0); greenApp.setMaterial(new Material(ambientColor, emissiveColor, diffuseColor, specularColor, 5)); // Set up geometry Cone leftCone = new Cone(0.4f, 0.6f, Primitive.GENERATE_NORMALS, redApp); Cone rightCone = new Cone(0.4f, 0.6f, Primitive.GENERATE_NORMALS, greenApp); leftConeBody = leftCone.getShape(Cone.BODY); leftConeCap = leftCone.getShape(Cone.CAP); rightConeBody = rightCone.getShape(Cone.BODY); rightConeCap = rightCone.getShape(Cone.CAP); leftTrans = new Vector3f(-0.6f, 0, 0); rightTrans = new Vector3f(0.6f, 0, 0); while (true) { // compute data which is can be used // for both left and right eye computeSharedData(); if (stereoSupport) { if (!sharedStereoZbuffer) { gc.setStereoMode(GraphicsContext3D.STEREO_BOTH); // This clear both left and right buffers, we // must set STEREO_BOTH before it. Otherwise // it only clear LEFT or RIGHT buffer unless // this is invoke twice for each buffer. gc.clear(); } gc.setStereoMode(GraphicsContext3D.STEREO_LEFT); renderLeft(); gc.setStereoMode(GraphicsContext3D.STEREO_RIGHT); renderRight(); } else { gc.clear(); renderLeft(); } // This swap both left and right buffers so // there is no need to set STEREO_BOTH before it canvas.swap(); // Be polite to other threads ! Thread.yield(); } } private void createUniverse() { // Preferred to use Stereo GraphicsConfigTemplate3D gct = new GraphicsConfigTemplate3D(); gct.setStereo(GraphicsConfigTemplate3D.PREFERRED); GraphicsConfiguration config = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(gct); canvas = new Canvas3D(config); Map map = canvas.queryProperties(); stereoSupport = canvas.getStereoAvailable(); if (stereoSupport) { System.out.println("This machine support stereo, you should see a red cone on the left and green cone on the right."); // User can overide the above default behavior using // java3d property. String str = System.getProperty("j3d.sharedstereozbuffer", defaultSharedStereoZbuffer); sharedStereoZbuffer = (new Boolean(str)).booleanValue(); System.out.println("********** Enabling stereo"); canvas.setStereoEnable( true ); } else { System.out.println("Stereo is not support, you should only see the left red cone."); } if (!canvas.getDoubleBufferAvailable()) { System.out.println("Double buffer is not support !"); } // we must stop the Renderer in PureImmediate mode canvas.stopRenderer(); // 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(5); // Start a new thread that will continuously render (new Thread(this)).start(); } /** * Creates new form StereoTestJava3D */ public StereoTestJava3D() { // Initialize the GUI components initComponents(); // Create Canvas3D and SimpleUniverse; add canvas to drawing panel createUniverse(); drawingPanel.add(canvas, java.awt.BorderLayout.CENTER); } // ---------------------------------------------------------------- /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents private void initComponents() { drawingPanel = new javax.swing.JPanel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setTitle("StereoTestJava3D"); drawingPanel.setLayout(new java.awt.BorderLayout()); drawingPanel.setPreferredSize(new java.awt.Dimension(512, 256)); getContentPane().add(drawingPanel, java.awt.BorderLayout.CENTER); pack(); }// </editor-fold>//GEN-END:initComponents /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new StereoTestJava3D().setVisible(true); } }); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel drawingPanel; // End of variables declaration//GEN-END:variables } =========================================== =========================================== // StereoTestJogl import java.awt.Frame; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.media.opengl.*; import javax.media.opengl.awt.GLCanvas; import javax.media.opengl.glu.GLU; import com.jogamp.opengl.util.FPSAnimator; import com.jogamp.opengl.util.gl2.GLUT; public class StereoTestJogl implements GLEventListener { private GLU glu = new GLU(); private GLUT glut = new GLUT(); public static void main(String[] args) { StereoTestJogl StereoTestJogl = new StereoTestJogl(); GLCapabilities glCaps = new GLCapabilities(GLProfile.get(GLProfile.GL2)); glCaps.setStereo(true); GLCanvas canvas = new GLCanvas(glCaps); canvas.addGLEventListener(StereoTestJogl); final Frame frame = new Frame("Stereo Test"); frame.add(canvas); frame.setSize(800, 600); frame.setLocationRelativeTo(null); final FPSAnimator animator = new FPSAnimator(canvas, 60); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { animator.stop(); frame.dispose(); System.exit(0); } }); frame.setVisible(true); animator.start(); canvas.requestFocusInWindow(); } public void init(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(45.0f, 800/600.0f, 1, 100); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt(0, 0, 4, 0, 0, 0, 0, 1, 0); gl.glEnable(GL.GL_DEPTH_TEST); gl.glEnable(GL2.GL_LIGHTING); gl.glEnable(GL2.GL_LIGHT0); } public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); gl.glDrawBuffer(GL2GL3.GL_BACK_LEFT); gl.glClear(GL.GL_COLOR_BUFFER_BIT |GL.GL_DEPTH_BUFFER_BIT); gl.glPushMatrix(); gl.glTranslated(-0.2, 0, 0); drawScene(gl); gl.glPopMatrix(); gl.glDrawBuffer(GL2GL3.GL_BACK_RIGHT); gl.glClear(GL.GL_COLOR_BUFFER_BIT |GL.GL_DEPTH_BUFFER_BIT); gl.glPushMatrix(); gl.glTranslated(0.2, 0, 0); drawScene(gl); gl.glPopMatrix(); } private void drawScene(GL2 gl) { glut.glutSolidTeapot(1); // glut.glutSolidTorus( 0.5,1,50,50); // glut.glutSolidDodecahedron(); // glut.glutSolidTetrahedron(); } public void dispose(GLAutoDrawable drawable) {} public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {} }
jdverret@tx.rr.com
|
This post was updated on .
Hi Harvey, Hi Julien, and Hi Jody,
first of all, thanks a lot to you - Julien and Harvey - for starting saving Java 3D! We are also using Java 3D for our CELLmicrocosmos project, and as these are quite large software projects running since several years (area: Bioinformatics & Visualization), we were quite unhappy about the situation of J3D. Still, it runs on many machines, but as you said, on Mac OS X it is already a huge problem. So we are happy that you started porting J3D to JOGL. I made a few tests with our major projects MembraneEditor and CellExplorer, and both work very fine with your j3d-1.6.0-pre8. I did it by using Eclipse, importing Jogamp as a separate project, binding it e.g. to the CellExplorer project via the Build Path and then I just substituted the standard J3D jars (j3dcore/j3dutil/vecmath). Moreover, I use the ancient j3d-org-geom-core.jar. I just left it in the Build Path, and still it seems to work. However, I did only some first tests, to I may add small bugs later. But, here the topic of jodyv is Stereo, and this is also a major topic of our projects. And yes, we have the same problem as Jody, stereo does not work. To help you to evaluate this problem, I just coded some small example how the standard stereo method of Java3D works (I stole Jody's cone ;-) . It is even more easy than the one of Jody, as it does not use immediate mode and this means, the this Jody's example is closer to OpenGL. I use only Java 3D coding now. Here is the source code: ---------------------------------------------------------------------------------------------------------------- import java.awt.Dimension; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import javax.media.j3d.Appearance; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.DirectionalLight; import javax.media.j3d.GraphicsConfigTemplate3D; import javax.media.j3d.Material; import javax.media.j3d.PointLight; import javax.swing.JFrame; import javax.vecmath.Color3f; import javax.vecmath.Point3d; import javax.vecmath.Point3f; import javax.vecmath.Vector3f; import com.sun.j3d.utils.behaviors.vp.OrbitBehavior; import com.sun.j3d.utils.geometry.Cone; import com.sun.j3d.utils.geometry.Primitive; import com.sun.j3d.utils.universe.SimpleUniverse; /** * Simple Java 3D Stereoscopy test example. * * There are two ways to activate stereoscopy here: * 1. Use the code block _STEREO_CANVAS_ and the last code block in * StereoTestJava3DStandard() * 2. Deactivate the code blocks mentioned in 1. and activate the line * SimpleUniverse universe = new SimpleUniverse(); and start the * program with the VM argument -Dj3d.stereo=PREFERRED * * You need some professional 3D equipment such as NVIDIA Quadro (FX) or * ATI/ASUS FireGL, compatible monitors and to activate the stereoscopic * capabilities in the graphics driver preferences. * * @author bjoern */ public class StereoTestJava3DStandard { public StereoTestJava3DStandard() { BranchGroup rootBG = new BranchGroup(); BoundingSphere universeBounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100000.0); // add directional light (for front of object) Color3f lightColor = new Color3f(1, 1, 1); Vector3f lightDir = new Vector3f(0, 0, -1); DirectionalLight dirLight = new DirectionalLight(true, lightColor, lightDir); rootBG.addChild(dirLight); dirLight.setInfluencingBounds(universeBounds); // add point light (for bottom of object) PointLight pointLight = new PointLight(true, new Color3f(1, 1, 1), new Point3f(0, -1, 0), new Point3f(1, 1, 1)); pointLight.setInfluencingBounds(universeBounds); rootBG.addChild(pointLight); // add colored cone Appearance redApp = new Appearance(); Color3f ambientColor = new Color3f(0, 0, 0); Color3f emissiveColor = new Color3f(0, 0, 0); Color3f diffuseColor = new Color3f(1, 0, 0); Color3f specularColor = new Color3f(1, 1, 1); redApp.setMaterial(new Material(ambientColor, emissiveColor, diffuseColor, specularColor, 5)); Cone cone = new Cone(0.4f, 0.6f, Primitive.GENERATE_NORMALS, 64, 64, redApp); rootBG.addChild(cone); // create stereo canvas and universe (-> _STEREO_CANVAS_) GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); template.setStereo(GraphicsConfigTemplate3D.PREFERRED); template.setSceneAntialiasing(GraphicsConfigTemplate3D.PREFERRED); GraphicsConfiguration config = GraphicsEnvironment .getLocalGraphicsEnvironment().getDefaultScreenDevice() .getBestConfiguration(template); Canvas3D stereoCanvas = new Canvas3D(config); SimpleUniverse universe = new SimpleUniverse(stereoCanvas); // create standard canvas and universe (used only without // _STEREO_CANVAS_) // activate 3D stereoscopy with VM argument: // -Dj3d.stereo=PREFERRED // SimpleUniverse universe = new SimpleUniverse(); universe.getViewingPlatform().setNominalViewingTransform(); universe.addBranchGraph(rootBG); // attach orbit behavior for mouse navigation OrbitBehavior orbit = new OrbitBehavior(universe.getCanvas(), OrbitBehavior.REVERSE_ALL); orbit.setSchedulingBounds(universeBounds); universe.getViewingPlatform().setViewPlatformBehavior(orbit); // create the window and add the 3D canvas (used only with // _STEREO_CANVAS_) JFrame frame = new JFrame(); frame.setSize(new Dimension(200, 200)); frame.setMinimumSize(new Dimension(200, 200)); frame.add(stereoCanvas); frame.setVisible(true); } public static void main(String[] args) { // start the program new StereoTestJava3DStandard(); } } ---------------------------------------------------------------------------------------------------------------- So, if I use this example with standard Java 3D libraries on my computer (incl. PNY/NVIDIA Quadro 4000 + Planar StereoMirror Monitor), the cone is rendered for the left and the right eye. And now - this should be interesting also for Jody - if I use your libraries, then neither the left nor the right perspective is rendered. Exceptionally the centered perspective is rendered (cyclopean perspective). In other words, stereo is completely ignored. By the way, these are the files found in my build path: gluegen-rt-natives-windows-i586.jar j3dcore.jar j3dutils.jar joal-natives-windows-i586.jar jocl-natives-windows-i586.jar jogl-all-natives-windows-amd64.jar jogl-all-noawt.jar jogl-awt.jar vecmath.jar You can run the example above in two ways. If you just copy it this way, then it will try to start stereoscopy mode, if it is available by the hardware. The other way is, to use just a completely regular canvas (see the comment in the source code) and use then the VM argument : -Dj3d.stereo=PREFERRED This was the standard way how I used all these years the stereo method. I just tested it now on Windows 7 (64 bit). Of course, I also tested Jody's example. With the old libraries, I see one cone for each eye. With the JOGL J3D libraries, I see only - oh - a black background. I think, this is the case, because Jody's pipeline addresses explicitely the left and right eye. So, maybe it is really easy for Harvey to fix this problem by just adding some swith, but it might also be a little bit complicated. For example, in J3D you can easily manipulate the eye distance in a stereo environment with this method: ---------------------------------------------------------------------------------------------------------------- public void setEyeDistance(double d) { Canvas3D canvas = universe.getCanvas(); if (canvas == null) return; double lx = -d/2; Point3d left = new Point3d(); canvas.getView().getPhysicalBody().getLeftEyePosition(left); left.setX(lx); double rx = d/2; Point3d right= new Point3d(); canvas.getView().getPhysicalBody().getRightEyePosition(right); right.setX(rx); canvas.setLeftManualEyeInImagePlate(left); canvas.setRightManualEyeInImagePlate(right); canvas.getView().getPhysicalBody().setLeftEyePosition(left); canvas.getView().getPhysicalBody().setRightEyePosition(right); } ---------------------------------------------------------------------------------------------------------------- So if you - Harvey - already were coding in this area, maybe it runs already, if you attach a small swith. But if you did not work with this PhysicalBody methods, it might be even more work. So if there are more questions and I can help in this issue, please let me know. However, thanks a lot for your great work!!! Björn |
Hi everyone,
We are using Java3D as a rendering engine in our open source scientific visualization software VisNow (http://visnow.icm.edu.pl). So far we were forced to stick to v1.5.2 as it was no longer developed, but it was some problem recently especially on MacOS X. So I will add another compliments to Harvey and other - great work porting Java3D to JOGL!!! We'll switch to it in our software soon - right after we confirm all tests are working properly. As far as stereo rendering - we are using stereo under Linux (Linux 64-bit + Nvidia Quadro 6000 + 331.38 driver) and have quite similar problems as in your posts, but with some exceptions. I'll summarize them in points for our setup: - we observed that stereo is working properly on JRE 1.6 and it does not work on JRE 1.7 - it applies to both old Java3D 1.5.2 and new 1.6.0-pre9 - the result on JRE 1.7 is that only one image eye is visible - pure JOGL stereo works fine on both platforms 1.6 and 1.7 - the code above works properly (1.6) only with changes: template.setStereo(GraphicsConfigTemplate3D.REQUIRED); stereoCanvas.setStereoEnable(true); It seems that something has changed in Java 7 that is causing Canvas3D to improperly interpret stereo rendering. I've only found one such report similar to our problems and related to Java 7: http://stackoverflow.com/questions/21239229/stereo-problems-on-linux-using-java-7-how-to-change-the-gc-of-a-component-afte?rq=1 Unfortunately Harvey told me that he's short on time now to take a deeper look into the problem. Anyone have any ideas? |
Administrator
|
Hi
Please can you indicate exactly which version of Java you use under GNU Linux? Please test at least once with OpenJDK. If there is a regression in Java itself, this bug should be reproducible without Java3D and reported against Java.
Julien Gouesse | Personal blog | Website
|
This post was updated on .
Hi,
I've tested this issue under Oracle JDK 1.7.0_51, OpenJDK 1.7.0_51, IBM JDK 1.7, Oracle JDK 1.6.0_43 and IBM JDK 1.6. See below for details. On all platforms it works fine on Java 6 and does not work with Java 7. See also this post for reference: http://stackoverflow.com/questions/21239229/stereo-problems-on-linux-using-java-7-how-to-change-the-gc-of-a-component-afte?rq=1 1) Oracle JDK 1.7.0_51 - stereo rendering does not work with Java3D Canvas3D, works fine with JOGL GLCanvas java version "1.7.0_51" Java(TM) SE Runtime Environment (build 1.7.0_51-b13) Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode) java.runtime.name = Java(TM) SE Runtime Environment java.vm.version = 24.51-b03 java.vm.vendor = Oracle Corporation java.vm.name = Java HotSpot(TM) 64-Bit Server VM java.specification.version = 1.7 java.runtime.version = 1.7.0_51-b13 os.arch = amd64 os.name = Linux os.version = 3.11.10-7-desktop 2) OpenJDK 1.7.0_51 - stereo rendering does not work with Java3D Canvas3D, works fine with JOGL GLCanvas java version "1.7.0_51" OpenJDK Runtime Environment (IcedTea 2.4.4) (suse-24.13.5-x86_64) OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode) java.runtime.name = OpenJDK Runtime Environment java.vm.version = 24.45-b08 java.vm.vendor = Oracle Corporation java.vm.name = OpenJDK 64-Bit Server VM java.specification.version = 1.7 java.runtime.version = 1.7.0_51-b00 os.arch = amd64 os.name = Linux os.version = 3.11.10-7-desktop 3) IBM JDK 1.7.0 - stereo rendering does not work with Java3D Canvas3D, works fine with JOGL GLCanvas java version "1.7.0" Java(TM) SE Runtime Environment (build pxa6470_27-20131115_04) IBM J9 VM (build 2.7, JRE 1.7.0 Linux amd64-64 Compressed References 20131114_175264 (JIT enabled, AOT enabled) J9VM - R27_Java727_GA_20131114_0833_B175264 JIT - tr.r13.java_20131113_50523 GC - R27_Java727_GA_20131114_0833_B175264_CMPRSS J9CL - 20131114_175264) JCL - 20131113_01 based on Oracle 7u45-b18 java.runtime.name = Java(TM) SE Runtime Environment java.vm.version = 2.7 java.vm.vendor = IBM Corporation java.vm.name = IBM J9 VM java.specification.version = 1.7 java.runtime.version = pxa6470_27-20131115_04 os.arch = amd64 os.name = Linux os.version = 3.11.10-7-desktop 4) Oracle JDK 1.6.0_43 - stereo rendering works properly with both Java3D Canvas3Dand JOGL GLCanvas java version "1.6.0_43" Java(TM) SE Runtime Environment (build 1.6.0_43-b01) Java HotSpot(TM) 64-Bit Server VM (build 20.14-b01, mixed mode) java.runtime.name = Java(TM) SE Runtime Environment java.vm.version = 20.14-b01 java.vm.vendor = Sun Microsystems Inc. java.vm.name = Java HotSpot(TM) 64-Bit Server VM java.specification.version = 1.6 java.runtime.version = 1.6.0_43-b01 os.arch = amd64 os.name = Linux os.version = 3.11.10-7-desktop 5) IBM JDK 1.6.0 - stereo rendering works properly with both Java3D Canvas3Dand JOGL GLCanvas java version "1.6.0" Java(TM) SE Runtime Environment (build pxa6460sr15fp1-20140110_01(SR15 FP1)) IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Linux amd64-64 jvmxa6460sr15-20131231_180656 (JIT enabled, AOT enabled) J9VM - 20131231_180656 JIT - r9_20130920_46510ifx3 GC - GA24_Java6_SR15_20131231_1152_B180656) JCL - 20140107_01 java.runtime.name = Java(TM) SE Runtime Environment java.vm.version = 2.4 java.vm.vendor = IBM Corporation java.vm.name = IBM J9 VM java.specification.version = 1.6 java.runtime.version = pxa6460sr15fp1-20140110_01 (SR15 FP1) os.arch = amd64 os.name = Linux os.version = 3.11.10-7-desktop |
In reply to this post by babor
The changes seen in the Java 7 update are caused by the following bug-fix 5 years ago: Is it possibly for you to set the stereo GC on the parent component before you add the Canvas3D to it?http://bugs.java.com/view_bug.do?bug_id=6804747 http://hg.openjdk.java.net/jdk7u/jdk7u/jdk/rev/66d6db0a1de6 2014-03-06 10:57 GMT+01:00 babor [via jogamp] <[hidden email]>: Hi everyone, |
First of all, even if you could do that it seems highly impractical - every time you wish to add Canvas3D to any container you'd have to set GC to the whole hierarchy up to the JFrame or Window. Secondly, the GC you have with stereo enabled is javax.media.j3d.JoglGraphicsConfiguration and as it cannot be cast to sun.awt.X11GraphicsConfig you can't use it in JFrame constructor (as setGraphicsConfiguration is private in Component). Finally, I am aware of this change in setGraphicsConfiguration in Java 7, but it should not influence stereo on Canvas3D as it does not influence stereo on GLCanvas in JOGL (and they both extend java.awt.Canvas). |
I have posted the issue to OpenJDK awt-dev:
http://mail.openjdk.java.net/pipermail/awt-dev/2014-March/007173.html |
Administrator
|
In reply to this post by babor
Maybe it would be possible to write a dirty kludge to work around this known regression in AWT but I'm against this option because it isn't suitable on the long term, it would probably be difficult to maintain on all supported platforms (especially under Mac) and this bug should be fixed in AWT itself. Moreover, the fact that GLCanvas and Canvas3D both extend java.awt.Canvas doesn't mean that they don't work differently. Canvas3D was initially written not with JOGL in mind as Java3D had to stay compatible with several renderers. If you really want to avoid this kind of trouble in the future, rather use another scenegraph whose canvases and windows directly extend JOGL canvases. The poorly implemented Java3D canvases won't be rewritten and we won't provide some NEWT compatible Java3D canvases which means that you'll be concerned by all regressions in AWT affecting its canvases based on it or on Swing. Xerxes just did the right thing. I imagine that this is typically not the kind of answer you would like to get but I still plan to write detailed migration guides to help developers to switch to more viable scenegraphs on the long term and I can help you. Some of us try to keep Java3D alive as is, without changing its public API but some of its design flaws prevent us from making it evolve without risking to break it. You might have to live with Java3D and undergo some remaining AWT bugs or to switch to another scenegraph (which is doable but not without any risk).
Julien Gouesse | Personal blog | Website
|
Thanks for your comments. Surely the idea of different scenegraph is acceptable, but at the moment we'd like to keep Java3D API within our application. Changing the scenegraph will be quite a challenge for us.
In the meantime I have a kind of the solution - it works fine but is not very "graceful" :) Following the path that AWT Component overrides GC of Canvas3D when it is added to a parent, it is possible to react on such event, find the topmost Component and reset the original Canvas3D GC to the whole hierarchy using reflection on setGraphicsConfiguration (quite as Xerxes suggested). A wrapped Canvas3D can look like this: import java.awt.Component; import java.awt.Container; import java.awt.GraphicsConfiguration; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.lang.reflect.Method; import javax.media.j3d.Canvas3D; public class WrappedCanvas3D extends Canvas3D { private GraphicsConfiguration initialGC; public WrappedCanvas3D(GraphicsConfiguration graphicsConfiguration) { super(graphicsConfiguration); initialGC = this.getGraphicsConfiguration(); this.addHierarchyListener(new HierarchyListener() { @Override public void hierarchyChanged(HierarchyEvent e) { if(e.getChangeFlags() == HierarchyEvent.PARENT_CHANGED) { try { Class c = java.awt.Component.class; Method method = c.getDeclaredMethod("setGraphicsConfiguration", GraphicsConfiguration.class); method.setAccessible(true); Component topmostComponent = getTopmostComponent(e.getChangedParent()); if(topmostComponent != null && initialGC != null) method.invoke(topmostComponent, initialGC); } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } } } }); } private Component getTopmostComponent(Component component) { if(component == null) return null; Container parent = component.getParent(); if(parent == null || !(parent instanceof Component)) return component; return getTopmostComponent((Component)parent); } } |
Anthony have created a new OpenJDK bugreport to track the AWT regression that broke Java3D stereo.
http://mail.openjdk.java.net/pipermail/awt-dev/2014-March/007175.html https://bugs.openjdk.java.net/browse/JDK-8036875 - Component.setGraphicsConfiguration() breaks some 3D applications Cheers Xerxes |
Administrator
|
In reply to this post by babor
Your source code is available on Github but I haven't found yet the classes that rely on Java3D. Several JOGL users have already switched from Java3D to Ardor3D or use them both, this is still a challenge but it's worth the change. Can't you use an existing method of SwingUtilities instead of getTopmostComponent?
Julien Gouesse | Personal blog | Website
|
The most important class that uses Canvas3D is pl.edu.icm.visnow.geometries.viewer3d.Display3DPanel I assume you mean SwingUtilities.getWindowAncestor? Sure I can :) I'd also add some security for backward compatibility on Java 6. As a result we have: import java.awt.Container; import java.awt.GraphicsConfiguration; import java.awt.Window; import java.awt.event.HierarchyEvent; import java.awt.event.HierarchyListener; import java.lang.reflect.Method; import javax.media.j3d.Canvas3D; import javax.swing.JComponent; import javax.swing.SwingUtilities; /** * @author Bartosz Borucki (babor@icm.edu.pl) * University of Warsaw, Interdisciplinary Centre * for Mathematical and Computational Modelling */ public class WrappedCanvas3D extends Canvas3D { private GraphicsConfiguration initialGC; public WrappedCanvas3D(GraphicsConfiguration graphicsConfiguration) { super(graphicsConfiguration); initialGC = this.getGraphicsConfiguration(); this.addHierarchyListener(new HierarchyListener() { @Override public void hierarchyChanged(HierarchyEvent e) { if(e.getChangeFlags() == HierarchyEvent.PARENT_CHANGED) { Container parent = e.getChangedParent(); try { Class<?> c = java.awt.Component.class; Method method = c.getDeclaredMethod("setGraphicsConfiguration", GraphicsConfiguration.class); if(method == null) return; method.setAccessible(true); if(parent == null) return; Window parentWindow = SwingUtilities.getWindowAncestor(parent); if(parentWindow != null && initialGC != null) method.invoke(parentWindow, initialGC); } catch (NoSuchMethodException ex) { //in case of Java 6 ignore this exception } catch (Exception ex) { throw new RuntimeException(ex.getMessage()); } if(parent instanceof JComponent) ((JComponent)parent).revalidate(); } } }); } } |
Hello All,
In an effort to try to restart this discussion, and make some progress on this issue, I have posted this message: http://mail.openjdk.java.net/pipermail/awt-dev/2014-December/008787.html Hoping we can revive the Java 3D stereo capability. Many Thanks, -Julien C |
Hi all,
I do not really understand why you are making these efforts to enable stereo with Java3D. I coded now a little example based on our CELLmicrocosmos projects, and it works fine with Java 8 u60 and Java 7 u80-b15. So please check it and let me know if it solves your problems (or not at all ;- ) JogampJ3DStereoSample.java import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import javax.media.j3d.AmbientLight; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.GraphicsConfigTemplate3D; import javax.media.j3d.Transform3D; import javax.media.j3d.TransformGroup; import javax.swing.JFrame; import javax.swing.JPanel; import javax.vecmath.Color3f; import javax.vecmath.Matrix4d; import javax.vecmath.Point3d; import javax.vecmath.Vector3d; import com.sun.j3d.utils.behaviors.vp.OrbitBehavior; import com.sun.j3d.utils.behaviors.vp.ViewPlatformAWTBehavior; import com.sun.j3d.utils.geometry.ColorCube; import com.sun.j3d.utils.universe.ConfiguredUniverse; public class JogampJ3DStereoSample { private static boolean CHECK_SCREEN_UPDATES = false; /** * This is a simple example showing how to use a 3D-stereoscopic canvas with Java3D. * This works also very nice with Jogamp's Java3D implementation. * Tested with J3D Version 1.6_pre11 and Java 8 u60 and Java 7 u80-b15. * Thanks go to Julien Gousse, Harvey Harrison and all other contributors for their great work!!! * * @author Bjorn Sommer for CELLmicrocosmos.org */ public static void main(String[] args) { // create universe and Canvas3D with stereo support GraphicsConfigTemplate3D template = new GraphicsConfigTemplate3D(); template.setStereo(GraphicsConfigTemplate3D.PREFERRED); GraphicsConfiguration config = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getBestConfiguration(template); Canvas3D canvas3D = !CHECK_SCREEN_UPDATES? new Canvas3D(config): new Canvas3D(config) { private static final long serialVersionUID = 500419811339553034L; // this is a nice place to force e.g. an offscreen canvas or 2D labels on the 3D screen to be updated // - and yes, this also works perfect with Jogamp's J3D! public void postRender() { super.postRender(); System.out.print("update..."); } }; if (canvas3D.getStereoAvailable()) { System.out.println("Stereo available"); } else { System.out.println("Okay, Stereo is not working. \n" + "If you have an NVIDIA Quadro graphics or similar professional graphics, check out that stereo is activated in the driver.\n" + "Example: 1. NVIDIA Control Panel -> 3D Settings -> Manage 3D Settings -> Global Settings -> Stereo: Enable -> On \n" + " Note: You might have to swap the eyes here in the settings - depends on the configuration." + " 2. NVIDIA Control Panel -> Stereoscopic 3D -> Set up stereoscopic 3D -> Enable Stereo 3D\n" + " Note: This setting is optional and depends on your configuration/driver. \n" + " It might be also that this checkbox has to be deactivated - although this\n" + " theoretically does not make any sense. But it debends on the hardware configuration.\n\n" + "If you do not have a (semi-)professional graphics card, this will usually not work at all. \n" + "Then, you need e.g. a 3D TV and do the side-by-side rendering with Java3D on your own - \n" + "but this makes only sense in full screen mode."); } // create an object BranchGroup bg1 = new BranchGroup(); TransformGroup tg1 = new TransformGroup(); Transform3D t3d1 = new Transform3D(); t3d1.set(new Vector3d(0,0,0)); t3d1.rotX(Math.toRadians(45)); tg1.setTransform(t3d1); ColorCube colorCube = new ColorCube(0.3); // create a light BranchGroup bg2 = new BranchGroup(); TransformGroup tg2 = new TransformGroup(); Transform3D t3d2 = new Transform3D(); t3d2.set(new Vector3d(0,0,0)); tg2.setTransform(t3d2); AmbientLight aLight = new AmbientLight(); aLight.setEnable(true); aLight.setColor(new Color3f(1,1,1)); Dimension dimension = new Dimension(400,400); // create the panel and add the Canvas3D JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add("Center", canvas3D); canvas3D.setVisible(true); canvas3D.setSize(dimension); // create the universe ConfiguredUniverse universe = new ConfiguredUniverse(canvas3D); // add object to scene tg1.addChild(colorCube); bg1.addChild(tg1); universe.addBranchGraph(bg1); // add light to scene tg2.addChild(aLight); bg2.addChild(tg2); universe.addBranchGraph(bg2); // set the position of the view Transform3D t3dVP = new Transform3D(new Matrix4d( 1,0,0,0, 0,1,0,0, 0,0,1,3, 0,0,0,1)); universe.getViewingPlatform().getViewPlatformTransform().setTransform(t3dVP);; // create the panel and frame panel.setSize(dimension); panel.setVisible(true); JFrame frame = new JFrame(); frame.setSize(dimension); frame.add(panel); frame.setVisible(true); // set the eye positions Point3d eyePosRight= new Point3d(-0.01,0,0); Point3d eyePosLeft= new Point3d(0.01,0,0); canvas3D.setLeftManualEyeInImagePlate(eyePosLeft); canvas3D.setRightManualEyeInImagePlate(eyePosRight); canvas3D.getView().getPhysicalBody().setLeftEyePosition(eyePosLeft); canvas3D.getView().getPhysicalBody().setRightEyePosition(eyePosRight); // add a behavior // note: I experienced here, without the behavior, that Java likes to show a white screen instead of the image OrbitBehavior orbitBehavior = new OrbitBehavior(canvas3D, ViewPlatformAWTBehavior.KEY_LISTENER | OrbitBehavior.REVERSE_ROTATE | OrbitBehavior.REVERSE_TRANSLATE | OrbitBehavior.PROPORTIONAL_ZOOM); orbitBehavior.setSchedulingBounds(new BoundingSphere(new Point3d(0, 0, 0), 100)); universe.getViewingPlatform().setViewPlatformBehavior(orbitBehavior); } } |
Looking for something completely different, I just came across this info from Andrew Davison:
Starting with Java 7, you have a redraw problem caused by the heavyweight/lightweight conflict. Sometime, you see only the background - this is very annoying and my example above had the same problem in case the OrbitBehavior was not added. Just add this line to the code: System.setProperty("sun.awt.noerasebackground", "true"); Thanks, Andrew! His book Killer Game Programming you certainly all know, at this website I found also this valuable info (look for the Java 3D section): http://fivedots.coe.psu.ac.th/~ad/jg/ This hint might also solve problems with Mac OS X. I experienced that sometime popup elements are not shown on the Canvas3D. Okay, but I did not test it by now, maybe not ... |
Administrator
|
Actually, this property works less and less as time goes by:
https://jogamp.org/bugzilla/show_bug.cgi?id=1182
Julien Gouesse | Personal blog | Website
|
Yes, Julien, might be in the future. But did somebody of you test my code above, which should solve your stereo issues with J3D?
see JogampJ3DStereoSample.java |
In reply to this post by jodyv
After much procrastination, I finally decided to test getting Java3D stereo
via JOGL working under linux. (See my original post on Aug 30, 2013) My solution was basically this: o Get JOGL jars for java3d from here: http://forum.jogamp.org/Java3D-1-6-0-pre8-released-and-future-plans-tt4029680.html o Get Java 1.6 from here: http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html In this case, I downloaded jdk1.6.0_45 o Complie using 1.6 javac and classpath set to JOGL and the above java3d jars. My StereoTestJava3D post on Aug 30, 2013 works. The basic trick as Mr. Babor alluded in Mar 06, 2014 post was to use JRE 1.6 (vice JRE 1.7) I might also add that I perceive that the JOGL implementation of Java3D is much faster than the prior 1.5 (non-JOGL) baseline. Thank you very much for investigating my problem. Also, many thanks to you for continuing the J3D development. |
Administrator
|
Hi
Does your trick work with a more recent build of Java3D?
Julien Gouesse | Personal blog | Website
|
Free forum by Nabble | Edit this page |