Login  Register

Java3D stereo

Posted by jodyv on Aug 30, 2013; 5:35am
URL: https://forum.jogamp.org/Java3D-stereo-tp4029914.html

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