JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
StereoDeviceRenderer.java
Go to the documentation of this file.
1/**
2 * Copyright 2014 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl.util.stereo;
29
30import com.jogamp.math.FovHVHalves;
31import com.jogamp.nativewindow.util.DimensionImmutable;
32import com.jogamp.nativewindow.util.RectangleImmutable;
33import com.jogamp.opengl.GL;
34
35/**
36 * Stereoscopic device rendering interface.
37 * <p>
38 * The following pseudo-code describes how to implement a renderer
39 * using a {@link StereoDeviceRenderer}.
40 * See {@link StereoClientRenderer} which implements the following:
41 * <ul>
42 * <li>device.{@link #beginFrame(GL)}</li>
43 * <li>For both eyes:<ul>
44 * <li>device.{@link #updateViewerPose(int)}</li>
45 * <li>if device.{@link #ppAvailable()}: Set the render target, e.g. FBO</li>
46 * <li>Set the viewport using {@link Eye#getViewport()}</li>
47 * <li>{@link StereoGLEventListener#reshapeForEye(com.jogamp.opengl.GLAutoDrawable, int, int, int, int, EyeParameter, ViewerPose) upstream.reshapeEye(..)}</li>
48 * <li>{@link StereoGLEventListener#display(com.jogamp.opengl.GLAutoDrawable, int) upstream.display(..)}.</li>
49 * </ul></li>
50 * <li>Reset the viewport</li>
51 * <li>If device.{@link #ppAvailable()}:<ul>
52 * <li>device.{@link #ppBegin(GL)}</li>
53 * <li>Use render target, e.g. FBO's texture</li>
54 * <li>device.{@link #ppBothEyes(GL)} or device.{@link #ppOneEye(GL, int)} for both eyes</li>
55 * <li>device.{@link #ppEnd(GL)}</li>
56 * </ul></li>
57 * <li>device.{@link #endFrame(GL)}</li>
58 * </ul>
59 * </p>
60 * <a name="asymFOVRendering"><h5>Correct {@link FovHVHalves Asymmetric FOV} Rendering</h5></a>
61 * <p>
62 * The {@link StereoClientRenderer} shall render both images for each eye correctly <i>Off-axis</i>
63 * utilizing an asymmetric camera frustum, i.e. by using {@link StereoDevice StereoDevice}'s {@link StereoDevice#getDefaultFOV() default} {@link FovHVHalves}.<br>
64 *
65 * Some references:
66 * <ul>
67 * <li><a href="https://en.wikipedia.org/wiki/Binocular_vision">Wiki: Binocular Vision</a></li>
68 * <li><a href="http://paulbourke.net/stereographics/stereorender/">Paul Burke: Stereo Graphics - Stereo Renderer</a></li>
69 * <li><a href="https://en.wikipedia.org/wiki/Distortion_%28optics%29">Wiki: Distortion (Optics)</a></li>
70 * </ul>
71 * </p>
72 */
73public interface StereoDeviceRenderer {
74 /**
75 * Distortion Bit: Barrel distortion compensating lens pincushion distortion
76 */
77 public static final int DISTORTION_BARREL = 1 << 0;
78
79 /**
80 * Distortion Bit: Chromatic distortion compensating lens chromatic aberration.
81 */
82 public static final int DISTORTION_CHROMATIC = 1 << 1;
83
84 /**
85 * Distortion Bit: Vignette distortion compensating lens chromatic aberration.
86 */
87 public static final int DISTORTION_VIGNETTE = 1 << 2;
88
89 /**
90 * Distortion Bit: Timewarp distortion technique to predict
91 * {@link ViewerPose} movement to reduce latency.
92 * <p>
93 * FIXME: Explanation needs refinement!
94 * </p>
95 */
96 public static final int DISTORTION_TIMEWARP = 1 << 3;
97
98
99 /** Returns the {@link StereoDevice} of this {@link StereoDeviceRenderer} instance. */
101
102 /**
103 * Interface describing one eye of the stereoscopic device,
104 * see {@link StereoDeviceRenderer#getEye(int)}.
105 */
106 public static interface Eye {
107 /**
108 * Returns the viewport for this eye.
109 */
111 /**
112 * Returns the {@link EyeParameter} of this eye.
113 */
115 }
116
117 /**
118 * Returns the {@link Eye} instance for the denoted <code>eyeNum</code>.
119 */
120 public Eye getEye(final int eyeNum);
121
122 /**
123 * Updates the {@link ViewerPose} and returns it.
124 */
126
127 /**
128 * Returns the last {@link ViewerPose}.
129 */
131
132 /**
133 * Returns used distortion compensation bits, e.g. {@link #DISTORTION_BARREL},
134 * in case the stereoscopic display requires such, i.e. in case lenses are utilized.
135 * <p>
136 * Distortion requires {@link #ppAvailable() post-processing}.
137 * </p>
138 */
139 public int getDistortionBits();
140
141 /**
142 * Method returns <code>true</code> if using <i>side-by-side</i> (SBS)
143 * stereoscopic images, otherwise <code>false</code>.
144 * <p>
145 * SBS requires that both eye's images are presented
146 * <i>side-by-side</i> in the final framebuffer.
147 * </p>
148 * <p>
149 * Either the renderer presents the images <i>side-by-side</i> according to the {@link Eye#getViewport() eye's viewport},
150 * or {@link #ppAvailable() post-processing} is utilized to merge {@link #getTextureCount() textures}
151 * to a <i>side-by-side</i> configuration.
152 * </p>
153 */
154 public boolean usesSideBySideStereo();
155
156 /**
157 * Returns the surface size for each eye's a single image in pixel units.
158 */
160
161 /**
162 * Returns the total surface size required for the complete images in pixel units.
163 * <p>
164 * If {@link #usesSideBySideStereo()} the total size spans over both {@link #getEyeSurfaceSize()}, side-by-side.
165 * </p>
166 * <p>
167 * Otherwise the size is equal to {@link #getEyeSurfaceSize()}.
168 * </p>
169 */
171
172 /**
173 * Returns the used texture-image count for post-processing, see {@link #ppAvailable()}.
174 * <p>
175 * In case the renderer does not support multiple textures for post-processing,
176 * or no post-processing at all, method returns zero despite the request
177 * from {@link StereoDevice#createRenderer(int, int, float[], com.jogamp.math.FovHVHalves[], float)}.
178 * </p>
179 */
180 public int getTextureCount();
181
182 /** Returns the desired texture-image unit for post-processing, see {@link #ppAvailable()}. */
183 public int getTextureUnit();
184
185 /** Initialize OpenGL related resources */
186 public void init(final GL gl);
187
188 /** Release all OpenGL related resources */
189 public void dispose(final GL gl);
190
191 /** Notifying that a new frame is about to start. */
192 public void beginFrame(final GL gl);
193
194 /** Notifying that the frame has been rendered completely. */
195 public void endFrame(final GL gl);
196
197 /**
198 * Returns <code>true</code> if stereoscopic post-processing is required and available,
199 * otherwise <code>false</code>.
200 * <p>
201 * Stereoscopic post-processing is available if:
202 * <ul>
203 * <li>one of the <i>distortion</i> bits are set, see {@link #getDistortionBits()}</li>
204 * </ul>
205 * </p>
206 * <p>
207 * If stereoscopic post-processing is used
208 * the following post-processing methods must be called to before {@link #endFrame()}:
209 * <ul>
210 * <li>{@link #ppBegin(GL)}</li>
211 * <li>{@link #ppOneEye(GL, int)} for both eyes</li>
212 * <li>{@link #ppEnd(GL)}</li>
213 * </ul>
214 * </p>
215 */
216 public boolean ppAvailable();
217
218 /**
219 * Begin stereoscopic post-processing, see {@link #ppAvailable()}.
220 * <p>
221 * {@link #updateViewerPose(int)} for both eyes must be called upfront
222 * when rendering upstream {@link StereoGLEventListener}.
223 * </p>
224 *
225 * @param gl
226 */
227 public void ppBegin(final GL gl);
228
229 /**
230 * Performs stereoscopic post-processing for one eye, see {@link #ppAvailable()}.
231 * @param gl
232 * @param eyeNum
233 */
234 public void ppOneEye(final GL gl, final int eyeNum);
235
236 /**
237 * End stereoscopic post-processing, see {@link #ppAvailable()}.
238 * @param gl
239 */
240 public void ppEnd(final GL gl);
241
242}
Constant single eye parameter of the viewer, relative to its ViewerPose.
position and orientation of viewer.
Definition: ViewerPose.java:36
Immutable Dimension Interface, consisting of it's read only components:
Immutable Rectangle interface, with its position on the top-left.
Interface describing one eye of the stereoscopic device, see StereoDeviceRenderer#getEye(int).
RectangleImmutable getViewport()
Returns the viewport for this eye.
EyeParameter getEyeParameter()
Returns the EyeParameter of this eye.
Stereoscopic device rendering interface.
void endFrame(final GL gl)
Notifying that the frame has been rendered completely.
int getDistortionBits()
Returns used distortion compensation bits, e.g.
DimensionImmutable[] getEyeSurfaceSize()
Returns the surface size for each eye's a single image in pixel units.
Eye getEye(final int eyeNum)
Returns the Eye instance for the denoted eyeNum.
void init(final GL gl)
Initialize OpenGL related resources.
void ppEnd(final GL gl)
End stereoscopic post-processing, see ppAvailable().
ViewerPose updateViewerPose()
Updates the ViewerPose and returns it.
static final int DISTORTION_BARREL
Distortion Bit: Barrel distortion compensating lens pincushion distortion.
static final int DISTORTION_TIMEWARP
Distortion Bit: Timewarp distortion technique to predict ViewerPose movement to reduce latency.
static final int DISTORTION_CHROMATIC
Distortion Bit: Chromatic distortion compensating lens chromatic aberration.
void beginFrame(final GL gl)
Notifying that a new frame is about to start.
boolean ppAvailable()
Returns true if stereoscopic post-processing is required and available, otherwise false.
void ppOneEye(final GL gl, final int eyeNum)
Performs stereoscopic post-processing for one eye, see ppAvailable().
void ppBegin(final GL gl)
Begin stereoscopic post-processing, see ppAvailable().
StereoDevice getDevice()
Returns the StereoDevice of this StereoDeviceRenderer instance.
int getTextureCount()
Returns the used texture-image count for post-processing, see ppAvailable().
static final int DISTORTION_VIGNETTE
Distortion Bit: Vignette distortion compensating lens chromatic aberration.
boolean usesSideBySideStereo()
Method returns true if using side-by-side (SBS) stereoscopic images, otherwise false.
void dispose(final GL gl)
Release all OpenGL related resources.
DimensionImmutable getTotalSurfaceSize()
Returns the total surface size required for the complete images in pixel units.
ViewerPose getLastViewerPose()
Returns the last ViewerPose.
int getTextureUnit()
Returns the desired texture-image unit for post-processing, see ppAvailable().
Interface describing a native stereoscopic device.