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