diff options
Diffstat (limited to 'src')
8 files changed, 116 insertions, 48 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java index 2091d0843..d32c981a3 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDevice.java @@ -46,6 +46,9 @@ public interface StereoDevice { // NOP } + /** Return the factory used to create this device. */ + public StereoDeviceFactory getFactory(); + /** Disposes this {@link StereoDevice}. */ public void dispose(); diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java index 46ce82f03..c4180585c 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoDeviceFactory.java @@ -45,7 +45,25 @@ public abstract class StereoDeviceFactory { private static final String GenericStereoDeviceClazzName = "jogamp.opengl.util.stereo.GenericStereoDeviceFactory"; private static final String isAvailableMethodName = "isAvailable"; - public static enum DeviceType { Default, Generic, OculusVR }; + /** {@link StereoDevice} type used for {@link StereoDeviceFactory#createFactory(DeviceType) createFactory(type)}. */ + public static enum DeviceType { + /** + * Auto selection of device in the following order: + * <ol> + * <li>{@link DeviceType#OculusVR}</li> + * <li>{@link DeviceType#Generic}</li> + * </ol> + */ + Default, + /** + * Generic software implementation. + */ + Generic, + /** + * OculusVR implementation. + */ + OculusVR + }; public static StereoDeviceFactory createDefaultFactory() { final ClassLoader cl = StereoDeviceFactory.class.getClassLoader(); diff --git a/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java b/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java index 30559924d..36e8bc5a5 100644 --- a/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java +++ b/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDevice.java @@ -41,6 +41,7 @@ import com.jogamp.opengl.math.FloatUtil; import com.jogamp.opengl.math.FovHVHalves; import com.jogamp.opengl.util.stereo.EyeParameter; import com.jogamp.opengl.util.stereo.StereoDevice; +import com.jogamp.opengl.util.stereo.StereoDeviceFactory; import com.jogamp.opengl.util.stereo.StereoDeviceRenderer; import com.jogamp.opengl.util.stereo.StereoUtil; @@ -207,16 +208,20 @@ public class GenericStereoDevice implements StereoDevice { final float[] DEFAULT_EYE_POSITION_OFFSET_STEREO = { 0.0f, 0.3f, 3.0f }; // 0.3 up, 3 back final float[] DEFAULT_EYE_POSITION_OFFSET_MONO = { 0.0f, 0.0f, 3.0f }; // 3 back + final DimensionImmutable surfaceSizeInPixel = new Dimension(1280, 800); + final float[] screenSizeInMeters = new float[] { 0.1498f, 0.0936f }; + final float interpupillaryDistanceInMeters = 0.0635f; + final float pupilCenterFromScreenTopInMeters = screenSizeInMeters[1] / 2f; final float d2r = FloatUtil.PI / 180.0f; { config01Mono01 = new Config( "Def01Mono01", ShutterType.RollingTopToBottom, - new Dimension(1280, 800), // resolution - new float[] { 0.1498f, 0.0936f }, // screenSize [m] - new Dimension(1280, 800), // eye textureSize - 0.0936f/2f, // pupilCenterFromScreenTop [m] - 0.0635f, // IPD [m] + surfaceSizeInPixel, // resolution + screenSizeInMeters, // screenSize [m] + surfaceSizeInPixel, // eye textureSize + pupilCenterFromScreenTopInMeters, // pupilCenterFromScreenTop [m] + interpupillaryDistanceInMeters, // IPD [m] new int[] { 0 }, // eye order new EyeParameter[] { new EyeParameter(0, DEFAULT_EYE_POSITION_OFFSET_MONO, @@ -231,11 +236,7 @@ public class GenericStereoDevice implements StereoDevice { } { - final DimensionImmutable surfaceSizeInPixel = new Dimension(1280, 800); - final float[] screenSizeInMeters = new float[] { 0.1498f, 0.0936f }; final DimensionImmutable eyeTextureSize = new Dimension(surfaceSizeInPixel.getWidth()/2, surfaceSizeInPixel.getHeight()); - final float interpupillaryDistanceInMeters = 0.0635f; - final float pupilCenterFromScreenTopInMeters = screenSizeInMeters[1] / 2f; final float[] horizPupilCenterFromLeft = Config.getHorizPupilCenterFromLeft(screenSizeInMeters[0], interpupillaryDistanceInMeters); final float vertPupilCenterFromTop = Config.getVertPupilCenterFromTop(screenSizeInMeters[1], pupilCenterFromScreenTopInMeters); final float fovy = 45f; @@ -249,7 +250,7 @@ public class GenericStereoDevice implements StereoDevice { surfaceSizeInPixel, // resolution screenSizeInMeters, // screenSize [m] eyeTextureSize, // eye textureSize - 0.0936f/2f, // pupilCenterFromScreenTop [m] + pupilCenterFromScreenTopInMeters, // pupilCenterFromScreenTop [m] interpupillaryDistanceInMeters, // IPD [m] new int[] { 0, 1 }, // eye order new EyeParameter[] { @@ -274,11 +275,7 @@ public class GenericStereoDevice implements StereoDevice { if(StereoDevice.DEBUG) { System.err.println("Caught: "+t.getMessage()); t.printStackTrace(); } } - final DimensionImmutable surfaceSizeInPixel = new Dimension(1280, 800); - final float[] screenSizeInMeters = new float[] { 0.1498f, 0.0936f }; final DimensionImmutable eyeTextureSize = new Dimension(1122, 1553); - final float interpupillaryDistanceInMeters = 0.0635f; - final float pupilCenterFromScreenTopInMeters = screenSizeInMeters[1] / 2f; final float[] horizPupilCenterFromLeft = Config.getHorizPupilCenterFromLeft(screenSizeInMeters[0], interpupillaryDistanceInMeters); final float vertPupilCenterFromTop = Config.getVertPupilCenterFromTop(screenSizeInMeters[1], pupilCenterFromScreenTopInMeters); final float fovy = 129f; @@ -313,6 +310,7 @@ public class GenericStereoDevice implements StereoDevice { configs = new Config[] { config01Mono01, config02StereoSBS01, config03StereoSBSLense01 }; } + private final StereoDeviceFactory factory; public final int deviceIndex; public final Config config; @@ -321,7 +319,8 @@ public class GenericStereoDevice implements StereoDevice { private boolean sensorsStarted = false; - public GenericStereoDevice(final int deviceIndex, final StereoDevice.Config customConfig) { + public GenericStereoDevice(final StereoDeviceFactory factory, final int deviceIndex, final StereoDevice.Config customConfig) { + this.factory = factory; this.deviceIndex = deviceIndex; if( customConfig instanceof GenericStereoDevice.Config) { @@ -341,6 +340,9 @@ public class GenericStereoDevice implements StereoDevice { } @Override + public final StereoDeviceFactory getFactory() { return factory; } + + @Override public String toString() { return "GenericStereoDevice["+config+", surfacePos "+surfacePos+"]"; } @@ -431,26 +433,34 @@ public class GenericStereoDevice implements StereoDevice { defaultEyeParam.distNoseToPupilX, defaultEyeParam.distMiddleToPupilY, defaultEyeParam.eyeReliefZ); } + final boolean usePP = null != config.distortionMeshProducer && 0 != distortionBits; // use post-processing + final RectangleImmutable[] eyeViewports = new RectangleImmutable[eyeParam.length]; final DimensionImmutable eyeTextureSize = config.eyeTextureSize; final DimensionImmutable totalTextureSize; if( 1 < eyeParam.length ) { // Stereo SBS totalTextureSize = new Dimension(eyeTextureSize.getWidth()*2, eyeTextureSize.getHeight()); + if( 1 == textureCount ) { // validated in ctor below! eyeViewports[0] = new Rectangle(0, 0, - totalTextureSize.getWidth() / 2, totalTextureSize.getHeight()); + eyeTextureSize.getWidth(), eyeTextureSize.getHeight()); - eyeViewports[1] = new Rectangle((totalTextureSize.getWidth() + 1) / 2, 0, - totalTextureSize.getWidth() / 2, totalTextureSize.getHeight()); + eyeViewports[1] = new Rectangle(eyeTextureSize.getWidth(), 0, + eyeTextureSize.getWidth(), eyeTextureSize.getHeight()); } else { eyeViewports[0] = new Rectangle(0, 0, eyeTextureSize.getWidth(), eyeTextureSize.getHeight()); - eyeViewports[1] = eyeViewports[0]; + if( usePP ) { + eyeViewports[1] = eyeViewports[0]; + } else { + eyeViewports[1] = new Rectangle(eyeTextureSize.getWidth(), 0, + eyeTextureSize.getWidth(), eyeTextureSize.getHeight()); + } } } else { // Mono totalTextureSize = eyeTextureSize; - eyeViewports[0] = new Rectangle(0, 0, totalTextureSize.getWidth(), totalTextureSize.getHeight()); + eyeViewports[0] = new Rectangle(0, 0, eyeTextureSize.getWidth(), eyeTextureSize.getHeight()); } return new GenericStereoDeviceRenderer(this, distortionBits, textureCount, eyePositionOffset, eyeParam, pixelsPerDisplayPixel, textureUnit, eyeTextureSize, totalTextureSize, eyeViewports); diff --git a/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDeviceFactory.java b/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDeviceFactory.java index a59e8d833..f2fa74743 100644 --- a/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDeviceFactory.java +++ b/src/jogl/classes/jogamp/opengl/util/stereo/GenericStereoDeviceFactory.java @@ -38,6 +38,6 @@ public class GenericStereoDeviceFactory extends StereoDeviceFactory { @Override public final StereoDevice createDevice(final int deviceIndex, final StereoDevice.Config config, final boolean verbose) { - return new GenericStereoDevice(deviceIndex, config); + return new GenericStereoDevice(this, deviceIndex, config); } } diff --git a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java index 2832012e4..f6dc8bf9f 100644 --- a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java +++ b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDevice.java @@ -41,6 +41,7 @@ import com.jogamp.oculusvr.ovrHmdDesc; import com.jogamp.oculusvr.ovrSizei; import com.jogamp.opengl.math.FovHVHalves; import com.jogamp.opengl.util.stereo.StereoDevice; +import com.jogamp.opengl.util.stereo.StereoDeviceFactory; import com.jogamp.opengl.util.stereo.StereoDeviceRenderer; import com.jogamp.opengl.util.stereo.StereoUtil; @@ -48,6 +49,7 @@ public class OVRStereoDevice implements StereoDevice { /** 1.6 up, 5 forward */ private static final float[] DEFAULT_EYE_POSITION_OFFSET = { 0.0f, 1.6f, -5.0f }; + private final StereoDeviceFactory factory; public final OvrHmdContext handle; public final int deviceIndex; public final ovrHmdDesc hmdDesc; @@ -57,7 +59,11 @@ public class OVRStereoDevice implements StereoDevice { private final int[] eyeRenderOrder; private final int supportedDistortionBits, recommendedDistortionBits, minimumDistortionBits; - public OVRStereoDevice(final OvrHmdContext nativeContext, final int deviceIndex) { + public OVRStereoDevice(final StereoDeviceFactory factory, final OvrHmdContext nativeContext, final int deviceIndex) { + if( null == nativeContext ) { + throw new IllegalArgumentException("Passed null nativeContext"); + } + this.factory = factory; this.handle = nativeContext; this.deviceIndex = deviceIndex; this.hmdDesc = ovrHmdDesc.create(); @@ -75,6 +81,9 @@ public class OVRStereoDevice implements StereoDevice { } @Override + public final StereoDeviceFactory getFactory() { return factory; } + + @Override public final String toString() { final StringBuilder sb = new StringBuilder(); sb.append("OVRStereoDevice[product "+hmdDesc.getProductNameAsString()); diff --git a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java index b292c882d..06f716ddc 100644 --- a/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java +++ b/src/oculusvr/classes/jogamp/opengl/oculusvr/OVRStereoDeviceFactory.java @@ -44,9 +44,16 @@ public class OVRStereoDeviceFactory extends StereoDeviceFactory { } @Override - public final StereoDevice createDevice(final int deviceIndex, Config config, final boolean verbose) { + public final StereoDevice createDevice(final int deviceIndex, final Config config, final boolean verbose) { final OvrHmdContext hmdCtx = OVR.ovrHmd_Create(deviceIndex); - final OVRStereoDevice ctx = new OVRStereoDevice(hmdCtx, deviceIndex); + if( null == hmdCtx ) { + if( verbose ) { + System.err.println("Failed to create hmdCtx for device index "+deviceIndex+" on thread "+Thread.currentThread().getName()); + Thread.dumpStack(); + } + return null; + } + final OVRStereoDevice ctx = new OVRStereoDevice(this, hmdCtx, deviceIndex); if( verbose ) { System.err.println(OVRVersion.getAvailableCapabilitiesInfo(ctx.hmdDesc, deviceIndex, null).toString()); } diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java index 0c7bdc81d..9098ad00f 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/av/MovieSBSStereo.java @@ -203,6 +203,7 @@ public class MovieSBSStereo implements StereoGLEventListener { renderString(drawable, font, pixelSize, text4, 1 /* col */, -2 /* row */, 0, height, 1, true); } } }; + private final boolean enableTextRendererGLEL = false; private InfoTextRendererGLELBase textRendererGLEL = null; private boolean displayOSD = false; @@ -534,8 +535,12 @@ public class MovieSBSStereo implements StereoGLEventListener { } final int rmode = drawable.getChosenGLCapabilities().getSampleBuffers() ? 0 : Region.VBAA_RENDERING_BIT; final boolean lowPerfDevice = gl.isGLES(); - textRendererGLEL = new InfoTextRendererGLELBase(rmode, lowPerfDevice); - textRendererGLEL.init(drawable); + if( enableTextRendererGLEL ) { + textRendererGLEL = new InfoTextRendererGLELBase(rmode, lowPerfDevice); + textRendererGLEL.init(drawable); + } else { + textRendererGLEL = null; + } } protected void updateInterleavedVBO(final GL gl, final GLArrayDataServer iVBO, final Texture tex, final int eyeNum) { @@ -608,7 +613,9 @@ public class MovieSBSStereo implements StereoGLEventListener { } System.out.println("pR "+mPlayer); - textRendererGLEL.reshape(drawable, x, y, width, height); + if( null != textRendererGLEL ) { + textRendererGLEL.reshape(drawable, 0, 0, width, height); + } } private final float zNear = 0.1f; @@ -666,13 +673,17 @@ public class MovieSBSStereo implements StereoGLEventListener { st.useProgram(gl, true); st.uniform(gl, pmvMatrixUniform); st.useProgram(gl, false); - textRendererGLEL.reshape(drawable, x, y, width, height); + if( null != textRendererGLEL ) { + textRendererGLEL.reshape(drawable, 0, 0, width, height); + } } @Override public void dispose(final GLAutoDrawable drawable) { - textRendererGLEL.dispose(drawable); - textRendererGLEL = null; + if( null != textRendererGLEL ) { + textRendererGLEL.dispose(drawable); + textRendererGLEL = null; + } disposeImpl(drawable, true); } @@ -747,7 +758,7 @@ public class MovieSBSStereo implements StereoGLEventListener { pmvMatrix.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); pmvMatrix.glPushMatrix(); pmvMatrix.glTranslatef(0, 0, zoom); - if(rotate > 0) { + if( rotate > 0) { final float ang = ((System.currentTimeMillis() - startTime) * 360.0f) / 8000.0f; pmvMatrix.glRotatef(ang, 0, 0, 1); } else { @@ -778,7 +789,9 @@ public class MovieSBSStereo implements StereoGLEventListener { st.useProgram(gl, false); pmvMatrix.glPopMatrix(); - textRendererGLEL.display(drawable); + if( null != textRendererGLEL ) { + textRendererGLEL.display(drawable); + } } static class StereoGLMediaEventListener implements GLMediaEventListener { diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java b/src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java index 05685c05a..142c941a5 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/stereo/StereoDemo01.java @@ -41,7 +41,6 @@ import javax.media.opengl.GLProfile; import jogamp.opengl.util.stereo.GenericStereoDevice; import com.jogamp.common.util.IOUtil; -import com.jogamp.common.util.ReflectionUtil; import com.jogamp.newt.event.KeyAdapter; import com.jogamp.newt.event.KeyEvent; import com.jogamp.newt.opengl.GLWindow; @@ -88,6 +87,16 @@ import com.jogamp.opengl.util.stereo.StereoUtil; * java StereoDemo01 -time 10000000 -filmURI http://whoknows.not/Some_SBS_3D_Movie.mkv * </pre> * <p> + * In case user likes to utilize the {@link StereoDeviceFactory.DeviceType#Generic Generic} software implementation, + * which is selected {@link StereoDeviceFactory.DeviceType#Default Default} if no other device is available + * or explicit via <code>-device Generic</code>, the user can chose between different <i>generic</i> stereo modes: + * <pre> + * mono : <code>-device Generic -deviceIndex 0</code> + * stereo-sbs : <code>-device Generic -deviceIndex 1</code> + * stereo-sbs-lense: <code>-device Generic -deviceIndex 2</code> + * </pre> + * </p> + * <p> * Key 'R' enables/disables the VR's sensors, i.e. head rotation .. * </p> * @@ -106,7 +115,6 @@ public class StereoDemo01 { static boolean useAutoSwap = false; static String useFilmFile = null; static String useFilmURI = null; - static String stereoRendererListenerName = null; static StereoDeviceFactory.DeviceType deviceType = StereoDeviceFactory.DeviceType.Default; static int deviceIndex = 0; @@ -162,9 +170,6 @@ public class StereoDemo01 { } else if(args[i].equals("-autoSwap")) { i++; useAutoSwap = MiscUtils.atob(args[i], useAutoSwap); - } else if(args[i].equals("-test")) { - i++; - stereoRendererListenerName = args[i]; } else if(args[i].equals("-filmFile")) { i++; useFilmFile = args[i]; @@ -173,13 +178,6 @@ public class StereoDemo01 { useFilmURI = args[i]; } } - if( null != stereoRendererListenerName ) { - try { - final Object stereoRendererListener = ReflectionUtil.createInstance(stereoRendererListenerName, null); - } catch (final Exception e) { - e.printStackTrace(); - } - } final StereoGLEventListener upstream; final MovieSBSStereo movieSimple; final URI movieURI; @@ -256,10 +254,10 @@ public class StereoDemo01 { final PointImmutable devicePos = stereoDevice.getPosition(); final DimensionImmutable deviceRes = stereoDevice.getSurfaceSize(); - window.setSize(deviceRes.getWidth(), deviceRes.getHeight()); if( useStereoScreen ) { window.setPosition(devicePos.getX(), devicePos.getY()); } + window.setSurfaceSize(deviceRes.getWidth(), deviceRes.getHeight()); // might be not correct .. window.setAutoSwapBufferMode(useAutoSwap); window.setUndecorated(true); @@ -281,8 +279,9 @@ public class StereoDemo01 { System.err.println("Default Fov[1]: "+defaultEyeFov[1].toStringInDegrees()); } - final float[] eyePositionOffset = null == movieSimple || isGenericDevice ? stereoDevice.getDefaultEyePositionOffset() // default - : new float[] { 0f, 0.3f, 0f }; // better fixed movie position + final boolean usesLenses = 0 != ( StereoDeviceRenderer.DISTORTION_BARREL & stereoDevice.getMinimumDistortionBits() ); + final float[] eyePositionOffset = null != movieSimple && usesLenses ? new float[] { 0f, 0.3f, 0f } // better fixed movie position w/ lenses + : stereoDevice.getDefaultEyePositionOffset(); // default System.err.println("Eye Position Offset: "+Arrays.toString(eyePositionOffset)); final int textureUnit = 0; @@ -338,6 +337,15 @@ public class StereoDemo01 { animator.start(); } window.setVisible(true); + + // Correct window size to actual pixel size, + // which ration is unknown before window creation when using multiple displays! + System.err.println("Window.0.windowSize : "+window.getWidth()+" x "+window.getHeight()); + System.err.println("Window.0.surfaceSize: "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); + window.setSurfaceSize(deviceRes.getWidth(), deviceRes.getHeight()); + System.err.println("Window.1.windowSize : "+window.getWidth()+" x "+window.getHeight()); + System.err.println("Window.1.surfaceSize: "+window.getSurfaceWidth()+" x "+window.getSurfaceHeight()); + if( useAnimator ) { animator.setUpdateFPSFrames(60, System.err); } |