From 78b4918b207e16b967e8335fb8ec1b31c706c507 Mon Sep 17 00:00:00 2001
From: Sven Gothel
+ * Composable pipeline which wraps an underlying {@link GL} implementation,
+ * providing error checking after each OpenGL method call. If an error occurs,
+ * causes a {@link GLException} to be thrown at exactly the point of failure.
+ *
+ * Sample code which installs this pipeline, manual:
+ *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL()));
+ *
+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}.
+ *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGL3 extends DebugGL4bc { + public DebugGL3(final GL3 downstream) { + super((GL4bc)downstream); + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/DebugGL3bc.java b/src/jogl/classes/com/jogamp/opengl/DebugGL3bc.java new file mode 100644 index 000000000..d92f6043f --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/DebugGL3bc.java @@ -0,0 +1,21 @@ +package com.jogamp.opengl; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGL3bc extends DebugGL4bc { + public DebugGL3bc(final GL3bc downstream) { + super((GL4bc)downstream); + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/DebugGL4.java b/src/jogl/classes/com/jogamp/opengl/DebugGL4.java new file mode 100644 index 000000000..76f5a4ac3 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/DebugGL4.java @@ -0,0 +1,21 @@ +package com.jogamp.opengl; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGL4 extends DebugGL4bc { + public DebugGL4(final GL4 downstream) { + super((GL4bc)downstream); + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/DebugGLES2.java b/src/jogl/classes/com/jogamp/opengl/DebugGLES2.java new file mode 100644 index 000000000..e2b280515 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/DebugGLES2.java @@ -0,0 +1,21 @@ +package com.jogamp.opengl; + +/** + *
+ * Composable pipeline which wraps an underlying {@link GL} implementation, + * providing error checking after each OpenGL method call. If an error occurs, + * causes a {@link GLException} to be thrown at exactly the point of failure. + *
+ *+ * Sample code which installs this pipeline, manual: + *
+ * gl = drawable.setGL(new DebugGL(drawable.getGL())); + *+ * For automatic instantiation see {@link GLPipelineFactory#create(String, Class, GL, Object[])}. + * + */ +public class DebugGLES2 extends DebugGLES3 { + public DebugGLES2(final GLES2 downstream) { + super((GLES3)downstream); + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/com/jogamp/opengl/DefaultGLCapabilitiesChooser.java new file mode 100644 index 000000000..88a88087f --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/DefaultGLCapabilitiesChooser.java @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2003-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 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: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl; + +import com.jogamp.nativewindow.NativeWindowException; + +import java.util.List; + +import com.jogamp.nativewindow.CapabilitiesImmutable; + +import com.jogamp.common.ExceptionUtils; +import com.jogamp.common.util.PropertyAccess; + +import jogamp.opengl.Debug; + +/**
The default implementation of the {@link + GLCapabilitiesChooser} interface, which provides consistent visual + selection behavior across platforms. The precise algorithm is + deliberately left loosely specified. Some properties are:
+ ++ * The animator thread can still be retrieved via {@link GLAnimatorControl#getThread()}. + *
+ *+ * All {@link GLAnimatorControl} states already reflect its stopped state. + *
+ *+ * After this handler method is called, the {@link GLAnimatorControl} is stopped. + *
+ *+ * Any exception thrown by this method will be ignored. + *
+ * @param animator the {@link GLAnimatorControl} + * @param drawable the causing {@link GLAutoDrawable} + * @param cause the uncaught exception + * @see GLAnimatorControl#setUncaughtExceptionHandler(UncaughtExceptionHandler) + * @since 2.2 + */ + void uncaughtException(final GLAnimatorControl animator, final GLAutoDrawable drawable, final Throwable cause); + } + + /** + * Indicates whether this animator has been {@link #start() started}. + * + * @see #start() + * @see #stop() + * @see #isPaused() + * @see #pause() + * @see #resume() + */ + boolean isStarted(); + + /** + * Indicates whether this animator {@link #isStarted() is started} and {@link #isPaused() is not paused}. + * + * @see #start() + * @see #stop() + * @see #pause() + * @see #resume() + */ + boolean isAnimating(); + + /** + * Indicates whether this animator {@link #isStarted() is started} + * and either {@link #pause() manually paused} or paused + * automatically due to no {@link #add(GLAutoDrawable) added} {@link GLAutoDrawable}s. + * + * @see #start() + * @see #stop() + * @see #pause() + * @see #resume() + */ + boolean isPaused(); + + /** + * @return The animation thread if running, otherwise null. + * + * @see #start() + * @see #stop() + */ + Thread getThread(); + + /** + * Starts this animator, if not running. + *+ * In most situations this method blocks until + * completion, except when called from the animation thread itself + * or in some cases from an implementation-internal thread like the + * AWT event queue thread. + *
+ *+ * Note that an animator w/o {@link #add(GLAutoDrawable) added drawables} + * will be paused automatically. + *
+ *+ * If started, all counters (time, frames, ..) are reset to zero. + *
+ * + * @return true is started due to this call, + * otherwise false, ie started already or unable to start. + * + * @see #stop() + * @see #isAnimating() + * @see #isPaused() + * @see #getThread() + */ + boolean start(); + + /** + * Stops this animator. + *+ * In most situations this method blocks until + * completion, except when called from the animation thread itself + * or in some cases from an implementation-internal thread like the + * AWT event queue thread. + *
+ * + * @return true is stopped due to this call, + * otherwise false, ie not started or unable to stop. + * + * @see #start() + * @see #isAnimating() + * @see #getThread() + */ + boolean stop(); + + /** + * Pauses this animator. + *+ * In most situations this method blocks until + * completion, except when called from the animation thread itself + * or in some cases from an implementation-internal thread like the + * AWT event queue thread. + *
+ * + * @return false if not started, already paused or failed to pause, otherwise true + * + * @see #resume() + * @see #isAnimating() + */ + boolean pause(); + + /** + * Resumes animation if paused. + *+ * In most situations this method blocks until + * completion, except when called from the animation thread itself + * or in some cases from an implementation-internal thread like the + * AWT event queue thread. + *
+ *+ * If resumed, all counters (time, frames, ..) are reset to zero. + *
+ * + * @return false if not started, not paused or unable to resume, otherwise true + * + * @see #pause() + * @see #isAnimating() + */ + boolean resume(); + + /** + * Adds a drawable to this animator's list of rendering drawables. + *+ * This allows the animator thread to become {@link #isAnimating() animating}, + * in case the first drawable is added and the animator {@link #isStarted() is started}. + *
+ * + * @param drawable the drawable to be added + * @throws IllegalArgumentException if drawable was already added to this animator + */ + void add(GLAutoDrawable drawable); + + /** + * Removes a drawable from the animator's list of rendering drawables. + *+ * This method should get called in case a drawable becomes invalid, + * and will not be recovered. + *
+ *+ * This allows the animator thread to become {@link #isAnimating() not animating}, + * in case the last drawable has been removed. + *
+ * + * @param drawable the drawable to be removed + * @throws IllegalArgumentException if drawable was not added to this animator + */ + void remove(GLAutoDrawable drawable); + + /** + * Returns the {@link UncaughtExceptionHandler} invoked when this {@link GLAnimatorControl animator} abruptly {@link #stop() stops} + * due to an uncaught exception from one of its {@link GLAutoDrawable}s. + *
+ * Default is null
.
+ *
null
to unset the handler.
+ * @see UncaughtExceptionHandler#uncaughtException(GLAnimatorControl, GLAutoDrawable, Throwable)
+ * @since 2.2
+ */
+ void setUncaughtExceptionHandler(final UncaughtExceptionHandler handler);
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/GLArrayData.java b/src/jogl/classes/com/jogamp/opengl/GLArrayData.java
new file mode 100644
index 000000000..ea2dfb0f3
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/GLArrayData.java
@@ -0,0 +1,210 @@
+/**
+ * Copyright 2010 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;
+
+import java.nio.Buffer;
+
+import com.jogamp.opengl.fixedfunc.GLPointerFunc;
+
+/**
+ *
+ * The total number of bytes hold by the referenced buffer is:
+ * getComponentSize()* getComponentNumber() * getElementNumber()
+ *
+ */
+public interface GLArrayData {
+ /**
+ * Implementation and type dependent object association.
+ *
+ * One currently known use case is to associate a {@link com.jogamp.opengl.util.glsl.ShaderState ShaderState}
+ * to an GLSL aware vertex attribute object, allowing to use the ShaderState to handle it's
+ * data persistence, location and state change.
+ * This is implicitly done via {@link com.jogamp.opengl.util.glsl.ShaderState#ownAttribute(GLArrayData, boolean) shaderState.ownAttribute(GLArrayData, boolean)}.
+ *
+ * This clears the location, i.e. sets it to -1. + *
+ * @see #setLocation(int) + * @see #setLocation(GL2ES2, int) + */ + public void setName(String newName); + + + /** + * Returns the shader attribute location for this name, + * -1 if not yet determined + */ + public int getLocation(); + + /** + * Sets the given location of the shader attribute + * + * @return the given location + * @see com.jogamp.opengl.util.glsl.ShaderState#vertexAttribPointer(GL2ES2, GLArrayData) + */ + public int setLocation(int v); + + /** + * Retrieves the location of the shader attribute from the linked shader program. + *+ * No validation is performed within the implementation. + *
+ * @param gl + * @param program + * @return ≥0 denotes a valid attribute location as found and used in the given shader program. + * <0 denotes an invalid location, i.e. not found or used in the given shader program. + */ + public int setLocation(GL2ES2 gl, int program); + + /** + * Binds the location of the shader attribute to the given location for the unlinked shader program. + *+ * No validation is performed within the implementation. + *
+ * @param gl + * @param program + * @return the given location + */ + public int setLocation(GL2ES2 gl, int program, int location); + + /** + * Determines whether the data is server side (VBO) and enabled, + * or a client side array (false). + */ + public boolean isVBO(); + + /** + * The VBO buffer offset or 0 if not a VBO + */ + public long getVBOOffset(); + + /** + * The VBO name or 0 if not a VBO + */ + public int getVBOName(); + + /** + * The VBO usage or 0 if not a VBO + * @return 0 if not a GPU buffer, otherwise {@link GL2ES2#GL_STREAM_DRAW}, {@link GL#GL_STATIC_DRAW} or {@link GL#GL_DYNAMIC_DRAW} + */ + public int getVBOUsage(); + + /** + * The VBO target or 0 if not a VBO + * @return 0 if not a GPU buffer, otherwise {@link GL#GL_ARRAY_BUFFER} or {@link GL#GL_ELEMENT_ARRAY_BUFFER} + */ + public int getVBOTarget(); + + + /** + * The Buffer holding the data, may be null if a GPU buffer without client bound data + */ + public Buffer getBuffer(); + + /** + * The number of components per element + */ + public int getComponentCount(); + + /** + * The component's GL data type, ie. GL_FLOAT + */ + public int getComponentType(); + + /** + * The component's size in bytes + */ + public int getComponentSizeInBytes(); + + /** + * The current number of used elements. + *+ * On element consist out of {@link #getComponentCount()} components. + *
+ * In case the buffer's position is 0 (sealed, flipped), it's based on it's limit instead of it's position. + */ + public int getElementCount(); + + /** + * The currently used size in bytes.
+ * Default behavior (of the fixed function pipeline) is true
+ * for fixed point data type and false
for floating point data types.
+ *
+ Since the {@link GLContext} {@link GLContext#makeCurrent makeCurrent} + implementation is synchronized, i.e. blocks if the context + is current on another thread, the internal + {@link GLContext} for the GLAutoDrawable can be used for the event + based rendering mechanism and by end users directly. +
+
+ The implementation shall initialize itself as soon as possible,
+ which is only possible after the attached {@link com.jogamp.nativewindow.NativeSurface NativeSurface} becomes visible and and is realized.
+ The following initialization sequence should be implemented:
+
+ Another implementation detail is the {@link GLDrawable} reconfiguration. One use case is where a window is being
+ dragged to another screen with a different pixel configuration, ie {@link GLCapabilities}. The implementation
+ shall be able to detect such cases in conjunction with the associated {@link com.jogamp.nativewindow.NativeSurface NativeSurface}.
+ For example, AWT's {@link java.awt.Canvas} 's {@link java.awt.Canvas#getGraphicsConfiguration getGraphicsConfiguration()}
+ is capable to determine a display device change. This is demonstrated within {@link com.jogamp.opengl.awt.GLCanvas}'s
+ and NEWT's AWTCanvas
{@link com.jogamp.opengl.awt.GLCanvas#getGraphicsConfiguration getGraphicsConfiguration()}
+ specialization. Another demonstration is NEWT's {@link com.jogamp.nativewindow.NativeWindow NativeWindow}
+ implementation on the Windows platform, which utilizes the native platform's MonitorFromWindow(HWND) function.
+ All OpenGL resources shall be regenerated, while the drawable's {@link GLCapabilities} has
+ to be chosen again. The following protocol shall be satisfied.
+
+ Avoiding breakage with older applications and because of the situation
+ mentioned above, the boolean
system property jogl.screenchange.action
will control the
+ screen change action as follows:
+
+ -Djogl.screenchange.action=false Disable the {@link GLDrawable} reconfiguration (the default) + -Djogl.screenchange.action=true Enable the {@link GLDrawable} reconfiguration ++ +
this
instance.
+ */
+ public GLDrawable getDelegatedDrawable();
+
+ /**
+ * Returns the context associated with this drawable. The returned
+ * context will be synchronized.
+ * Don't rely on it's identity, the context may change.
+ */
+ public GLContext getContext();
+
+ /**
+ * Associate the new context, newtCtx
, to this auto-drawable.
+ * + * Remarks: + *
destroyPrevCtx
is true
,
+ * otherwise it will be disassociated from this auto-drawable
+ * via {@link GLContext#setGLDrawable(GLDrawable, boolean) setGLDrawable(null, true);} including {@link GL#glFinish() glFinish()}.null
for dis-association.
+ * @param destroyPrevCtx if true
, destroy the previous context if exists
+ * @return the previous GLContext, maybe null
+ *
+ * @see GLContext#setGLDrawable(GLDrawable, boolean)
+ * @see GLContext#setGLReadDrawable(GLDrawable)
+ * @see jogamp.opengl.GLDrawableHelper#switchContext(GLDrawable, GLContext, boolean, GLContext, int)
+ */
+ public GLContext setContext(GLContext newCtx, boolean destroyPrevCtx);
+
+ /**
+ * Adds the given {@link GLEventListener listener} to the end of this drawable queue.
+ * The {@link GLEventListener listeners} are notified of events in the order of the queue.
+ * + * The newly added listener's {@link GLEventListener#init(GLAutoDrawable) init(..)} + * method will be called once before any other of it's callback methods. + * See {@link #getGLEventListenerInitState(GLEventListener)} for details. + *
+ * @param listener The GLEventListener object to be inserted + */ + public void addGLEventListener(GLEventListener listener); + + /** + * Adds the given {@link GLEventListener listener} at the given index of this drawable queue. + * The {@link GLEventListener listeners} are notified of events in the order of the queue. + *+ * The newly added listener's {@link GLEventListener#init(GLAutoDrawable) init(..)} + * method will be called once before any other of it's callback methods. + * See {@link #getGLEventListenerInitState(GLEventListener)} for details. + *
+ * @param index Position where the listener will be inserted. + * Should be within (0 <= index && index <= size()). + * An index value of -1 is interpreted as the end of the list, size(). + * @param listener The GLEventListener object to be inserted + * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1 + */ + public void addGLEventListener(int index, GLEventListener listener) throws IndexOutOfBoundsException; + + /** + * Returns the number of {@link GLEventListener} of this drawable queue. + * @return The number of GLEventListener objects of this drawable queue. + */ + public int getGLEventListenerCount(); + + /** + * Returns true if all added {@link GLEventListener} are initialized, otherwise false. + * @since 2.2 + */ + boolean areAllGLEventListenerInitialized(); + + /** + * Returns the {@link GLEventListener} at the given index of this drawable queue. + * @param index Position of the listener to be returned. + * Should be within (0 <= index && index < size()). + * An index value of -1 is interpreted as last listener, size()-1. + * @return The GLEventListener object at the given index. + * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index < size()), or -1 + */ + public GLEventListener getGLEventListener(int index) throws IndexOutOfBoundsException; + + /** + * Retrieves whether the given {@link GLEventListener listener} is initialized or not. + *+ * After {@link #addGLEventListener(GLEventListener) adding} a {@link GLEventListener} it is + * marked uninitialized and added to a list of to be initialized {@link GLEventListener}. + * If such uninitialized {@link GLEventListener}'s handler methods (reshape, display) + * are about to be invoked, it's {@link GLEventListener#init(GLAutoDrawable) init(..)} method is invoked first. + * Afterwards the {@link GLEventListener} is marked initialized + * and removed from the list of to be initialized {@link GLEventListener}. + *
+ *
+ * This methods returns the {@link GLEventListener} initialized state,
+ * i.e. returns false
if it is included in the list of to be initialized {@link GLEventListener},
+ * otherwise true
.
+ *
+ * This methods allows manually setting the {@link GLEventListener} initialized state, + * i.e. adding it to, or removing it from the list of to be initialized {@link GLEventListener}. + * See {@link #getGLEventListenerInitState(GLEventListener)} for details. + *
+ *+ * Warning: This method does not validate whether the given {@link GLEventListener listener's} + * is member of this drawable queue, i.e. {@link #addGLEventListener(GLEventListener) added}. + *
+ *+ * This method is only exposed to allow users full control over the {@link GLEventListener}'s state + * and is usually not recommended to change. + *
+ *+ * One use case is moving a {@link GLContext} and their initialized {@link GLEventListener} + * from one {@link GLAutoDrawable} to another, + * where a subsequent {@link GLEventListener#init(GLAutoDrawable) init(..)} call after adding it + * to the new owner is neither required nor desired. + * See {@link com.jogamp.opengl.util.GLDrawableUtil#swapGLContextAndAllGLEventListener(GLAutoDrawable, GLAutoDrawable) swapGLContextAndAllGLEventListener(..)}. + *
+ * @param listener the GLEventListener object to perform a state change. + * @param initialized iftrue
, mark the listener initialized, otherwise uninitialized.
+ */
+ public void setGLEventListenerInitState(GLEventListener listener, boolean initialized);
+
+ /**
+ * Disposes the given {@link GLEventListener listener} via {@link GLEventListener#dispose(GLAutoDrawable) dispose(..)}
+ * if it has been initialized and added to this queue.
+ *
+ * If remove
is true
, the {@link GLEventListener} is removed from this drawable queue before disposal,
+ * otherwise marked uninitialized.
+ *
+ * If an {@link GLAnimatorControl} is being attached and the current thread is different + * than {@link GLAnimatorControl#getThread() the animator's thread}, it is paused during the operation. + *
+ *+ * Note that this is an expensive operation, since {@link GLEventListener#dispose(GLAutoDrawable) dispose(..)} + * is decorated by {@link GLContext#makeCurrent()} and {@link GLContext#release()}. + *
+ *+ * Use {@link #removeGLEventListener(GLEventListener) removeGLEventListener(listener)} instead + * if you just want to remove the {@link GLEventListener listener} and don't care about the disposal of the it's (OpenGL) resources. + *
+ *+ * Also note that this is done from within a particular drawable's + * {@link GLEventListener} handler (reshape, display, etc.), that it is not + * guaranteed that all other listeners will be evaluated properly + * during this update cycle. + *
+ * @param listener The GLEventListener object to be disposed and removed ifremove
is true
+ * @param remove pass true
to have the listener
removed from this drawable queue, otherwise pass false
+ * @return the disposed and/or removed GLEventListener, or null if no action was performed, i.e. listener was not added
+ */
+ public GLEventListener disposeGLEventListener(GLEventListener listener, boolean remove);
+
+ /**
+ * Removes the given {@link GLEventListener listener} from this drawable queue.
+ * + * This is an inexpensive operation, since the removed listener's + * {@link GLEventListener#dispose(GLAutoDrawable) dispose(..)} method will not be called. + *
+ *+ * Use {@link #disposeGLEventListener(GLEventListener, boolean) disposeGLEventListener(listener, true)} + * instead to ensure disposal of the {@link GLEventListener listener}'s (OpenGL) resources. + *
+ *+ * Note that if this is done from within a particular drawable's + * {@link GLEventListener} handler (reshape, display, etc.), that it is not + * guaranteed that all other listeners will be evaluated properly + * during this update cycle. + *
+ * @param listener The GLEventListener object to be removed + * @return the removed GLEventListener, or null if listener was not added + */ + public GLEventListener removeGLEventListener(GLEventListener listener); + + /** + * Registers the usage of an animator, an {@link com.jogamp.opengl.GLAnimatorControl} implementation. + * The animator will be queried whether it's animating, ie periodically issuing {@link #display()} calls or not. + *
+ * This method shall be called by an animator implementation only,
+ * e.g. {@link com.jogamp.opengl.util.Animator#add(com.jogamp.opengl.GLAutoDrawable)}, passing it's control implementation,
+ * and {@link com.jogamp.opengl.util.Animator#remove(com.jogamp.opengl.GLAutoDrawable)}, passing null
.
+ *
+ * Impacts {@link #display()} and {@link #invoke(boolean, GLRunnable)} semantics.
null
reference indicates no animator is using
+ * this GLAutoDrawable
,GLAutoDrawable
.
+ *
+ * @throws GLException if an animator is already registered.
+ * @see #display()
+ * @see #invoke(boolean, GLRunnable)
+ * @see com.jogamp.opengl.GLAnimatorControl
+ */
+ public abstract void setAnimator(GLAnimatorControl animatorControl) throws GLException;
+
+ /**
+ * @return the registered {@link com.jogamp.opengl.GLAnimatorControl} implementation, using this GLAutoDrawable
.
+ *
+ * @see #setAnimator(com.jogamp.opengl.GLAnimatorControl)
+ * @see com.jogamp.opengl.GLAnimatorControl
+ */
+ public GLAnimatorControl getAnimator();
+
+ /**
+ * Dedicates this instance's {@link GLContext} to the given thread.setExclusiveContextThread(null)
has been called.
+ *
+ * Default non-exclusive behavior is requested via setExclusiveContextThread(null)
,
+ * which will cause the next call of {@link #display()} on the exclusive thread to
+ * release the {@link GLContext}. Only after it's async release, {@link #getExclusiveContextThread()}
+ * will return null
.
+ *
+ * To release a previous made exclusive thread, a user issues setExclusiveContextThread(null)
+ * and may poll {@link #getExclusiveContextThread()} until it returns null
,
+ * while the exclusive thread is still running.
+ *
+ * Note: Setting a new exclusive thread without properly releasing a previous one + * will throw an GLException. + *
+ *+ * Note: Utilizing this feature w/ AWT could lead to an AWT-EDT deadlock, depending on the AWT implementation. + * Hence it is advised not to use it with native AWT GLAutoDrawable like GLCanvas. + *
+ *+ * One scenario could be to dedicate the context to the {@link GLAnimatorControl#getThread() animator thread} + * and spare redundant context switches, see {@link com.jogamp.opengl.util.AnimatorBase#setExclusiveContext(boolean)}. + *
+ * @param t the exclusive thread to claim the context, ornull
for default operation.
+ * @return previous exclusive context thread
+ * @throws GLException If an exclusive thread is still active but a new one is attempted to be set
+ * @see com.jogamp.opengl.util.AnimatorBase#setExclusiveContext(boolean)
+ */
+ public Thread setExclusiveContextThread(Thread t) throws GLException;
+
+ /**
+ * @see #setExclusiveContextThread(Thread)
+ */
+ public Thread getExclusiveContextThread();
+
+ /**
+ * Enqueues a one-shot {@link GLRunnable},
+ * which will be executed within the next {@link #display()} call
+ * after all registered {@link GLEventListener}s
+ * {@link GLEventListener#display(GLAutoDrawable) display(GLAutoDrawable)}
+ * methods have been called.
+ *
+ * If no {@link GLAnimatorControl} is animating (default),
+ * or if the current thread is the animator thread,
+ * a {@link #display()} call is issued after enqueue the GLRunnable
,
+ * hence the {@link GLRunnable} will be executed right away.
+ *
+ * If an {@link GLAnimatorControl animator} is running,
+ * no explicit {@link #display()} call is issued, allowing the {@link GLAnimatorControl animator} to perform at due time.
+ *
+ * If wait
is true
the call blocks until the glRunnable
+ * has been executed by the {@link GLAnimatorControl animator}, otherwise the method returns immediately.
+ *
+ * If wait
is true
and
+ * {@link #isRealized()} returns false
or {@link #getContext()} returns null
,
+ * the call is ignored and returns false
.
+ * This helps avoiding deadlocking the caller.
+ *
+ * The internal queue of {@link GLRunnable}'s is being flushed with {@link #destroy()} + * where all blocked callers are being notified. + *
+ *
+ * To avoid a deadlock situation which causes an {@link IllegalStateException} one should
+ * avoid issuing {@link #invoke(boolean, GLRunnable) invoke} while this GLAutoDrawable is being locked.
+ * Detected deadlock situations throwing an {@link IllegalStateException} are:
+ *
true
block until execution of glRunnable
is finished, otherwise return immediately w/o waiting
+ * @param glRunnable the {@link GLRunnable} to execute within {@link #display()}
+ * @return true
if the {@link GLRunnable} has been processed or queued, otherwise false
.
+ * @throws IllegalStateException in case of a detected deadlock situation ahead, see above.
+ *
+ * @see #setAnimator(GLAnimatorControl)
+ * @see #display()
+ * @see GLRunnable
+ * @see #invoke(boolean, List)
+ * @see #flushGLRunnables()
+ */
+ public boolean invoke(boolean wait, GLRunnable glRunnable) throws IllegalStateException ;
+
+ /**
+ * Extends {@link #invoke(boolean, GLRunnable)} functionality
+ * allowing to inject a list of {@link GLRunnable}s.
+ * @param wait if true
block until execution of the last glRunnable
is finished, otherwise return immediately w/o waiting
+ * @param glRunnables the {@link GLRunnable}s to execute within {@link #display()}
+ * @return true
if the {@link GLRunnable}s has been processed or queued, otherwise false
.
+ * @throws IllegalStateException in case of a detected deadlock situation ahead, see {@link #invoke(boolean, GLRunnable)}.
+ * @see #invoke(boolean, GLRunnable)
+ * @see #flushGLRunnables()
+ */
+ public boolean invoke(boolean wait, List+ * The executor which might have been blocked until notified + * will be unblocked and all tasks removed from the queue. + *
+ * @see #invoke(boolean, GLRunnable) + * @since 2.2 + */ + public void flushGLRunnables(); + + /** Destroys all resources associated with this GLAutoDrawable, + inclusive the GLContext. + If a window is attached to it's implementation, it shall be closed. + Causes disposing of all OpenGL resources + by calling {@link GLEventListener#dispose dispose(..)} for all + registered {@link GLEventListener}s. Called automatically by the + window system toolkit upon receiving a destroy notification. This + routine may be called manually. */ + public void destroy(); + + /** + *+ * Causes OpenGL rendering to be performed for this GLAutoDrawable + * in the following order: + *
+ * May be called periodically by a running {@link com.jogamp.opengl.GLAnimatorControl} implementation,
+ * which must register itself with {@link #setAnimator(com.jogamp.opengl.GLAnimatorControl)}.
+ * Called automatically by the window system toolkit upon receiving a repaint() request,
+ * except an {@link com.jogamp.opengl.GLAnimatorControl} implementation {@link com.jogamp.opengl.GLAnimatorControl#isAnimating()}.
+ * This routine may also be called manually for better control over the + * rendering process. It is legal to call another GLAutoDrawable's + * display method from within the {@link GLEventListener#display + * display(..)} callback.
+ *+ * In case of a new generated OpenGL context, + * the implementation shall call {@link GLEventListener#init init(..)} for all + * registered {@link GLEventListener}s before making the + * actual {@link GLEventListener#display display(..)} calls, + * in case this has not been done yet.
+ * + * @see #setAnimator(com.jogamp.opengl.GLAnimatorControl) + */ + public void display(); + + /** Enables or disables automatic buffer swapping for this drawable. + By default this property is set to true; when true, after all + GLEventListeners have been called for a display() event, the + front and back buffers are swapped, displaying the results of + the render. When disabled, the user is responsible for calling + {@link #swapBuffers(..)} manually. */ + public void setAutoSwapBufferMode(boolean enable); + + /** Indicates whether automatic buffer swapping is enabled for this + drawable. See {@link #setAutoSwapBufferMode}. */ + public boolean getAutoSwapBufferMode(); + + /** + * @param flags Additional context creation flags. + * + * @see GLContext#setContextCreationFlags(int) + * @see GLContext#enableGLDebugMessage(boolean) + */ + public void setContextCreationFlags(int flags); + + /** + * @return Additional context creation flags + */ + public int getContextCreationFlags(); + + /** + * {@inheritDoc} + *+ * This GLAutoDrawable implementation holds it's own GLContext reference, + * thus created a GLContext using this methods won't replace it implicitly. + * To replace or set this GLAutoDrawable's GLContext you need to call {@link #setContext(GLContext, boolean)}. + *
+ *+ * The GLAutoDrawable implementation shall also set the + * context creation flags as customized w/ {@link #setContextCreationFlags(int)}. + *
+ */ + @Override + public GLContext createContext(GLContext shareWith); + + /** Returns the {@link GL} pipeline object this GLAutoDrawable uses. + If this method is called outside of the {@link + GLEventListener}'s callback methods (init, display, etc.) it may + return null. Users should not rely on the identity of the + returned GL object; for example, users should not maintain a + hash table with the GL object as the key. Additionally, the GL + object should not be cached in client code, but should be + re-fetched from the GLAutoDrawable at the beginning of each call + to init, display, etc. */ + public GL getGL(); + + /** Sets the {@link GL} pipeline object this GLAutoDrawable uses. + This should only be called from within the GLEventListener's + callback methods, and usually only from within the init() + method, in order to install a composable pipeline. See the JOGL + demos for examples. + @return the set GL pipeline or null if not successful */ + public GL setGL(GL gl); + + /** + * Method may return the upstream UI toolkit object + * holding this {@link GLAutoDrawable} instance, if exist. + *+ * Currently known Java UI toolkits and it's known return types are: + * + *
Toolkit | GLAutoDrawable Implementation | ~ | Return Type of getUpstreamWidget() | + *
NEWT | {@link com.jogamp.newt.opengl.GLWindow} | has a | {@link com.jogamp.newt.Window} | + *
SWT | {@link com.jogamp.opengl.swt.GLCanvas} | is a | {@link org.eclipse.swt.widgets.Canvas} | + *
AWT | {@link com.jogamp.opengl.awt.GLCanvas} | is a | {@link java.awt.Canvas} | + *
AWT | {@link com.jogamp.opengl.awt.GLJPanel} | is a | {@link javax.swing.JPanel} | + *
+ * This method may also return null
if no UI toolkit is being used,
+ * as common for offscreen rendering.
+ *
+ * See GLAutoDrawable Locking. + *
+ * @since 2.2 + */ + public RecursiveLock getUpstreamLock(); + + /** + * Indicates whether the current thread is capable of + * performing OpenGL-related work. + *+ * Implementation utilizes this knowledge to determine + * whether {@link #display()} performs the OpenGL commands on the current thread directly + * or spawns them on the dedicated OpenGL thread. + *
+ * @since 2.2 + */ + public boolean isThreadGLCapable(); + +} diff --git a/src/jogl/classes/com/jogamp/opengl/GLBase.java b/src/jogl/classes/com/jogamp/opengl/GLBase.java new file mode 100644 index 000000000..19b7808fc --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/GLBase.java @@ -0,0 +1,646 @@ +/** + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2010 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; + +/** + *The base interface from which all GL profiles derive, providing + * checked conversion down to concrete profiles, access to the + * OpenGL context associated with the GL and extension/function + * availability queries as described below.
+ * + * While the APIs for vendor extensions are unconditionally
+ * exposed, the underlying functions may not be present. The method
+ * {@link #isFunctionAvailable} should be used to query the
+ * availability of any non-core function before it is used for the
+ * first time; for example,
+ * gl.isFunctionAvailable("glProgramStringARB")
. On
+ * certain platforms (Windows in particular), the most "core"
+ * functionality is only OpenGL 1.1, so in theory any routines first
+ * exposed in OpenGL 1.2, 1.3, and 1.4, 1.5, or 2.0 as well as vendor
+ * extensions should all be queried. Calling an unavailable function
+ * will cause a {@link GLException} to be raised.
gl.isExtensionAvailable("GL_ARB_vertex_program");
.
+ * However, in this case it is up to the end user to know which
+ * routines or functionality are associated with which OpenGL
+ * extensions. It may also be used to test for the availability of a
+ * particular version of OpenGL: for example,
+ * gl.isExtensionAvailable("GL_VERSION_1_5");
.
+ *
+ * Exceptions to the window system extension naming rules: + * + *
wglAllocateMemoryNV
/
+ * glXAllocateMemoryNV
and associated routines. {@link
+ * #glAllocateMemoryNV} has been provided for window system-independent
+ * access to VAR. {@link #isFunctionAvailable} will translate an argument
+ * of "glAllocateMemoryNV" or "glFreeMemoryNV" into the appropriate
+ * window system-specific name.
+ *
+ * + * + */ +public interface GLBase { + + /** + * Indicates whether this GL object conforms to any of the OpenGL profiles. + */ + public boolean isGL(); + + /** + * Indicates whether this GL object conforms to the OpenGL ≥ 4.0 compatibility profile. + * The GL4 compatibility profile includes the GL2, GL2ES1, GL2ES2, GL3, GL3bc and GL4 profile. + * @see GLContext#isGL4bc() + */ + public boolean isGL4bc(); + + /** + * Indicates whether this GL object conforms to the OpenGL ≥ 4.0 core profile. + * The GL4 core profile includes the GL2ES2, and GL3 profile. + * @see GLContext#isGL4() + */ + public boolean isGL4(); + + /** + * Indicates whether this GL object conforms to the OpenGL ≥ 3.1 compatibility profile. + * The GL3 compatibility profile includes the GL2, GL2ES1, GL2ES2 and GL3 profile. + * @see GLContext#isGL3bc() + */ + public boolean isGL3bc(); + + /** + * Indicates whether this GL object conforms to the OpenGL ≥ 3.1 core profile. + * The GL3 core profile includes the GL2ES2 profile. + * @see GLContext#isGL3() + */ + public boolean isGL3(); + + /** + * Indicates whether this GL object conforms to the OpenGL ≤ 3.0 profile. + * The GL2 profile includes the GL2ES1 and GL2ES2 profile. + * @see GLContext#isGL2() + */ + public boolean isGL2(); + + /** + * Indicates whether this GL object conforms to the OpenGL ES ≥ 1.0 profile. + * @see GLContext#isGLES1() + */ + public boolean isGLES1(); + + /** + * Indicates whether this GL object conforms to the OpenGL ES ≥ 2.0 profile. + *
+ * Remark: ES2 compatible desktop profiles are not included. + * To query whether core ES2 functionality is provided, use {@link #isGLES2Compatible()}. + *
+ * @see #isGLES2Compatible() + * @see GLContext#isGLES2() + */ + public boolean isGLES2(); + + /** + * Indicates whether this GL object conforms to the OpenGL ES ≥ 3.0 profile. + *+ * Remark: ES3 compatible desktop profiles are not included. + * To query whether core ES3 functionality is provided, use {@link #isGLES3Compatible()}. + *
+ * @see #isGLES3Compatible() + * @see GLContext#isGLES3() + */ + public boolean isGLES3(); + + /** + * Indicates whether this GL object conforms to one of the OpenGL ES profiles, + * see {@link #isGLES1()}, {@link #isGLES2()} and {@link #isGLES3()}. + * @see GLContext#isGLES() + */ + public boolean isGLES(); + + /** + * Indicates whether this GL object conforms to a GL2ES1 compatible profile. + * @see GLContext#isGL2ES1() + */ + public boolean isGL2ES1(); + + /** + * Indicates whether this GL object conforms to a GL2ES2 compatible profile. + * @see GLContext#isGL2ES2() + */ + public boolean isGL2ES2(); + + /** + * Indicates whether this GL object conforms to a either a GL2GL3 or GL3ES3 compatible profile. + * @see GLContext#isGL2ES3() + */ + public boolean isGL2ES3(); + + /** + * Indicates whether this GL object conforms to a GL3ES3 compatible profile. + * @see GLContext#isGL3ES3() + */ + public boolean isGL3ES3(); + + /** + * Returns true if this GL object conforms to a GL4ES3 compatible profile, i.e. if {@link #isGLES3Compatible()} returns true. + *Includes [ GL ≥ 4.3, GL ≥ 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ]
+ * @see GLContext#isGL4ES3() + */ + public boolean isGL4ES3(); + + /** + * Indicates whether this GL object conforms to a GL2GL3 compatible profile. + * @see GLContext#isGL2GL3() + */ + public boolean isGL2GL3(); + + /** + * Indicates whether this GL object uses a GL4 core profile.Includes [ GL4 ].
+ * @see GLContext#isGL4core() + */ + public boolean isGL4core(); + + /** + * Indicates whether this GL object uses a GL3 core profile.Includes [ GL4, GL3 ].
+ * @see GLContext#isGL3core() + */ + public boolean isGL3core(); + + /** + * Indicates whether this GL object uses a GL core profile.Includes [ GL4, GL3, GLES3, GL2ES2 ].
+ * @see GLContext#isGLcore() + */ + public boolean isGLcore(); + + /** + * Indicates whether this GL object is compatible with the core OpenGL ES2 functionality. + * @return true if this context is an ES2 context or implements + * the extensionGL_ARB_ES2_compatibility
, otherwise false
+ * @see GLContext#isGLES2Compatible()
+ */
+ public boolean isGLES2Compatible();
+
+ /**
+ * Indicates whether this GL object is compatible with the core OpenGL ES3 functionality.
+ *
+ * Return true if the underlying context is an ES3 context or implements
+ * the extension GL_ARB_ES3_compatibility
, otherwise false.
+ *
+ * Includes [ GL ≥ 4.3, GL ≥ 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ] + *
+ * @see GLContext#isGLES3Compatible() + */ + public boolean isGLES3Compatible(); + + /** + * Indicates whether this GL object supports GLSL. + * @see GLContext#hasGLSL() + */ + public boolean hasGLSL(); + + /** + * Returns the downstream GL instance in case this is a wrapping pipeline, otherwisenull
.
+ * + * See {@link #getRootGL()} for retrieving the implementing root instance. + *
+ * @throws GLException if the downstream instance is not null and not a GL implementation + * @see #getRootGL() + */ + public GL getDownstreamGL() throws GLException; + + /** + * Returns the implementing root instance, considering a wrapped pipelined hierarchy, see {@link #getDownstreamGL()}. + *+ * If this instance is not a wrapping pipeline, i.e. has no downstream instance, + * this instance is returned. + *
+ * @throws GLException if the root instance is not a GL implementation + */ + public GL getRootGL() throws GLException; + + /** + * Casts this object to the GL interface. + * @throws GLException if this object is not a GL implementation + */ + public GL getGL() throws GLException; + + /** + * Casts this object to the GL4bc interface. + * @throws GLException if this object is not a GL4bc implementation + */ + public GL4bc getGL4bc() throws GLException; + + /** + * Casts this object to the GL4 interface. + * @throws GLException if this object is not a GL4 implementation + */ + public GL4 getGL4() throws GLException; + + /** + * Casts this object to the GL3bc interface. + * @throws GLException if this object is not a GL3bc implementation + */ + public GL3bc getGL3bc() throws GLException; + + /** + * Casts this object to the GL3 interface. + * @throws GLException if this object is not a GL3 implementation + */ + public GL3 getGL3() throws GLException; + + /** + * Casts this object to the GL2 interface. + * @throws GLException if this object is not a GL2 implementation + */ + public GL2 getGL2() throws GLException; + + /** + * Casts this object to the GLES1 interface. + * @throws GLException if this object is not a GLES1 implementation + */ + public GLES1 getGLES1() throws GLException; + + /** + * Casts this object to the GLES2 interface. + * @throws GLException if this object is not a GLES2 implementation + */ + public GLES2 getGLES2() throws GLException; + + /** + * Casts this object to the GLES3 interface. + * @throws GLException if this object is not a GLES3 implementation + */ + public GLES3 getGLES3() throws GLException; + + /** + * Casts this object to the GL2ES1 interface. + * @throws GLException if this object is not a GL2ES1 implementation + */ + public GL2ES1 getGL2ES1() throws GLException; + + /** + * Casts this object to the GL2ES2 interface. + * @throws GLException if this object is not a GL2ES2 implementation + */ + public GL2ES2 getGL2ES2() throws GLException; + + /** + * Casts this object to the GL2ES3 interface. + * @throws GLException if this object is not a GL2ES3 implementation + */ + public GL2ES3 getGL2ES3() throws GLException; + + /** + * Casts this object to the GL3ES3 interface. + * @throws GLException if this object is not a GL3ES3 implementation + */ + public GL3ES3 getGL3ES3() throws GLException; + + /** + * Casts this object to the GL4ES3 interface. + * @throws GLException if this object is not a GL4ES3 implementation + */ + public GL4ES3 getGL4ES3() throws GLException; + + /** + * Casts this object to the GL2GL3 interface. + * @throws GLException if this object is not a GL2GL3 implementation + */ + public GL2GL3 getGL2GL3() throws GLException; + + /** + * Returns the GLProfile associated with this GL object. + */ + public GLProfile getGLProfile(); + + /** + * Returns the GLContext associated which this GL object. + */ + public GLContext getContext(); + + /** + * Returns true if the specified OpenGL core- or extension-function can be + * used successfully through this GL instance given the current host (OpenGL + * client) and display (OpenGL server) configuration.+ * By "successfully" we mean that the function is both callable + * on the machine running the program and available on the current + * display.
+ * + * In order to call a function successfully, the function must be both + * callable on the machine running the program and available on + * the display device that is rendering the output (note: on non-networked, + * single-display machines these two conditions are identical; on networked and/or + * multi-display machines this becomes more complicated). These conditions are + * met if the function is either part of the core OpenGL version supported by + * both the host and display, or it is an OpenGL extension function that both + * the host and display support.
+ * + * A GL function is callable if it is successfully linked at runtime, + * hence the GLContext must be made current at least once. + * + * @param glFunctionName the name of the OpenGL function (e.g., use + * "glBindRenderbufferEXT" or "glBindRenderbuffer" to check if {@link + * GL#glBindRenderbuffer(int,int)} is available). + */ + public boolean isFunctionAvailable(String glFunctionName); + + /** + * Returns true if the specified OpenGL extension can be + * used successfully through this GL instance given the current host (OpenGL + * client) and display (OpenGL server) configuration.
+ *
+ * @param glExtensionName the name of the OpenGL extension (e.g.,
+ * "GL_ARB_vertex_program").
+ */
+ public boolean isExtensionAvailable(String glExtensionName);
+
+ /**
+ * Returns true
if basic FBO support is available, otherwise false
.
+ *
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= 3.0 [core, compat] or implements the extensions
+ * GL_ARB_ES2_compatibility
, GL_ARB_framebuffer_object
, GL_EXT_framebuffer_object
or GL_OES_framebuffer_object
.
+ *
+ * Basic FBO support may only include one color attachment and no multisampling, + * as well as limited internal formats for renderbuffer. + *
+ * @see GLContext#hasBasicFBOSupport() + */ + public boolean hasBasicFBOSupport(); + + /** + * Returnstrue
if full FBO support is available, otherwise false
.
+ *
+ * Full FBO is supported if the context is either GL >= core 3.0 [ES, core, compat] or implements the extensions
+ * ARB_framebuffer_object
, or all of
+ * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
+ * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ *
+ * Full FBO support includes multiple color attachments and multisampling. + *
+ * @see GLContext#hasFullFBOSupport() + */ + public boolean hasFullFBOSupport(); + + /** + * Returns the maximum number of FBO RENDERBUFFER samples + * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false. + * @see GLContext#getMaxRenderbufferSamples() + */ + public int getMaxRenderbufferSamples(); + + /** + * Returns true if the GL context supports non power of two (NPOT) textures, + * otherwise false. + *+ * NPOT textures are supported in OpenGL >= 3, GLES2 or if the + * 'GL_ARB_texture_non_power_of_two' extension is available. + *
+ */ + public boolean isNPOTTextureAvailable(); + + public boolean isTextureFormatBGRA8888Available(); + + /** Provides a platform-independent way to specify the minimum swap + interval for buffer swaps. An argument of 0 disables + sync-to-vertical-refresh completely, while an argument of 1 + causes the application to wait until the next vertical refresh + until swapping buffers. The default, which is platform-specific, + is usually either 0 or 1. This function is not guaranteed to + have an effect, and in particular only affects heavyweight + onscreen components. + + @see #getSwapInterval + @throws GLException if this context is not the current + */ + public void setSwapInterval(int interval); + + /** Provides a platform-independent way to get the swap + interval set by {@link #setSwapInterval}.
+ *
+ * Note: it is the intent to add new extensions as quickly as possible
+ * to the core GL API. Therefore it is unlikely that most vendors will
+ * use this extension mechanism, but it is being provided for
+ * completeness.
+ */
+ public Object getExtension(String extensionName);
+
+ /** Aliased entrypoint of void {@native glClearDepth}(GLclampd depth);
and void {@native glClearDepthf}(GLclampf depth);
. */
+ public void glClearDepth( double depth );
+
+ /** Aliased entrypoint of void {@native glDepthRange}(GLclampd depth);
and void {@native glDepthRangef}(GLclampf depth);
. */
+ public void glDepthRange(double zNear, double zFar);
+
+ /**
+ * @param target a GL buffer (VBO) target as used in {@link GL#glBindBuffer(int, int)}, ie {@link GL#GL_ELEMENT_ARRAY_BUFFER}, {@link GL#GL_ARRAY_BUFFER}, ..
+ * @return the GL buffer name bound to a target via {@link GL#glBindBuffer(int, int)} or 0 if unbound.
+ * @see #getBufferStorage(int)
+ */
+ public int getBoundBuffer(int target);
+
+ /**
+ * @param bufferName a GL buffer name, generated with e.g. {@link GL#glGenBuffers(int, int[], int)} and used in {@link GL#glBindBuffer(int, int)}, {@link GL#glBufferData(int, long, java.nio.Buffer, int)} or {@link GL2#glNamedBufferDataEXT(int, long, java.nio.Buffer, int)}.
+ * @return the size of the given GL buffer storage, see {@link GLBufferStorage}
+ * @see #getBoundBuffer(int)
+ */
+ public GLBufferStorage getBufferStorage(int bufferName);
+
+ /**
+ * Returns the {@link GLBufferStorage} instance as mapped via OpenGL's native {@link GL#glMapBuffer(int, int) glMapBuffer(..)} implementation.
+ *
+ * Throws a {@link GLException} if GL-function constraints are not met. + *
+ *+ * {@link GL#glMapBuffer(int, int)} wrapper calls this method and returns {@link GLBufferStorage#getMappedBuffer()}. + *
+ *+ * A zero {@link GLBufferStorage#getSize()} will avoid a native call and returns the unmapped {@link GLBufferStorage}. + *
+ *+ * A null native mapping result indicating an error will + * not cause a GLException but returns the unmapped {@link GLBufferStorage}. + * This allows the user to handle this case. + *
+ * @param target denotes the buffer via it's bound target + * @param access the mapping access mode + * @throws GLException if buffer is not bound to target + * @throws GLException if buffer is not tracked + * @throws GLException if buffer is already mapped + * @throws GLException if buffer has invalid store size, i.e. less-than zero + */ + public GLBufferStorage mapBuffer(int target, int access) throws GLException; + + /** + * Returns the {@link GLBufferStorage} instance as mapped via OpenGL's native {@link GL#glMapBufferRange(int, long, long, int) glMapBufferRange(..)} implementation. + *+ * Throws a {@link GLException} if GL-function constraints are not met. + *
+ *+ * {@link GL#glMapBufferRange(int, long, long, int)} wrapper calls this method and returns {@link GLBufferStorage#getMappedBuffer()}. + *
+ *+ * A zero {@link GLBufferStorage#getSize()} will avoid a native call and returns the unmapped {@link GLBufferStorage}. + *
+ *+ * A null native mapping result indicating an error will + * not cause a GLException but returns the unmapped {@link GLBufferStorage}. + * This allows the user to handle this case. + *
+ * @param target denotes the buffer via it's bound target + * @param offset offset of the mapped buffer's storage + * @param length length of the mapped buffer's storage + * @param access the mapping access mode + * @throws GLException if buffer is not bound to target + * @throws GLException if buffer is not tracked + * @throws GLException if buffer is already mapped + * @throws GLException if buffer has invalid store size, i.e. less-than zero + * @throws GLException if buffer mapping range does not fit, incl. offset + */ + public GLBufferStorage mapBufferRange(final int target, final long offset, final long length, final int access) throws GLException; + + /** + * @return true if a VBO is bound to {@link GL#GL_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false + */ + public boolean isVBOArrayBound(); + + /** + * @return true if a VBO is bound to {@link GL#GL_ELEMENT_ARRAY_BUFFER} via {@link GL#glBindBuffer(int, int)}, otherwise false + */ + public boolean isVBOElementArrayBound(); + + /** + * Return the framebuffer name bound to this context, + * see {@link GL#glBindFramebuffer(int, int)}. + *+ * Calls {@link GLContext#getBoundFramebuffer(int)}. + *
+ */ + public int getBoundFramebuffer(int target); + + /** + * Return the default draw framebuffer name. + *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link com.jogamp.opengl.FBObject}) based drawable
+ * is being used.
+ *
+ * Calls {@link GLContext#getDefaultDrawFramebuffer()}. + *
+ */ + public int getDefaultDrawFramebuffer(); + + /** + * Return the default read framebuffer name. + *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link com.jogamp.opengl.FBObject}) based drawable
+ * is being used.
+ *
+ * Calls {@link GLContext#getDefaultReadFramebuffer()}. + *
+ */ + public int getDefaultReadFramebuffer(); + + /** + * Returns the default color buffer within the current bound + * {@link #getDefaultReadFramebuffer()}, i.e. GL_READ_FRAMEBUFFER, + * which will be used as the source for pixel reading commands, + * like {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels} etc. + *+ * For offscreen framebuffer objects this is {@link GL#GL_COLOR_ATTACHMENT0}, + * otherwise this is {@link GL#GL_FRONT} for single buffer configurations + * and {@link GL#GL_BACK} for double buffer configurations. + *
+ *+ * Note-1: Neither ES1 nor ES2 supports selecting the read buffer via glReadBuffer + * and {@link GL#GL_BACK} is the default. + *
+ *+ * Note-2: ES3 only supports {@link GL#GL_BACK}, {@link GL#GL_NONE} or {@link GL#GL_COLOR_ATTACHMENT0}+i + *
+ *+ * Note-3: See {@link com.jogamp.opengl.util.GLDrawableUtil#swapBuffersBeforeRead(GLCapabilitiesImmutable) swapBuffersBeforeRead} + * for read-pixels and swap-buffers implications. + *
+ *+ * Calls {@link GLContext#getDefaultReadBuffer()}. + *
+ */ + public int getDefaultReadBuffer(); +} + diff --git a/src/jogl/classes/com/jogamp/opengl/GLBufferStorage.java b/src/jogl/classes/com/jogamp/opengl/GLBufferStorage.java new file mode 100644 index 000000000..5db97d42f --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/GLBufferStorage.java @@ -0,0 +1,160 @@ +/** + * 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; + +import java.nio.ByteBuffer; +import java.nio.IntBuffer; + +/** + * OpenGL buffer storage object reflecting it's + *+ * Buffer storage is created via: + *
glBufferStorage
- storage creation with target+ * Buffer storage is disposed via: + *
+ * GL buffer storage is mapped via + *
+ * GL buffer storage is unmapped via + *
true
if buffer's storage is mutable, i.e.
+ * created via {@link GL#glBufferData(int, long, java.nio.Buffer, int)}.
+ *
+ * Returns false
if buffer's storage is immutable, i.e.
+ * created via glBufferStorage
. FIXME: Add GL 4.4 support!
+ *
source
into this instance.
+ * @return this instance
+ */
+ public GLCapabilities copyFrom(final GLCapabilitiesImmutable source) {
+ super.copyFrom(source);
+ glProfile = source.getGLProfile();
+ isPBuffer = source.isPBuffer();
+ isFBO = source.isFBO();
+ doubleBuffered = source.getDoubleBuffered();
+ stereo = source.getStereo();
+ hardwareAccelerated = source.getHardwareAccelerated();
+ depthBits = source.getDepthBits();
+ stencilBits = source.getStencilBits();
+ accumRedBits = source.getAccumRedBits();
+ accumGreenBits = source.getAccumGreenBits();
+ accumBlueBits = source.getAccumBlueBits();
+ accumAlphaBits = source.getAccumAlphaBits();
+ sampleBuffers = source.getSampleBuffers();
+ numSamples = source.getNumSamples();
+ sampleExtension = source.getSampleExtension();
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = super.hashCode();
+ hash = ((hash << 5) - hash) + this.glProfile.hashCode() ;
+ hash = ((hash << 5) - hash) + ( this.hardwareAccelerated ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.stereo ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.isFBO ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.isPBuffer ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.sampleBuffers ? 1 : 0 );
+ hash = ((hash << 5) - hash) + this.getNumSamples();
+ hash = ((hash << 5) - hash) + this.sampleExtension.hashCode();
+ hash = ((hash << 5) - hash) + this.depthBits;
+ hash = ((hash << 5) - hash) + this.stencilBits;
+ hash = ((hash << 5) - hash) + this.accumRedBits;
+ hash = ((hash << 5) - hash) + this.accumGreenBits;
+ hash = ((hash << 5) - hash) + this.accumBlueBits;
+ hash = ((hash << 5) - hash) + this.accumAlphaBits;
+ return hash;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if(this == obj) { return true; }
+ if(!(obj instanceof GLCapabilitiesImmutable)) {
+ return false;
+ }
+ final GLCapabilitiesImmutable other = (GLCapabilitiesImmutable)obj;
+ boolean res = super.equals(obj) &&
+ other.getGLProfile()==glProfile &&
+ other.isPBuffer()==isPBuffer &&
+ other.isFBO()==isFBO &&
+ other.getDoubleBuffered() == doubleBuffered &&
+ other.getStereo()==stereo &&
+ other.getHardwareAccelerated()==hardwareAccelerated &&
+ other.getDepthBits()==depthBits &&
+ other.getStencilBits()==stencilBits &&
+ other.getAccumRedBits()==accumRedBits &&
+ other.getAccumGreenBits()==accumGreenBits &&
+ other.getAccumBlueBits()==accumBlueBits &&
+ other.getAccumAlphaBits()==accumAlphaBits &&
+ other.getSampleBuffers()==sampleBuffers;
+ if(res && sampleBuffers) {
+ res = other.getNumSamples()==getNumSamples() &&
+ other.getSampleExtension().equals(sampleExtension) ;
+ }
+ return res;
+ }
+
+ /** comparing hw/sw, stereo, multisample, stencil, RGBA and depth only */
+ @Override
+ public int compareTo(final CapabilitiesImmutable o) {
+ if ( ! ( o instanceof GLCapabilitiesImmutable ) ) {
+ final Class> c = (null != o) ? o.getClass() : null ;
+ throw new ClassCastException("Not a GLCapabilitiesImmutable object, but " + c);
+ }
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) o;
+
+ if(hardwareAccelerated && !caps.getHardwareAccelerated()) {
+ return 1;
+ } else if(!hardwareAccelerated && caps.getHardwareAccelerated()) {
+ return -1;
+ }
+
+ if(stereo && !caps.getStereo()) {
+ return 1;
+ } else if(!stereo && caps.getStereo()) {
+ return -1;
+ }
+
+ if(doubleBuffered && !caps.getDoubleBuffered()) {
+ return 1;
+ } else if(!doubleBuffered && caps.getDoubleBuffered()) {
+ return -1;
+ }
+
+ final int ms = getNumSamples();
+ final int xms = caps.getNumSamples() ;
+
+ if(ms > xms) {
+ return 1;
+ } else if( ms < xms ) {
+ return -1;
+ }
+ // ignore the sample extension
+
+ if(stencilBits > caps.getStencilBits()) {
+ return 1;
+ } else if(stencilBits < caps.getStencilBits()) {
+ return -1;
+ }
+
+ final int sc = super.compareTo(caps); // RGBA
+ if(0 != sc) {
+ return sc;
+ }
+
+ if(depthBits > caps.getDepthBits()) {
+ return 1;
+ } else if(depthBits < caps.getDepthBits()) {
+ return -1;
+ }
+
+ return 0; // they are equal: hw/sw, stereo, multisample, stencil, RGBA and depth
+ }
+
+ @Override
+ public final GLProfile getGLProfile() {
+ return glProfile;
+ }
+
+ /** Sets the GL profile you desire */
+ public void setGLProfile(final GLProfile profile) {
+ glProfile=profile;
+ }
+
+ @Override
+ public final boolean isPBuffer() {
+ return isPBuffer;
+ }
+
+ /**
+ * Requesting offscreen pbuffer mode.
+ * + * If enabled this method also invokes {@link #setOnscreen(boolean) setOnscreen(false)}. + *
+ *+ * Defaults to false. + *
+ *+ * Requesting offscreen pbuffer mode disables the offscreen auto selection. + *
+ */ + public void setPBuffer(final boolean enable) { + if(enable) { + setOnscreen(false); + } + isPBuffer = enable; + } + + @Override + public final boolean isFBO() { + return isFBO; + } + + /** + * Requesting offscreen FBO mode. + *+ * If enabled this method also invokes {@link #setOnscreen(boolean) setOnscreen(false)}. + *
+ *+ * Defaults to false. + *
+ *+ * Requesting offscreen FBO mode disables the offscreen auto selection. + *
+ */ + public void setFBO(final boolean enable) { + if(enable) { + setOnscreen(false); + } + isFBO = enable; + } + + @Override + public final boolean getDoubleBuffered() { + return doubleBuffered; + } + + /** Enables or disables double buffering. */ + public void setDoubleBuffered(final boolean enable) { + doubleBuffered = enable; + } + + @Override + public final boolean getStereo() { + return stereo; + } + + /** Enables or disables stereo viewing. */ + public void setStereo(final boolean enable) { + stereo = enable; + } + + @Override + public final boolean getHardwareAccelerated() { + return hardwareAccelerated; + } + + /** Enables or disables hardware acceleration. */ + public void setHardwareAccelerated(final boolean enable) { + hardwareAccelerated = enable; + } + + @Override + public final int getDepthBits() { + return depthBits; + } + + /** Sets the number of bits requested for the depth buffer. */ + public void setDepthBits(final int depthBits) { + this.depthBits = depthBits; + } + + @Override + public final int getStencilBits() { + return stencilBits; + } + + /** Sets the number of bits requested for the stencil buffer. */ + public void setStencilBits(final int stencilBits) { + this.stencilBits = stencilBits; + } + + @Override + public final int getAccumRedBits() { + return accumRedBits; + } + + /** Sets the number of bits requested for the accumulation buffer's + red component. On some systems only the accumulation buffer + depth, which is the sum of the red, green, and blue bits, is + considered. */ + public void setAccumRedBits(final int accumRedBits) { + this.accumRedBits = accumRedBits; + } + + @Override + public final int getAccumGreenBits() { + return accumGreenBits; + } + + /** Sets the number of bits requested for the accumulation buffer's + green component. On some systems only the accumulation buffer + depth, which is the sum of the red, green, and blue bits, is + considered. */ + public void setAccumGreenBits(final int accumGreenBits) { + this.accumGreenBits = accumGreenBits; + } + + @Override + public final int getAccumBlueBits() { + return accumBlueBits; + } + + /** Sets the number of bits requested for the accumulation buffer's + blue component. On some systems only the accumulation buffer + depth, which is the sum of the red, green, and blue bits, is + considered. */ + public void setAccumBlueBits(final int accumBlueBits) { + this.accumBlueBits = accumBlueBits; + } + + @Override + public final int getAccumAlphaBits() { + return accumAlphaBits; + } + + /** Sets number of bits requested for accumulation buffer's alpha + component. On some systems only the accumulation buffer depth, + which is the sum of the red, green, and blue bits, is + considered. */ + public void setAccumAlphaBits(final int accumAlphaBits) { + this.accumAlphaBits = accumAlphaBits; + } + + /** + * Sets the desired extension for full-scene antialiasing + * (FSAA), default is {@link #DEFAULT_SAMPLE_EXTENSION}. + */ + public void setSampleExtension(final String se) { + sampleExtension = se; + } + + @Override + public final String getSampleExtension() { + return sampleExtension; + } + + /** + * Defaults to false.EGL.EGL_SAMPLES, GLX.GLX_SAMPLES, WGLExt.WGL_SAMPLES_ARB
+ * if available, or any other known fallback one, ie EGLExt.EGL_COVERAGE_SAMPLES_NV
+ */
+ public static final String DEFAULT_SAMPLE_EXTENSION = "default" ;
+
+ /**
+ * Returns the GL profile you desire or used by the drawable.
+ */
+ GLProfile getGLProfile();
+
+ /**
+ * Returns the number of bits for the accumulation
+ * buffer's alpha component. On some systems only the accumulation
+ * buffer depth, which is the sum of the red, green, and blue bits,
+ * is considered.
+ */
+ int getAccumAlphaBits();
+
+ /**
+ * Returns the number of bits for the accumulation
+ * buffer's blue component. On some systems only the accumulation
+ * buffer depth, which is the sum of the red, green, and blue bits,
+ * is considered.
+ */
+ int getAccumBlueBits();
+
+ /**
+ * Returns the number of bits for the accumulation
+ * buffer's green component. On some systems only the accumulation
+ * buffer depth, which is the sum of the red, green, and blue bits,
+ * is considered.
+ */
+ int getAccumGreenBits();
+
+ /**
+ * Returns the number of bits for the accumulation
+ * buffer's red component. On some systems only the accumulation
+ * buffer depth, which is the sum of the red, green, and blue bits,
+ * is considered.
+ */
+ int getAccumRedBits();
+
+ /**
+ * Returns the number of depth buffer bits.
+ */
+ int getDepthBits();
+
+ /**
+ * Returns whether double-buffering is requested, available or chosen.
+ * + * Default is true. + *
+ */ + boolean getDoubleBuffered(); + + /** + * Returns whether hardware acceleration is requested, available or chosen. + *+ * Default is true. + *
+ */ + boolean getHardwareAccelerated(); + + /** + * Returns the extension for full-scene antialiasing + * (FSAA). + *+ * Default is {@link #DEFAULT_SAMPLE_EXTENSION}. + *
+ */ + String getSampleExtension(); + + /** + * Returns whether sample buffers for full-scene antialiasing + * (FSAA) should be allocated for this drawable. + *+ * Default is false. + *
+ */ + boolean getSampleBuffers(); + + /** + * Returns the number of sample buffers to be allocated if sample + * buffers are enabled, otherwise returns 0. + *+ * Default is 0 due to disable sample buffers per default. + *
+ */ + int getNumSamples(); + + /** + * Returns the number of stencil buffer bits. + *+ * Default is 0. + *
+ */ + int getStencilBits(); + + /** + * Returns whether stereo is requested, available or chosen. + *+ * Default is false. + *
+ */ + boolean getStereo(); + + /** + * Returns whether pbuffer offscreen mode is requested, available or chosen. + *+ * Default is false. + *
+ *
+ * For chosen capabilities, only the selected offscreen surface is set to true
.
+ *
+ * Default is false. + *
+ *
+ * For chosen capabilities, only the selected offscreen surface is set to true
.
+ *
true
(default), bootstrapping the available GL profiles
+ * will use the highest compatible GL context for each profile,
+ * hence skipping querying lower profiles if a compatible higher one is found:
+ *
+ * Can be turned off with property jogl.debug.GLContext.NoProfileAliasing
.
+ *
GL_ARB_ES3_compatibility
*/
+ public static final VersionNumber Version4_3 = new VersionNumber(4, 3, 0);
+
+ protected static final VersionNumber Version8_0 = new VersionNumber(8, 0, 0);
+
+ private static final String S_EMPTY = "";
+
+ //
+ // Cached keys, bits [0..15]
+ //
+
+ /** Context option bits, full bit mask covering 16 bits [0..15], i.e. 0x0000FFFF
, {@value}. */
+ protected static final int CTX_IMPL_FULL_MASK = 0x0000FFFF;
+
+ /** Context option bits, cached bit mask covering 10 bits [0..9], i.e. 0x000003FF
, {@value}. Leaving 6 bits for non cached options, i.e. 10:6. */
+ protected static final int CTX_IMPL_CACHE_MASK = 0x000003FF;
+
+ /** ARB_create_context
related: created via ARB_create_context. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_IS_ARB_CREATED = 1 << 0;
+ /** ARB_create_context
related: desktop compatibility profile. Cache key value. See {@link #isGLCompatibilityProfile()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_PROFILE_COMPAT = 1 << 1;
+ /** ARB_create_context
related: desktop core profile. Cache key value. See {@link #isGLCoreProfile()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_PROFILE_CORE = 1 << 2;
+ /** ARB_create_context
related: ES profile. Cache key value. See {@link #isGLES()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_PROFILE_ES = 1 << 3;
+ /** ARB_create_context
related: flag forward compatible. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_OPTION_FORWARD = 1 << 4;
+ /** ARB_create_context
related: flag debug. Cache key value. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ public static final int CTX_OPTION_DEBUG = 1 << 5;
+ /** Context uses software rasterizer, otherwise hardware rasterizer. Cache key value. See {@link #isHardwareRasterizer()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 6;
+
+ //
+ // Non cached keys, 6 bits [10..15]
+ //
+
+ /** GL_ARB_ES2_compatibility
implementation related: Context is compatible w/ ES2. Not a cache key. See {@link #isGLES2Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_IMPL_ES2_COMPAT = 1 << 10;
+
+ /** GL_ARB_ES3_compatibility
implementation related: Context is compatible w/ ES3. Not a cache key. See {@link #isGLES3Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */
+ protected static final int CTX_IMPL_ES3_COMPAT = 1 << 11;
+
+ /**
+ * Context supports basic FBO, details see {@link #hasBasicFBOSupport()}.
+ * Not a cache key.
+ * @see #hasBasicFBOSupport()
+ * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
+ */
+ protected static final int CTX_IMPL_FBO = 1 << 12;
+
+ /**
+ * Context supports OES_single_precision
, fp32, fixed function point (FFP) compatibility entry points,
+ * see {@link #hasFP32CompatAPI()}.
+ * Not a cache key.
+ * @see #hasFP32CompatAPI()
+ * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)
+ */
+ protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 13;
+
+ private static final ThreadLocalnull
.
+ * + * Returns this GLContext, if it is a shared master. + *
+ * @since 2.2.1 + */ + public final GLContext getSharedMaster() { + return GLContextShareSet.getSharedMaster(this); + } + + /** Returns a new list of created GLContext shared with this GLContext. */ + public final Listnull
.
+ */
+ public final GLRendererQuirks getRendererQuirks() { return glRendererQuirks; }
+
+ /**
+ * Returns true if the quirk
exist in {@link #getRendererQuirks()}, otherwise false.
+ * + * Convenience method for: + *
+ * final GLRendererQuirks glrq = ctx.getRendererQuirks(); + * boolean hasQuirk = null != glrq ? glrq.exist(quirk) : false ; + *+ * + * @param quirk the quirk to be tested, e.g. {@link GLRendererQuirks#NoDoubleBufferedPBuffer}. + * @throws IllegalArgumentException if the quirk is out of range + */ + public final boolean hasRendererQuirk(final int quirk) throws IllegalArgumentException { + return null != glRendererQuirks ? glRendererQuirks.exist(quirk) : false ; + } + + /** + * Sets the read/write drawable for framebuffer operations, i.e. reassociation of the context's drawable. + *
+ * If the arguments reflect the current state of this context + * this method is a no-operation and returns the old and current {@link GLDrawable}. + *
+ *+ * Remarks: + *
null
to remove association.
+ * @param setWriteOnly Only change the write-drawable, if setWriteOnly
is true
and
+ * if the {@link #getGLReadDrawable() read-drawable} differs
+ * from the {@link #getGLDrawable() write-drawable}.
+ * Otherwise set both drawables, read and write.
+ * @return The previous read/write drawable if operation succeeds
+ *
+ * @throws GLException in case null
is being passed,
+ * this context is made current on another thread
+ * or operation fails.
+ *
+ * @see #isGLReadDrawableAvailable()
+ * @see #setGLReadDrawable(GLDrawable)
+ * @see #getGLReadDrawable()
+ * @see #setGLDrawable(GLDrawable, boolean)
+ * @see #getGLDrawable()
+ */
+ public abstract GLDrawable setGLDrawable(GLDrawable readWrite, boolean setWriteOnly);
+
+ /**
+ * Returns the write-drawable this context uses for framebuffer operations.
+ * + * If the read-drawable has not been changed manually via {@link #setGLReadDrawable(GLDrawable)}, + * it equals to the write-drawable (default). + *
+ *+ * Method is only thread-safe while context is {@link #makeCurrent() made current}. + *
+ * @see #setGLDrawable(GLDrawable, boolean) + * @see #setGLReadDrawable(GLDrawable) + */ + public abstract GLDrawable getGLDrawable(); + + /** + * Query whether using a distinguished read-drawable is supported. + * @return true if using a read-drawable is supported with your driver/OS, otherwise false. + */ + public abstract boolean isGLReadDrawableAvailable(); + + /** + * Set the read-Drawable for read framebuffer operations.+ * If the context was current on this thread, it is being released before switching the drawable + * and made current afterwards. However the user shall take extra care that not other thread + * attempts to make this context current. Otherwise a race condition may happen. + *
+ * + * @param read the read-drawable for read framebuffer operations. + * If null is passed, the default write drawable will be set. + * @return the previous read-drawable + * + * @throws GLException in case a read drawable is not supported or + * this context is made current on another thread. + * + * @see #isGLReadDrawableAvailable() + * @see #getGLReadDrawable() + */ + public abstract GLDrawable setGLReadDrawable(GLDrawable read); + + /** + * Returns the read-Drawable this context uses for read framebuffer operations. + *+ * If the read-drawable has not been changed manually via {@link #setGLReadDrawable(GLDrawable)}, + * it equals to the write-drawable (default). + *
+ *+ * Method is only thread-safe while context is {@link #makeCurrent() made current}. + *
+ * @see #isGLReadDrawableAvailable() + * @see #setGLReadDrawable(GLDrawable) + * @see #getGLReadDrawable() + */ + public abstract GLDrawable getGLReadDrawable(); + + /** + * Makes this GLContext current on the calling thread. + *+ * Recursive call to {@link #makeCurrent()} and hence {@link #release()} are supported. + *
+ *+ * There are two return values that indicate success and one that + * indicates failure. + *
+ *+ * A return value of {@link #CONTEXT_CURRENT_NEW} + * indicates that that context has been made current for the 1st time, + * or that the state of the underlying context or drawable has + * changed since the last time this context was current. + * In this case, the application may wish to initialize the render state. + *
+ *+ * A return value of {@link #CONTEXT_CURRENT} indicates that the context has + * been made current, with its previous state restored. + *
+ *+ * If the context could not be made current (for example, because + * the underlying drawable has not ben realized on the display) , + * a value of {@link #CONTEXT_NOT_CURRENT} is returned. + *
+ *+ * This method is blocking, i.e. waits until another thread has + * released the context. + *
+ *+ * The drawable's surface is being locked at entry + * and unlocked at {@link #release()} + *
+ * + * @return+ * Recursive call to {@link #release()} and hence {@link #makeCurrent()} are supported. + *
+ *+ * The drawable's surface is being unlocked at exit, + * assumed to be locked by {@link #makeCurrent()}. + *
+ * + * @throws GLException if the context had not previously been made + * current on the current thread + */ + public abstract void release() throws GLException; + + /** + * Copies selected groups of OpenGL state variables from the + * supplied source context into this one. Themask
+ * parameter indicates which groups of state variables are to be
+ * copied. mask
contains the bitwise OR of the same
+ * symbolic names that are passed to the GL command {@link
+ * GL2#glPushAttrib glPushAttrib}. The single symbolic constant
+ * {@link GL2#GL_ALL_ATTRIB_BITS GL_ALL_ATTRIB_BITS} can be used to
+ * copy the maximum possible portion of rendering state. + * + * Not all values for GL state can be copied. For example, pixel + * pack and unpack state, render mode state, and select and feedback + * state are not copied. The state that can be copied is exactly the + * state that is manipulated by the GL command {@link + * GL2#glPushAttrib glPushAttrib}.
+ * + * On most platforms, this context may not be current to any thread, + * including the calling thread, when this method is called. Some + * platforms have additional requirements such as whether this + * context or the source context must occasionally be made current + * in order for the results of the copy to be seen; these + * requirements are beyond the scope of this specification. + * + * @param source the source OpenGL context from which to copy state + * @param mask a mask of symbolic names indicating which groups of state to copy + + * @throws GLException if an OpenGL-related error occurred + */ + public abstract void copy(GLContext source, int mask) throws GLException; + + /** + * Returns the GL object bound to this thread current context. + * If no context is current, throw an GLException + * + * @return the current context's GL object on this thread + * @throws GLException if no context is current + */ + public static GL getCurrentGL() throws GLException { + final GLContext glc = getCurrent(); + if(null==glc) { + throw new GLException(getThreadName()+": No OpenGL context current on this thread"); + } + return glc.getGL(); + } + + /** + * Returns this thread current context. + * If no context is current, returns null. + * + * @return the context current on this thread, or null if no context + * is current. + */ + public static GLContext getCurrent() { + return currentContext.get(); + } + + /** + * @return true if this GLContext is current on this thread + */ + public final boolean isCurrent() { + return getCurrent() == this ; + } + + /** + * @throws GLException if this GLContext is not current on this thread + */ + public final void validateCurrent() throws GLException { + if(getCurrent() != this) { + throw new GLException(getThreadName()+": This context is not current. Current context: "+getCurrent()+", this context "+this); + } + } + + /** Returns a String representation of the {@link #makeCurrent()} result. */ + public static final String makeCurrentResultToString(final int res) { + switch(res) { + case CONTEXT_NOT_CURRENT: return "CONTEXT_NOT_CURRENT"; + case CONTEXT_CURRENT: return "CONTEXT_CURRENT"; + case CONTEXT_CURRENT_NEW: return "CONTEXT_CURRENT_NEW"; + default: return "INVALID_VALUE"; + } + } + + /** + * Sets the thread-local variable returned by {@link #getCurrent} + * and has no other side-effects. For use by third parties adding + * new GLContext implementations; not for use by end users. + */ + protected static void setCurrent(final GLContext cur) { + if( TRACE_SWITCH ) { + if(null == cur) { + System.err.println(getThreadName()+": GLContext.ContextSwitch: - setCurrent() - NULL"); + } else { + System.err.println(getThreadName()+": GLContext.ContextSwitch: - setCurrent() - obj " + toHexString(cur.hashCode()) + ", ctx " + toHexString(cur.getHandle())); + } + } + currentContext.set(cur); + } + + /** + * Destroys this OpenGL context and frees its associated + * resources. + *
+ * The context may be current w/o recursion when calling destroy()
,
+ * in which case this method destroys the context and releases the lock.
+ *
+ * major.minor ([option]?[options,]*) - gl-version + *
ES profile
ES profileCompatibility profile
Compatibility profile including fixed function pipeline and deprecated functionalityCore profile
Core profileforward
Forward profile excluding deprecated functionalityarb
refers to an ARB_create_context created contextdebug
refers to a debug contextES2 compatible
refers to an ES2 compatible implementationsoftware
refers to a software implementation of the rasterizerhardware
refers to a hardware implementation of the rasterizerrow 2, cell 1 | + *row 2, cell 2 | + *
ES2 | 2.0 (ES profile, ES2 compatible, hardware) - 2.0 ES Profile | |
ATI | GL2 | 3.0 (Compatibility profile, arb, hardware) - 3.2.9704 Compatibility Profile Context |
ATI | GL3 | 3.3 (Core profile, any, new, hardware) - 1.4 (3.2.9704 Compatibility Profile Context) |
ATI | GL3bc | 3.3 (Compatibility profile, arb, hardware) - 1.4 (3.2.9704 Compatibility Profile Context) |
NV | GL2 | 3.0 (Compatibility profile, arb, hardware) - 3.0.0 NVIDIA 195.36.07.03 |
NV | GL3 | 3.3 (Core profile, arb, hardware) - 3.3.0 NVIDIA 195.36.07.03 |
NV | GL3bc | 3.3 (Compatibility profile, arb, hardware) - 3.3.0 NVIDIA 195.36.07.03 |
NV | GL2 | 3.0 (Compatibility profile, arb, ES2 compatible, hardware) - 3.0.0 NVIDIA 290.10 |
GL_VERSION
not being the GL version.
+ *
+ * In case no such version exists within GL_VERSION
,
+ * the {@link VersionNumberString#zeroVersion zero version} instance is returned.
+ *
+ * The vendor's version is usually the vendor's OpenGL driver version. + *
+ */ + public final VersionNumberString getGLVendorVersionNumber() { return ctxVendorVersion; } + public final boolean isGLCompatibilityProfile() { return ( 0 != ( CTX_PROFILE_COMPAT & ctxOptions ) ); } + public final boolean isGLCoreProfile() { return ( 0 != ( CTX_PROFILE_CORE & ctxOptions ) ); } + public final boolean isGLESProfile() { return ( 0 != ( CTX_PROFILE_ES & ctxOptions ) ); } + public final boolean isGLForwardCompatible() { return ( 0 != ( CTX_OPTION_FORWARD & ctxOptions ) ); } + public final boolean isGLDebugEnabled() { return ( 0 != ( CTX_OPTION_DEBUG & ctxOptions ) ); } + public final boolean isCreatedWithARBMethod() { return ( 0 != ( CTX_IS_ARB_CREATED & ctxOptions ) ); } + + /** + * Returns the matching GLSL version number, queried by this context GL + * via {@link GL2ES2#GL_SHADING_LANGUAGE_VERSION} if ≥ ES2.0 or GL2.0, + * otherwise a static match is being utilized. + *+ * The context must have been current once, + * otherwise the {@link VersionNumberString#zeroVersion zero version} instance is returned. + *
+ *
+ * Examples w/ major.minor
:
+ *
+ * 1.00 (ES 2.0), 3.00 (ES 3.0) + * 1.10 (GL 2.0), 1.20 (GL 2.1), 1.50 (GL 3.2), + * 3.30 (GL 3.3), 4.00 (GL 4.0), 4.10 (GL 4.1), 4.20 (GL 4.2) + *+ * + *
+ * Matching could also refer to the maximum GLSL version usable by this context + * since normal GL implementations are capable of using a lower GLSL version as well. + * The latter is not true on OSX w/ a GL3 context. + *
+ * + * @return GLSL version number if context has been made current at least once, + * otherwise the {@link VersionNumberString#zeroVersion zero version} instance is returned. + * + * @see #getGLVersionNumber() + */ + public final VersionNumber getGLSLVersionNumber() { + return ctxGLSLVersion; + } + + /** + * Returns the GLSL version string as to be used in a shader program, including a terminating newline '\n', + * i.e. for desktop + *+ * #version 110 + * .. + * #version 150 core + * #version 330 compatibility + * ... + *+ * And for ES: + *
+ * #version 100 + * #version 300 es + * .. + *+ *
+ * If context has not been made current yet, a string of zero length is returned. + *
+ * @see #getGLSLVersionNumber() + */ + public final String getGLSLVersionString() { + if( ctxGLSLVersion.isZero() ) { + return S_EMPTY; + } + final int minor = ctxGLSLVersion.getMinor(); + final String profileOpt; + if( isGLES() ) { + profileOpt = ctxGLSLVersion.compareTo(Version3_0) >= 0 ? " es" : S_EMPTY; + } else if( isGLCoreProfile() ) { + profileOpt = ctxGLSLVersion.compareTo(Version1_50) >= 0 ? " core" : S_EMPTY; + } else if( isGLCompatibilityProfile() ) { + profileOpt = ctxGLSLVersion.compareTo(Version1_50) >= 0 ? " compatibility" : S_EMPTY; + } else { + throw new InternalError("Neither ES, Core nor Compat: "+this); // see validateProfileBits(..) + } + return "#version " + ctxGLSLVersion.getMajor() + ( minor < 10 ? "0"+minor : minor ) + profileOpt + "\n" ; + } + + protected static final VersionNumber getStaticGLSLVersionNumber(final int glMajorVersion, final int glMinorVersion, final int ctxOptions) { + if( 0 != ( CTX_PROFILE_ES & ctxOptions ) ) { + if( 3 == glMajorVersion ) { + return Version3_0; // ES 3.0 -> GLSL 3.00 + } else if( 2 == glMajorVersion ) { + return Version1_0; // ES 2.0 -> GLSL 1.00 + } + } else if( 1 == glMajorVersion ) { + return Version1_10; // GL 1.x -> GLSL 1.10 + } else if( 2 == glMajorVersion ) { + switch ( glMinorVersion ) { + case 0: return Version1_10; // GL 2.0 -> GLSL 1.10 + default: return Version1_20; // GL 2.1 -> GLSL 1.20 + } + } else if( 3 == glMajorVersion && 2 >= glMinorVersion ) { + switch ( glMinorVersion ) { + case 0: return Version1_30; // GL 3.0 -> GLSL 1.30 + case 1: return Version1_40; // GL 3.1 -> GLSL 1.40 + default: return Version1_50; // GL 3.2 -> GLSL 1.50 + } + } + // The new default: GL >= 3.3, ES >= 3.0 + return new VersionNumber(glMajorVersion, glMinorVersion * 10, 0); // GL M.N -> GLSL M.N + } + + /** + * @return true if this context is an ES2 context or implements + * the extensionGL_ARB_ES3_compatibility
or GL_ARB_ES2_compatibility
, otherwise false
+ */
+ public final boolean isGLES2Compatible() {
+ return 0 != ( ctxOptions & ( CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ) ) ;
+ }
+
+ /**
+ * Return true if this context is an ES3 context or implements
+ * the extension GL_ARB_ES3_compatibility
, otherwise false.
+ * + * Includes [ GL ≥ 4.3, GL ≥ 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ] + *
+ */ + public final boolean isGLES3Compatible() { + return 0 != ( ctxOptions & CTX_IMPL_ES3_COMPAT ) ; + } + + /** + * @return true if impl. is a hardware rasterizer, otherwise false. + * @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile) + * @see GLProfile#isHardwareRasterizer() + */ + public final boolean isHardwareRasterizer() { + return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ; + } + + /** + * @return true if context supports GLSL, i.e. is either {@link #isGLES3()}, {@link #isGLES2()}, {@link #isGL3()} or {@link #isGL2()} and major-version > 1. + * @see GLProfile#hasGLSL() + */ + public final boolean hasGLSL() { + return isGLES3() || + isGLES2() || + isGL3() || + isGL2() && ctxVersion.getMajor()>1 ; + } + + /** + * Returnstrue
if basic FBO support is available, otherwise false
.
+ *
+ * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= 3.0 [core, compat] or implements the extensions
+ * GL_ARB_ES2_compatibility
, GL_ARB_framebuffer_object
, GL_EXT_framebuffer_object
or GL_OES_framebuffer_object
.
+ *
+ * Basic FBO support may only include one color attachment and no multisampling, + * as well as limited internal formats for renderbuffer. + *
+ * @see #CTX_IMPL_FBO + */ + public final boolean hasBasicFBOSupport() { + return 0 != ( ctxOptions & CTX_IMPL_FBO ) ; + } + + /** + * Returnstrue
if full FBO support is available, otherwise false
.
+ *
+ * Full FBO is supported if the context is either GL >= 3.0 [ES, core, compat] or implements the extensions
+ * ARB_framebuffer_object
, or all of
+ * EXT_framebuffer_object
, EXT_framebuffer_multisample
,
+ * EXT_framebuffer_blit
, GL_EXT_packed_depth_stencil
.
+ *
+ * Full FBO support includes multiple color attachments and multisampling. + *
+ */ + public final boolean hasFullFBOSupport() { + return hasBasicFBOSupport() && !hasRendererQuirk(GLRendererQuirks.NoFullFBOSupport) && + ( isGL3ES3() || // GL >= 3.0 [ES, core, compat] + isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object + ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object* + isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) && + isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) && + isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) + ) + ) ; + } + + /** + * Returnstrue
if OES_single_precision
, fp32, fixed function point (FFP) compatibility entry points available,
+ * otherwise false
.
+ * @see #CTX_IMPL_FP32_COMPAT_API
+ */
+ public final boolean hasFP32CompatAPI() {
+ return 0 != ( ctxOptions & CTX_IMPL_FP32_COMPAT_API ) ;
+ }
+
+ /**
+ * Returns the maximum number of FBO RENDERBUFFER samples
+ * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false.
+ */
+ public final int getMaxRenderbufferSamples() {
+ if( hasFullFBOSupport() ) {
+ final GL gl = getGL();
+ final int[] val = new int[] { 0 } ;
+ try {
+ gl.glGetIntegerv(GL2ES3.GL_MAX_SAMPLES, val, 0);
+ final int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR == glerr) {
+ return val[0];
+ } else if(DEBUG) {
+ System.err.println("GLContext.getMaxRenderbufferSamples: GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr));
+ }
+ } catch (final GLException gle) { gle.printStackTrace(); }
+ }
+ return 0;
+ }
+
+ /** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returns true
. */
+ public boolean isNPOTTextureAvailable() {
+ return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two);
+ }
+
+ public boolean isTextureFormatBGRA8888Available() {
+ return isGL2GL3() ||
+ isExtensionAvailable(GLExtensions.EXT_texture_format_BGRA8888) ||
+ isExtensionAvailable(GLExtensions.IMG_texture_format_BGRA8888) ;
+ }
+
+ /**
+ * Indicates whether this GLContext is capable of GL4bc. Includes [ GL4bc ].
+ * @see GLProfile#isGL4bc() + */ + public final boolean isGL4bc() { + return 0 != (ctxOptions & CTX_PROFILE_COMPAT) && + ctxVersion.getMajor() >= 4; + } + + /** + * Indicates whether this GLContext is capable of GL4.Includes [ GL4bc, GL4 ].
+ * @see GLProfile#isGL4() + */ + public final boolean isGL4() { + return 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)) && + ctxVersion.getMajor() >= 4; + } + + /** + * Indicates whether this GLContext uses a GL4 core profile.Includes [ GL4 ].
+ */ + public final boolean isGL4core() { + return 0 != ( ctxOptions & CTX_PROFILE_CORE ) && + ctxVersion.getMajor() >= 4; + } + + /** + * Indicates whether this GLContext is capable of GL3bc.Includes [ GL4bc, GL3bc ].
+ * @see GLProfile#isGL3bc() + */ + public final boolean isGL3bc() { + return 0 != (ctxOptions & CTX_PROFILE_COMPAT) && + ctxVersion.compareTo(Version3_1) >= 0 ; + } + + /** + * Indicates whether this GLContext is capable of GL3.Includes [ GL4bc, GL4, GL3bc, GL3 ].
+ * @see GLProfile#isGL3() + */ + public final boolean isGL3() { + return 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)) && + ctxVersion.compareTo(Version3_1) >= 0 ; + } + + /** + * Indicates whether this GLContext uses a GL3 core profile.Includes [ GL4, GL3 ].
+ */ + public final boolean isGL3core() { + return 0 != ( ctxOptions & CTX_PROFILE_CORE ) && + ctxVersion.compareTo(Version3_1) >= 0; + } + + /** + * Indicates whether this GLContext uses a GL core profile.Includes [ GL4, GL3, GLES3, GLES2 ].
+ */ + public final boolean isGLcore() { + return ( 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 2 ) || + ( 0 != ( ctxOptions & CTX_PROFILE_CORE ) && + ctxVersion.compareTo(Version3_1) >= 0 + ) ; + } + + /** + * Indicates whether this GLContext allows CPU data sourcing (indices, vertices ..) as opposed to using a GPU buffer source (VBO), + * e.g. {@link GL2#glDrawElements(int, int, int, java.nio.Buffer)}. + *Includes [GL2ES1, GLES2] == [ GL4bc, GL3bc, GL2, GLES1, GL2ES1, GLES2 ].
+ *See Bug 852 - https://jogamp.org/bugzilla/show_bug.cgi?id=852
+ */ + public final boolean isCPUDataSourcingAvail() { + return isGL2ES1() || isGLES2(); + } + + /** + * Indicates whether this GLContext's native profile does not implement a default vertex array object (VAO), + * starting w/ OpenGL 3.1 core. + *Includes [ GL4, GL3 ].
+ *+ Due to GL 3.1 core spec: E.1. DEPRECATED AND REMOVED FEATURES (p 296), + GL 3.2 core spec: E.2. DEPRECATED AND REMOVED FEATURES (p 331) + there is no more default VAO buffer 0 bound, hence generating and binding one + to avoid INVALID_OPERATION at VertexAttribPointer. + More clear is GL 4.3 core spec: 10.4 (p 307). + *+ *
+ ES 3.x is not included here.
+ Due to it's ES 2.0 backward compatibility it still supports the following features:
+ client side vertex arrays
+ default vertex array object
+
+ Binding a custom VAO with ES 3.0 would cause client side vertex arrays via {@link GL2ES1#glVertexPointer(int, int, int, java.nio.Buffer) glVertexPointer}
+ to produce GL_INVALID_OPERATION
.
+
+ However, they are marked deprecated:
+ GL ES 3.0 spec F.1. Legacy Features (p 322).
+ GL ES 3.1 spec F.1. Legacy Features (p 454).
+ *
+ * + * If no default VAO is implemented in the native OpenGL profile, + * an own default VAO is being used, see {@link #getDefaultVAO()}. + *
+ * @see #getDefaultVAO() + */ + public final boolean hasNoDefaultVAO() { + return // ES 3.x not included, see above. ( 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 3 ) || + ( 0 != ( ctxOptions & CTX_IS_ARB_CREATED ) && + 0 != ( ctxOptions & CTX_PROFILE_CORE ) && + ctxVersion.compareTo(Version3_1) >= 0 + ) ; + } + + /** + * If this GLContext does not implement a default VAO, see {@link #hasNoDefaultVAO()}, + * an own default VAO will be created and bound at context creation. + *
+ * If this GLContext does implement a default VAO, i.e. {@link #hasNoDefaultVAO()}
+ * returns false
, this method returns 0
.
+ *
+ * Otherwise this method returns the VAO object name + * representing this GLContext's own default VAO. + *
+ * @see #hasNoDefaultVAO() + */ + public abstract int getDefaultVAO(); + + /** + * Indicates whether this GLContext is capable of GL2.Includes [ GL4bc, GL3bc, GL2 ].
+ * @see GLProfile#isGL2() + */ + public final boolean isGL2() { + return 0 != ( ctxOptions & CTX_PROFILE_COMPAT ) && ctxVersion.getMajor()>=1 ; + } + + /** + * Indicates whether this GLContext is capable of GL2GL3.Includes [ GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3 ].
+ * @see GLProfile#isGL2GL3() + */ + public final boolean isGL2GL3() { + return isGL2() || isGL3(); + } + + /** + * Indicates whether this GLContext is capable of GLES1.Includes [ GLES1 ].
+ * @see GLProfile#isGLES1() + */ + public final boolean isGLES1() { + return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() == 1 ; + } + + /** + * Indicates whether this GLContext is capable of GLES2.Includes [ GLES2, GLES3 ].
+ * @see GLProfile#isGLES2() + */ + public final boolean isGLES2() { + if( 0 != ( ctxOptions & CTX_PROFILE_ES ) ) { + final int major = ctxVersion.getMajor(); + return 2 == major || 3 == major; + } + return false; + } + + /** + * Indicates whether this GLContext is capable of GLES3.Includes [ GLES3 ].
+ * @see GLProfile#isGLES3() + */ + public final boolean isGLES3() { + return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() == 3 ; + } + + /** + * Indicates whether this GLContext is capable of GLES.Includes [ GLES3, GLES1, GLES2 ].
+ * @see GLProfile#isGLES() + */ + public final boolean isGLES() { + return 0 != ( CTX_PROFILE_ES & ctxOptions ) ; + } + + /** + * Indicates whether this GLContext is capable of GL2ES1.Includes [ GL4bc, GL3bc, GL2, GLES1, GL2ES1 ].
+ * @see GLProfile#isGL2ES1() + */ + public final boolean isGL2ES1() { + return isGLES1() || isGL2(); + } + + /** + * Indicates whether this GLContext is capable of GL2ES2.Includes [ GL4bc, GL4, GL3bc, GL3, GLES3, GL2, GL2GL3, GL2ES2, GLES2 ].
+ * @see GLProfile#isGL2ES2() + */ + public final boolean isGL2ES2() { + return isGLES2() || isGL2GL3(); + } + + /** + * Indicates whether this GLContext is capable of GL2ES3.Includes [ GL4bc, GL4, GL3bc, GL3, GLES3, GL3ES3, GL2, GL2GL3 ].
+ * @see GLProfile#isGL2ES3() + * @see #isGL3ES3() + * @see #isGL2GL3() + */ + public final boolean isGL2ES3() { + return isGL3ES3() || isGL2GL3(); + } + + /** + * Indicates whether this GLContext is capable of GL3ES3.Includes [ GL4bc, GL4, GL3bc, GL3, GLES3 ].
+ * @see GLProfile#isGL3ES3() + */ + public final boolean isGL3ES3() { + return isGL4ES3() || isGL3(); + } + + /** + * Returns true if this profile is capable of GL4ES3, i.e. if {@link #isGLES3Compatible()} returns true. + *Includes [ GL ≥ 4.3, GL ≥ 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ]
+ * @see GLProfile#isGL4ES3() + */ + public final boolean isGL4ES3() { + return isGLES3Compatible() ; + } + + /** + * Set the swap interval of the current context and attached drawable. + * @param interval Should be ≥ 0. 0 disables the vertical synchronization, + * where ≥ 1 is the number of vertical refreshes before a swap buffer occurs. + * A value < 0 is ignored. + * @return true if the operation was successful, otherwise false + * + * @throws GLException if the context is not current. + */ + public final boolean setSwapInterval(final int interval) throws GLException { + validateCurrent(); + if(0<=interval) { + if( !drawableRetargeted || !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget) ) { + if( setSwapIntervalImpl(interval) ) { + currentSwapInterval = interval; + return true; + } + } + } + return false; + } + protected boolean setSwapIntervalImpl(final int interval) { + return false; + } + /** Return the current swap interval. + *
+ * If the context has not been made current at all,
+ * the default value -1
is returned.
+ *
+ * For a valid context the default value is 1
+ * in case of an EGL based profile (ES1 or ES2) and -1
+ * (undefined) for desktop.
+ *
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}. + *
+ */ + public abstract int getBoundFramebuffer(int target); + + /** + * Return the default draw framebuffer name. + *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link com.jogamp.opengl.FBObject}) based drawable
+ * is being used.
+ *
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}. + *
+ */ + public abstract int getDefaultDrawFramebuffer(); + + /** + * Return the default read framebuffer name. + *
+ * May differ from it's default zero
+ * in case an framebuffer object ({@link com.jogamp.opengl.FBObject}) based drawable
+ * is being used.
+ *
+ * Method is only thread-safe while context is {@link #makeCurrent() made current}. + *
+ */ + public abstract int getDefaultReadFramebuffer(); + + /** + * Returns the default color buffer within the current bound + * {@link #getDefaultReadFramebuffer()}, i.e. GL_READ_FRAMEBUFFER​, + * which will be used as the source for pixel reading commands, + * like {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels} etc. + *+ * For offscreen framebuffer objects this is {@link GL#GL_COLOR_ATTACHMENT0}, + * otherwise this is {@link GL#GL_FRONT} for single buffer configurations + * and {@link GL#GL_BACK} for double buffer configurations. + *
+ *+ * Note-1: Neither ES1 nor ES2 supports selecting the read buffer via glReadBuffer + * and {@link GL#GL_BACK} is the default. + *
+ *+ * Note-2: ES3 only supports {@link GL#GL_BACK}, {@link GL#GL_NONE} or {@link GL#GL_COLOR_ATTACHMENT0}+i + *
+ *+ * Note-3: See {@link com.jogamp.opengl.util.GLDrawableUtil#swapBuffersBeforeRead(GLCapabilitiesImmutable) swapBuffersBeforeRead} + * for read-pixels and swap-buffers implications. + *
+ *+ * Method is only thread-safe while context is {@link #makeCurrent() made current}. + *
+ */ + public abstract int getDefaultReadBuffer(); + + /** + * Get the default pixel data type, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}. + *+ * Method is only thread-safe while context is {@link #makeCurrent() made current}. + *
+ */ + public abstract int getDefaultPixelDataType(); + + /** + * Get the default pixel data format, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}. + *+ * Method is only thread-safe while context is {@link #makeCurrent() made current}. + *
+ */ + public abstract int getDefaultPixelDataFormat(); + + /** + * @return The extension implementing the GLDebugOutput feature, + * either {@link GLExtensions#ARB_debug_output} or {@link GLExtensions#AMD_debug_output}. + * If unavailable or called before initialized via {@link #makeCurrent()}, null is returned. + */ + public abstract String getGLDebugMessageExtension(); + + /** + * @return the current synchronous debug behavior, set via {@link #setGLDebugSynchronous(boolean)}. + */ + public abstract boolean isGLDebugSynchronous(); + + /** + * Enables or disables the synchronous debug behavior via + * {@link GL2GL3#GL_DEBUG_OUTPUT_SYNCHRONOUS glEnable/glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS)}, + * if extension is {@link GLExtensions#ARB_debug_output}. + * There is no equivalent for {@link GLExtensions#AMD_debug_output}. + * The default is true
, ie {@link GL2GL3#GL_DEBUG_OUTPUT_SYNCHRONOUS}.
To enable the GLDebugOutput feature {@link #enableGLDebugMessage(boolean) enableGLDebugMessage(true)} + * or {@link #setContextCreationFlags(int) setContextCreationFlags}({@link GLContext#CTX_OPTION_DEBUG}) + * shall be called before context creation via {@link #makeCurrent()}!
+ * + *In case {@link GLAutoDrawable} are being used, + * {@link GLAutoDrawable#setContextCreationFlags(int) glAutoDrawable.setContextCreationFlags}({@link GLContext#CTX_OPTION_DEBUG}) + * shall be issued before context creation via {@link #makeCurrent()}!
+ * + *After context creation, the GLDebugOutput feature may be enabled or disabled at any time using this method.
+ * + * @param enable If true enables, otherwise disables the GLDebugOutput feature. + * + * @throws GLException if this context is not current or GLDebugOutput registration failed (enable) + * + * @see #setContextCreationFlags(int) + * @see #addGLDebugListener(GLDebugListener) + * @see GLAutoDrawable#setContextCreationFlags(int) + */ + public abstract void enableGLDebugMessage(boolean enable) throws GLException; + + /** + * Add {@link GLDebugListener}.+ * The minor version number is ignored by the upper limit validation + * and the major version number may exceed by one. + *
+ *+ * The upper limit check is relaxed since we don't want to cut-off + * unforseen new GL version since the release of JOGL. + *
+ *+ * Hence it is important to iterate through GL version from the upper limit + * and {@link #decrementGLVersion(int, int[], int[])} until invalid. + *
+ */ + public static final boolean isValidGLVersion(final int ctxProfile, final int major, final int minor) { + if( 1>major || 0>minor ) { + return false; + } + if( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) { + if( major >= ES_VERSIONS.length + 1 ) return false; + } else { + if( major>=GL_VERSIONS.length + 1 ) return false; + } + return true; + } + + /** + * Clip the given GL version to the maximum known valid version if exceeding. + * @return true if clipped, i.e. given value exceeds maximum, otherwise false. + */ + public static final boolean clipGLVersion(final int ctxProfile, final int major[], final int minor[]) { + final int m = major[0]; + final int n = minor[0]; + + if( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) { + if( m >= ES_VERSIONS.length ) { + major[0] = ES_VERSIONS.length - 1; + minor[0] = ES_VERSIONS[major[0]].length - 1; + return true; + } + if( n >= ES_VERSIONS[m].length ) { + minor[0] = ES_VERSIONS[m].length - 1; + return true; + } + } else if( m >= GL_VERSIONS.length ) { // !isES + major[0] = GL_VERSIONS.length - 1; + minor[0] = GL_VERSIONS[major[0]].length - 1; + return true; + } else if( n >= GL_VERSIONS[m].length ) { // !isES + minor[0] = GL_VERSIONS[m].length - 1; + return true; + } + return false; + } + + /** + * Decrement the given GL version by one + * and return true if still valid, otherwise false. + *+ * If the given version exceeds the maximum known valid version, + * it is {@link #clipGLVersion(int, int[], int[]) clipped} and + * true is returned. + *
+ * + * @param ctxProfile + * @param major + * @param minor + * @return + */ + public static final boolean decrementGLVersion(final int ctxProfile, final int major[], final int minor[]) { + if( !clipGLVersion(ctxProfile, major, minor) ) { + int m = major[0]; + int n = minor[0] - 1; + if(n < 0) { + if( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) { + if( m >= 3 ) { + m -= 1; + } else { + m = 0; // major decr [1,2] -> 0 + } + n = ES_VERSIONS[m].length-1; + } else { + m -= 1; + n = GL_VERSIONS[m].length-1; + } + } + if( !isValidGLVersion(ctxProfile, m, n) ) { + return false; + } + major[0]=m; + minor[0]=n; + } + return true; + } + + protected static int composeBits(final int a8, final int b8, final int c16) { + return ( ( a8 & 0x000000FF ) << 24 ) | + ( ( b8 & 0x000000FF ) << 16 ) | + ( ( c16 & 0x0000FFFF ) ) ; + } + + private static void validateProfileBits(final int bits, final String argName) { + int num = 0; + if( 0 != ( CTX_PROFILE_COMPAT & bits ) ) { num++; } + if( 0 != ( CTX_PROFILE_CORE & bits ) ) { num++; } + if( 0 != ( CTX_PROFILE_ES & bits ) ) { num++; } + if(1!=num) { + throw new GLException("Internal Error: "+argName+": 1 != num-profiles: "+num); + } + } + + // + // version mapping + // + + /** + * @see #getDeviceVersionAvailableKey(com.jogamp.nativewindow.AbstractGraphicsDevice, int, int) + */ + protected static final IdentityHashMapnull
+ */
+ protected static Integer getAvailableGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile) {
+ final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, reqProfile);
+ Integer val;
+ synchronized(deviceVersionAvailable) {
+ val = deviceVersionAvailable.get( objectKey );
+ }
+ return val;
+ }
+
+ /**
+ * @param reqMajor Key Value either 1, 2, 3 or 4
+ * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @param major if not null, returns the used major version
+ * @param minor if not null, returns the used minor version
+ * @param ctp if not null, returns the used context profile
+ */
+ protected static boolean getAvailableGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile,
+ final int[] major, final int minor[], final int ctp[]) {
+
+ final Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile);
+ if(null==valI) {
+ return false;
+ }
+
+ final int bits32 = valI.intValue();
+
+ if(null!=major) {
+ major[0] = ( bits32 & 0xFF000000 ) >>> 24 ;
+ }
+ if(null!=minor) {
+ minor[0] = ( bits32 & 0x00FF0000 ) >>> 16 ;
+ }
+ if(null!=ctp) {
+ ctp[0] = ( bits32 & 0x0000FFFF ) ;
+ }
+ return true;
+ }
+
+ /**
+ * returns the highest GLProfile string regarding the implementation version and context profile bits.
+ * @throws GLException if version and context profile bits could not be mapped to a GLProfile
+ */
+ protected static String getGLProfile(final int major, final int minor, final int ctp)
+ throws GLException {
+ if(0 != ( CTX_PROFILE_COMPAT & ctp )) {
+ if(major >= 4) { return GLProfile.GL4bc; }
+ else if(major == 3 && minor >= 1) { return GLProfile.GL3bc; }
+ else { return GLProfile.GL2; }
+ } else if(0 != ( CTX_PROFILE_CORE & ctp )) {
+ if(major >= 4) { return GLProfile.GL4; }
+ else if(major == 3 && minor >= 1) { return GLProfile.GL3; }
+ } else if(0 != ( CTX_PROFILE_ES & ctp )) {
+ if(major == 3) { return GLProfile.GLES3; }
+ else if(major == 2) { return GLProfile.GLES2; }
+ else if(major == 1) { return GLProfile.GLES1; }
+ }
+ throw new GLException("Unhandled OpenGL version/profile: "+GLContext.getGLVersion(major, minor, ctp, null));
+ }
+
+ /**
+ * Returns the GLProfile's major version number at reqMajorCTP[0] and it's context property (CTP) at reqMajorCTP[1] for availability mapping request.
+ */
+ protected static final void getRequestMajorAndCompat(final GLProfile glp, final int[/*2*/] reqMajorCTP) {
+ final GLProfile glpImpl = glp.getImpl();
+ if( glpImpl.isGL4() ) {
+ reqMajorCTP[0]=4;
+ } else if ( glpImpl.isGL3() || glpImpl.isGLES3() ) {
+ reqMajorCTP[0]=3;
+ } else if (glpImpl.isGLES1()) {
+ reqMajorCTP[0]=1;
+ } else /* if (glpImpl.isGL2() || glpImpl.isGLES2()) */ {
+ reqMajorCTP[0]=2;
+ }
+ if( glpImpl.isGLES() ) {
+ reqMajorCTP[1]=CTX_PROFILE_ES;
+ } else if( glpImpl.isGL2() ) { // incl GL3bc and GL4bc
+ reqMajorCTP[1]=CTX_PROFILE_COMPAT;
+ } else {
+ reqMajorCTP[1]=CTX_PROFILE_CORE;
+ }
+ }
+
+ /**
+ * @param device the device the context profile is being requested for
+ * @param GLProfile the GLProfile the context profile is being requested for
+ * @return the GLProfile's context property (CTP) if available, otherwise 0
+ */
+ protected static final int getAvailableContextProperties(final AbstractGraphicsDevice device, final GLProfile glp) {
+ final int[] reqMajorCTP = new int[] { 0, 0 };
+ getRequestMajorAndCompat(glp, reqMajorCTP);
+
+ final int _major[] = { 0 };
+ final int _minor[] = { 0 };
+ final int _ctp[] = { 0 };
+ if( GLContext.getAvailableGLVersion(device, reqMajorCTP[0], reqMajorCTP[1], _major, _minor, _ctp)) {
+ return _ctp[0];
+ }
+ return 0; // n/a
+ }
+
+ /**
+ * @param device the device the profile is being requested
+ * @param major Key Value either 1, 2, 3 or 4
+ * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @return the highest GLProfile for the device regarding availability, version and profile bits.
+ */
+ protected static GLProfile getAvailableGLProfile(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile)
+ throws GLException {
+ final String glpName = getAvailableGLProfileName(device, reqMajor, reqProfile);
+ return null != glpName ? GLProfile.get(device, glpName) : null;
+ }
+
+ /**
+ * @param device the device the profile is being requested
+ * @param major Key Value either 1, 2, 3 or 4
+ * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @return the highest GLProfile name for the device regarding availability, version and profile bits.
+ */
+ /* package */ static String getAvailableGLProfileName(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile)
+ throws GLException {
+ final int major[] = { 0 };
+ final int minor[] = { 0 };
+ final int ctp[] = { 0 };
+ if(GLContext.getAvailableGLVersion(device, reqMajor, reqProfile, major, minor, ctp)) {
+ return GLContext.getGLProfile(major[0], minor[0], ctp[0]);
+ }
+ return null;
+ }
+
+ /**
+ * @param device the device the profile is being requested
+ * @param major Key Value either 1, 2, 3 or 4
+ * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ */
+ protected static String getAvailableGLVersionAsString(final AbstractGraphicsDevice device, final int major, final int profile) {
+ final int _major[] = { 0 };
+ final int _minor[] = { 0 };
+ final int _ctp[] = { 0 };
+ if(getAvailableGLVersion(device, major, profile, _major, _minor, _ctp)) {
+ return getGLVersion(_major[0], _minor[0], _ctp[0], null);
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if it is possible to create an framebuffer object (FBO).
+ * + * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent. + *
+ *+ * FBO support is queried as described in {@link #hasBasicFBOSupport()}. + *
+ * + * @param device the device to request whether FBO is available for + * @param glp {@link GLProfile} to check for FBO capabilities + * @see GLContext#hasBasicFBOSupport() + */ + public static final boolean isFBOAvailable(final AbstractGraphicsDevice device, final GLProfile glp) { + return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) ); + } + + /** + * @return1
if using a hardware rasterizer, 0
if using a software rasterizer and -1
if not determined yet.
+ * @see GLContext#isHardwareRasterizer()
+ * @see GLProfile#isHardwareRasterizer()
+ */
+ public static final int isHardwareRasterizer(final AbstractGraphicsDevice device, final GLProfile glp) {
+ final int r;
+ final int ctp = getAvailableContextProperties(device, glp);
+ if(0 == ctp) {
+ r = -1;
+ } else if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctp ) ) {
+ r = 1;
+ } else {
+ r = 0;
+ }
+ return r;
+ }
+
+ /**
+ * @param device the device to request whether the profile is available for
+ * @param reqMajor Key Value either 1, 2, 3 or 4
+ * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @param isHardware return value of one boolean, whether the profile is a hardware rasterizer or not
+ * @return true if the requested GL version is available regardless of a software or hardware rasterizer, otherwise false.
+ */
+ protected static boolean isGLVersionAvailable(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile, final boolean isHardware[]) {
+ final Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile);
+ if(null==valI) {
+ return false;
+ }
+ isHardware[0] = 0 == ( valI.intValue() & GLContext.CTX_IMPL_ACCEL_SOFT ) ;
+ return true;
+ }
+
+ public static boolean isGLES1Available(final AbstractGraphicsDevice device, final boolean isHardware[]) {
+ return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES, isHardware);
+ }
+
+ public static boolean isGLES2Available(final AbstractGraphicsDevice device, final boolean isHardware[]) {
+ return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES, isHardware);
+ }
+
+ public static boolean isGLES3Available(final AbstractGraphicsDevice device, final boolean isHardware[]) {
+ return isGLVersionAvailable(device, 3, GLContext.CTX_PROFILE_ES, isHardware);
+ }
+
+ /**
+ * Returns true if a ES3 compatible profile is available,
+ * i.e. either a ≥ 4.3 context or a ≥ 3.1 context supporting GL_ARB_ES3_compatibility
,
+ * otherwise false.
+ * + * Includes [ GL ≥ 4.3, GL ≥ 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ] + *
+ */ + public static final boolean isGLES3CompatibleAvailable(final AbstractGraphicsDevice device) { + final int major[] = { 0 }; + final int minor[] = { 0 }; + final int ctp[] = { 0 }; + boolean ok; + + ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_ES, major, minor, ctp); + if( !ok ) { + ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, major, minor, ctp); + } + if( !ok ) { + GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_COMPAT, major, minor, ctp); + } + return 0 != ( ctp[0] & CTX_IMPL_ES3_COMPAT ); + } + + public static boolean isGL4bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[]) { + return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT, isHardware); + } + + public static boolean isGL4Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { + return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE, isHardware); + } + + public static boolean isGL3bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[]) { + return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT, isHardware); + } + + public static boolean isGL3Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { + return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE, isHardware); + } + + public static boolean isGL2Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { + return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT, isHardware); + } + + protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) { + boolean needColon = false; + final StringBuilder sb = new StringBuilder(); + sb.append(major); + sb.append("."); + sb.append(minor); + sb.append(" ("); + needColon = appendString(sb, "ES profile", needColon, 0 != ( CTX_PROFILE_ES & ctp )); + needColon = appendString(sb, "Compat profile", needColon, 0 != ( CTX_PROFILE_COMPAT & ctp )); + needColon = appendString(sb, "Core profile", needColon, 0 != ( CTX_PROFILE_CORE & ctp )); + needColon = appendString(sb, "forward", needColon, 0 != ( CTX_OPTION_FORWARD & ctp )); + needColon = appendString(sb, "arb", needColon, 0 != ( CTX_IS_ARB_CREATED & ctp )); + needColon = appendString(sb, "debug", needColon, 0 != ( CTX_OPTION_DEBUG & ctp )); + needColon = appendString(sb, "ES2 compat", needColon, 0 != ( CTX_IMPL_ES2_COMPAT & ctp )); + needColon = appendString(sb, "ES3 compat", needColon, 0 != ( CTX_IMPL_ES3_COMPAT & ctp )); + needColon = appendString(sb, "FBO", needColon, 0 != ( CTX_IMPL_FBO & ctp )); + needColon = appendString(sb, "FP32 compat", needColon, 0 != ( CTX_IMPL_FP32_COMPAT_API & ctp )); + if( 0 != ( CTX_IMPL_ACCEL_SOFT & ctp ) ) { + needColon = appendString(sb, "software", needColon, true); + } else { + needColon = appendString(sb, "hardware", needColon, true); + } + sb.append(")"); + if(null!=gl_version) { + sb.append(" - "); + sb.append(gl_version); + } + return sb.toString(); + } + + // + // internal string utils + // + + protected static String toHexString(final int hex) { + return "0x" + Integer.toHexString(hex); + } + + protected static String toHexString(final long hex) { + return "0x" + Long.toHexString(hex); + } + + private static boolean appendString(final StringBuilder sb, final String string, boolean needColon, final boolean condition) { + if(condition) { + if(needColon) { + sb.append(", "); + } + sb.append(string); + needColon=true; + } + return needColon; + } + + protected static String getThreadName() { return Thread.currentThread().getName(); } + +} + diff --git a/src/jogl/classes/com/jogamp/opengl/GLDebugListener.java b/src/jogl/classes/com/jogamp/opengl/GLDebugListener.java new file mode 100644 index 000000000..30e1a49c2 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/GLDebugListener.java @@ -0,0 +1,44 @@ +/** + * Copyright 2011 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; + +/** + * Listener for {@link GLDebugMessage}s. + * + *One can enable GLDebugOutput via {@link GLContext#enableGLDebugMessage(boolean)} + * and add listeners via {@link GLContext#addGLDebugListener(GLDebugListener)}. + */ +public interface GLDebugListener { + /** + * Handle {@link GLDebugMessage} message sent from native GL implementation. + * + *
Since this method is invoked directly by the GL implementation, it shall + * return as fast as possible.
+ */ + void messageSent(GLDebugMessage event); +} diff --git a/src/jogl/classes/com/jogamp/opengl/GLDebugMessage.java b/src/jogl/classes/com/jogamp/opengl/GLDebugMessage.java new file mode 100644 index 000000000..a8868026b --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/GLDebugMessage.java @@ -0,0 +1,253 @@ +/** + * Copyright 2011 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; + +import com.jogamp.common.os.Platform; + +/** + * OpenGL debug message generated by the driver + * and delivered via {@link GLDebugListener}. + */ +public class GLDebugMessage { + final GLContext source; + final long when; + final int dbgSource; + final int dbgType; + final int dbgId; + final int dbgSeverity; + final String dbgMsg; + + /** + * @param source The source of the event + * @param when The time of the event + * @param dbgSource The ARB source + * @param dbgType The ARB type + * @param dbgId The ARB id + * @param dbgSeverity The ARB severity level + * @param dbgMsg The debug message + */ + public GLDebugMessage(final GLContext source, final long when, final int dbgSource, final int dbgType, final int dbgId, final int dbgSeverity, final String dbgMsg) { + this.source = source; + this.when = when; + this.dbgSource = dbgSource; + this.dbgType = dbgType; + this.dbgId = dbgId; + this.dbgSeverity = dbgSeverity; + this.dbgMsg = dbgMsg; + } + + /** + * + * @param source + * @param when + * @param dbgId + * @param amdDbgCategory + * @param dbgSeverity AMD severity level equals ARB severity level (value and semantic) + * @param dbgMsg + * @return + */ + public static GLDebugMessage translateAMDEvent(final GLContext source, final long when, final int dbgId, final int amdDbgCategory, final int dbgSeverity, final String dbgMsg) { + int dbgSource, dbgType; + + // AMD category == ARB source/type + switch(amdDbgCategory) { + case GL2GL3.GL_DEBUG_CATEGORY_API_ERROR_AMD: + dbgSource = GL2ES2.GL_DEBUG_SOURCE_API; + dbgType = GL2ES2.GL_DEBUG_TYPE_ERROR; + break; + + // + // def source / other type + // + + case GL2GL3.GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD: + dbgSource = GL2ES2.GL_DEBUG_SOURCE_WINDOW_SYSTEM; + dbgType = GL2ES2.GL_DEBUG_TYPE_OTHER; + break; + + case GL2GL3.GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD: + dbgSource = GL2ES2.GL_DEBUG_SOURCE_SHADER_COMPILER; + dbgType = GL2ES2.GL_DEBUG_TYPE_OTHER; + break; + + case GL2GL3.GL_DEBUG_CATEGORY_APPLICATION_AMD: + dbgSource = GL2ES2.GL_DEBUG_SOURCE_APPLICATION; + dbgType = GL2ES2.GL_DEBUG_TYPE_OTHER; + break; + + + // + // other source / def type + // + + case GL2GL3.GL_DEBUG_CATEGORY_DEPRECATION_AMD: + dbgSource = GL2ES2.GL_DEBUG_SOURCE_OTHER; + dbgType = GL2ES2.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR; + break; + + case GL2GL3.GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD: + dbgSource = GL2ES2.GL_DEBUG_SOURCE_OTHER; + dbgType = GL2ES2.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR; + break; + + case GL2GL3.GL_DEBUG_CATEGORY_PERFORMANCE_AMD: + dbgSource = GL2ES2.GL_DEBUG_SOURCE_OTHER; + dbgType = GL2ES2.GL_DEBUG_TYPE_PERFORMANCE; + break; + + case GL2GL3.GL_DEBUG_CATEGORY_OTHER_AMD: + default: + dbgSource = GL2ES2.GL_DEBUG_SOURCE_OTHER; + dbgType = GL2ES2.GL_DEBUG_TYPE_OTHER; + } + + return new GLDebugMessage(source, when, dbgSource, dbgType, dbgId, dbgSeverity, dbgMsg); + } + + public static int translateARB2AMDCategory(final int dbgSource, final int dbgType) { + switch (dbgSource) { + case GL2ES2.GL_DEBUG_SOURCE_WINDOW_SYSTEM: + return GL2GL3.GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD; + + case GL2ES2.GL_DEBUG_SOURCE_SHADER_COMPILER: + return GL2GL3.GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD; + + case GL2ES2.GL_DEBUG_SOURCE_APPLICATION: + return GL2GL3.GL_DEBUG_CATEGORY_APPLICATION_AMD; + } + + switch(dbgType) { + case GL2ES2.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + return GL2GL3.GL_DEBUG_CATEGORY_DEPRECATION_AMD; + + case GL2ES2.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + return GL2GL3.GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD; + + case GL2ES2.GL_DEBUG_TYPE_PERFORMANCE: + return GL2GL3.GL_DEBUG_CATEGORY_PERFORMANCE_AMD; + } + + return GL2GL3.GL_DEBUG_CATEGORY_OTHER_AMD; + } + + public GLContext getSource() { + return source; + } + + public long getWhen() { + return when; + } + + public int getDbgSource() { + return dbgSource; + } + + public int getDbgType() { + return dbgType; + } + + public int getDbgId() { + return dbgId; + } + + public int getDbgSeverity() { + return dbgSeverity; + } + + public String getDbgMsg() { + return dbgMsg; + } + + public StringBuilder toString(StringBuilder sb) { + final String crtab = Platform.getNewline()+"\t"; + if(null==sb) { + sb = new StringBuilder(); + } + sb.append("GLDebugEvent[ id "); + toHexString(sb, dbgId) + .append(crtab).append("type ").append(getDbgTypeString(dbgType)) + .append(crtab).append("severity ").append(getDbgSeverityString(dbgSeverity)) + .append(crtab).append("source ").append(getDbgSourceString(dbgSource)) + .append(crtab).append("msg ").append(dbgMsg) + .append(crtab).append("when ").append(when); + if(null != source) { + sb.append(crtab).append("source ").append(source.getGLVersion()).append(" - hash 0x").append(Integer.toHexString(source.hashCode())); + } + sb.append("]"); + return sb; + } + + @Override + public String toString() { + return toString(null).toString(); + } + + public static String getDbgSourceString(final int dbgSource) { + switch(dbgSource) { + case GL2ES2.GL_DEBUG_SOURCE_API: return "GL API"; + case GL2ES2.GL_DEBUG_SOURCE_SHADER_COMPILER: return "GLSL or extension compiler"; + case GL2ES2.GL_DEBUG_SOURCE_WINDOW_SYSTEM: return "Native Windowing binding"; + case GL2ES2.GL_DEBUG_SOURCE_THIRD_PARTY: return "Third party"; + case GL2ES2.GL_DEBUG_SOURCE_APPLICATION: return "Application"; + case GL2ES2.GL_DEBUG_SOURCE_OTHER: return "generic"; + default: return "Unknown (" + toHexString(dbgSource) + ")"; + } + } + + public static String getDbgTypeString(final int dbgType) { + switch(dbgType) { + case GL2ES2.GL_DEBUG_TYPE_ERROR: return "Error"; + case GL2ES2.GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: return "Warning: marked for deprecation"; + case GL2ES2.GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: return "Warning: undefined behavior"; + case GL2ES2.GL_DEBUG_TYPE_PERFORMANCE: return "Warning: implementation dependent performance"; + case GL2ES2.GL_DEBUG_TYPE_PORTABILITY: return "Warning: vendor-specific extension use"; + case GL2ES2.GL_DEBUG_TYPE_OTHER: return "Warning: generic"; + default: return "Unknown (" + toHexString(dbgType) + ")"; + } + } + + public static String getDbgSeverityString(final int dbgSeverity) { + switch(dbgSeverity) { + case GL2ES2.GL_DEBUG_SEVERITY_HIGH: return "High: dangerous undefined behavior"; + case GL2ES2.GL_DEBUG_SEVERITY_MEDIUM: return "Medium: Severe performance/deprecation/other warnings"; + case GL2ES2.GL_DEBUG_SEVERITY_LOW: return "Low: Performance warnings (redundancy/undefined)"; + default: return "Unknown (" + toHexString(dbgSeverity) + ")"; + } + } + + public static StringBuilder toHexString(StringBuilder sb, final int i) { + if(null==sb) { + sb = new StringBuilder(); + } + return sb.append("0x").append(Integer.toHexString(i)); + } + public static String toHexString(final int i) { + return "0x"+Integer.toHexString(i); + } + +} diff --git a/src/jogl/classes/com/jogamp/opengl/GLDrawable.java b/src/jogl/classes/com/jogamp/opengl/GLDrawable.java new file mode 100644 index 000000000..c801ba463 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/GLDrawable.java @@ -0,0 +1,251 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 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: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl; + +import com.jogamp.nativewindow.AbstractGraphicsConfiguration; +import com.jogamp.nativewindow.NativeSurface; +import com.jogamp.nativewindow.NativeSurfaceHolder; + + +/** An abstraction for an OpenGL rendering target. A GLDrawable's + primary functionality is to create OpenGL contexts which can be + used to perform rendering. A GLDrawable does not automatically + create an OpenGL context, but all implementations of {@link + GLAutoDrawable} do so upon creation. */ + +public interface GLDrawable extends NativeSurfaceHolder { + /** + * Creates a new context for drawing to this drawable that will + * optionally share buffer objects, textures and other server-side OpenGL + * objects with the specified GLContext. + *
+ * The GLContext share
need not be associated with this
+ * GLDrawable and may be null if sharing of display lists and other
+ * objects is not desired. See the note in the overview
+ * documentation
+ * context sharing
+ * as well as {@link GLSharedContextSetter}.
+ *
+ * If realized, the {@link #getHandle() drawable handle} may become + * valid while it's {@link NativeSurface surface} is being {@link NativeSurface#lockSurface() locked}. + *
+ *
+ * End users do not need to call this method; it is not necessary to
+ * call setRealized
on a {@link GLAutoDrawable}
+ * as these perform the appropriate calls on their underlying GLDrawables internally.
+ *
+ * Developers implementing new OpenGL components for various window
+ * toolkits need to call this method against GLDrawables obtained
+ * from the GLDrawableFactory via the
+ * {@link GLDrawableFactory#createGLDrawable(NativeSurface)} method.
+ * It must typically be
+ * called with an argument of true
when the component
+ * associated with the GLDrawable is realized and with an argument
+ * of false
just before the component is unrealized.
+ * For the AWT, this means calling setRealized(true)
in
+ * the addNotify
method and with an argument of
+ * false
in the removeNotify
method.
+ *
+ * GLDrawable
implementations should handle multiple
+ * cycles of setRealized(true)
/
+ * setRealized(false)
calls. Most, if not all, Java
+ * window toolkits have a persistent object associated with a given
+ * component, regardless of whether that component is currently
+ * realized. The GLDrawable
object associated with a
+ * particular component is intended to be similarly persistent. A
+ * GLDrawable
is intended to be created for a given
+ * component when it is constructed and live as long as that
+ * component. setRealized
allows the
+ * GLDrawable
to re-initialize and destroy any
+ * associated resources as the component becomes realized and
+ * unrealized, respectively.
+ *
+ * With an argument of true
,
+ * the minimum implementation shall call
+ * {@link NativeSurface#lockSurface() NativeSurface's lockSurface()} and if successful:
+ *
+ * Calling this method has no other effects. For example, if
+ * removeNotify
is called on a Canvas implementation
+ * for which a GLDrawable has been created, it is also necessary to
+ * destroy all OpenGL contexts associated with that GLDrawable. This
+ * is not done automatically by the implementation.
+ *
true
if this drawable is realized, otherwise true
.
+ * + * A drawable can be realized and unrealized via {@link #setRealized(boolean)}. + *
+ * @see #setRealized(boolean) + */ + public boolean isRealized(); + + /** + * Returns the width of this {@link GLDrawable}'s {@link #getNativeSurface() surface} client area in pixel units. + * @see NativeSurface#getSurfaceWidth() + */ + public int getSurfaceWidth(); + + /** + * Returns the height of this {@link GLDrawable}'s {@link #getNativeSurface() surface} client area in pixel units. + * @see NativeSurface#getSurfaceHeight() + */ + public int getSurfaceHeight(); + + /** + * Returnstrue
if the drawable is rendered in
+ * OpenGL's coordinate system, origin at bottom left.
+ * Otherwise returns false
, i.e. origin at top left.
+ *
+ * Default impl. is true
, i.e. OpenGL coordinate system.
+ *
+ * Currently only MS-Windows bitmap offscreen drawable uses a non OpenGL orientation and hence returns false
.
+ * This removes the need of a vertical flip when used in AWT or Windows applications.
+ *
+ This query only returns the chosen capabilities if {@link #isRealized()}. +
++ On some platforms, the pixel format is not directly associated + with the drawable; a best attempt is made to return a reasonable + value in this case. +
++ This object shall be directly associated to the attached {@link NativeSurface}'s + {@link AbstractGraphicsConfiguration}, and if changes are necessary, + they should reflect those as well. +
+ @return The immutable queried instance. + @see #getRequestedGLCapabilities() + */ + public GLCapabilitiesImmutable getChosenGLCapabilities(); + + /** Fetches the {@link GLCapabilitiesImmutable} corresponding to the user requested + OpenGL capabilities (pixel format / visual / GLProfile) for this drawable. ++ If {@link #isRealized() realized}, {@link #getChosenGLCapabilities() the chosen capabilities} + reflect the actual selected OpenGL capabilities. +
+ @return The immutable queried instance. + @see #getChosenGLCapabilities() + @since 2.2 + */ + public GLCapabilitiesImmutable getRequestedGLCapabilities(); + + /** Fetches the {@link GLProfile} for this drawable. + Returns the GLProfile object, no copy. + */ + public GLProfile getGLProfile(); + + /** + * {@inheritDoc} + *+ * Returns the underlying {@link NativeSurface} which {@link NativeSurface#getSurfaceHandle() native handle} + * represents this OpenGL drawable's native resource. + *
+ * + * @see #getHandle() + */ + @Override + public NativeSurface getNativeSurface(); + + /** + * Returns the GL drawable handle, + * guaranteed to be valid after {@link #setRealized(boolean) realization} + * and while it's {@link NativeSurface surface} is being {@link NativeSurface#lockSurface() locked}. + *+ * It is usually identical to the underlying windowing toolkit {@link NativeSurface surface}'s + * {@link com.jogamp.nativewindow.NativeSurface#getSurfaceHandle() handle} + * or an intermediate layer to suite GL, e.g. an EGL surface. + *
+ *
+ * On EGL it is represented by the EGLSurface.
+ * On X11/GLX it is represented by either the Window XID, GLXPixmap, or GLXPbuffer.
+ * On Windows it is represented by the HDC, which may change with each {@link NativeSurface#lockSurface()}.
+ *
Provides a virtual machine- and operating system-independent + mechanism for creating {@link GLDrawable}s. +
+The {@link com.jogamp.opengl.GLCapabilities} objects passed + in to the various factory methods are used as a hint for the + properties of the returned drawable. The default capabilities + selection algorithm (equivalent to passing in a null {@link + GLCapabilitiesChooser}) is described in {@link + DefaultGLCapabilitiesChooser}. Sophisticated applications needing + to change the selection algorithm may pass in their own {@link + GLCapabilitiesChooser} which can select from the available pixel + formats. The GLCapabilitiesChooser mechanism may not be supported + by all implementations or on all platforms, in which case any + passed GLCapabilitiesChooser will be ignored. +
+ + Because of the multithreaded nature of the Java platform's
+ Abstract Window Toolkit, it is typically not possible to immediately
+ reject a given {@link GLCapabilities} as being unsupportable by
+ either returning null
from the creation routines or
+ raising a {@link GLException}. The semantics of the rejection
+ process are (unfortunately) left unspecified for now. The current
+ implementation will cause a {@link GLException} to be raised
+ during the first repaint of the {@link com.jogamp.opengl.awt.GLCanvas} or {@link
+ com.jogamp.opengl.awt.GLJPanel} if the capabilities can not be met.
+ {@link GLOffscreenAutoDrawable} are created lazily,
+ see {@link #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int) createOffscreenAutoDrawable(..)}.
+
The concrete GLDrawableFactory subclass instantiated by {@link
+ #getFactory getFactory} can be changed by setting the system
+ property opengl.factory.class.name
to the
+ fully-qualified name of the desired class.
+
+ * This functionality is not available on all platforms and + * graphics hardware. Returns true if the settings were successfully + * changed, false if not. This method may return false for some + * values of the incoming arguments even on hardware which does + * support the underlying functionality.
+ *+ * If this method returns true, the display settings will + * automatically be reset to their original values upon JVM exit + * (assuming the JVM does not crash); if the user wishes to change + * the display settings back to normal ahead of time, + * use {@link #resetDisplayGamma(NativeSurface)} or {@link #resetAllDisplayGamma()}. + *
+ *
+ * It is recommended to call {@link #resetDisplayGamma(NativeSurface)} or {@link #resetAllDisplayGamma()}
+ * before calling e.g. System.exit()
from the application rather than
+ * rely on the shutdown hook functionality due to inevitable race
+ * conditions and unspecified behavior during JVM teardown.
+ *
+ * This method may be called multiple times during the application's + * execution, but calling {@link #resetDisplayGamma(NativeSurface)} + * will only reset the settings to the values + * before the first call to this method.
+ * + * @param surface denominates the display device + * @param gamma The gamma value, typically > 1.0 (default values vary, but typically roughly 1.0) + * @param brightness The brightness value between -1.0 and 1.0, inclusive (default values vary, but typically 0) + * @param contrast The contrast, greater than 0.0 (default values vary, but typically 1) + * + * @return true if gamma settings were successfully changed, false if not + * @throws IllegalArgumentException if any of the parameters were out-of-bounds + * @see #resetDisplayGamma(NativeSurface) + * @see #resetAllDisplayGamma() + */ + public abstract boolean setDisplayGamma(final NativeSurface surface, final float gamma, final float brightness, final float contrast) throws IllegalArgumentException; + + /** + * Resets the gamma, brightness and contrast values of the display associated with the givensurface
+ * to its original values before {@link #setDisplayGamma(NativeSurface, float, float, float) setDisplayGamma}
+ * was called the first time.
+ * + * While it is not explicitly required that this method be called before + * exiting manually, calling it is recommended because of the inevitable + * unspecified behavior during JVM teardown. + *
+ */ + public abstract void resetDisplayGamma(final NativeSurface surface); + + /** + * Resets the gamma, brightness and contrast values of all modified + * displays to their original values before {@link #setDisplayGamma(NativeSurface, float, float, float) setDisplayGamma} + * was called the first time. + *+ * While it is not explicitly required that this method be called before + * exiting manually, calling it is recommended because of the inevitable + * unspecified behavior during JVM teardown. + *
+ */ + public abstract void resetAllDisplayGamma(); + + protected abstract void resetAllDisplayGammaNoSync(); + + /** + * Retrieve the defaultdevice
{@link AbstractGraphicsDevice#getConnection() connection},
+ * {@link AbstractGraphicsDevice#getUnitID() unit ID} and {@link AbstractGraphicsDevice#getUniqueID() unique ID name}. for this factorynull
default device, which must not be opened, ie. it's native handle is null
.
+ * + * This method shall return the default device if available + * even if the GLDrawableFactory is not functional and hence not compatible. + * The latter situation may happen because no native OpenGL implementation is available for the specific implementation. + *
+ * @return the default shared device for this factory, eg. :0.0 on X11 desktop. + * @see #getIsDeviceCompatible(AbstractGraphicsDevice) + */ + public abstract AbstractGraphicsDevice getDefaultDevice(); + + /** + * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may benull
for the platform's default device.
+ * @return true if the device is compatible with this factory, ie. if it can be used for GLDrawable creation. Otherwise false.
+ * This implies validation whether the implementation is functional.
+ *
+ * @see #getDefaultDevice()
+ */
+ public abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device);
+
+ protected final AbstractGraphicsDevice validateDevice(AbstractGraphicsDevice device) {
+ if(null==device) {
+ device = getDefaultDevice();
+ if(null==device) {
+ throw new InternalError("no default device available");
+ }
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: "+getClass().getSimpleName()+".validateDevice: using default device : "+device);
+ }
+ }
+
+ // Always validate the device,
+ // since even the default device may not be used by this factory.
+ if( !getIsDeviceCompatible(device) ) {
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: "+getClass().getSimpleName()+".validateDevice: device not compatible : "+device);
+ }
+ return null;
+ }
+ return device;
+ }
+
+ /**
+ * Validate and start the shared resource runner thread if necessary and
+ * if the implementation uses it.
+ *
+ * @return the shared resource runner thread, if implementation uses it.
+ */
+ protected abstract Thread getSharedResourceThread();
+
+ /**
+ * Create the shared resource used internally as a reference for capabilities etc.
+ *
+ * Returns true if a shared resource could be created
+ * for the device
{@link AbstractGraphicsDevice#getConnection()}.
+ * This does not imply a shared resource is mapped (ie. made persistent), but is available in general
.
+ *
null
for the platform's default device.
+ * @return true if a shared resource could been created, otherwise false.
+ */
+ protected final boolean createSharedResource(final AbstractGraphicsDevice device) {
+ return createSharedResourceImpl(device);
+ }
+ protected abstract boolean createSharedResourceImpl(AbstractGraphicsDevice device);
+
+ /**
+ * Returns true if the quirk
exist in the shared resource's context {@link GLRendererQuirks}.
+ * + * Convenience method for: + *
+ final GLRendererQuirks glrq = factory.getRendererQuirks(device); + return null != glrq ? glrq.exist(quirk) : false; + *+ * + * + * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be
null
for the platform's default device.
+ * @param glp {@link GLProfile} to identify the device's {@link GLRendererQuirks}, maybe {@code null}
+ * @param quirk the quirk to be tested, e.g. {@link GLRendererQuirks#NoDoubleBufferedPBuffer}.
+ * @throws IllegalArgumentException if the quirk is out of range
+ * @see #getRendererQuirks(AbstractGraphicsDevice, GLProfile)
+ * @see GLRendererQuirks
+ */
+ public final boolean hasRendererQuirk(final AbstractGraphicsDevice device, final GLProfile glp, final int quirk) {
+ final GLRendererQuirks glrq = getRendererQuirks(device, glp);
+ return null != glrq ? glrq.exist(quirk) : false;
+ }
+
+ /**
+ * Returns the shared resource's context {@link GLRendererQuirks}.
+ * + * Implementation calls {@link GLContext#getRendererQuirks()} on the shared resource context. + *
+ *
+ * In case no shared device exist yet or the implementation doesn't support tracking quirks,
+ * the result is always null
.
+ *
null
for the platform's default device.
+ * @param glp {@link GLProfile} to identify the device's {@link GLRendererQuirks}, maybe {@code null}
+ * @see GLContext#getRendererQuirks()
+ * @see GLRendererQuirks
+ */
+ public abstract GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device, final GLProfile glp);
+
+ /**
+ * Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
+ */
+ public static GLDrawableFactory getDesktopFactory() {
+ GLProfile.initSingleton();
+ return nativeOSFactory;
+ }
+
+ /**
+ * Returns the sole GLDrawableFactory instance for EGL if exist or null
+ */
+ public static GLDrawableFactory getEGLFactory() {
+ GLProfile.initSingleton();
+ return eglFactory;
+ }
+
+ /**
+ * Returns the sole GLDrawableFactory instance.
+ *
+ * @param glProfile GLProfile to determine the factory type, ie EGLDrawableFactory,
+ * or one of the native GLDrawableFactory's, ie X11/GLX, Windows/WGL or MacOSX/CGL.
+ */
+ public static GLDrawableFactory getFactory(final GLProfile glProfile) throws GLException {
+ return getFactoryImpl(glProfile.getImplName());
+ }
+
+ protected static GLDrawableFactory getFactoryImpl(final String glProfileImplName) throws GLException {
+ if ( GLProfile.usesNativeGLES(glProfileImplName) ) {
+ if(null!=eglFactory) {
+ return eglFactory;
+ }
+ } else if(null!=nativeOSFactory) {
+ return nativeOSFactory;
+ }
+ throw new GLException("No GLDrawableFactory available for profile: "+glProfileImplName);
+ }
+
+ protected static GLDrawableFactory getFactoryImpl(final AbstractGraphicsDevice device) throws GLException {
+ if(null != nativeOSFactory && nativeOSFactory.getIsDeviceCompatible(device)) {
+ return nativeOSFactory;
+ }
+ if(null != eglFactory && eglFactory.getIsDeviceCompatible(device)) {
+ return eglFactory;
+ }
+ throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+device);
+ }
+
+ /**
+ * Returns an array of available GLCapabilities for the device.null
for the platform's default device.
+ * @return A list of {@link com.jogamp.opengl.GLCapabilitiesImmutable}'s, maybe empty if none is available.
+ */
+ public final List+ * The chosen {@link GLCapabilitiesImmutable} are referenced within the target + * {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.
+ *
+ *+ * An onscreen GLDrawable is created if {@link CapabilitiesImmutable#isOnscreen() caps.isOnscreen()} is true. + *
+ *+ * A FBO drawable is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()} + * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true. + *
+ *+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()} + * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice, GLProfile) canCreateGLPbuffer(device)} is true. + *
+ *+ * If not onscreen and neither FBO nor Pbuffer is available, + * a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated. + *
+ * + * @throws IllegalArgumentException if the passed target is null + * @throws GLException if any window system-specific errors caused + * the creation of the GLDrawable to fail. + * + * @see #canCreateGLPbuffer(AbstractGraphicsDevice, GLProfile) + * @see GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) + * @see com.jogamp.opengl.GLCapabilities#isOnscreen() + * @see com.jogamp.opengl.GLCapabilities#isFBO() + * @see com.jogamp.opengl.GLCapabilities#isPBuffer() + * @see GraphicsConfigurationFactory#chooseGraphicsConfiguration(CapabilitiesImmutable, CapabilitiesImmutable, CapabilitiesChooser, AbstractGraphicsScreen, int) + */ + public abstract GLDrawable createGLDrawable(NativeSurface target) + throws IllegalArgumentException, GLException; + + /** + * Creates a {@link GLDrawable#isRealized() realized} {@link GLOffscreenAutoDrawable} + * incl it's offscreen {@link NativeSurface} with the given capabilites and dimensions. + *
+ * The {@link GLOffscreenAutoDrawable}'s {@link GLDrawable} is {@link GLDrawable#isRealized() realized}
+ * without an assigned {@link GLContext}, hence not initialized completely.
+ *
+ * The {@link GLContext} can be assigned later manually via {@link GLAutoDrawable#setContext(GLContext, boolean) setContext(ctx)}
+ * or it will be created lazily at the 1st {@link GLAutoDrawable#display() display()} method call.
+ *
+ * Lazy {@link GLContext} creation will take a shared {@link GLContext} into account
+ * which has been set {@link GLOffscreenAutoDrawable#setSharedContext(GLContext) directly}
+ * or {@link GLOffscreenAutoDrawable#setSharedAutoDrawable(GLAutoDrawable) via another GLAutoDrawable}.
+ *
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} == true
,
+ * it is auto-configured. Auto configuration will set {@link GLCapabilitiesImmutable caps} to offscreen
+ * and FBO or Pbuffer, whichever is available in that order.
+ *
+ * A FBO based auto drawable, {@link GLOffscreenAutoDrawable.FBO}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()} + * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true. + *
+ *+ * A Pbuffer based auto drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()} + * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice, GLProfile) canCreateGLPbuffer(device)} is true. + *
+ *+ * If neither FBO nor Pbuffer is available, + * a simple pixmap/bitmap auto drawable is created, which is unlikely to be hardware accelerated. + *
+ *
+ * The resulting {@link GLOffscreenAutoDrawable} has it's own independent device instance using device
details.
+ *
null
for the platform's default device.
+ * @param caps the requested GLCapabilties
+ * @param chooser the custom chooser, may be null for default
+ * @param width the requested offscreen width
+ * @param height the requested offscreen height
+ * @return the created and realized offscreen {@link GLOffscreenAutoDrawable} instance
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int)
+ */
+ public abstract GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height) throws GLException;
+
+ /**
+ * Creates a {@link GLDrawable#isRealized() realized} dummy {@link GLAutoDrawable}
+ * incl it's dummy, invisible {@link NativeSurface}
+ * as created with {@link #createDummyDrawable(AbstractGraphicsDevice, boolean, GLCapabilitiesImmutable, GLCapabilitiesChooser)}.
+ *
+ * The dummy {@link GLAutoDrawable}'s {@link GLDrawable} is {@link GLDrawable#isRealized() realized}
+ * without an assigned {@link GLContext}, hence not initialized completely.
+ * The {@link GLContext} can be assigned later manually via {@link GLAutoDrawable#setContext(GLContext, boolean) setContext(ctx)}
+ * or it will be created lazily at the 1st {@link GLAutoDrawable#display() display()} method call.
+ * Lazy {@link GLContext} creation will take a shared {@link GLContext} into account
+ * which has been set {@link GLOffscreenAutoDrawable#setSharedContext(GLContext) directly}
+ * or {@link GLOffscreenAutoDrawable#setSharedAutoDrawable(GLAutoDrawable) via another GLAutoDrawable}.
+ *
null
for the platform's default device.
+ * @param createNewDevice if true
a new independent device instance is created from the deviceReq
, otherwise deviceReq
is used as-is and must be valid!
+ * @param capsRequested the desired {@link GLCapabilitiesImmutable}, incl. it's {@link GLProfile}.
+ * For shared context, same {@link GLCapabilitiesImmutable#getVisualID(com.jogamp.nativewindow.VisualIDHolder.VIDType)}
+ * across shared drawables will yield best compatibility.
+ * @param chooser the custom chooser, may be null for default
+ * @return the created and realized dummy {@link GLAutoDrawable} instance
+ *
+ * @see #createDummyDrawable(AbstractGraphicsDevice, boolean, GLCapabilitiesImmutable, GLCapabilitiesChooser)
+ */
+ public abstract GLAutoDrawable createDummyAutoDrawable(AbstractGraphicsDevice deviceReq, boolean createNewDevice, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser);
+
+ /**
+ * Creates an {@link GLDrawable#isRealized() unrealized} offscreen {@link GLDrawable}
+ * incl it's offscreen {@link NativeSurface} with the given capabilites and dimensions.
+ *
+ * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
+ * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} == true
,
+ * it is auto-configured. The latter will set offscreen and also FBO or Pbuffer, whichever is available in that order.
+ *
+ * A resizeable FBO drawable, {@link GLFBODrawable.Resizeable}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()} + * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true. + *
+ *+ * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()} + * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice, GLProfile) canCreateGLPbuffer(device)} is true. + *
+ *+ * If neither FBO nor Pbuffer is available, + * a simple pixmap/bitmap drawable is created, which is unlikely to be hardware accelerated. + *
+ *
+ * The resulting {@link GLDrawable} has it's own independent device instance using device
details.
+ *
null
for the platform's default device.
+ * @param caps the requested GLCapabilties
+ * @param chooser the custom chooser, may be null for default
+ * @param width the requested offscreen width
+ * @param height the requested offscreen height
+ *
+ * @return the created unrealized offscreen {@link GLDrawable}
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the Offscreen to fail.
+ *
+ * @see #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)
+ */
+ public abstract GLDrawable createOffscreenDrawable(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height) throws GLException;
+
+ /**
+ * Creates an {@link GLDrawable#isRealized() unrealized} dummy {@link GLDrawable}.
+ * A dummy drawable is not visible on screen and will not be used to render directly to, it maybe on- or offscreen.
+ * + * It is used to allow the creation of a {@link GLContext} to query information. + * It also allows creation of framebuffer objects which are used for rendering or creating a shared GLContext w/o actually rendering to this dummy drawable's framebuffer. + *
+ * @param deviceReq which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may benull
for the platform's default device.
+ * @param createNewDevice if true
a new independent device instance is created from the deviceReq
, otherwise deviceReq
is used as-is and must be valid!
+ * @param capsRequested the desired {@link GLCapabilitiesImmutable}, incl. it's {@link GLProfile}.
+ * For shared context, same {@link GLCapabilitiesImmutable#getVisualID(com.jogamp.nativewindow.VisualIDHolder.VIDType) visual ID}
+ * or {@link GLCapabilitiesImmutable caps}
+ * across shared drawables will yield best compatibility.
+ * @param chooser the custom chooser, may be null for default
+ * @return the created unrealized dummy {@link GLDrawable}
+ */
+ public abstract GLDrawable createDummyDrawable(AbstractGraphicsDevice deviceReq, boolean createNewDevice, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser);
+
+ /**
+ * Creates a proxy {@link NativeSurface} w/ defined surface handle,
+ * i.e. a {@link jogamp.nativewindow.WrappedSurface} or {@link jogamp.nativewindow.windows.GDISurface} instance.
+ *
+ * It's {@link AbstractGraphicsConfiguration} is properly set according to the given
+ * windowHandle
's native visualID if set or the given {@link GLCapabilitiesImmutable}.
+ *
+ * Lifecycle (creation and destruction) of the given surface handle shall be handled by the caller + * via {@link ProxySurface#createNotify()} and {@link ProxySurface#destroyNotify()}. + *
+ *+ * Such surface can be used to instantiate a GLDrawable. With the help of {@link GLAutoDrawableDelegate} + * you will be able to implement a new native windowing system binding almost on-the-fly, + * see {@link com.jogamp.opengl.swt.GLCanvas}. + *
+ *
+ * The resulting {@link GLOffscreenAutoDrawable} has it's own independent device instance using device
details
+ * which may be blocking depending on platform and windowing-toolkit requirements.
+ *
null
for the platform's default device.
+ * Caller has to ensure it is compatible w/ the given windowHandle
+ * @param screenIdx matching screen index of given windowHandle
+ * @param windowHandle the native window handle
+ * @param caps the requested GLCapabilties
+ * @param chooser the custom chooser, may be null for default
+ * @param upstream optional {@link UpstreamSurfaceHook} allowing control of the {@link ProxySurface}'s lifecycle and data it presents.
+ * @return the created {@link ProxySurface} instance w/ defined surface handle.
+ */
+ public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device,
+ int screenIdx,
+ long windowHandle,
+ GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream);
+
+ /**
+ * Returns true if it is possible to create an framebuffer object (FBO).
+ * + * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent. + *
+ *+ * FBO support is queried as described in {@link GLContext#hasBasicFBOSupport()}. + *
+ * + * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may benull
for the platform's default device.
+ * @param glp {@link GLProfile} to check for FBO capabilities
+ * @see GLContext#hasBasicFBOSupport()
+ */
+ public abstract boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp);
+
+ /**
+ * Returns true if it is possible to create an pbuffer surface.
+ * + * Some older graphics cards do not have this capability, + * as well as some new GL implementation, i.e. OpenGL 3 core on OSX. + *
+ * + * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may benull
for the platform's default device.
+ * @param glp {@link GLProfile} to check for FBO capabilities
+ */
+ public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device, GLProfile glp);
+
+ //----------------------------------------------------------------------
+ // Methods for interacting with third-party OpenGL libraries
+
+ /**
+ * Creates a GLContext object representing an existing OpenGL + * context in an external (third-party) OpenGL-based library. This + * GLContext object may be used to draw into this preexisting + * context using its {@link GL} and {@link + * com.jogamp.opengl.glu.GLU} objects. New contexts created through + * {@link GLDrawable}s may share textures and display lists with + * this external context.
+ * + * The underlying OpenGL context must be current on the current
+ * thread at the time this method is called. The user is responsible
+ * for the maintenance of the underlying OpenGL context; calls to
+ * makeCurrent
and release
on the returned
+ * GLContext object have no effect. If the underlying OpenGL context
+ * is destroyed, the destroy
method should be called on
+ * the GLContext
. A new GLContext
object
+ * should be created for each newly-created underlying OpenGL
+ * context.
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the external GLContext to fail.
+ */
+ public abstract GLContext createExternalGLContext()
+ throws GLException;
+
+ /**
+ * Returns true if it is possible to create an external GLDrawable
+ * object via {@link #createExternalGLDrawable}.
+ *
+ * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be null
for the platform's default device.
+ */
+ public abstract boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device);
+
+ /**
+ *
Creates a {@link GLDrawable} object representing an existing + * OpenGL drawable in an external (third-party) OpenGL-based + * library. This GLDrawable object may be used to create new, + * fully-functional {@link GLContext}s on the OpenGL drawable. This + * is useful when interoperating with a third-party OpenGL-based + * library and it is essential to not perturb the state of the + * library's existing context, even to the point of not sharing + * textures or display lists with that context.
+ * + *An underlying OpenGL context must be current on the desired + * drawable and the current thread at the time this method is + * called. The user is responsible for the maintenance of the + * underlying drawable. If one or more contexts are created on the + * drawable using {@link GLDrawable#createContext}, and the drawable + * is deleted by the third-party library, the user is responsible + * for calling {@link GLContext#destroy} on these contexts.
+ * + * Calls to setSize
, getWidth
and
+ * getHeight
are illegal on the returned GLDrawable. If
+ * these operations are required by the user, they must be performed
+ * by the third-party library.
It is legal to create both an external GLContext and + * GLDrawable representing the same third-party OpenGL entities. + * This can be used, for example, to query current state information + * using the external GLContext and then create and set up new + * GLContexts using the external GLDrawable.
+ * + *This functionality may not be available on all platforms and + * {@link #canCreateExternalGLDrawable} should be called first to + * see if it is present. For example, on X11 platforms, this API + * requires the presence of GLX 1.3 or later. + * + * @throws GLException if any window system-specific errors caused + * the creation of the external GLDrawable to fail. + */ + public abstract GLDrawable createExternalGLDrawable() + throws GLException; +} diff --git a/src/jogl/classes/com/jogamp/opengl/GLEventListener.java b/src/jogl/classes/com/jogamp/opengl/GLEventListener.java new file mode 100644 index 000000000..8c5dfd3b3 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/GLEventListener.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution 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. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl; + +import java.util.EventListener; + +/** Declares events which client code can use to manage OpenGL + rendering into a {@link GLAutoDrawable}. At the time any of these + methods is called, the drawable has made its associated OpenGL + context current, so it is valid to make OpenGL calls. */ + +public interface GLEventListener extends EventListener { + /** Called by the drawable immediately after the OpenGL context is + initialized. Can be used to perform one-time OpenGL + initialization per GLContext, such as setup of lights and display lists.
+ + Note that this method may be called more than once if the underlying + OpenGL context for the GLAutoDrawable is destroyed and + recreated, for example if a GLCanvas is removed from the widget + hierarchy and later added again. + */ + public void init(GLAutoDrawable drawable); + + /** Notifies the listener to perform the release of all OpenGL + resources per GLContext, such as memory buffers and GLSL programs.
+ + Called by the drawable before the OpenGL context is + destroyed by an external event, like a reconfiguration of the + {@link GLAutoDrawable} closing an attached window, + but also manually by calling {@link GLAutoDrawable#destroy destroy}.
+ + Note that this event does not imply the end of life of the application. + It could be produced with a followup call to {@link #init(GLAutoDrawable)} + in case the GLContext has been recreated, + e.g. due to a pixel configuration change in a multihead environment. + */ + public void dispose(GLAutoDrawable drawable); + + /** Called by the drawable to initiate OpenGL rendering by the + client. After all GLEventListeners have been notified of a + display event, the drawable will swap its buffers if {@link + GLAutoDrawable#setAutoSwapBufferMode setAutoSwapBufferMode} is + enabled. */ + public void display(GLAutoDrawable drawable); + + /** + * Called by the drawable during the first repaint after the + * component has been resized. + *
+ * The client can update it's viewport associated data + * and view volume of the window appropriately. + *
+ *
+ * For efficiency the GL viewport has already been updated
+ * via glViewport(x, y, width, height)
when this method is called.
+ *
+ * A {@link GLFBODrawable} is uninitialized until a {@link GLContext} is bound + * and made current the first time, hence only then it's capabilities fully reflect expectations, + * i.e. color, depth, stencil and MSAA bits will be valid only after the first {@link GLContext#makeCurrent() makeCurrent()} call. + * On-/offscreen bits are valid after {@link #setRealized(boolean) setRealized(true)}. + *
+ * + *+ * MSAA is used if {@link GLCapabilitiesImmutable#getNumSamples() requested}. + *
+ *+ * Double buffering is used if {@link GLCapabilitiesImmutable#getDoubleBuffered() requested}. + *
+ *+ * In MSAA mode, it always uses the implicit 2nd {@link FBObject framebuffer} {@link FBObject#getSamplingSinkFBO() sink}. + * Hence double buffering is always the case w/ MSAA. + *
+ *+ * In non MSAA a second explicit {@link FBObject framebuffer} is being used. + * This method allows compliance w/ the spec, i.e. read and draw framebuffer selection + * and double buffer usage for e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels(..)}. + * This method also allows usage of both textures seperately. + *
+ *+ * It would be possible to implement double buffering simply using + * {@link Colorbuffer}s with one {@link FBObject framebuffer}. + * This would require mode selection and hence complicate the API. Besides, it would + * not support differentiation of read and write framebuffer and hence not be spec compliant. + *
+ *+ * Actual swapping of the {@link Colorbuffer}s and/or {@link FBObject framebuffer} + * is performed either in the {@link jogamp.opengl.GLContextImpl#contextMadeCurrent(boolean) context current hook} + * or when {@link jogamp.opengl.GLDrawableImpl#swapBuffersImpl(boolean) swapping buffers}, whatever comes first. + *
+ */ +public interface GLFBODrawable extends GLDrawable { + // public enum DoubleBufferMode { NONE, TEXTURE, FBO }; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support + + /** FBO Mode Bit: Use a {@link TextureAttachment} for the {@link #getColorbuffer(int) render colorbuffer}, see {@link #setFBOMode(int)}. */ + public static final int FBOMODE_USE_TEXTURE = 1 << 0; + + /** + * @returntrue
if initialized, i.e. a {@link GLContext} is bound and made current once, otherwise false
.
+ */
+ public boolean isInitialized();
+
+ /**
+ * Set the FBO mode bits used for FBO creation.
+ * + * Default value is: {@link #FBOMODE_USE_TEXTURE}. + *
+ *+ * If {@link GLRendererQuirks#BuggyColorRenderbuffer} is set, + * {@link #FBOMODE_USE_TEXTURE} is always added at initialization. + *
+ * + * @param modeBits custom FBO mode bits like {@link #FBOMODE_USE_TEXTURE}. + * @throws IllegalStateException if already initialized, see {@link #isInitialized()}. + */ + void setFBOMode(final int modeBits) throws IllegalStateException; + + /** + * @return the used FBO mode bits, mutable via {@link #setFBOMode(int)} + */ + int getFBOMode(); + + /** + * Notify this instance about upstream size change + * to reconfigure the {@link FBObject}. + * @param gl GL context object bound to this drawable, will be made current during operation. + * A prev. current context will be make current after operation. + * @throws GLException if resize operation failed + */ + void resetSize(final GL gl) throws GLException; + + /** + * @return the used texture unit + */ + int getTextureUnit(); + + /** + * + * @param unit the texture unit to be used + */ + void setTextureUnit(final int unit); + + /** + * Set the number of sample buffers if using MSAA + * + * @param gl GL context object bound to this drawable, will be made current during operation. + * A prev. current context will be make current after operation. + * @param newSamples new sample size + * @throws GLException if resetting the FBO failed + */ + void setNumSamples(final GL gl, final int newSamples) throws GLException; + + /** + * @return the number of sample buffers if using MSAA, otherwise 0 + */ + int getNumSamples(); + + /** + * Sets the number of buffers (FBO) being used if using {@link GLCapabilities#getDoubleBuffered() double buffering}. + *+ * If {@link GLCapabilities#getDoubleBuffered() double buffering} is not chosen, this is a NOP. + *
+ *+ * Must be called before {@link #isInitialized() initialization}, otherwise an exception is thrown. + *
+ * @return the new number of buffers (FBO) used, maybe different than the requestedbufferCount
(see above)
+ * @throws IllegalStateException if already initialized, see {@link #isInitialized()}.
+ */
+ int setNumBuffers(final int bufferCount) throws IllegalStateException, GLException;
+
+ /**
+ * @return the number of buffers (FBO) being used. 1 if not using {@link GLCapabilities#getDoubleBuffered() double buffering},
+ * otherwise ≥ 2, depending on {@link #setNumBuffers(int)}.
+ */
+ int getNumBuffers();
+
+ /**
+ * @return the used {@link DoubleBufferMode}
+ */
+ // DoubleBufferMode getDoubleBufferMode(); // TODO: Add or remove TEXTURE (only) DoubleBufferMode support
+
+ /**
+ * Sets the {@link DoubleBufferMode}. Must be called before {@link #isInitialized() initialization},
+ * otherwise an exception is thrown.
+ * + * This call has no effect is MSAA is selected, since MSAA always forces the mode to {@link DoubleBufferMode#FBO FBO}. + * Also setting the mode to {@link DoubleBufferMode#NONE NONE} where double buffering is {@link GLCapabilitiesImmutable#getDoubleBuffered() requested} + * or setting a double buffering mode w/o {@link GLCapabilitiesImmutable#getDoubleBuffered() request} will be ignored. + *
+ *+ * Since {@link DoubleBufferMode#TEXTURE TEXTURE} mode is currently not implemented, this method has no effect. + *
+ * @throws GLException if already initialized, see {@link #isInitialized()}. + */ + // void setDoubleBufferMode(DoubleBufferMode mode) throws GLException; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support + + /** + * If MSAA is being used and {@link GL#GL_FRONT} is requested, + * the internal {@link FBObject} {@link FBObject#getSamplingSinkFBO() sample sink} is being returned. + * + * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names + * @return the named {@link FBObject} + * @throws IllegalArgumentException if an illegal buffer name is being used + */ + FBObject getFBObject(final int bufferName) throws IllegalArgumentException; + + /** + * Returns the named {@link Colorbuffer} instance. + *+ * If MSAA is being used, only the {@link GL#GL_FRONT} buffer is accessible + * and an exception is being thrown if {@link GL#GL_BACK} is being requested. + *
+ *+ * Depending on the {@link #setFBOMode(int) fbo mode} the resulting {@link Colorbuffer} + * is either a {@link TextureAttachment} if {@link #FBOMODE_USE_TEXTURE} is set, + * otherwise a {@link ColorAttachment}. + * See {@link Colorbuffer#isTextureAttachment()}. + *
+ * @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names + * @return the named {@link Colorbuffer} + * @throws IllegalArgumentException if using MSAA and {@link GL#GL_BACK} is requested or an illegal buffer name is being used + */ + Colorbuffer getColorbuffer(final int bufferName) throws IllegalArgumentException; + + /** Resizeable {@link GLFBODrawable} specialization */ + public interface Resizeable extends GLFBODrawable { + /** + * Resize this {@link GLFBODrawable}'s surface. + *+ * This drawable is being locked during operation. + *
+ * @param context the {@link GLContext} bound to this drawable, will be made current during operation + * A prev. current context will be make current after operation. + * @param newWidth new width in pixel units + * @param newHeight new width in pixel units + * @throws NativeWindowException in case the surface could no be locked + * @throws GLException in case an error during the resize operation occurred + */ + void setSurfaceSize(GLContext context, int newWidth, int newHeight) throws NativeWindowException, GLException; + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/GLOffscreenAutoDrawable.java b/src/jogl/classes/com/jogamp/opengl/GLOffscreenAutoDrawable.java new file mode 100644 index 000000000..a2d0f5fdb --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/GLOffscreenAutoDrawable.java @@ -0,0 +1,69 @@ +/** + * Copyright 2012 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; + +import com.jogamp.nativewindow.NativeWindowException; + +import com.jogamp.opengl.FBObject; + +/** + * Platform-independent {@link GLAutoDrawable} specialization, + * exposing offscreen functionality. + *+ * This class distinguishes itself from {@link GLAutoDrawable} + * with it's {@link #setSurfaceSize(int, int)} functionality. + *
+ *
+ * OpenGL Context Sharing
+ * To share a {@link GLContext} see the following note in the documentation overview:
+ * context sharing
+ * as well as {@link GLSharedContextSetter}.
+ *
downstream
+ * and optional arguments additionalArgs
for the constructor.
+ *
+ * + * Sample code which installs a Debug and Trace pipeline + * automatic w/ user defined interface, here: GL2ES2: + *
+ * gl = drawable.setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", GL2ES2.class, gl, null) ); + * gl = drawable.setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", GL2ES2.class, gl, new Object[] { System.err } ) ); + *+ * or automatic w/ automatic defined class: + *
+ * gl = drawable.setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, gl, null) ); + * gl = drawable.setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, gl, new Object[] { System.err } ) ); + *+ * + * + *
+ * The upstream GL instance is determined as follows: + *
pipelineClazzBaseName
as the class name's full basename, incl. package namedownstream
class and it's superclasses, do:downstream
class and superclass interfaces, do:reqInterface
is not null and the interface is unequal, continue loop.downstream
is not instance of interface, continue loop.jogl.disable.openglcore
disables querying possible existing native OpenGL core profiles.
+ * + * This exclusion is disabled for {@link Platform.OSType#MACOS}. + *
+ */ + public static final boolean disableOpenGLCore; + + /** + * In case the implementation of the ARB_create_context + * context creation extension is buggy on one platform, + * setting the propertyjogl.disable.openglarbcontext
disables utilizing it.
+ * + * This exclusion also disables {@link #disableOpenGLES OpenGL ES}. + *
+ *+ * This exclusion is disabled for {@link Platform.OSType#MACOS}. + *
+ */ + public static final boolean disableOpenGLARBContext; + + /** + * In case no OpenGL ES profiles are required + * and if one platform may have a buggy implementation, + * setting the propertyjogl.disable.opengles
disables querying possible existing OpenGL ES profiles.
+ */
+ public static final boolean disableOpenGLES;
+
+ /**
+ * In case no OpenGL desktop profiles are required
+ * and if one platform may have a buggy implementation,
+ * setting the property jogl.disable.opengldesktop
disables querying possible existing OpenGL desktop profiles.
+ */
+ public static final boolean disableOpenGLDesktop;
+
+ /**
+ * Disable surfaceless OpenGL context capability and its probing
+ * by setting the property jogl.disable.surfacelesscontext
.
+ * + * By default surfaceless OpenGL context capability is probed, + * i.e. whether an OpenGL context can be made current without a default framebuffer. + *
+ *+ * If probing fails or if this property is set, the {@link GLRendererQuirks quirk} {@link GLRendererQuirks#NoSurfacelessCtx} + * is being set. + *
+ */ + public static final boolean disableSurfacelessContext; + + /** + * We have to disable support for ANGLE, the D3D ES2 emulation on Windows provided w/ Firefox and Chrome. + * When run in the mentioned browsers, the eglInitialize(..) implementation crashes. + *
+ * This can be overridden by explicitly enabling ANGLE on Windows by setting the property
+ * jogl.enable.ANGLE
.
+ *
true
if JOGL has been initialized, i.e. manually via {@link #initSingleton()} or implicit,
+ * otherwise returns false
.
+ *
+ * @since 2.2.1
+ */
+ public static boolean isInitialized() {
+ initLock.lock();
+ try {
+ return initialized;
+ } finally {
+ initLock.unlock();
+ }
+ }
+
+ /**
+ * Static initialization of JOGL.
+ *
+ * + * This method shall not need to be called for other reasons than having a defined initialization sequence. + *
+ * + *+ * In case this method is not invoked, GLProfile is initialized implicit by + * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}. + *
+ * + *
+ * To initialize JOGL at startup ASAP, this method may be invoked in the main class's + * static initializer block, in the static main() method or in the Applet init() method. + *
+ * + *+ * Since JOGL's initialization is complex and involves multi threading, it is not recommended + * to be have it invoked on the AWT EDT thread. In case all JOGL usage is performed + * on the AWT EDT, invoke this method outside the AWT EDT - see above. + *
+ * + */ + public static void initSingleton() { + final boolean justInitialized; + initLock.lock(); + try { + if(!initialized) { + initialized = true; + justInitialized = true; + if(DEBUG) { + System.err.println("GLProfile.initSingleton() - thread "+Thread.currentThread().getName()); + ExceptionUtils.dumpStack(System.err); + } + + if(ReflectionUtil.DEBUG_STATS_FORNAME) { + ReflectionUtil.resetForNameCount(); + } + + // run the whole static initialization privileged to speed up, + // since this skips checking further access + AccessController.doPrivileged(new PrivilegedAction+ * void myCombine(double[] coords, Object[] data, + * float[] weight, Object[] outData) + * { + * MyVertex newVertex = new MyVertex(); + * + * newVertex.x = coords[0]; + * newVertex.y = coords[1]; + * newVertex.z = coords[2]; + * newVertex.r = weight[0]*data[0].r + + * weight[1]*data[1].r + + * weight[2]*data[2].r + + * weight[3]*data[3].r; + * newVertex.g = weight[0]*data[0].g + + * weight[1]*data[1].g + + * weight[2]*data[2].g + + * weight[3]*data[3].g; + * newVertex.b = weight[0]*data[0].b + + * weight[1]*data[1].b + + * weight[2]*data[2].b + + * weight[3]*data[3].b; + * newVertex.a = weight[0]*data[0].a + + * weight[1]*data[1].a + + * weight[2]*data[2].a + + * weight[3]*data[3].a; + * outData = newVertex; + * }+ * + * @param coords + * Specifics the location of the new vertex. + * @param data + * Specifics the vertices used to create the new vertex. + * @param weight + * Specifics the weights used to create the new vertex. + * @param outData + * Reference user the put the coodinates of the new vertex. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #combineData combineData + */ + public void combine(double[] coords, Object[] data, + float[] weight, Object[] outData); + + + /** + * The same as the {@link #combine combine} callback method except + * that it takes an additional reference argument. This reference is + * identical to the opaque reference provided when {@link + * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called. + * + * @param coords + * Specifics the location of the new vertex. + * @param data + * Specifics the vertices used to create the new vertex. + * @param weight + * Specifics the weights used to create the new vertex. + * @param outData + * Reference user the put the coodinates of the new vertex. + * @param polygonData + * Specifics a reference to user-defined data. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #combine combine + */ + public void combineData(double[] coords, Object[] data, + float[] weight, Object[] outData, + Object polygonData); + + + /** + * The error callback method is called when an error is encountered. + * The one argument is of type int; it indicates the specific error that + * occurred and will be set to one of GLU_TESS_MISSING_BEGIN_POLYGON, + * GLU_TESS_MISSING_END_POLYGON, GLU_TESS_MISSING_BEGIN_CONTOUR, + * GLU_TESS_MISSING_END_CONTOUR, GLU_TESS_COORD_TOO_LARGE, + * GLU_TESS_NEED_COMBINE_CALLBACK or GLU_OUT_OF_MEMORY. + * Character strings describing these errors can be retrieved with the + * {@link GLU#gluErrorString gluErrorString} call.
+ * + * The GLU library will recover from the first four errors by inserting the + * missing call(s). GLU_TESS_COORD_TOO_LARGE indicates that some + * vertex coordinate exceeded the predefined constant + * GLU_TESS_MAX_COORD in absolute value, and that the value has been + * clamped. (Coordinate values must be small enough so that two can be + * multiplied together without overflow.) + * GLU_TESS_NEED_COMBINE_CALLBACK indicates that the tessellation + * detected an intersection between two edges in the input data, and the + * GLU_TESS_COMBINE or GLU_TESS_COMBINE_DATA callback was not + * provided. No output is generated. GLU_OUT_OF_MEMORY indicates that + * there is not enough memory so no output is generated. + * + * @param errnum + * Specifics the error number code. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #errorData errorData + */ + public void error(int errnum); + + + /** + * The same as the {@link #error error} callback method except that + * it takes an additional reference argument. This reference is + * identical to the opaque reference provided when {@link + * GLU#gluTessBeginPolygon gluTessBeginPolygon} was called. + * + * @param errnum + * Specifics the error number code. + * @param polygonData + * Specifics a reference to user-defined data. + * + * @see GLU#gluTessCallback gluTessCallback + * @see #error error + */ + public void errorData(int errnum, Object polygonData); + + //void mesh(jogamp.opengl.tessellator.GLUmesh mesh); +} diff --git a/src/jogl/classes/com/jogamp/opengl/glu/GLUtessellatorCallbackAdapter.java b/src/jogl/classes/com/jogamp/opengl/glu/GLUtessellatorCallbackAdapter.java new file mode 100644 index 000000000..b9503f12e --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/glu/GLUtessellatorCallbackAdapter.java @@ -0,0 +1,96 @@ +/* +* Portions Copyright (C) 2003-2006 Sun Microsystems, Inc. +* All rights reserved. +*/ + +/* +** License Applicability. Except to the extent portions of this file are +** made subject to an alternative license as permitted in the SGI Free +** Software License B, Version 2.0 (the "License"), the contents of this +** file are subject only to the provisions of the License. You may not use +** this file except in compliance with the License. You may obtain a copy +** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 +** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: +** +** http://oss.sgi.com/projects/FreeB +** +** Note that, as provided in the License, the Software is distributed on an +** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS +** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND +** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A +** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. +** +** NOTE: The Original Code (as defined below) has been licensed to Sun +** Microsystems, Inc. ("Sun") under the SGI Free Software License B +** (Version 1.1), shown above ("SGI License"). Pursuant to Section +** 3.2(3) of the SGI License, Sun is distributing the Covered Code to +** you under an alternative license ("Alternative License"). This +** Alternative License includes all of the provisions of the SGI License +** except that Section 2.2 and 11 are omitted. Any differences between +** the Alternative License and the SGI License are offered solely by Sun +** and not by SGI. +** +** Original Code. The Original Code is: OpenGL Sample Implementation, +** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, +** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. +** Copyright in any portions created by third parties is as indicated +** elsewhere herein. All Rights Reserved. +** +** Additional Notice Provisions: The application programming interfaces +** established by SGI in conjunction with the Original Code are The +** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released +** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version +** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X +** Window System(R) (Version 1.3), released October 19, 1998. This software +** was created using the OpenGL(R) version 1.2.1 Sample Implementation +** published by SGI, but has not been independently verified as being +** compliant with the OpenGL(R) version 1.2.1 Specification. +** +** Author: Eric Veach, July 1994 +** Java Port: Pepijn Van Eeckhoudt, July 2003 +** Java Port: Nathan Parker Burg, August 2003 +*/ +package com.jogamp.opengl.glu; + +/** + * The GLUtessellatorCallbackAdapter provides a default implementation of + * {@link GLUtessellatorCallback GLUtessellatorCallback} + * with empty callback methods. This class can be extended to provide user + * defined callback methods. + * + * @author Eric Veach, July 1994 + * @author Java Port: Pepijn Van Eechhoudt, July 2003 + * @author Java Port: Nathan Parker Burg, August 2003 + */ + +public class GLUtessellatorCallbackAdapter implements GLUtessellatorCallback { + @Override + public void begin(final int type) {} + @Override + public void edgeFlag(final boolean boundaryEdge) {} + @Override + public void vertex(final Object vertexData) {} + @Override + public void end() {} +// public void mesh(jogamp.opengl.tessellator.GLUmesh mesh) {} + @Override + public void error(final int errnum) {} + @Override + public void combine(final double[] coords, final Object[] data, + final float[] weight, final Object[] outData) {} + @Override + public void beginData(final int type, final Object polygonData) {} + @Override + public void edgeFlagData(final boolean boundaryEdge, + final Object polygonData) {} + @Override + public void vertexData(final Object vertexData, final Object polygonData) {} + @Override + public void endData(final Object polygonData) {} + @Override + public void errorData(final int errnum, final Object polygonData) {} + @Override + public void combineData(final double[] coords, final Object[] data, + final float[] weight, final Object[] outData, + final Object polygonData) {} +} -- cgit v1.2.3