28package com.jogamp.opengl.util.stereo;
30import com.jogamp.nativewindow.util.DimensionImmutable;
31import com.jogamp.nativewindow.util.RectangleImmutable;
32import com.jogamp.opengl.GL;
33import com.jogamp.opengl.GL2ES2;
34import com.jogamp.opengl.GLAutoDrawable;
35import com.jogamp.opengl.GLEventListener;
37import jogamp.opengl.GLDrawableHelper;
38import jogamp.opengl.GLDrawableHelper.GLEventListenerAction;
40import com.jogamp.opengl.FBObject;
41import com.jogamp.opengl.FBObject.Attachment;
42import com.jogamp.opengl.FBObject.TextureAttachment;
43import com.jogamp.opengl.FBObject.Attachment.Type;
44import com.jogamp.opengl.util.CustomGLEventListener;
57 private final GLDrawableHelper helper;
59 private final boolean ownsDevice;
61 private final int magFilter;
62 private final int minFilter;
64 private int numSamples;
68 final int magFilter,
final int minFilter,
final int numSamples) {
70 if( 0 > fboCount || 2 < fboCount ) {
71 throw new IllegalArgumentException(
"fboCount must be within [0..2], has "+fboCount+
", due to "+deviceRenderer);
73 this.helper =
new GLDrawableHelper();
74 this.deviceRenderer = deviceRenderer;
75 this.ownsDevice = ownsDevice;
76 this.magFilter = magFilter;
77 this.minFilter = minFilter;
79 this.numSamples = numSamples;
82 for(
int i=0; i<fboCount; i++) {
89 for(
int i=0; i<fbos.length; i++) {
90 fbos[i].
init(gl, sizes[i].getWidth(), sizes[i].getHeight(), numSamples);
91 if( i>0 && fbos[i-1].getNumSamples() != fbos[i].getNumSamples()) {
92 throw new InternalError(
"sample size mismatch: \n\t0: "+fbos[i-1]+
"\n\t1: "+fbos[i]);
101 ssink.
init(gl, sizes[i].getWidth(), sizes[i].getHeight(), 0);
109 fboTexs[i] = fbos[i].
attachTexture2D(gl, 0,
false, magFilter, minFilter, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
113 System.err.println(
"FBO["+i+
"]: "+fbos[i]);
118 @SuppressWarnings(
"unused")
119 private
void resetFBOs(final GL gl, final DimensionImmutable size) {
120 for(
int i=0; i<fbos.length; i++) {
121 fbos[i].
reset(gl, size.getWidth(), size.getHeight(), numSamples);
122 if( i>0 && fbos[i-1].getNumSamples() != fbos[i].getNumSamples()) {
123 throw new InternalError(
"sample size mismatch: \n\t0: "+fbos[i-1]+
"\n\t1: "+fbos[i]);
137 helper.addGLEventListener(l);
140 helper.removeGLEventListener(l);
146 deviceRenderer.
init(gl);
152 initFBOs(gl, textureSize);
153 helper.init(drawable,
false);
161 helper.disposeAllGLEventListener(drawable,
false);
162 for(
int i=0; i<fbos.length; i++) {
181 final int fboCount = fbos.length;
182 final int displayRepeatFlags;
183 if( 1 >= fboCount ) {
186 displayRepeatFlags = 0;
190 final int eyeCount = eyeOrder.length;
194 if( 1 == fboCount ) {
198 for(
int eyeNum=0; eyeNum<eyeCount; eyeNum++) {
199 final int eyeName = eyeOrder[eyeNum];
201 fbos[eyeName].
bind(gl);
204 final StereoDeviceRenderer.Eye eye = deviceRenderer.
getEye(eyeName);
208 final int displayFlags = eyeNum > 0 ? CustomGLEventListener.DISPLAY_REPEAT | displayRepeatFlags : 0;
209 final GLEventListenerAction reshapeDisplayAction =
new GLEventListenerAction() {
213 eye.getEyeParameter(), viewerPose);
214 sl.
display(drawable, displayFlags);
216 helper.runForAllGLEventListener(drawable, reshapeDisplayAction);
223 if( 1 == fboCount ) {
231 if( 1 == fboCount ) {
232 fbos[0].
use(gl, fboTexs[0]);
233 for(
int eyeNum=0; eyeNum<eyeCount; eyeNum++) {
234 deviceRenderer.
ppOneEye(gl, eyeOrder[eyeNum]);
238 for(
int eyeNum=0; eyeNum<eyeCount; eyeNum++) {
239 final int eyeName = eyeOrder[eyeNum];
240 fbos[eyeName].
use(gl, fboTexs[eyeName]);
241 deviceRenderer.
ppOneEye(gl, eyeName);
242 fbos[eyeName].
unuse(gl);
245 deviceRenderer.
ppEnd(gl);
Core utility class simplifying usage of framebuffer objects (FBO) with all GLProfiles.
final void attachRenderbuffer(final GL gl, final Attachment.Type atype, final int reqBits)
Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,...
final void bind(final GL gl)
Bind this FBO, i.e.
final TextureAttachment attachTexture2D(final GL gl, final int attachmentPoint, final boolean alpha)
Attaches a Colorbuffer, i.e.
final int getNumSamples()
Returns the number of samples for multisampling (MSAA).
FBObject setSamplingSink(final FBObject newSamplingSink)
Setting this FBO sampling sink.
final void destroy(final GL gl)
final void unuse(final GL gl)
Unbind texture, ie bind 'non' texture 0.
final void use(final GL gl, final TextureAttachment ta)
Synchronize the sampling sink and bind the given TextureAttachment, if not null.
final Colorbuffer getSamplingSink()
Return the multisampling Colorbuffer sink, if using multisampling.
static final int DEFAULT_BITS
Request default bit count for depth- or stencil buffer (depth 24 bits, stencil 8 bits),...
final boolean resetSamplingSink(final GL gl)
Manually validates the MSAA sampling sink, if used.
final ColorAttachment attachColorbuffer(final GL gl, final int attachmentPoint, final boolean alpha)
Attaches a newly created and initialized Colorbuffer, i.e.
final void unbind(final GL gl)
Unbind this FBO, i.e.
final boolean reset(final GL gl, int newWidth, int newHeight, int newSamples)
Resets this FBO's instance.
void init(final GL gl, final int newWidth, final int newHeight, final int newSamples)
Initializes this FBO's instance.
final Colorbuffer getColorbuffer(final int attachmentPoint)
Return the Colorbuffer attachment at attachmentPoint if it is attached to this FBO,...
StereoClientRenderer utilizing StereoDeviceRenderer implementing GLEventListener for convenience.
StereoClientRenderer(final StereoDeviceRenderer deviceRenderer, final boolean ownsDevice, final int magFilter, final int minFilter, final int numSamples)
final void addGLEventListener(final StereoGLEventListener l)
void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height)
Called by the drawable during the first repaint after the component has been resized.
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
final void removeGLEventListener(final StereoGLEventListener l)
void dispose(final GLAutoDrawable drawable)
Notifies the listener to perform the release of all OpenGL resources per GLContext,...
final StereoDeviceRenderer getStereoDeviceRenderer()
position and orientation of viewer.
Immutable Dimension Interface, consisting of it's read only components:
Immutable Rectangle interface, with its position on the top-left.
int getX()
x-position, left of rectangle.
int getY()
y-position, top of rectangle.
TextureAttachment getTextureAttachment()
Casts this object to a TextureAttachment reference, see isTextureAttachment().
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
boolean getAutoSwapBufferMode()
Indicates whether automatic buffer swapping is enabled for this drawable.
GL2ES2 getGL2ES2()
Casts this object to the GL2ES2 interface.
void setSwapInterval(int interval)
Set the swap interval of the current context and attached onscreen GLDrawable.
int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
void swapBuffers()
Swaps the front and back buffers of this drawable.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
static final int GL_MULTISAMPLE
Common in ES1, GL2 and GL3.
void glEnable(int cap)
Entry point to C language function: void {@native glEnable}(GLenum cap) Part of GL_ES_VERSION_2_0,...
void glViewport(int x, int y, int width, int height)
Entry point to C language function: void {@native glViewport}(GLint x, GLint y, GLsizei width,...
static final int GL_CLAMP_TO_EDGE
GL_ES_VERSION_2_0, GL_VERSION_1_2, GL_VERSION_ES_1_0, GL_SGIS_texture_edge_clamp Alias for: GL_CLAMP_...
Extended GLEventListener interface supporting more fine grained control over the implementation.
void display(final GLAutoDrawable drawable, final int flags)
Extended display method, allowing to pass a display flag, e.g.
static final int DISPLAY_DONTCLEAR
display flag: Do not clear any target buffer, e.g.
Stereoscopic device rendering interface.
void endFrame(final GL gl)
Notifying that the frame has been rendered completely.
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.
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().
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.
int[] getEyeRenderOrder()
Returns an array of the preferred eye rendering order.
Extended GLEventListener and CustomGLEventListener interface supporting stereoscopic client rendering...
void reshapeForEye(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height, final EyeParameter eyeParam, final ViewerPose viewerPose)
Stereo capable specialization of reshape(GLAutoDrawable, int, int, int, int) for one StereoDeviceRend...