
com.jogamp.opengl.util.stereo.StereoDeviceRenderer Maven / Gradle / Ivy
Show all versions of jogl-all Show documentation
/**
* Copyright 2014 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
package com.jogamp.opengl.util.stereo;
import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.RectangleImmutable;
import javax.media.opengl.GL;
import com.jogamp.opengl.math.FovHVHalves;
/**
* Stereoscopic device rendering interface.
*
* The following pseudo-code describes how to implement a renderer
* using a {@link StereoDeviceRenderer}.
* See {@link StereoClientRenderer} which implements the following:
*
* - device.{@link #beginFrame(GL)}
* - For both eyes:
* - device.{@link #updateEyePose(int)}
* - if device.{@link #ppAvailable()}: Set the render target, e.g. FBO
* - Set the viewport using {@link Eye#getViewport()}
* - {@link StereoGLEventListener#reshapeForEye(javax.media.opengl.GLAutoDrawable, int, int, int, int, EyeParameter, EyePose) upstream.reshapeEye(..)}
* - {@link StereoGLEventListener#display(javax.media.opengl.GLAutoDrawable, int) upstream.display(..)}.
*
* - Reset the viewport
* - If device.{@link #ppAvailable()}:
* - device.{@link #ppBegin(GL)}
* - Use render target, e.g. FBO's texture
* - device.{@link #ppBothEyes(GL)} or device.{@link #ppOneEye(GL, int)} for both eyes
* - device.{@link #ppEnd(GL)}
*
* - device.{@link #endFrame(GL)}
*
*
* Correct {@link FovHVHalves Asymmetric FOV} Rendering
*
* The {@link StereoClientRenderer} shall render both images for each eye correctly Off-axis
* utilizing an asymmetric camera frustum, i.e. by using {@link StereoDevice StereoDevice}'s {@link StereoDevice#getDefaultFOV() default} {@link FovHVHalves}.
*
* Some references:
*
* - Wiki: Binocular Vision
* - Paul Burke: Stereo Graphics - Stereo Renderer
* - Wiki: Distortion (Optics)
*
*
*/
public interface StereoDeviceRenderer {
/**
* Distortion Bit: Barrel distortion compensating lens pincushion distortion
*/
public static final int DISTORTION_BARREL = 1 << 0;
/**
* Distortion Bit: Chromatic distortion compensating lens chromatic aberration.
*/
public static final int DISTORTION_CHROMATIC = 1 << 1;
/**
* Distortion Bit: Vignette distortion compensating lens chromatic aberration.
*/
public static final int DISTORTION_VIGNETTE = 1 << 2;
/**
* Distortion Bit: Timewarp distortion technique to predict
* {@link EyePose} movement to reduce latency.
*
* FIXME: Explanation needs refinement!
*
*/
public static final int DISTORTION_TIMEWARP = 1 << 3;
/** Returns the {@link StereoDevice} of this {@link StereoDeviceRenderer} instance. */
public StereoDevice getDevice();
/**
* Interface describing one eye of the stereoscopic device,
* see {@link StereoDeviceRenderer#getEye(int)}.
*/
public static interface Eye {
/**
* Returns the viewport for this eye.
*/
public RectangleImmutable getViewport();
/**
* Returns the {@link EyeParameter} of this eye.
*/
public EyeParameter getEyeParameter();
/**
* Returns the last {@link EyePose} of this eye.
*/
public EyePose getLastEyePose();
}
/**
* Returns the {@link Eye} instance for the denoted eyeNum
.
*/
public Eye getEye(final int eyeNum);
/**
* Updates the {@link Eye#getLastEyePose()}
* for the denoted eyeNum
.
*/
public EyePose updateEyePose(final int eyeNum);
/**
* Returns used distortion compensation bits, e.g. {@link #DISTORTION_BARREL},
* in case the stereoscopic display requires such, i.e. in case lenses are utilized.
*
* Distortion requires {@link #ppAvailable() post-processing}.
*
*/
public int getDistortionBits();
/**
* Method returns true
if using side-by-side (SBS)
* stereoscopic images, otherwise false
.
*
* SBS requires that both eye's images are presented
* side-by-side in the final framebuffer.
*
*
* Either the renderer presents the images side-by-side according to the {@link Eye#getViewport() eye's viewport},
* or {@link #ppAvailable() post-processing} is utilized to merge {@link #getTextureCount() textures}
* to a side-by-side configuration.
*
*/
public boolean usesSideBySideStereo();
/**
* Returns the unified surface size of one eye's a single image in pixel units.
*/
public DimensionImmutable getSingleSurfaceSize();
/**
* Returns the total surface size required for the complete images in pixel units.
*
* If {@link #usesSideBySideStereo()} the total size spans over both {@link #getSingleSurfaceSize()}, side-by-side.
*
*
* Otherwise the size is equal to {@link #getSingleSurfaceSize()}.
*
*/
public DimensionImmutable getTotalSurfaceSize();
/**
* Returns the used texture-image count for post-processing, see {@link #ppAvailable()}.
*
* In case the renderer does not support multiple textures for post-processing,
* or no post-processing at all, method returns zero despite the request
* from {@link StereoDevice#createRenderer(int, int, float[], com.jogamp.opengl.math.FovHVHalves[], float)}.
*
*/
public int getTextureCount();
/** Returns the desired texture-image unit for post-processing, see {@link #ppAvailable()}. */
public int getTextureUnit();
/** Initialize OpenGL related resources */
public void init(final GL gl);
/** Release all OpenGL related resources */
public void dispose(final GL gl);
/** Notifying that a new frame is about to start. */
public void beginFrame(final GL gl);
/** Notifying that the frame has been rendered completely. */
public void endFrame(final GL gl);
/**
* Returns true
if stereoscopic post-processing is required and available,
* otherwise false
.
*
* Stereoscopic post-processing is available if:
*
* - one of the distortion bits are set, see {@link #getDistortionBits()}
*
*
*
* If stereoscopic post-processing is used
* the following post-processing methods must be called to before {@link #endFrame()}:
*
* - {@link #ppBegin(GL)}
* - {@link #ppOneEye(GL, int)} for both eyes
* - {@link #ppEnd(GL)}
*
*
*/
public boolean ppAvailable();
/**
* Begin stereoscopic post-processing, see {@link #ppAvailable()}.
*
* {@link #updateEyePose(int)} for both eyes must be called upfront
* when rendering upstream {@link StereoGLEventListener}.
*
*
* @param gl
*/
public void ppBegin(final GL gl);
/**
* Performs stereoscopic post-processing for one eye, see {@link #ppAvailable()}.
* @param gl
* @param eyeNum
*/
public void ppOneEye(final GL gl, final int eyeNum);
/**
* End stereoscopic post-processing, see {@link #ppAvailable()}.
* @param gl
*/
public void ppEnd(final GL gl);
}