summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax/media
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/javax/media')
-rw-r--r--src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java257
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAnimatorControl.java194
-rw-r--r--src/jogl/classes/javax/media/opengl/GLArrayData.java141
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawable.java277
-rw-r--r--src/jogl/classes/javax/media/opengl/GLBase.java347
-rw-r--r--src/jogl/classes/javax/media/opengl/GLCapabilities.java462
-rw-r--r--src/jogl/classes/javax/media/opengl/GLCapabilitiesChooser.java56
-rw-r--r--src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java150
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java780
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawable.java175
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java554
-rw-r--r--src/jogl/classes/javax/media/opengl/GLEventListener.java92
-rw-r--r--src/jogl/classes/javax/media/opengl/GLException.java68
-rw-r--r--src/jogl/classes/javax/media/opengl/GLPbuffer.java91
-rw-r--r--src/jogl/classes/javax/media/opengl/GLPipelineFactory.java194
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java1609
-rw-r--r--src/jogl/classes/javax/media/opengl/GLRunnable.java47
-rw-r--r--src/jogl/classes/javax/media/opengl/GLUniformData.java154
-rw-r--r--src/jogl/classes/javax/media/opengl/Threading.java166
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java51
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java75
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java1074
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java1721
-rw-r--r--src/jogl/classes/javax/media/opengl/fixedfunc/GLLightingFunc.java49
-rw-r--r--src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java74
-rw-r--r--src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFunc.java38
-rw-r--r--src/jogl/classes/javax/media/opengl/glu/GLUnurbs.java8
-rw-r--r--src/jogl/classes/javax/media/opengl/glu/GLUquadric.java33
-rw-r--r--src/jogl/classes/javax/media/opengl/glu/GLUtessellator.java66
-rw-r--r--src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java356
-rw-r--r--src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java84
31 files changed, 9443 insertions, 0 deletions
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
new file mode 100644
index 000000000..9352ad4f3
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -0,0 +1,257 @@
+/*
+ * 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 javax.media.opengl;
+
+import javax.media.nativewindow.NativeWindowException;
+import jogamp.opengl.Debug;
+import java.util.List;
+import javax.media.nativewindow.CapabilitiesImmutable;
+
+/** <P> 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: </P>
+
+ <UL>
+
+ <LI> As long as there is at least one available non-null
+ GLCapabilities which matches the "stereo" option, will return a
+ valid index.
+
+ <LI> Attempts to match as closely as possible the given
+ GLCapabilities, but will select one with fewer capabilities (i.e.,
+ lower color depth) if necessary.
+
+ <LI> Prefers hardware-accelerated visuals to
+ non-hardware-accelerated.
+
+ <LI> If there is no exact match, prefers a more-capable visual to
+ a less-capable one.
+
+ <LI> If there is more than one exact match, chooses an arbitrary
+ one.
+
+ <LI> May select the opposite of a double- or single-buffered
+ visual (based on the user's request) in dire situations.
+
+ <LI> Color depth (including alpha) mismatches are weighted higher
+ than depth buffer mismatches, which are in turn weighted higher
+ than accumulation buffer (including alpha) and stencil buffer
+ depth mismatches.
+
+ <LI> If a valid windowSystemRecommendedChoice parameter is
+ supplied, chooses that instead of using the cross-platform code.
+
+ </UL>
+*/
+
+public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
+ private static final boolean DEBUG = Debug.debug("CapabilitiesChooser");
+
+ public int chooseCapabilities(final CapabilitiesImmutable desired,
+ final List /*<CapabilitiesImmutable>*/ available,
+ final int windowSystemRecommendedChoice) {
+ if ( null == desired ) {
+ throw new NativeWindowException("Null desired capabilities");
+ }
+ if ( 0 == available.size() ) {
+ throw new NativeWindowException("Empty available capabilities");
+ }
+
+ final GLCapabilitiesImmutable gldes = (GLCapabilitiesImmutable) desired;
+ final int availnum = available.size();
+
+ if (DEBUG) {
+ System.err.println("Desired: " + gldes);
+ System.err.println("Available: " + availnum);
+ for (int i = 0; i < available.size(); i++) {
+ System.err.println(i + ": " + available.get(i));
+ }
+ System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice);
+ }
+
+ if (windowSystemRecommendedChoice >= 0 &&
+ windowSystemRecommendedChoice < availnum &&
+ null != available.get(windowSystemRecommendedChoice)) {
+ if (DEBUG) {
+ System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice);
+ System.err.println(available.get(windowSystemRecommendedChoice));
+ }
+ return windowSystemRecommendedChoice;
+ }
+
+ // Create score array
+ int[] scores = new int[availnum];
+ int NO_SCORE = -9999999;
+ int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
+ int STENCIL_MISMATCH_PENALTY = 500;
+ // Pseudo attempt to keep equal rank penalties scale-equivalent
+ // (e.g., stencil mismatch is 3 * accum because there are 3 accum
+ // components)
+ int COLOR_MISMATCH_PENALTY_SCALE = 36;
+ int DEPTH_MISMATCH_PENALTY_SCALE = 6;
+ int ACCUM_MISMATCH_PENALTY_SCALE = 1;
+ int STENCIL_MISMATCH_PENALTY_SCALE = 3;
+ for (int i = 0; i < scores.length; i++) {
+ scores[i] = NO_SCORE;
+ }
+ // Compute score for each
+ for (int i = 0; i < availnum; i++) {
+ GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i);
+ if (cur == null) {
+ continue;
+ }
+ if (gldes.isOnscreen() != cur.isOnscreen()) {
+ continue;
+ }
+ if (!gldes.isOnscreen() && gldes.isPBuffer() && !cur.isPBuffer()) {
+ continue; // only skip if requested Offscreen && PBuffer, but no PBuffer available
+ }
+ if (gldes.getStereo() != cur.getStereo()) {
+ continue;
+ }
+ int score = 0;
+ // Compute difference in color depth
+ // (Note that this decides the direction of all other penalties)
+ score += (COLOR_MISMATCH_PENALTY_SCALE *
+ ((cur.getRedBits() + cur.getGreenBits() + cur.getBlueBits() + cur.getAlphaBits()) -
+ (gldes.getRedBits() + gldes.getGreenBits() + gldes.getBlueBits() + gldes.getAlphaBits())));
+ // Compute difference in depth buffer depth
+ score += (DEPTH_MISMATCH_PENALTY_SCALE * sign(score) *
+ Math.abs(cur.getDepthBits() - gldes.getDepthBits()));
+ // Compute difference in accumulation buffer depth
+ score += (ACCUM_MISMATCH_PENALTY_SCALE * sign(score) *
+ Math.abs((cur.getAccumRedBits() + cur.getAccumGreenBits() + cur.getAccumBlueBits() + cur.getAccumAlphaBits()) -
+ (gldes.getAccumRedBits() + gldes.getAccumGreenBits() + gldes.getAccumBlueBits() + gldes.getAccumAlphaBits())));
+ // Compute difference in stencil bits
+ score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - gldes.getStencilBits());
+ if (cur.getDoubleBuffered() != gldes.getDoubleBuffered()) {
+ score += sign(score) * DOUBLE_BUFFER_MISMATCH_PENALTY;
+ }
+ if ((gldes.getStencilBits() > 0) && (cur.getStencilBits() == 0)) {
+ score += sign(score) * STENCIL_MISMATCH_PENALTY;
+ }
+ scores[i] = score;
+ }
+ // Now prefer hardware-accelerated visuals by pushing scores of
+ // non-hardware-accelerated visuals out
+ boolean gotHW = false;
+ int maxAbsoluteHWScore = 0;
+ for (int i = 0; i < availnum; i++) {
+ int score = scores[i];
+ if (score == NO_SCORE) {
+ continue;
+ }
+ GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i);
+ if (cur.getHardwareAccelerated()) {
+ int absScore = Math.abs(score);
+ if (!gotHW ||
+ (absScore > maxAbsoluteHWScore)) {
+ gotHW = true;
+ maxAbsoluteHWScore = absScore;
+ }
+ }
+ }
+ if (gotHW) {
+ for (int i = 0; i < availnum; i++) {
+ int score = scores[i];
+ if (score == NO_SCORE) {
+ continue;
+ }
+ GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i);
+ if (!cur.getHardwareAccelerated()) {
+ if (score <= 0) {
+ score -= maxAbsoluteHWScore;
+ } else if (score > 0) {
+ score += maxAbsoluteHWScore;
+ }
+ scores[i] = score;
+ }
+ }
+ }
+
+ if (DEBUG) {
+ System.err.print("Scores: [");
+ for (int i = 0; i < availnum; i++) {
+ if (i > 0) {
+ System.err.print(",");
+ }
+ System.err.print(" " + scores[i]);
+ }
+ System.err.println(" ]");
+ }
+
+ // Ready to select. Choose score closest to 0.
+ int scoreClosestToZero = NO_SCORE;
+ int chosenIndex = -1;
+ for (int i = 0; i < availnum; i++) {
+ int score = scores[i];
+ if (score == NO_SCORE) {
+ continue;
+ }
+ // Don't substitute a positive score for a smaller negative score
+ if ((scoreClosestToZero == NO_SCORE) ||
+ (Math.abs(score) < Math.abs(scoreClosestToZero) &&
+ ((sign(scoreClosestToZero) < 0) || (sign(score) > 0)))) {
+ scoreClosestToZero = score;
+ chosenIndex = i;
+ }
+ }
+ if (chosenIndex < 0) {
+ throw new NativeWindowException("Unable to select one of the provided GLCapabilities");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen index: " + chosenIndex);
+ System.err.println("Chosen capabilities:");
+ System.err.println(available.get(chosenIndex));
+ }
+
+ return chosenIndex;
+ }
+
+ private static int sign(int score) {
+ if (score < 0) {
+ return -1;
+ }
+ return 1;
+ }
+
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLAnimatorControl.java b/src/jogl/classes/javax/media/opengl/GLAnimatorControl.java
new file mode 100644
index 000000000..2c8c7cca3
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLAnimatorControl.java
@@ -0,0 +1,194 @@
+/**
+ * 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 javax.media.opengl;
+
+/**
+ * An animator control interface,
+ * which implementation may drive a {@link javax.media.opengl.GLAutoDrawable} animation.
+ */
+public interface GLAnimatorControl {
+
+ /**
+ * @return Time of the first display call in milliseconds.
+ * This value is reset if started or resumed.
+ *
+ * @see #start()
+ * @see #resume()
+ */
+ long getStartTime();
+
+ /**
+ * @return Time of the last display call in milliseconds.
+ * This value is reset if started or resumed.
+ *
+ * @see #start()
+ * @see #resume()
+ */
+ long getCurrentTime();
+
+ /**
+ * @return Duration <code>getCurrentTime() - getStartTime()</code>.
+ *
+ * @see #getStartTime()
+ * @see #getCurrentTime()
+ */
+ long getDuration();
+
+
+ /**
+ * @return Number of frame cycles displayed
+ * since the first display call, ie <code>getStartTime()</code>.
+ * This value is reset if started or resumed.
+ *
+ * @see #start()
+ * @see #resume()
+ */
+ int getTotalFrames();
+
+ /** Reset all performance counter (startTime, currentTime, frame number) */
+ public void resetCounter();
+
+ /**
+ * Indicates whether this animator is running, ie. has been started and not stopped.
+ *
+ * @see #start()
+ * @see #stop()
+ * @see #pause()
+ * @see #resume()
+ */
+ boolean isStarted();
+
+ /**
+ * Indicates whether this animator is running and animating,<br>
+ * the latter is true if it has {@link GLAutoDrawable}s to render and is not paused.
+ *
+ * @see #start()
+ * @see #stop()
+ * @see #pause()
+ * @see #resume()
+ */
+ boolean isAnimating();
+
+ /**
+ * Indicates whether this animator is running and paused.
+ *
+ * @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.
+ * <P>
+ * 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.
+ * <P>
+ * 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 #getThread()
+ */
+ boolean start();
+
+ /**
+ * Stops this animator.
+ * <P>
+ * 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.
+ * <P>
+ * 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 if not started or already paused, otherwise true
+ *
+ * @see #resume()
+ * @see #isAnimating()
+ */
+ boolean pause();
+
+ /**
+ * Resumes animation if paused.
+ * <P>
+ * 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.
+ * <P>
+ * If resumed, all counters (time, frames, ..) are reset to zero.
+ *
+ * @return false if if not started or not paused, otherwise true
+ *
+ * @see #pause()
+ * @see #isAnimating()
+ */
+ boolean resume();
+
+ /**
+ * Removes a drawable from the animator's list of rendering drawables.<br>
+ * This method should get called in case a drawable becomes invalid,
+ * and will not be recovered.<br>
+ * This allows the animator thread to become idle in case the last drawable
+ * has reached it's end of life.<br>
+ *
+ * @param drawable the to be removed drawable
+ */
+ void remove(GLAutoDrawable drawable);
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLArrayData.java b/src/jogl/classes/javax/media/opengl/GLArrayData.java
new file mode 100644
index 000000000..6c8122f27
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLArrayData.java
@@ -0,0 +1,141 @@
+/**
+ * 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 javax.media.opengl;
+
+import java.nio.*;
+
+/**
+ *
+ * The total number of bytes hold by the referenced buffer is:
+ * getComponentSize()* getComponentNumber() * getElementNumber()
+ *
+ */
+public interface GLArrayData {
+
+ /**
+ * Returns true if this data set is intended for a GLSL vertex shader attribute,
+ * otherwise false, ie intended for fixed function vertex pointer
+ */
+ public boolean isVertexAttribute();
+
+ /**
+ * The index of the predefined array index, see list below,
+ * or -1 in case of a shader attribute array.
+ *
+ * @see javax.media.opengl.GL2#GL_VERTEX_ARRAY
+ * @see javax.media.opengl.GL2#GL_NORMAL_ARRAY
+ * @see javax.media.opengl.GL2#GL_COLOR_ARRAY
+ * @see javax.media.opengl.GL2#GL_TEXTURE_COORD_ARRAY
+ */
+ public int getIndex();
+
+ /**
+ * The name of the reflecting shader array attribute.
+ */
+ public String getName();
+
+ /**
+ * Set a new name for this array.
+ */
+ public void setName(String newName);
+
+
+ /**
+ * Returns the shader attribute location for this name,
+ * -1 if not yet determined
+ */
+ public int getLocation();
+
+ /**
+ * Sets the determined location of the shader attribute
+ * This is usually done within ShaderState.
+ *
+ * @see com.jogamp.opengl.util.glsl.ShaderState#glVertexAttribPointer(GL2ES2, GLArrayData)
+ */
+ public void setLocation(int v);
+
+ /**
+ * Determines wheather the data is server side (VBO),
+ * or a client side array (false).
+ */
+ public boolean isVBO();
+
+ /**
+ * The offset, if it's an VBO, otherwise -1
+ */
+ public long getOffset();
+
+ /**
+ * The VBO name, if it's an VBO, otherwise -1
+ */
+ public int getVBOName();
+
+ /**
+ * The Buffer holding the data, may be null in case of VBO
+ */
+ public Buffer getBuffer();
+
+ /**
+ * The number of components per element
+ */
+ public int getComponentNumber();
+
+ /**
+ * The component's GL data type, ie. GL_FLOAT
+ */
+ public int getComponentType();
+
+ /**
+ * The components size in bytes
+ */
+ public int getComponentSize();
+
+ /**
+ * Return the number of elements.
+ */
+ public int getElementNumber();
+
+ /**
+ * True, if GL shall normalize fixed point data while converting
+ * them into float
+ */
+ public boolean getNormalized();
+
+ /**
+ * The distance to the next payload,
+ * allowing interleaved arrays.
+ */
+ public int getStride();
+
+ public String toString();
+
+ public void destroy(GL gl);
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
new file mode 100644
index 000000000..cf24d1028
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -0,0 +1,277 @@
+/*
+ * 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 javax.media.opengl;
+
+import jogamp.opengl.Debug;
+import java.security.*;
+
+/** A higher-level abstraction than {@link GLDrawable} which supplies
+ an event based mechanism ({@link GLEventListener}) for performing
+ OpenGL rendering. A GLAutoDrawable automatically creates a primary
+ rendering context which is associated with the GLAutoDrawable for
+ the lifetime of the object. This context has the {@link
+ GLContext#setSynchronized synchronized} property enabled so that
+ calls to {@link GLContext#makeCurrent makeCurrent} will block if
+ the context is current on another thread. This allows the internal
+ GLContext for the GLAutoDrawable to be used both by the event
+ based rendering mechanism as well by end users directly.<P>
+
+ The implementation shall initialize itself as soon as possible,
+ ie if the attached {@link javax.media.nativewindow.NativeSurface NativeSurface} becomes visible/realized.
+ The following protocol shall be satisfied:
+ <ul>
+ <li> Create the {@link GLDrawable} with the requested {@link GLCapabilities}</li>
+ <li> Notify {@link GLDrawable} to validate the {@link GLCapabilities} by calling {@link GLDrawable#setRealized setRealized(true)}.</li>
+ <li> Create the new {@link GLContext}.</li>
+ <li> Initialize all OpenGL resources by calling {@link GLEventListener#init init(..)} for all
+ registered {@link GLEventListener}s. This can be done immediatly, or with the followup {@link #display display(..)} call.</li>
+ <li> Send a reshape event by calling {@link GLEventListener#reshape reshape(..)} for all
+ registered {@link GLEventListener}s. This shall be done after the {@link GLEventListener#init init(..)} calls.</li>
+ </ul><P>
+
+ Another implementation detail is the drawable 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 javax.media.nativewindow.NativeSurface NativeSurface}.<br>
+ 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 javax.media.opengl.awt.GLCanvas}'s
+ and NEWT's <code>AWTCanvas</code> {@link javax.media.opengl.awt.GLCanvas#getGraphicsConfiguration getGraphicsConfiguration()}
+ specialization. Another demonstration is NEWT's {@link javax.media.nativewindow.NativeWindow NativeWindow}
+ implementation on the Windows platform, which utilizes the native platform's <i>MonitorFromWindow(HWND)</i> function.<br>
+ All OpenGL resources shall be regenerated, while the drawable's {@link GLCapabilities} has
+ to be choosen again. The following protocol shall be satisfied.
+ <ul>
+ <li> Controlled disposal:</li>
+ <ul>
+ <li> Dispose all OpenGL resources by calling {@link GLEventListener#dispose dispose(..)} for all
+ registered {@link GLEventListener}s.</li>
+ <li> Destroy the {@link GLContext}.</li>
+ <li> Notify {@link GLDrawable} of the invalid state by calling {@link GLDrawable#setRealized setRealized(false)}.</li>
+ </ul>
+ <li> Controlled regeneration:</li>
+ <ul>
+ <li> Create the new {@link GLDrawable} with the requested {@link GLCapabilities}
+ <li> Notify {@link GLDrawable} to revalidate the {@link GLCapabilities} by calling {@link GLDrawable#setRealized setRealized(true)}.</li>
+ <li> Create the new {@link GLContext}.</li>
+ <li> Initialize all OpenGL resources by calling {@link GLEventListener#init init(..)} for all
+ registered {@link GLEventListener}s. This can be done immediatly, or with the followup {@link #display display(..)} call.</li>
+ <li> Send a reshape event by calling {@link GLEventListener#reshape reshape(..)} for all
+ registered {@link GLEventListener}s. This shall be done after the {@link GLEventListener#init init(..)} calls.</li>
+ </ul>
+ </ul>
+ Note: Current graphics driver keep the surface configuration for a given window, even if the window is moved to
+ a monitor with a different pixel configuration, ie 32bpp to 16bpp. However, it is best to not assume such behavior
+ and make your application comply with the above protocol.<P>
+
+ However, to not introduce to much breakage with older applications and because of the situation
+ mentioned above, the <code>boolean</code> system property <code>jogl.screenchange.action</code> will control the
+ screen change action as follows:<br>
+
+ <PRE>
+ -Djogl.screenchange.action=false Disable the drawable reconfiguration (the default)
+ -Djogl.screenchange.action=true Enable the drawable reconfiguration
+ </PRE>
+ */
+public interface GLAutoDrawable extends GLDrawable {
+ /** Flag reflecting wheather the drawable reconfiguration will be issued in
+ * case a screen device change occured, e.g. in a multihead environment,
+ * where you drag the window to another monitor. */
+ public static final boolean SCREEN_CHANGE_ACTION_ENABLED = Debug.getBooleanProperty("jogl.screenchange.action", true, AccessController.getContext());
+
+ /**
+ * 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 a new context to this drawable.
+ */
+ public void setContext(GLContext context);
+
+ /** Adds a {@link GLEventListener} to the end of this drawable queue.
+ The listeners are notified of events in the order of the queue. */
+ public void addGLEventListener(GLEventListener listener);
+
+ /**
+ * Adds a {@link GLEventListener} at the given index of this drawable queue.
+ * The listeners are notified of events in the order of the queue.
+ * @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;
+
+ /** Removes a {@link GLEventListener} from this drawable. 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. */
+ public void removeGLEventListener(GLEventListener listener);
+
+ /**
+ * <p>
+ * Registers the usage of an animator, an {@link javax.media.opengl.GLAnimatorControl} implementation.
+ * The animator will be queried whether it's animating, ie periodically issuing {@link #display()} calls or not.</p><br>
+ * <p>
+ * This method shall be called by an animator implementation only,<br>
+ * e.g. {@link com.jogamp.opengl.util.Animator#add(javax.media.opengl.GLAutoDrawable)}, passing it's control implementation,<br>
+ * and {@link com.jogamp.opengl.util.Animator#remove(javax.media.opengl.GLAutoDrawable)}, passing <code>null</code>.</p><br>
+ * <p>
+ * Impacts {@link #display()} and {@link #invoke(boolean, GLRunnable)} semantics.</p><br>
+ *
+ * @param animator <code>null</code> reference indicates no animator is using
+ * this <code>GLAutoDrawable</code>,<br>
+ * a valid reference indicates an animator is using this <code>GLAutoDrawable</code>.
+ *
+ * @throws GLException if an animator is already registered.
+ * @see #display()
+ * @see #invoke(boolean, GLRunnable)
+ * @see javax.media.opengl.GLAnimatorControl
+ */
+ public abstract void setAnimator(GLAnimatorControl animatorControl) throws GLException;
+
+ /**
+ * @return the registered {@link javax.media.opengl.GLAnimatorControl} implementation, using this <code>GLAutoDrawable</code>.
+ *
+ * @see #setAnimator(javax.media.opengl.GLAnimatorControl)
+ * @see javax.media.opengl.GLAnimatorControl
+ */
+ public GLAnimatorControl getAnimator();
+
+ /**
+ * <p>
+ * Enqueues a one-shot {@link javax.media.opengl.GLRunnable},
+ * which will be executed with the next {@link #display()} call.</p>
+ * <p>
+ * If a {@link javax.media.opengl.GLAnimatorControl} is registered, or if it's not animating, the default situation,<br>
+ * or if the current thread is the animator thread,<br>
+ * a {@link #display()} call has to be issued after enqueue the <code>GLRunnable</code>.<br>
+ * No extra synchronization must be performed in case <code>wait</code> is true, since it is executed in the current thread.</p>
+ * <p>
+ * If {@link javax.media.opengl.GLAnimatorControl} is registered and is animating,<br>
+ * no call of {@link #display()} must be issued, since the animator thread will performs it.<br>
+ * If <code>wait</code> is true, the implementation must wait until the <code>GLRunnable</code> is executed.<br>
+ * </p><br>
+ *
+ * @see #setAnimator(javax.media.opengl.GLAnimatorControl)
+ * @see #display()
+ * @see javax.media.opengl.GLRunnable
+ */
+ public void invoke(boolean wait, GLRunnable glRunnable);
+
+ /** 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();
+
+ /**
+ * <p>
+ * Causes OpenGL rendering to be performed for this GLAutoDrawable
+ * in the following order:
+ * <ul>
+ * <li> Calling {@link GLEventListener#display display(..)} for all
+ * registered {@link GLEventListener}s. </li>
+ * <li> Executes all one-shot {@link javax.media.opengl.GLRunnable},
+ * enqueued via {@link #invoke(boolean, GLRunnable)}.</li>
+ * </ul></p>
+ * <p>
+ * May be called periodically by a running {@link javax.media.opengl.GLAnimatorControl} implementation,<br>
+ * which must register itself with {@link #setAnimator(javax.media.opengl.GLAnimatorControl)}.</p>
+ * <p>
+ * Called automatically by the window system toolkit upon receiving a repaint() request, <br>
+ * except an {@link javax.media.opengl.GLAnimatorControl} implementation {@link javax.media.opengl.GLAnimatorControl#isAnimating()}.</p>
+ * <p>
+ * 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.</p>
+ * <p>
+ * In case of a new generated OpenGL context,
+ * the implementation shall call {@link GLEventListener#init init(..)} for all
+ * registered {@link GLEventListener}s <i>before</i> making the
+ * actual {@link GLEventListener#display display(..)} calls,
+ * in case this has not been done yet.</p>
+ *
+ * @see #setAnimator(javax.media.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 onOrOff);
+
+ /** Indicates whether automatic buffer swapping is enabled for this
+ drawable. See {@link #setAutoSwapBufferMode}. */
+ public boolean getAutoSwapBufferMode();
+
+ /** 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);
+
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
new file mode 100644
index 000000000..90b320ed3
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -0,0 +1,347 @@
+/**
+ * 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 javax.media.opengl;
+
+import java.nio.*;
+
+/**
+ * <P>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.</P>
+ *
+ * <P> 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,
+ * <code>gl.isFunctionAvailable("glProgramStringARB")</code>. 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. </P>
+ *
+ * {@link #isExtensionAvailable} may also be used to determine whether
+ * a specific extension is available before calling the routines or
+ * using the functionality it exposes: for example,
+ * <code>gl.isExtensionAvailable("GL_ARB_vertex_program");</code>.
+ * 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,
+ * <code>gl.isExtensionAvailable("GL_VERSION_1_5");</code>.
+ *
+ * <P> Exceptions to the window system extension naming rules:
+ *
+ * <UL>
+ *
+ * <LI> The memory allocators for the NVidia vertex_array_range (VAR)
+ * extension, in particular <code>wglAllocateMemoryNV</code> /
+ * <code>glXAllocateMemoryNV</code> 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. </P>
+ *
+ * <LI> WGL_ARB_pbuffer, WGL_ARB_pixel_format, and other
+ * platform-specific pbuffer functionality; the availability of
+ * pbuffers can be queried on Windows, X11 and Mac OS X platforms by
+ * querying {@link #isExtensionAvailable} with an argument of
+ * "GL_ARB_pbuffer" or "GL_ARB_pixel_format".
+ *
+ * </UL> <P>
+ *
+ */
+public interface GLBase {
+
+ /**
+ * Indicates whether this GL object conforms to any of the common GL profiles.
+ * @return whether this GL object conforms to any of the common GL profiles
+ */
+ public boolean isGL();
+
+ /**
+ * Indicates whether this GL object conforms to the GL4 compatibility profile.
+ * The GL4 compatibility profile merges the GL2 profile and GL4 core profile.
+ * @return whether this GL object conforms to the GL4 compatibility profile
+ */
+ public boolean isGL4bc();
+
+ /**
+ * Indicates whether this GL object conforms to the GL4 core profile.
+ * The GL4 core profile reflects OpenGL versions greater or equal 3.1
+ * @return whether this GL object conforms to the GL4 core profile
+ */
+ public boolean isGL4();
+
+ /**
+ * Indicates whether this GL object conforms to the GL3 compatibility profile.
+ * The GL3 compatibility profile merges the GL2 profile and GL3 core profile.
+ * @return whether this GL object conforms to the GL3 compatibility profile
+ */
+ public boolean isGL3bc();
+
+ /**
+ * Indicates whether this GL object conforms to the GL3 core profile.
+ * The GL3 core profile reflects OpenGL versions greater or equal 3.1
+ * @return whether this GL object conforms to the GL3 core profile
+ */
+ public boolean isGL3();
+
+ /**
+ * Indicates whether this GL object conforms to the GL2 profile.
+ * The GL2 profile reflects OpenGL versions greater or equal 1.5
+ * @return whether this GL object conforms to the GL2 profile
+ */
+ public boolean isGL2();
+
+ /**
+ * Indicates whether this GL object conforms to the GLES1 profile.
+ * @return whether this GL object conforms to the GLES1 profile
+ */
+ public boolean isGLES1();
+
+ /**
+ * Indicates whether this GL object conforms to the GLES2 profile.
+ * @return whether this GL object conforms to the GLES2 profile
+ */
+ public boolean isGLES2();
+
+ /**
+ * Indicates whether this GL object conforms to one of the OpenGL ES compatible profiles.
+ * @return whether this GL object conforms to one of the OpenGL ES profiles
+ */
+ public boolean isGLES();
+
+ /**
+ * Indicates whether this GL object conforms to the GL2ES1 compatible profile.
+ * @return whether this GL object conforms to the GL2ES1 profile
+ */
+ public boolean isGL2ES1();
+
+ /**
+ * Indicates whether this GL object conforms to the GL2ES2 compatible profile.
+ * @return whether this GL object conforms to the GL2ES2 profile
+ */
+ public boolean isGL2ES2();
+
+ /**
+ * Indicates whether this GL object conforms to the GL2GL3 compatible profile.
+ * @return whether this GL object conforms to the GL2GL3 profile
+ */
+ public boolean isGL2GL3();
+
+ /** Indicates whether this GL object supports GLSL. */
+ public boolean hasGLSL();
+
+ /**
+ * Casts this object to the GL interface.
+ * @return this object cast to the GL interface
+ * @throws GLException if this GLObject is not a GL implementation
+ */
+ public GL getGL() throws GLException;
+
+ /**
+ * Casts this object to the GL4bc interface.
+ * @return this object cast to the GL4bc interface
+ * @throws GLException if this GLObject is not a GL4bc implementation
+ */
+ public GL4bc getGL4bc() throws GLException;
+
+ /**
+ * Casts this object to the GL4 interface.
+ * @return this object cast to the GL4 interface
+ * @throws GLException if this GLObject is not a GL4 implementation
+ */
+ public GL4 getGL4() throws GLException;
+
+ /**
+ * Casts this object to the GL3bc interface.
+ * @return this object cast to the GL3bc interface
+ * @throws GLException if this GLObject is not a GL3bc implementation
+ */
+ public GL3bc getGL3bc() throws GLException;
+
+ /**
+ * Casts this object to the GL3 interface.
+ * @return this object cast to the GL3 interface
+ * @throws GLException if this GLObject is not a GL3 implementation
+ */
+ public GL3 getGL3() throws GLException;
+
+ /**
+ * Casts this object to the GL2 interface.
+ * @return this object cast to the GL2 interface
+ * @throws GLException if this GLObject is not a GL2 implementation
+ */
+ public GL2 getGL2() throws GLException;
+
+ /**
+ * Casts this object to the GLES1 interface.
+ * @return this object cast to the GLES1 interface
+ * @throws GLException if this GLObject is not a GLES1 implementation
+ */
+ public GLES1 getGLES1() throws GLException;
+
+ /**
+ * Casts this object to the GLES2 interface.
+ * @return this object cast to the GLES2 interface
+ * @throws GLException if this GLObject is not a GLES2 implementation
+ */
+ public GLES2 getGLES2() throws GLException;
+
+ /**
+ * Casts this object to the GL2ES1 interface.
+ * @return this object cast to the GL2ES1 interface
+ * @throws GLException if this GLObject is not a GL2ES1 implementation
+ */
+ public GL2ES1 getGL2ES1() throws GLException;
+
+ /**
+ * Casts this object to the GL2ES2 interface.
+ * @return this object cast to the GL2ES2 interface
+ * @throws GLException if this GLObject is not a GL2ES2 implementation
+ */
+ public GL2ES2 getGL2ES2() throws GLException;
+
+ /**
+ * Casts this object to the GL2GL3 interface.
+ * @return this object cast to the GL2GL3 interface
+ * @throws GLException if this GLObject is not a GL2GL3 implementation
+ */
+ public GL2GL3 getGL2GL3() throws GLException;
+
+ /**
+ * Returns the GLProfile with which this GL object is associated.
+ * @return the GLProfile with which this GL object is associated
+ */
+ public GLProfile getGLProfile();
+
+ /**
+ * Returns the GLContext with which this GL object is associated.
+ * @return the GLContext with which this GL object is associated
+ */
+ 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
+ * <i>client</i>) and display (OpenGL <i>server</i>) configuration.<P>
+ * By "successfully" we mean that the function is both <i>callable</i>
+ * on the machine running the program and <i>available</i> on the current
+ * display.<P>
+ *
+ * In order to call a function successfully, the function must be both
+ * <i>callable</i> on the machine running the program and <i>available</i> 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. <P>
+ *
+ * A GL function is <i>callable</i> 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
+ * <i>client</i>) and display (OpenGL <i>server</i>) configuration.<P>
+ *
+ * @param glExtensionName the name of the OpenGL extension (e.g.,
+ * "GL_ARB_vertex_program").
+ */
+ public boolean isExtensionAvailable(String glExtensionName);
+
+ /** 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}. <br>
+
+ If the interval is not set by {@link #setSwapInterval} yet,
+ -1 is returned, indicating that the platforms default
+ is being used.
+
+ @see #setSwapInterval
+ */
+ public int getSwapInterval();
+
+ /**
+ * Returns an object through which platform-specific OpenGL extensions
+ * (EGL, GLX, WGL, etc.) may be accessed. The data type of the returned
+ * object and its associated capabilities are undefined. Most
+ * applications will never need to call this method. It is highly
+ * recommended that any applications which do call this method perform
+ * all accesses on the returned object reflectively to guard
+ * themselves against changes to the implementation.
+ */
+ public Object getPlatformGLExtensions();
+
+ /**
+ * Returns an object providing access to the specified OpenGL
+ * extension. This is intended to provide a mechanism for vendors who
+ * wish to provide access to new OpenGL extensions without changing
+ * the public API of the core package. For example, a user may request
+ * access to extension "GL_VENDOR_foo" and receive back an object
+ * which implements a vendor-specified interface which can call the
+ * OpenGL extension functions corresponding to that extension. It is
+ * up to the vendor to specify both the extension name and Java API
+ * for accessing it, including which class or interface contains the
+ * functions.
+ *
+ * <P>
+ *
+ * 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);
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
new file mode 100644
index 000000000..1ae9e40aa
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -0,0 +1,462 @@
+/*
+ * 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 javax.media.opengl;
+
+import javax.media.nativewindow.Capabilities;
+
+/** Specifies a set of OpenGL capabilities.<br>
+ At creation time of a {@link GLDrawable} using {@link GLDrawableFactory},
+ an instance of this class is passed,
+ describing the desired capabilities that a rendering context
+ must support, such as the OpenGL profile, color depth and whether stereo is enabled.<br>
+
+ The actual capabilites of created {@link GLDrawable}s are then reflected by their own
+ GLCapabilites instance, which can be queried with {@link GLDrawable#getGLCapabilities()}.<br>
+
+ It currently contains the minimal number of routines which allow
+ configuration on all supported window systems. */
+public class GLCapabilities extends Capabilities implements Cloneable, GLCapabilitiesImmutable {
+ private GLProfile glProfile = null;
+ private boolean pbuffer = false;
+ private boolean doubleBuffered = true;
+ private boolean stereo = false;
+ private boolean hardwareAccelerated = true;
+ private int depthBits = 16;
+ private int stencilBits = 0;
+ private int accumRedBits = 0;
+ private int accumGreenBits = 0;
+ private int accumBlueBits = 0;
+ private int accumAlphaBits = 0;
+ // Shift bits from PIXELFORMATDESCRIPTOR not present because they
+ // are unlikely to be supported on Windows anyway
+
+ // Support for full-scene antialiasing (FSAA)
+ private boolean sampleBuffers = false;
+ private int numSamples = 2;
+
+ // Bits for pbuffer creation
+ private boolean pbufferFloatingPointBuffers;
+ private boolean pbufferRenderToTexture;
+ private boolean pbufferRenderToTextureRectangle;
+
+ /** Creates a GLCapabilities object. All attributes are in a default state.
+ * @param glp GLProfile, or null for the default GLProfile
+ */
+ public GLCapabilities(GLProfile glp) {
+ glProfile = (null!=glp)?glp:GLProfile.getDefault(GLProfile.getDefaultDevice());
+ }
+
+ public Object cloneMutable() {
+ return clone();
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (RuntimeException e) {
+ throw new GLException(e);
+ }
+ }
+
+ public int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + this.glProfile.hashCode() ;
+ hash = ((hash << 5) - hash) + ( this.pbuffer ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.stereo ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.hardwareAccelerated ? 1 : 0 );
+ 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;
+ hash = ((hash << 5) - hash) + ( this.sampleBuffers ? 1 : 0 );
+ hash = ((hash << 5) - hash) + this.numSamples;
+ hash = ((hash << 5) - hash) + ( this.pbufferFloatingPointBuffers ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.pbufferRenderToTexture ? 1 : 0 );
+ hash = ((hash << 5) - hash) + ( this.pbufferRenderToTextureRectangle ? 1 : 0 );
+ return hash;
+ }
+
+ public boolean equals(Object obj) {
+ if(this == obj) { return true; }
+ if(!(obj instanceof GLCapabilitiesImmutable)) {
+ return false;
+ }
+ GLCapabilitiesImmutable other = (GLCapabilitiesImmutable)obj;
+ boolean res = super.equals(obj) &&
+ other.getGLProfile()==glProfile &&
+ other.isPBuffer()==pbuffer &&
+ 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 &&
+ other.getPbufferFloatingPointBuffers()==pbufferFloatingPointBuffers &&
+ other.getPbufferRenderToTexture()==pbufferRenderToTexture &&
+ other.getPbufferRenderToTextureRectangle()==pbufferRenderToTextureRectangle;
+ if(sampleBuffers) {
+ res = res && other.getNumSamples()==numSamples;
+ }
+ return res;
+ }
+
+ /** comparing hw/sw, stereo, multisample, stencil, RGBA and depth only */
+ public int compareTo(Object o) {
+ if ( ! ( o instanceof GLCapabilities ) ) {
+ Class c = (null != o) ? o.getClass() : null ;
+ throw new ClassCastException("Not a GLCapabilities object: " + c);
+ }
+
+ final GLCapabilities caps = (GLCapabilities) o;
+
+ if(hardwareAccelerated && !caps.hardwareAccelerated) {
+ return 1;
+ } else if(!hardwareAccelerated && caps.hardwareAccelerated) {
+ return -1;
+ }
+
+ if(stereo && !caps.stereo) {
+ return 1;
+ } else if(!stereo && caps.stereo) {
+ return -1;
+ }
+
+ final int ms = sampleBuffers ? numSamples : 0;
+ final int xms = caps.sampleBuffers ? caps.numSamples : 0;
+
+ if(ms > xms) {
+ return 1;
+ } else if( ms < xms ) {
+ return -1;
+ }
+
+ if(stencilBits > caps.stencilBits) {
+ return 1;
+ } else if(stencilBits < caps.stencilBits) {
+ return -1;
+ }
+
+ final int sc = super.compareTo(caps); // RGBA
+ if(0 != sc) {
+ return sc;
+ }
+
+ if(depthBits > caps.depthBits) {
+ return 1;
+ } else if(depthBits < caps.depthBits) {
+ return -1;
+ }
+
+ return 0; // they are equal: hw/sw, stereo, multisample, stencil, RGBA and depth
+ }
+
+ /** Returns the GL profile you desire or used by the drawable. */
+ public GLProfile getGLProfile() {
+ return glProfile;
+ }
+
+ /** Sets the GL profile you desire */
+ public void setGLProfile(GLProfile profile) {
+ glProfile=profile;
+ }
+
+ /** Indicates whether pbuffer is used/requested. */
+ public boolean isPBuffer() {
+ return pbuffer;
+ }
+
+ /**
+ * Enables or disables pbuffer usage.<br>
+ * If enabled, onscreen := false.
+ * Defaults to false.
+ */
+ public void setPBuffer(boolean onOrOff) {
+ if(onOrOff) {
+ setOnscreen(false);
+ }
+ pbuffer = onOrOff;
+ }
+
+ /**
+ * Sets whether the drawable surface supports onscreen.<br>
+ * If enabled, pbuffer := false.<br>
+ * Defaults to true.
+ */
+ public void setOnscreen(boolean onscreen) {
+ if(onscreen) {
+ setPBuffer(false);
+ }
+ super.setOnscreen(onscreen);
+ }
+
+ /** Indicates whether double-buffering is enabled. */
+ public boolean getDoubleBuffered() {
+ return doubleBuffered;
+ }
+
+ /** Enables or disables double buffering. */
+ public void setDoubleBuffered(boolean onOrOff) {
+ doubleBuffered = onOrOff;
+ }
+
+ /** Indicates whether stereo is enabled. */
+ public boolean getStereo() {
+ return stereo;
+ }
+
+ /** Enables or disables stereo viewing. */
+ public void setStereo(boolean onOrOff) {
+ stereo = onOrOff;
+ }
+
+ /** Indicates whether hardware acceleration is enabled. */
+ public boolean getHardwareAccelerated() {
+ return hardwareAccelerated;
+ }
+
+ /** Enables or disables hardware acceleration. */
+ public void setHardwareAccelerated(boolean onOrOff) {
+ hardwareAccelerated = onOrOff;
+ }
+
+ /** Returns the number of bits requested for the depth buffer. */
+ public int getDepthBits() {
+ return depthBits;
+ }
+
+ /** Sets the number of bits requested for the depth buffer. */
+ public void setDepthBits(int depthBits) {
+ this.depthBits = depthBits;
+ }
+
+ /** Returns the number of bits requested for the stencil buffer. */
+ public int getStencilBits() {
+ return stencilBits;
+ }
+
+ /** Sets the number of bits requested for the stencil buffer. */
+ public void setStencilBits(int stencilBits) {
+ this.stencilBits = stencilBits;
+ }
+
+ /** Returns 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 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(int accumRedBits) {
+ this.accumRedBits = accumRedBits;
+ }
+
+ /** Returns 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 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(int accumGreenBits) {
+ this.accumGreenBits = accumGreenBits;
+ }
+
+ /** Returns 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 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(int accumBlueBits) {
+ this.accumBlueBits = accumBlueBits;
+ }
+
+ /** Returns the number of bits requested 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. */
+ public 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(int accumAlphaBits) {
+ this.accumAlphaBits = accumAlphaBits;
+ }
+
+ /** Indicates whether sample buffers for full-scene antialiasing
+ (FSAA) should be allocated for this drawable. Defaults to
+ false. */
+ public void setSampleBuffers(boolean onOrOff) {
+ sampleBuffers = onOrOff;
+ }
+
+ /** Returns whether sample buffers for full-scene antialiasing
+ (FSAA) should be allocated for this drawable. Defaults to
+ false. */
+ public boolean getSampleBuffers() {
+ return sampleBuffers;
+ }
+
+ /** If sample buffers are enabled, indicates the number of buffers
+ to be allocated. Defaults to 2. */
+ public void setNumSamples(int numSamples) {
+ this.numSamples = numSamples;
+ }
+
+ /** Returns the number of sample buffers to be allocated if sample
+ buffers are enabled. Defaults to 2. */
+ public int getNumSamples() {
+ return numSamples;
+ }
+
+ /** For pbuffers only, indicates whether floating-point buffers
+ should be used if available. Defaults to false. */
+ public void setPbufferFloatingPointBuffers(boolean onOrOff) {
+ pbufferFloatingPointBuffers = onOrOff;
+ }
+
+ /** For pbuffers only, returns whether floating-point buffers should
+ be used if available. Defaults to false. */
+ public boolean getPbufferFloatingPointBuffers() {
+ return pbufferFloatingPointBuffers;
+ }
+
+ /** For pbuffers only, indicates whether the render-to-texture
+ extension should be used if available. Defaults to false. */
+ public void setPbufferRenderToTexture(boolean onOrOff) {
+ pbufferRenderToTexture = onOrOff;
+ }
+
+ /** For pbuffers only, returns whether the render-to-texture
+ extension should be used if available. Defaults to false. */
+ public boolean getPbufferRenderToTexture() {
+ return pbufferRenderToTexture;
+ }
+
+ /** For pbuffers only, indicates whether the
+ render-to-texture-rectangle extension should be used if
+ available. Defaults to false. */
+ public void setPbufferRenderToTextureRectangle(boolean onOrOff) {
+ pbufferRenderToTextureRectangle = onOrOff;
+ }
+
+ /** For pbuffers only, returns whether the render-to-texture
+ extension should be used. Defaults to false. */
+ public boolean getPbufferRenderToTextureRectangle() {
+ return pbufferRenderToTextureRectangle;
+ }
+
+ public StringBuffer toString(StringBuffer sink) {
+ if(null == sink) {
+ sink = new StringBuffer();
+ }
+
+ int samples = sampleBuffers ? numSamples : 0 ;
+
+ super.toString(sink);
+
+ sink.append(", accum-rgba ").append(accumRedBits).append("/").append(accumGreenBits).append("/").append(accumBlueBits).append("/").append(accumAlphaBits);
+ sink.append(", dp/st/ms: ").append(depthBits).append("/").append(stencilBits).append("/").append(samples);
+ if(doubleBuffered) {
+ sink.append(", dbl");
+ } else {
+ sink.append(", one");
+ }
+ if(stereo) {
+ sink.append(", stereo");
+ } else {
+ sink.append(", mono ");
+ }
+ if(hardwareAccelerated) {
+ sink.append(", hw, ");
+ } else {
+ sink.append(", sw, ");
+ }
+ sink.append(glProfile);
+ if(!isOnscreen()) {
+ if(pbuffer) {
+ sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
+ .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
+ .append(", float ").append(pbufferFloatingPointBuffers?1:0)
+ .append("]");
+ } else {
+ sink.append(", pixmap");
+ }
+ }
+
+ return sink;
+ }
+
+ /** Returns a textual representation of this GLCapabilities
+ object. */
+ public String toString() {
+ StringBuffer msg = new StringBuffer();
+ msg.append("GLCaps[");
+ toString(msg);
+ msg.append("]");
+ return msg.toString();
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/GLCapabilitiesChooser.java
new file mode 100644
index 000000000..73a77de27
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilitiesChooser.java
@@ -0,0 +1,56 @@
+/*
+ * 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 javax.media.opengl;
+
+import javax.media.nativewindow.CapabilitiesChooser;
+
+/** Provides a mechanism by which applications can customize the
+ window type selection for a given {@link GLCapabilities}.
+ Developers can implement this interface and pass an instance into
+ the appropriate method of {@link GLDrawableFactory}; the chooser
+ will be called during the OpenGL context creation process. Note
+ that this is only a marker interface; its signature is the same as
+ {@link CapabilitiesChooser}, but the array of {@link Capabilities}
+ objects passed to {@link #chooseCapabilities chooseCapabilities}
+ will actually be an array of {@link GLCapabilities}. */
+
+public interface GLCapabilitiesChooser extends CapabilitiesChooser {
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
new file mode 100644
index 000000000..a89aec080
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilitiesImmutable.java
@@ -0,0 +1,150 @@
+/**
+ * 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 javax.media.opengl;
+
+import com.jogamp.common.type.WriteCloneable;
+import javax.media.nativewindow.CapabilitiesImmutable;
+
+/**
+ * Specifies an immutable set of OpenGL capabilities.<br>
+ *
+ * @see javax.media.opengl.GLCapabilities
+ * @see javax.media.nativewindow.CapabilitiesImmutable
+ */
+public interface GLCapabilitiesImmutable extends WriteCloneable, CapabilitiesImmutable {
+
+ /**
+ * Returns the number of bits requested 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 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.
+ */
+ int getAccumBlueBits();
+
+ /**
+ * Returns 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.
+ */
+ int getAccumGreenBits();
+
+ /**
+ * Returns 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.
+ */
+ int getAccumRedBits();
+
+ /**
+ * Returns the number of bits requested for the depth buffer.
+ */
+ int getDepthBits();
+
+ /**
+ * Indicates whether double-buffering is enabled.
+ */
+ boolean getDoubleBuffered();
+
+ /**
+ * Returns the GL profile you desire or used by the drawable.
+ */
+ GLProfile getGLProfile();
+
+ /**
+ * Indicates whether hardware acceleration is enabled.
+ */
+ boolean getHardwareAccelerated();
+
+ /**
+ * Returns the number of sample buffers to be allocated if sample
+ * buffers are enabled. Defaults to 2.
+ */
+ int getNumSamples();
+
+ /**
+ * For pbuffers only, returns whether floating-point buffers should
+ * be used if available. Defaults to false.
+ */
+ boolean getPbufferFloatingPointBuffers();
+
+ /**
+ * For pbuffers only, returns whether the render-to-texture
+ * extension should be used if available. Defaults to false.
+ */
+ boolean getPbufferRenderToTexture();
+
+ /**
+ * For pbuffers only, returns whether the render-to-texture
+ * extension should be used. Defaults to false.
+ */
+ boolean getPbufferRenderToTextureRectangle();
+
+ /**
+ * Returns whether sample buffers for full-scene antialiasing
+ * (FSAA) should be allocated for this drawable. Defaults to
+ * false.
+ */
+ boolean getSampleBuffers();
+
+ /**
+ * Returns the number of bits requested for the stencil buffer.
+ */
+ int getStencilBits();
+
+ /**
+ * Indicates whether stereo is enabled.
+ */
+ boolean getStereo();
+
+ /**
+ * Indicates whether pbuffer is used/requested.
+ */
+ boolean isPBuffer();
+
+ Object cloneMutable();
+
+ @Override
+ boolean equals(Object obj);
+
+ @Override
+ int hashCode();
+
+ @Override
+ String toString();
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
new file mode 100644
index 000000000..b859dee00
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -0,0 +1,780 @@
+/*
+ * 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 javax.media.opengl;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import jogamp.opengl.Debug;
+
+/** Abstraction for an OpenGL rendering context. In order to perform
+ OpenGL rendering, a context must be "made current" on the current
+ thread. OpenGL rendering semantics specify that only one context
+ may be current on the current thread at any given time, and also
+ that a given context may be current on only one thread at any
+ given time. Because components can be added to and removed from
+ the component hierarchy at any time, it is possible that the
+ underlying OpenGL context may need to be destroyed and recreated
+ multiple times over the lifetime of a given component. This
+ process is handled by the implementation, and the GLContext
+ abstraction provides a stable object which clients can use to
+ refer to a given context. */
+public abstract class GLContext {
+ protected static final boolean DEBUG0 = Debug.debug("GLContext");
+
+ /** Indicates that the context was not made current during the last call to {@link #makeCurrent makeCurrent}. */
+ public static final int CONTEXT_NOT_CURRENT = 0;
+ /** Indicates that the context was made current during the last call to {@link #makeCurrent makeCurrent}. */
+ public static final int CONTEXT_CURRENT = 1;
+ /** Indicates that a newly-created context was made current during the last call to {@link #makeCurrent makeCurrent}. */
+ public static final int CONTEXT_CURRENT_NEW = 2;
+
+ /** <code>ARB_create_context</code> related: created via ARB_create_context */
+ protected static final int CTX_IS_ARB_CREATED = 1 << 0;
+ /** <code>ARB_create_context</code> related: compatibility profile */
+ protected static final int CTX_PROFILE_COMPAT = 1 << 1;
+ /** <code>ARB_create_context</code> related: core profile */
+ protected static final int CTX_PROFILE_CORE = 1 << 2;
+ /** <code>ARB_create_context</code> related: ES profile */
+ protected static final int CTX_PROFILE_ES = 1 << 3;
+ /** <code>ARB_create_context</code> related: flag forward compatible */
+ protected static final int CTX_OPTION_FORWARD = 1 << 4;
+ /** <code>ARB_create_context</code> related: not flag forward compatible */
+ protected static final int CTX_OPTION_ANY = 1 << 5;
+ /** <code>ARB_create_context</code> related: flag debug */
+ protected static final int CTX_OPTION_DEBUG = 1 << 6;
+
+ /** GLContext {@link com.jogamp.gluegen.runtime.ProcAddressTable} caching related: GL software implementation */
+ protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 0;
+ /** GLContext {@link com.jogamp.gluegen.runtime.ProcAddressTable} caching related: GL hardware implementation */
+ protected static final int CTX_IMPL_ACCEL_HARD = 1 << 1;
+
+ private static ThreadLocal currentContext = new ThreadLocal();
+
+ private HashMap/*<int, Object>*/ attachedObjects = new HashMap();
+
+ /** The underlying native OpenGL context */
+ protected long contextHandle;
+
+ protected GLContext() {
+ resetStates();
+ }
+
+ protected int ctxMajorVersion;
+ protected int ctxMinorVersion;
+ protected int ctxOptions;
+ protected String ctxVersionString;
+
+ protected void resetStates() {
+ ctxMajorVersion=-1;
+ ctxMinorVersion=-1;
+ ctxOptions=0;
+ ctxVersionString=null;
+ if(null!=attachedObjects) {
+ attachedObjects.clear();
+ }
+ contextHandle=0;
+ }
+
+ /**
+ * Returns the GLDrawable to which this context may be used to
+ * draw.
+ */
+ public abstract GLDrawable getGLDrawable();
+
+ /**
+ * Return availability of GL read drawable.
+ * @return true if a GL read drawable is supported with your driver, otherwise false.
+ */
+ public abstract boolean isGLReadDrawableAvailable();
+
+ /**
+ * Set the read GLDrawable for read framebuffer operations.<br>
+ * The caller should query if this feature is supported via {@link #isGLReadDrawableAvailable()}.
+ *
+ * @param read the read GLDrawable for read framebuffer operations.
+ * If null is passed, the default write drawable will be set.
+ *
+ * @throws GLException in case a read drawable is not supported
+ * and the given drawable is not null and not equal to the internal write drawable.
+ *
+ * @see #isGLReadDrawableAvailable()
+ * @see #getGLReadDrawable()
+ */
+ public abstract void setGLReadDrawable(GLDrawable read);
+
+ /**
+ * Returns the read GLDrawable this context uses for read framebuffer operations.
+ * @see #isGLReadDrawableAvailable()
+ * @see #setGLReadDrawable(javax.media.opengl.GLDrawable)
+ */
+ public abstract GLDrawable getGLReadDrawable();
+
+ /**
+ * Makes this GLContext current on the calling thread.
+ *
+ * There are two return values that indicate success and one that
+ * indicates failure. A return value of CONTEXT_CURRENT_NEW
+ * indicates that that context has been made current, and that
+ * this is the first time this context has been made current, or
+ * that the state of the underlying context or drawable may have
+ * changed since the last time this context was made current. In
+ * this case, the application may wish to initialize the state. A
+ * return value of CONTEXT_CURRENT indicates that the context has
+ * been made currrent, 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 CONTEXT_NOT_CURRENT is returned.
+ *
+ * If the context is in use by another thread at the time of the
+ * call, then if isSynchronized() is true the call will
+ * block. If isSynchronized() is false, an exception will be
+ * thrown and the context will remain current on the other thread.
+ *
+ * @return CONTEXT_CURRENT if the context was successfully made current
+ * @return CONTEXT_CURRENT_NEW if the context was successfully made
+ * current, but need to be initialized.
+ *
+ * @return CONTEXT_NOT_CURRENT if the context could not be made current.
+ *
+ * @throws GLException if synchronization is disabled and the
+ * context is current on another thread, or because the context
+ * could not be created or made current due to non-recoverable,
+ * window system-specific errors.
+ */
+ public abstract int makeCurrent() throws GLException;
+
+ /**
+ * Releases control of this GLContext from the current thread.
+ *
+ * @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. The <code>mask</code>
+ * parameter indicates which groups of state variables are to be
+ * copied. <code>mask</code> contains the bitwise OR of the same
+ * symbolic names that are passed to the GL command {@link
+ * GL#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. <P>
+ *
+ * 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}. <P>
+ *
+ * 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 {
+ GLContext glc = getCurrent();
+ if(null==glc) {
+ throw new GLException("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 (GLContext) currentContext.get();
+ }
+
+ /**
+ * @return true if this GLContext is current on this thread
+ */
+ public final boolean isCurrent() {
+ return getCurrent() == this ;
+ }
+
+ /**
+ * 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(GLContext cur) {
+ currentContext.set(cur);
+ }
+
+ /**
+ * Destroys this OpenGL context and frees its associated
+ * resources. The context should have been released before this
+ * method is called.
+ */
+ public abstract void destroy();
+
+ /**
+ * Returns true if 'makeCurrent' will exhibit synchronized behavior.
+ */
+ public abstract boolean isSynchronized();
+
+ /**
+ * Determines whether 'makeCurrent' will exhibit synchronized behavior.
+ */
+ public abstract void setSynchronized(boolean isSynchronized);
+
+ /**
+ * Returns the GL pipeline object for this GLContext.
+ *
+ * @return the aggregated GL instance, or null if this context was not yet made current.
+ */
+ public abstract GL getGL();
+
+ /**
+ * Sets the GL pipeline object for this GLContext.
+ *
+ * @return the set GL pipeline or null if not successful
+ */
+ public abstract GL setGL(GL gl);
+
+ /**
+ * Returns the native GL context handle
+ */
+ public final long getHandle() { return contextHandle; }
+
+ /**
+ * Indicates whether the underlying OpenGL context has been created.
+ */
+ public final boolean isCreated() {
+ return 0 != contextHandle;
+ }
+
+ /**
+ * Returns the attached user object for the given name to this GLContext.
+ */
+ public final Object getAttachedObject(int name) {
+ return attachedObjects.get(new Integer(name));
+ }
+
+ /**
+ * Returns the attached user object for the given name to this GLContext.
+ */
+ public final Object getAttachedObject(String name) {
+ return attachedObjects.get(name);
+ }
+
+ /**
+ * Sets the attached user object for the given name to this GLContext.
+ * Returns the previously set object or null.
+ */
+ public final Object putAttachedObject(int name, Object obj) {
+ return attachedObjects.put(new Integer(name), obj);
+ }
+
+ /**
+ * Sets the attached user object for the given name to this GLContext.
+ * Returns the previously set object or null.
+ */
+ public final Object putAttachedObject(String name, Object obj) {
+ return attachedObjects.put(name, obj);
+ }
+
+ /**
+ * Classname, GL, GLDrawable
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName());
+ sb.append(" [");
+ this.append(sb);
+ sb.append("] ");
+ return sb.toString();
+ }
+
+ public final StringBuffer append(StringBuffer sb) {
+ sb.append("OpenGL ");
+ sb.append(getGLVersionMajor());
+ sb.append(".");
+ sb.append(getGLVersionMinor());
+ sb.append(", options 0x");
+ sb.append(Integer.toHexString(ctxOptions));
+ sb.append(", ");
+ sb.append(getGLVersion());
+ sb.append(", handle ");
+ sb.append(toHexString(contextHandle));
+ sb.append(", ");
+ sb.append(getGL());
+ if(getGLDrawable()!=getGLReadDrawable()) {
+ sb.append(",\n\tRead Drawable : ");
+ sb.append(getGLReadDrawable());
+ sb.append(",\n\tWrite Drawable: ");
+ sb.append(getGLDrawable());
+ } else {
+ sb.append(",\n\tDrawable: ");
+ sb.append(getGLDrawable());
+ }
+ return sb;
+ }
+
+ /** Returns a non-null (but possibly empty) string containing the
+ space-separated list of available platform-dependent (e.g., WGL,
+ GLX) extensions. Can only be called while this context is
+ current. */
+ public abstract String getPlatformExtensionsString();
+
+ /** Returns a non-null (but possibly empty) string containing the
+ space-separated list of available extensions.
+ Can only be called while this context is current.
+ This is equivalent to
+ {@link javax.media.opengl.GL#glGetString(int) glGetString}({@link javax.media.opengl.GL#GL_EXTENSIONS GL_EXTENSIONS})
+ */
+ public abstract String getGLExtensionsString();
+
+ public final int getGLVersionMajor() { return ctxMajorVersion; }
+ public final int getGLVersionMinor() { return ctxMinorVersion; }
+ public final boolean isGLCompatibilityProfile() { return ( 0 != ( CTX_PROFILE_COMPAT & ctxOptions ) ); }
+ public final boolean isGLCoreProfile() { return ( 0 != ( CTX_PROFILE_CORE & ctxOptions ) ); }
+ public final boolean isGLEmbeddedProfile() { return ( 0 != ( CTX_PROFILE_ES & ctxOptions ) ); }
+ public final boolean isGLForwardCompatible() { return ( 0 != ( CTX_OPTION_FORWARD & ctxOptions ) ); }
+ public final boolean isCreatedWithARBMethod() { return ( 0 != ( CTX_IS_ARB_CREATED & ctxOptions ) ); }
+
+ /**
+ * Returns a valid OpenGL version string, ie<br>
+ * <pre>
+ * major.minor ([option]?[options,]*) - gl-version
+ * </pre><br>
+ *
+ * <ul>
+ * <li> options
+ * <ul>
+ * <li> <code>old</code> refers to the non ARB_create_context created context</li>
+ * <li> <code>new</code> refers to the ARB_create_context created context</li>
+ * <li> <code>compatible profile</code></li>
+ * <li> <code>core profile</code></li>
+ * <li> <code>forward compatible</code></li>
+ * <li> <code>any</code> refers to the non forward compatible context</li>
+ * <li> <code>ES</code> refers to the GLES context variant</li>
+ * </ul></li>
+ * <li> <i>gl-version</i> the GL_VERSION string</li>
+ * </ul>
+ *
+ * e.g.:
+ * <table border="0">
+ * <tr> <td></td> <td></td> </tr>
+ * <tr>
+ * <td>row 2, cell 1</td>
+ * <td>row 2, cell 2</td>
+ * </tr>
+ * </table>
+ *
+ * <table border="0">
+ * <tr><td></td> <td>ES2</td> <td><code>2.0 (ES, any, new) - 2.0 ES Profile</code></td></tr>
+ * <tr><td>ATI</td><td>GL2</td> <td><code>3.0 (compatibility profile, any, new) - 3.2.9704 Compatibility Profile Context</code></td></tr>
+ * <tr><td>ATI</td><td>GL3</td> <td><code>3.3 (core profile, any, new) - 1.4 (3.2.9704 Compatibility Profile Context)</code></td></tr>
+ * <tr><td>ATI</td><td>GL3bc</td><td><code>3.3 (compatibility profile, any, new) - 1.4 (3.2.9704 Compatibility Profile Context)</code></td></tr>
+ * <tr><td>NV</td><td>GL2</td> <td><code>3.0 (compatibility profile, any, new) - 3.0.0 NVIDIA 195.36.07.03</code></td></tr>
+ * <tr><td>NV</td><td>GL3</td> <td><code>3.3 (core profile, any, new) - 3.3.0 NVIDIA 195.36.07.03</code></td></tr>
+ * <tr><td>NV</td><td>GL3bc</td> <td><code>3.3 (compatibility profile, any, new) - 3.3.0 NVIDIA 195.36.07.03</code></td></tr>
+ * </table>
+ */
+ public final String getGLVersion() {
+ return ctxVersionString;
+ }
+
+ public final boolean isGL4bc() {
+ return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & CTX_PROFILE_COMPAT);
+ }
+
+ public final boolean isGL4() {
+ return ctxMajorVersion>=4 && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
+ }
+
+ public final boolean isGL3bc() {
+ return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+ && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & CTX_PROFILE_COMPAT);
+ }
+
+ public final boolean isGL3() {
+ return ( ctxMajorVersion>3 || ctxMajorVersion==3 && ctxMinorVersion>=1 )
+ && 0 != (ctxOptions & CTX_IS_ARB_CREATED)
+ && 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE));
+ }
+
+ public final boolean isGL2() {
+ return ctxMajorVersion>=1 && 0!=(ctxOptions & CTX_PROFILE_COMPAT);
+ }
+
+ public final boolean isGL2GL3() {
+ return isGL2() || isGL3();
+ }
+
+ public final boolean isGLES1() {
+ return ctxMajorVersion==1 && 0!=(ctxOptions & CTX_PROFILE_ES);
+ }
+
+ public final boolean isGLES2() {
+ return ctxMajorVersion==2 && 0!=(ctxOptions & CTX_PROFILE_ES);
+ }
+
+ public final boolean isGLES() {
+ return isGLEmbeddedProfile();
+ }
+
+ public final boolean isGL2ES1() {
+ return isGL2() || isGLES1() ;
+ }
+
+ public final boolean isGL2ES2() {
+ return isGL2GL3() || isGLES2() ;
+ }
+
+ public final boolean hasGLSL() {
+ return isGL2ES2() ;
+ }
+
+ public static final int GL_VERSIONS[][] = {
+ /* 0.*/ { -1 },
+ /* 1.*/ { 0, 1, 2, 3, 4, 5 },
+ /* 2.*/ { 0, 1 },
+ /* 3.*/ { 0, 1, 2, 3 },
+ /* 4.*/ { 0, 1 } };
+
+ public static final int getMaxMajor() {
+ return GL_VERSIONS.length-1;
+ }
+
+ public static final int getMaxMinor(int major) {
+ if(1>major || major>=GL_VERSIONS.length) return -1;
+ return GL_VERSIONS[major].length-1;
+ }
+
+ public static final boolean isValidGLVersion(int major, int minor) {
+ if(1>major || major>=GL_VERSIONS.length) return false;
+ if(0>minor || minor>=GL_VERSIONS[major].length) return false;
+ return true;
+ }
+
+ public static final boolean decrementGLVersion(int major[], int minor[]) {
+ if(null==major || major.length<1 ||null==minor || minor.length<1) {
+ throw new GLException("invalid array arguments");
+ }
+ int m = major[0];
+ int n = minor[0];
+ if(!isValidGLVersion(m, n)) return false;
+
+ // decrement ..
+ n -= 1;
+ if(n < 0) {
+ m -= 1;
+ n = GL_VERSIONS[m].length-1;
+ }
+ if(!isValidGLVersion(m, n)) return false;
+ major[0]=m;
+ minor[0]=n;
+
+ return true;
+ }
+
+ protected static int compose8bit(int one, int two, int three, int four) {
+ return ( ( one & 0x000000FF ) << 24 ) |
+ ( ( two & 0x000000FF ) << 16 ) |
+ ( ( three & 0x000000FF ) << 8 ) |
+ ( ( four & 0x000000FF ) ) ;
+ }
+
+ protected static int getComposed8bit(int bits32, int which ) {
+ switch (which) {
+ case 1: return ( bits32 & 0xFF000000 ) >> 24 ;
+ case 2: return ( bits32 & 0x00FF0000 ) >> 16 ;
+ case 3: return ( bits32 & 0x0000FF00 ) >> 8 ;
+ case 4: return ( bits32 & 0xFF0000FF ) ;
+ }
+ throw new GLException("argument which out of range: "+which);
+ }
+
+ protected static String composed8BitToString(int bits32, boolean hex1, boolean hex2, boolean hex3, boolean hex4) {
+ int a = getComposed8bit(bits32, 1);
+ int b = getComposed8bit(bits32, 2);
+ int c = getComposed8bit(bits32, 3);
+ int d = getComposed8bit(bits32, 4);
+ return "["+toString(a, hex1)+", "+toString(b, hex2)+", "+toString(c, hex3)+", "+toString(d, hex4)+"]";
+ }
+
+ private static void validateProfileBits(int bits, 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(javax.media.nativewindow.AbstractGraphicsDevice, int, int)
+ */
+ protected static /*final*/ HashMap/*<DeviceVersionAvailableKey, Integer>*/ deviceVersionAvailable = new HashMap();
+
+ /**
+ * @see #getUniqueDeviceString(javax.media.nativewindow.AbstractGraphicsDevice)
+ */
+ private static /*final*/ HashSet/*<UniqueDeviceString>*/ deviceVersionsAvailableSet = new HashSet();
+
+ protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) {
+ return device.getUniqueID() + "-" + toHexString(compose8bit(major, profile, 0, 0));
+ }
+
+ protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ synchronized ( deviceVersionsAvailableSet ) {
+ return deviceVersionsAvailableSet.contains(device.getUniqueID());
+ }
+ }
+
+ protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ synchronized ( deviceVersionsAvailableSet ) {
+ String devKey = device.getUniqueID();
+ if ( deviceVersionsAvailableSet.contains(devKey) ) {
+ throw new InternalError("Already set: "+devKey);
+ }
+ deviceVersionsAvailableSet.add(devKey);
+ if (DEBUG0) {
+ String msg = getThreadName() + ": !!! createContextARB: SET mappedVersionsAvailableSet "+devKey;
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ System.err.println(msg);
+ }
+ }
+ }
+
+ /**
+ * Called by {@link jogamp.opengl.GLContextImpl#createContextARBMapVersionsAvailable} not intended to be used by
+ * implementations. However, if {@link #createContextARB} is not being used within
+ * {@link javax.media.opengl.GLDrawableFactory#getOrCreateSharedContext(javax.media.nativewindow.AbstractGraphicsDevice)},
+ * GLProfile has to map the available versions.
+ *
+ * @param reqMajor 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 old mapped value
+ *
+ * @see #createContextARBMapVersionsAvailable
+ */
+ protected static Integer mapAvailableGLVersion(AbstractGraphicsDevice device,
+ int reqMajor, int profile, int resMajor, int resMinor, int resCtp)
+ {
+ validateProfileBits(profile, "profile");
+ validateProfileBits(resCtp, "resCtp");
+
+ String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ Integer val = new Integer(compose8bit(resMajor, resMinor, resCtp, 0));
+ synchronized(deviceVersionAvailable) {
+ val = (Integer) deviceVersionAvailable.put( key, val );
+ }
+ return val;
+ }
+
+ protected static Integer getAvailableGLVersion(AbstractGraphicsDevice device, int reqMajor, int profile) {
+ String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ Integer val;
+ synchronized(deviceVersionAvailable) {
+ val = (Integer) deviceVersionAvailable.get( key );
+ }
+ 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(AbstractGraphicsDevice device,
+ int reqMajor, int reqProfile, int[] major, int minor[], int ctp[]) {
+
+ Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile);
+ if(null==valI) {
+ return false;
+ }
+
+ int val = valI.intValue();
+
+ if(null!=major) {
+ major[0] = getComposed8bit(val, 1);
+ }
+ if(null!=minor) {
+ minor[0] = getComposed8bit(val, 2);
+ }
+ if(null!=ctp) {
+ ctp[0] = getComposed8bit(val, 3);
+ }
+ return true;
+ }
+
+ /**
+ * @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}
+ */
+ public static boolean isGLVersionAvailable(AbstractGraphicsDevice device, int major, int profile) {
+ return null != getAvailableGLVersion(device, major, profile);
+ }
+
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
+ }
+
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
+ }
+
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
+ }
+
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
+ }
+
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
+ }
+
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
+ }
+
+ public static boolean isGL2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT);
+ }
+
+ /**
+ * @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}
+ */
+ public static String getAvailableGLVersionAsString(AbstractGraphicsDevice device, int major, int profile) {
+ int _major[] = { 0 };
+ int _minor[] = { 0 };
+ int _ctp[] = { 0 };
+ if(getAvailableGLVersion(device, major, profile, _major, _minor, _ctp)) {
+ return getGLVersion(_major[0], _minor[0], _ctp[0], null);
+ }
+ return null;
+ }
+
+ public static String getGLVersion(int major, int minor, int ctp, String gl_version) {
+ boolean needColon = false;
+ StringBuffer sb = new StringBuffer();
+ sb.append(major);
+ sb.append(".");
+ sb.append(minor);
+ sb.append(" (");
+ needColon = appendString(sb, "ES", needColon, 0 != ( CTX_PROFILE_ES & ctp ));
+ needColon = appendString(sb, "compatibility profile", needColon, 0 != ( CTX_PROFILE_COMPAT & ctp ));
+ needColon = appendString(sb, "core profile", needColon, 0 != ( CTX_PROFILE_CORE & ctp ));
+ needColon = appendString(sb, "forward compatible", needColon, 0 != ( CTX_OPTION_FORWARD & ctp ));
+ needColon = appendString(sb, "any", needColon, 0 != ( CTX_OPTION_ANY & ctp ));
+ needColon = appendString(sb, "new", needColon, 0 != ( CTX_IS_ARB_CREATED & ctp ));
+ needColon = appendString(sb, "old", needColon, 0 == ( CTX_IS_ARB_CREATED & ctp ));
+ sb.append(")");
+ if(null!=gl_version) {
+ sb.append(" - ");
+ sb.append(gl_version);
+ }
+ return sb.toString();
+ }
+
+ protected static String toString(int val, boolean hex) {
+ if(hex) {
+ return "0x" + Integer.toHexString(val);
+ }
+ return String.valueOf(val);
+ }
+
+ protected static String toHexString(int hex) {
+ return "0x" + Integer.toHexString(hex);
+ }
+
+ protected static String toHexString(long hex) {
+ return "0x" + Long.toHexString(hex);
+ }
+
+ private static boolean appendString(StringBuffer sb, String string, boolean needColon, 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/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java
new file mode 100644
index 000000000..f4cd77059
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java
@@ -0,0 +1,175 @@
+/*
+ * 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 javax.media.opengl;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.NativeSurface;
+
+
+/** 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 {
+ /**
+ * Creates a new context for drawing to this drawable that will
+ * optionally share display lists and other server-side OpenGL
+ * objects with the specified GLContext. <P>
+ *
+ * The GLContext <code>share</code> 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 on
+ * <a href="../../../overview-summary.html#SHARING">context sharing</a>.
+ */
+ public GLContext createContext(GLContext shareWith);
+
+ /**
+ * Indicates to on-screen GLDrawable implementations whether the
+ * underlying window has been created and can be drawn into. End
+ * users do not need to call this method; it is not necessary to
+ * call <code>setRealized</code> on a GLCanvas, a GLJPanel, or a
+ * GLPbuffer, as these perform the appropriate calls on their
+ * underlying GLDrawables internally.
+ *
+ * <P>
+ *
+ * Developers implementing new OpenGL components for various window
+ * toolkits need to call this method against GLDrawables obtained
+ * from the GLDrawableFactory via the {@link
+ * GLDrawableFactory#getGLDrawable
+ * GLDrawableFactory.getGLDrawable()} method. It must typically be
+ * called with an argument of <code>true</code> when the component
+ * associated with the GLDrawable is realized and with an argument
+ * of <code>false</code> just before the component is unrealized.
+ * For the AWT, this means calling <code>setRealized(true)</code> in
+ * the <code>addNotify</code> method and with an argument of
+ * <code>false</code> in the <code>removeNotify</code> method.
+ *
+ * <P>
+ *
+ * <code>GLDrawable</code> implementations should handle multiple
+ * cycles of <code>setRealized(true)</code> /
+ * <code>setRealized(false)</code> 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 <CODE>GLDrawable</CODE> object associated with a
+ * particular component is intended to be similarly persistent. A
+ * <CODE>GLDrawable</CODE> is intended to be created for a given
+ * component when it is constructed and live as long as that
+ * component. <code>setRealized</code> allows the
+ * <code>GLDrawable</code> to re-initialize and destroy any
+ * associated resources as the component becomes realized and
+ * unrealized, respectively.
+ *
+ * <P>
+ *
+ * With an argument of <code>true</code>,
+ * the minimum implementation shall call
+ * {@link NativeSurface#lockSurface() NativeSurface's lockSurface()} and if successfull:
+ * <ul>
+ * <li> Update the {@link GLCapabilities}, which are associated with
+ * the attached {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.</li>
+ * <li> Release the lock with {@link NativeSurface#unlockSurface() NativeSurface's unlockSurface()}.</li>
+ * </ul><br>
+ * This is important since {@link NativeSurface#lockSurface() NativeSurface's lockSurface()}
+ * ensures resolving the window/surface handles, and the drawable's {@link GLCapabilities}
+ * might have changed.
+ *
+ * <P>
+ *
+ * Calling this method has no other effects. For example, if
+ * <code>removeNotify</code> 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.
+ */
+ public void setRealized(boolean realized);
+
+ /** @return true if this drawable is realized, otherwise false */
+ public boolean isRealized();
+
+ /** Returns the current width of this GLDrawable. */
+ public int getWidth();
+
+ /** Returns the current height of this GLDrawable. */
+ public int getHeight();
+
+ /** Swaps the front and back buffers of this drawable. For {@link
+ GLAutoDrawable} implementations, when automatic buffer swapping
+ is enabled (as is the default), this method is called
+ automatically and should not be called by the end user. */
+ public void swapBuffers() throws GLException;
+
+ /** Fetches the {@link GLCapabilitiesImmutable} corresponding to the chosen
+ OpenGL capabilities (pixel format / visual / GLProfile) for this drawable.<br>
+ 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. <br>
+ 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 A copy of the queried object.
+ */
+ public GLCapabilitiesImmutable getChosenGLCapabilities();
+
+ /** Fetches the {@link GLProfile} for this drawable.
+ Returns the GLProfile object, no copy.
+ */
+ public GLProfile getGLProfile();
+
+ public NativeSurface getNativeSurface();
+
+ /**
+ * This is the GL/Windowing drawable handle.<br>
+ * It is usually the {@link javax.media.nativewindow.NativeSurface#getSurfaceHandle()},
+ * ie the native surface handle of the underlying windowing toolkit.<br>
+ * However, on X11/GLX this reflects a GLXDrawable, which represents a GLXWindow, GLXPixmap, or GLXPbuffer.<br>
+ * On EGL, this represents the EGLSurface.<br>
+ */
+ public long getHandle();
+
+ public GLDrawableFactory getFactory();
+
+ public String toString();
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
new file mode 100644
index 000000000..73b2b3823
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -0,0 +1,554 @@
+/*
+ * 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 javax.media.opengl;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jogamp.common.JogampRuntimeException;
+import jogamp.common.Debug;
+import com.jogamp.common.util.ReflectionUtil;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ProxySurface;
+
+/** <P> Provides a virtual machine- and operating system-independent
+ mechanism for creating {@link GLDrawable}s. </P>
+
+ <P> The {@link javax.media.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. </P>
+
+ <P> 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 <code>null</code> 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 javax.media.opengl.awt.GLCanvas} or {@link
+ javax.media.opengl.awt.GLJPanel} if the capabilities can not be met.<br>
+ {@link javax.media.opengl.GLPbuffer} are always
+ created immediately and their creation will fail with a
+ {@link javax.media.opengl.GLException} if errors occur. </P>
+
+ <P> The concrete GLDrawableFactory subclass instantiated by {@link
+ #getFactory getFactory} can be changed by setting the system
+ property <code>opengl.factory.class.name</code> to the
+ fully-qualified name of the desired class. </P>
+*/
+
+public abstract class GLDrawableFactory {
+
+ private static final GLDrawableFactory eglFactory;
+ private static final GLDrawableFactory nativeOSFactory;
+ private static final String nativeOSType;
+ static final String macosxFactoryClassNameCGL = "jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory";
+ static final String macosxFactoryClassNameAWTCGL = "jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory";
+
+ protected static ArrayList/*<GLDrawableFactoryImpl>*/ glDrawableFactories = new ArrayList();
+
+ // Shutdown hook mechanism for the factory
+ private static boolean factoryShutdownHookRegistered = false;
+ private static Thread factoryShutdownHook = null;
+
+ /**
+ * Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
+ */
+ static {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ registerFactoryShutdownHook();
+ return null;
+ }
+ });
+
+ nativeOSType = NativeWindowFactory.getNativeWindowType(true);
+
+ GLDrawableFactory tmp = null;
+ String factoryClassName = Debug.getProperty("jogl.gldrawablefactory.class.name", true, AccessController.getContext());
+ ClassLoader cl = GLDrawableFactory.class.getClassLoader();
+ if (null == factoryClassName) {
+ if ( nativeOSType.equals(NativeWindowFactory.TYPE_X11) ) {
+ factoryClassName = "jogamp.opengl.x11.glx.X11GLXDrawableFactory";
+ } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_WINDOWS) ) {
+ factoryClassName = "jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory";
+ } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_MACOSX) ) {
+ if(ReflectionUtil.isClassAvailable(macosxFactoryClassNameAWTCGL, cl)) {
+ factoryClassName = macosxFactoryClassNameAWTCGL;
+ } else {
+ factoryClassName = macosxFactoryClassNameCGL;
+ }
+ } else {
+ // may use egl*Factory ..
+ if (GLProfile.DEBUG) {
+ System.err.println("GLDrawableFactory.static - No native OS Factory for: "+nativeOSType+"; May use EGLDrawableFactory, if available." );
+ }
+ }
+ }
+ if (null != factoryClassName) {
+ if (GLProfile.DEBUG) {
+ System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nativeOSType+": "+factoryClassName);
+ }
+ try {
+ tmp = (GLDrawableFactory) ReflectionUtil.createInstance(factoryClassName, cl);
+ } catch (JogampRuntimeException jre) {
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName);
+ jre.printStackTrace();
+ }
+ }
+ }
+ nativeOSFactory = tmp;
+
+ tmp = null;
+ try {
+ tmp = (GLDrawableFactory) ReflectionUtil.createInstance("jogamp.opengl.egl.EGLDrawableFactory", cl);
+ } catch (JogampRuntimeException jre) {
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available");
+ jre.printStackTrace();
+ }
+ }
+ eglFactory = tmp;
+ }
+
+ private static synchronized void registerFactoryShutdownHook() {
+ if (factoryShutdownHookRegistered) {
+ return;
+ }
+ factoryShutdownHook = new Thread(new Runnable() {
+ public void run() {
+ GLDrawableFactory.shutdownImpl();
+ }
+ });
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ Runtime.getRuntime().addShutdownHook(factoryShutdownHook);
+ return null;
+ }
+ });
+ factoryShutdownHookRegistered = true;
+ }
+
+ private static synchronized void unregisterFactoryShutdownHook() {
+ if (!factoryShutdownHookRegistered) {
+ return;
+ }
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ Runtime.getRuntime().removeShutdownHook(factoryShutdownHook);
+ return null;
+ }
+ });
+ factoryShutdownHookRegistered = false;
+ }
+
+ private static void shutdownImpl() {
+ synchronized(glDrawableFactories) {
+ for(int i=0; i<glDrawableFactories.size(); i++) {
+ GLDrawableFactory factory = (GLDrawableFactory) glDrawableFactories.get(i);
+ factory.shutdownInstance();
+ }
+ glDrawableFactories.clear();
+ }
+ }
+
+ protected static void shutdown() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ unregisterFactoryShutdownHook();
+ return null;
+ }
+ });
+ shutdownImpl();
+ }
+
+ private AbstractGraphicsDevice defaultSharedDevice = null;
+
+ protected GLDrawableFactory() {
+ synchronized(glDrawableFactories) {
+ glDrawableFactories.add(this);
+ }
+ }
+
+ protected void enterThreadCriticalZone() {};
+ protected void leaveThreadCriticalZone() {};
+
+ protected abstract void shutdownInstance();
+
+ /**
+ * Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection},
+ * {@link AbstractGraphicsDevice#getUnitID() unit ID} and {@link AbstractGraphicsDevice#getUniqueID() unique ID name}. for this factory<br>
+ * The implementation must return a non <code>null</code> default device, which must not be opened, ie. it's native handle is <code>null</code>.
+ * @return the default shared device for this factory, eg. :0.0 on X11 desktop.
+ */
+ public abstract AbstractGraphicsDevice getDefaultDevice();
+
+ /**
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @return true if the device is compatible with this factory, ie. if it can be used for creation. Otherwise false.
+ */
+ 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");
+ }
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.validateDevice: using default device : "+device);
+ }
+ } else if( !getIsDeviceCompatible(device) ) {
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.validateDevice: device not compatible : "+device);
+ }
+ return null;
+ }
+ return device;
+ }
+
+ /**
+ * Returns true if a shared context is already mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
+ * or if a new shared context could be created and mapped. Otherwise return false.<br>
+ * Creation of the shared context is tried only once.
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ */
+ public final boolean getIsSharedContextAvailable(AbstractGraphicsDevice device) {
+ return null != getOrCreateSharedContext(device);
+ }
+
+ /**
+ * Returns the shared context mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
+ * either a preexisting or newly created, or <code>null</code> if creation failed or not supported.<br>
+ * Creation of the shared context is tried only once.
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ */
+ public final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) {
+ device = validateDevice(device);
+ if(null!=device) {
+ return getOrCreateSharedContextImpl(device);
+ }
+ return null;
+ }
+ protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
+
+ /**
+ * Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
+ */
+ public static GLDrawableFactory getDesktopFactory() {
+ return nativeOSFactory;
+ }
+
+ /**
+ * Returns the sole GLDrawableFactory instance for EGL if exist or null
+ */
+ public static GLDrawableFactory getEGLFactory() {
+ 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(GLProfile glProfile) throws GLException {
+ return getFactoryImpl(glProfile.getImplName());
+ }
+
+ protected static GLDrawableFactory getFactoryImpl(String glProfileImplName) throws GLException {
+ if ( GLProfile.usesNativeGLES(glProfileImplName) ) {
+ if(null==eglFactory) throw new GLException("EGLDrawableFactory unavailable: "+glProfileImplName);
+ return eglFactory;
+ }
+ if(null!=nativeOSFactory) {
+ return nativeOSFactory;
+ }
+ if(null!=eglFactory) {
+ return eglFactory;
+ }
+ throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+glProfileImplName);
+ }
+
+ protected static GLDrawableFactory getFactoryImpl(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.<br>
+ * The list is sorted by the native ID, ascending.<br>
+ * The chosen GLProfile statement in the result may not refer to the maximum available profile
+ * due to implementation constraints, ie using the shared resource.
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @return A list of {@link javax.media.opengl.GLCapabilitiesImmutable}'s, maybe empty if none is available.
+ */
+ public final List/*GLCapabilitiesImmutable*/ getAvailableCapabilities(AbstractGraphicsDevice device) {
+ device = validateDevice(device);
+ if(null!=device) {
+ return getAvailableCapabilitiesImpl(device);
+ }
+ return null;
+ }
+ protected abstract List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device);
+
+ //----------------------------------------------------------------------
+ // Methods to create high-level objects
+
+ /**
+ * Returns a GLDrawable according to it's chosen Capabilities,<br>
+ * which determines pixel format, on- and offscreen incl. PBuffer type.
+ * <p>
+ * The native platform's chosen Capabilties are referenced within the target
+ * NativeSurface's AbstractGraphicsConfiguration.<p>
+ *
+ * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is true,<br>
+ * an onscreen GLDrawable will be realized.
+ * <p>
+ * In case target's {@link javax.media.nativewindow.Capabilities#isOnscreen()} is false,<br>
+ * either a Pbuffer drawable is created if target's {@link javax.media.opengl.GLCapabilities#isPBuffer()} is true,<br>
+ * or a simple pixmap/bitmap drawable is created. The latter is unlikely to be hardware accelerated.<br>
+ * <p>
+ *
+ * @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 javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
+ */
+ public abstract GLDrawable createGLDrawable(NativeSurface target)
+ throws IllegalArgumentException, GLException;
+
+ /**
+ * Creates a Offscreen GLDrawable incl it's offscreen {@link javax.media.nativewindow.NativeSurface} with the given capabilites and dimensions.
+ * <p>
+ * A Pbuffer drawable/surface is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.<br>
+ * Otherwise a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.<br>
+ * </p>
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> 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 offscreen GLDrawable
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the Offscreen to fail.
+ */
+ public abstract GLDrawable createOffscreenDrawable(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable capabilities,
+ GLCapabilitiesChooser chooser,
+ int width, int height)
+ throws GLException;
+
+ /**
+ * Creates an offscreen NativeSurface.<br>
+ * A Pbuffer surface is created if both {@link javax.media.opengl.GLCapabilities#isPBuffer() caps.isPBuffer()}
+ * and {@link #canCreateGLPbuffer(javax.media.nativewindow.AbstractGraphicsDevice) canCreateGLPbuffer(device)} is true.<br>
+ * Otherwise a simple pixmap/bitmap surface is created. The latter is unlikely to be hardware accelerated.<br>
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> 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 offscreen native surface
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the GLDrawable to fail.
+ */
+ public abstract NativeSurface createOffscreenSurface(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable caps,
+ GLCapabilitiesChooser chooser,
+ int width, int height);
+
+ /**
+ * Highly experimental API entry, allowing developer of new windowing system bindings
+ * to leverage the native window handle to produce a NativeSurface implementation (ProxySurface), having the required GLCapabilities.<br>
+ * Such surface can be used to instantiate a GLDrawable and hence test your new binding w/o the
+ * costs of providing a full set of abstraction like the AWT GLCanvas or even the native NEWT bindings.
+ *
+ * @param device the platform's target device, shall not be <code>null</code>
+ * @param windowHandle the native window handle
+ * @param caps the requested GLCapabilties
+ * @param chooser the custom chooser, may be null for default
+ * @return The proxy surface wrapping the windowHandle on the device
+ */
+ public abstract ProxySurface createProxySurface(AbstractGraphicsDevice device,
+ long windowHandle,
+ GLCapabilitiesImmutable caps,
+ GLCapabilitiesChooser chooser);
+
+ /**
+ * Returns true if it is possible to create a GLPbuffer. Some older
+ * graphics cards do not have this capability.
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ */
+ public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device);
+
+ /**
+ * Creates a GLPbuffer with the given capabilites and dimensions. <P>
+ *
+ * See the note in the overview documentation on
+ * <a href="../../../overview-summary.html#SHARING">context sharing</a>.
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @param capabilities the requested capabilities
+ * @param chooser the custom chooser, may be null for default
+ * @param initialWidth initial width of pbuffer
+ * @param initialHeight initial height of pbuffer
+ * @param shareWith a shared GLContext this GLPbuffer shall use
+ *
+ * @return the new {@link GLPbuffer} specific {@link GLAutoDrawable}
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the GLPbuffer to fail.
+ */
+ public abstract GLPbuffer createGLPbuffer(AbstractGraphicsDevice device,
+ GLCapabilitiesImmutable capabilities,
+ GLCapabilitiesChooser chooser,
+ int initialWidth,
+ int initialHeight,
+ GLContext shareWith)
+ throws GLException;
+
+ //----------------------------------------------------------------------
+ // Methods for interacting with third-party OpenGL libraries
+
+ /**
+ * <P> 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
+ * javax.media.opengl.glu.GLU} objects. New contexts created through
+ * {@link GLDrawable}s may share textures and display lists with
+ * this external context. </P>
+ *
+ * <P> 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
+ * <code>makeCurrent</code> and <code>release</code> on the returned
+ * GLContext object have no effect. If the underlying OpenGL context
+ * is destroyed, the <code>destroy</code> method should be called on
+ * the <code>GLContext</code>. A new <code>GLContext</code> 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 javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ */
+ public abstract boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device);
+
+ /**
+ * <P> 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. </P>
+ *
+ * <P> 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. </P>
+ *
+ * <P> Calls to <code>setSize</code>, <code>getWidth</code> and
+ * <code>getHeight</code> are illegal on the returned GLDrawable. If
+ * these operations are required by the user, they must be performed
+ * by the third-party library. </P>
+ *
+ * <P> 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. </P>
+ *
+ * <P> 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/javax/media/opengl/GLEventListener.java b/src/jogl/classes/javax/media/opengl/GLEventListener.java
new file mode 100644
index 000000000..15fae4a39
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLEventListener.java
@@ -0,0 +1,92 @@
+/*
+ * 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 javax.media.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.<p>
+
+ 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.<P>
+
+ 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}.<P>
+
+ 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 the viewport
+ and view volume of the window appropriately, for example by a
+ call to {@link javax.media.opengl.GL#glViewport}; note that for
+ convenience the component has already called <code>glViewport(x,
+ y, width, height)</code> when this method is called, so the
+ client may not have to do anything in this method.
+ */
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height);
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLException.java b/src/jogl/classes/javax/media/opengl/GLException.java
new file mode 100644
index 000000000..644042e15
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLException.java
@@ -0,0 +1,68 @@
+/*
+ * 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 javax.media.opengl;
+
+/** A generic exception for OpenGL errors used throughout the binding
+ as a substitute for {@link RuntimeException}. */
+
+public class GLException extends RuntimeException {
+ /** Constructs a GLException object. */
+ public GLException() {
+ super();
+ }
+
+ /** Constructs a GLException object with the specified detail
+ message. */
+ public GLException(String message) {
+ super(message);
+ }
+
+ /** Constructs a GLException object with the specified detail
+ message and root cause. */
+ public GLException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /** Constructs a GLException object with the specified root
+ cause. */
+ public GLException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLPbuffer.java b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
new file mode 100644
index 000000000..0250365b0
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLPbuffer.java
@@ -0,0 +1,91 @@
+/*
+ * 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 javax.media.opengl;
+
+/** Provides offscreen rendering support via pbuffers. The principal
+ addition of this interface is a {@link #destroy} method to
+ deallocate the pbuffer and its associated resources. It also
+ contains experimental methods for accessing the pbuffer's contents
+ as a texture map and enabling rendering to floating-point frame
+ buffers. These methods are not guaranteed to be supported on all
+ platforms and may be deprecated in a future release. */
+
+public interface GLPbuffer extends GLAutoDrawable {
+ /** Indicates the GL_APPLE_float_pixels extension is being used for this pbuffer. */
+ public static final int APPLE_FLOAT = 1;
+
+ /** Indicates the GL_ATI_texture_float extension is being used for this pbuffer. */
+ public static final int ATI_FLOAT = 2;
+
+ /** Indicates the GL_NV_float_buffer extension is being used for this pbuffer. */
+ public static final int NV_FLOAT = 3;
+
+ /** Binds this pbuffer to its internal texture target. Only valid to
+ call if offscreen render-to-texture has been specified in the
+ NWCapabilities for this GLPbuffer. If the
+ render-to-texture-rectangle capability has also been specified,
+ this will use e.g. wglBindTexImageARB as its implementation and
+ cause the texture to be bound to e.g. the
+ GL_TEXTURE_RECTANGLE_NV state; otherwise, during the display()
+ phase the pixels will have been copied into an internal texture
+ target and this will cause that to be bound to the GL_TEXTURE_2D
+ state. */
+ public void bindTexture();
+
+ /** Unbinds the pbuffer from its internal texture target. */
+ public void releaseTexture();
+
+ /** Destroys the native resources associated with this pbuffer. It
+ is not valid to call display() or any other routines on this
+ pbuffer after it has been destroyed. Before destroying the
+ pbuffer, the application must destroy any additional OpenGL
+ contexts which have been created for the pbuffer via {@link
+ #createContext}. */
+ public void destroy();
+
+ /** Indicates which vendor's extension is being used to support
+ floating point channels in this pbuffer if that capability was
+ requested in the NWCapabilities during pbuffer creation. Returns
+ one of NV_FLOAT, ATI_FLOAT or APPLE_FLOAT, or throws GLException
+ if floating-point channels were not requested for this pbuffer.
+ This function may only be called once the init method for this
+ pbuffer's GLEventListener has been called. */
+ public int getFloatingPointMode();
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java b/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java
new file mode 100644
index 000000000..926651c1d
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLPipelineFactory.java
@@ -0,0 +1,194 @@
+/*
+ * 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.
+ */
+
+package javax.media.opengl;
+
+import java.lang.reflect.*;
+import java.util.StringTokenizer;
+
+import jogamp.opengl.*;
+
+/**
+ * Factory for pipelining GL instances
+ */
+public class GLPipelineFactory {
+ public static final boolean DEBUG = Debug.debug("GLPipelineFactory");
+
+ /**
+ * Creates a pipelined GL instance using the given downstream <code>downstream</code>
+ * and optional arguments <code>additionalArgs</code> for the constructor.<br>
+ *
+ * The upstream GL instance is determined as follows:
+ * <ul>
+ * <li> Use <code>pipelineClazzBaseName</code> as the class name's full basename, incl. package name</li>
+ * <li> For the <code>downstream</code> class and it's superclasses, do:</li>
+ * <ul>
+ * <li> For all <code>downstream</code> class and superclass interfaces, do:</li>
+ * <ul>
+ * <li> If <code>reqInterface</code> is not null and the interface is unequal, continue loop.</li>
+ * <li> If <code>downstream</code> is not instance of interface, continue loop.</li>
+ * <li> If upstream class is available use it, end loop.</li>
+ * </ul>
+ * </ul>
+ * </ul><br>
+ *
+ * @param pipelineClazzBaseName the basename of the pipline class name
+ * @param reqInterface optional requested interface to be used, may be null, in which case the first matching one is used
+ * @param downstream is always the 1st argument for the upstream constructor
+ * @param additionalArgs additional arguments for the upstream constructor
+ */
+ public static final GL create(String pipelineClazzBaseName, Class reqInterface, GL downstream, Object[] additionalArgs) {
+ Class downstreamClazz = downstream.getClass();
+ Class upstreamClazz = null;
+ Class interfaceClazz = null;
+
+ if(DEBUG) {
+ System.out.println("GLPipelineFactory: Start "+downstreamClazz.getName()+", req. Interface: "+reqInterface+" -> "+pipelineClazzBaseName);
+ }
+
+ // For all classes: child -> parent
+ do {
+ // For all interfaces: right -> left == child -> parent
+ // It is important that this matches with the gluegen cfg file's 'Implements' clause !
+ Class[] clazzes = downstreamClazz.getInterfaces();
+ for(int i=clazzes.length-1; null==upstreamClazz && i>=0; i--) {
+ if(DEBUG) {
+ System.out.println("GLPipelineFactory: Try "+downstreamClazz.getName()+" Interface["+i+"]: "+clazzes[i].getName());
+ }
+ if( reqInterface != null && !reqInterface.getName().equals(clazzes[i].getName()) ) {
+ if(DEBUG) {
+ System.out.println("GLPipelineFactory: requested Interface "+reqInterface+" is _not_ "+ clazzes[i].getName());
+ }
+ continue; // not the requested one ..
+ }
+ if( ! clazzes[i].isInstance(downstream) ) {
+ if(DEBUG) {
+ System.out.println("GLPipelineFactory: "+downstream.getClass().getName() + " is _not_ instance of "+ clazzes[i].getName());
+ }
+ continue; // not a compatible one
+ } else {
+ if(DEBUG) {
+ System.out.println("GLPipelineFactory: "+downstream.getClass().getName() + " _is_ instance of "+ clazzes[i].getName());
+ }
+ }
+ upstreamClazz = getUpstreamClazz(clazzes[i], pipelineClazzBaseName);
+ if( null != upstreamClazz ) {
+ interfaceClazz = clazzes[i];
+ }
+ }
+
+ if(null==upstreamClazz) {
+ downstreamClazz = downstreamClazz.getSuperclass();
+ }
+ } while (null!=downstreamClazz && null==upstreamClazz);
+
+
+ if(null==upstreamClazz) {
+ throw new GLException("No pipeline ("+pipelineClazzBaseName+"*) available for :"+downstream.getClass().getName());
+ }
+
+ if(DEBUG) {
+ System.out.println("GLPipelineFactory: Got : "+ upstreamClazz.getName()+", base interface: "+interfaceClazz.getName());
+ }
+
+ Class[] cstrArgTypes = new Class[ 1 + ( ( null==additionalArgs ) ? 0 : additionalArgs.length ) ] ;
+ {
+ int i = 0;
+ cstrArgTypes[i++] = interfaceClazz;
+ for(int j=0; null!=additionalArgs && j<additionalArgs.length; j++) {
+ cstrArgTypes[i++] = additionalArgs[j].getClass();
+ }
+ }
+ Constructor cstr = null;
+ try {
+ cstr = upstreamClazz.getDeclaredConstructor( cstrArgTypes );
+ } catch(NoSuchMethodException nsme) {
+ throw new GLException("Couldn't find pipeline constructor: " + upstreamClazz.getName() +
+ " ( "+getArgsClassNameList(downstreamClazz, additionalArgs) +" )");
+ }
+ Object instance = null;
+ try {
+ Object[] cstrArgs = new Object[ 1 + ( ( null==additionalArgs ) ? 0 : additionalArgs.length ) ] ;
+ {
+ int i = 0;
+ cstrArgs[i++] = downstream;
+ for(int j=0; null!=additionalArgs && j<additionalArgs.length; j++) {
+ cstrArgs[i++] = additionalArgs[j];
+ }
+ }
+ instance = cstr.newInstance( cstrArgs ) ;
+ } catch (Throwable t) { t.printStackTrace(); }
+ if(null==instance) {
+ throw new GLException("Error: Couldn't create instance of pipeline: "+upstreamClazz.getName()+
+ " ( "+getArgsClassNameList(downstreamClazz, additionalArgs) +" )");
+ }
+ if( ! (instance instanceof GL) ) {
+ throw new GLException("Error: "+upstreamClazz.getName()+" not an instance of GL");
+ }
+ return (GL) instance;
+ }
+
+ private static final String getArgsClassNameList(Class arg0, Object[] args) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(arg0.getName());
+ if(args!=null) {
+ for(int j=0; j<args.length; j++) {
+ sb.append(", ");
+ sb.append(args[j].getClass().getName());
+ }
+ }
+ return sb.toString();
+ }
+
+ private static final Class getUpstreamClazz(Class downstreamClazz, String pipelineClazzBaseName) {
+ String downstreamClazzName = downstreamClazz.getName();
+
+ StringTokenizer st = new StringTokenizer(downstreamClazzName, ".");
+ String downstreamClazzBaseName = downstreamClazzName;
+ while(st.hasMoreTokens()) {
+ downstreamClazzBaseName = st.nextToken();
+ }
+ String upstreamClazzName = pipelineClazzBaseName+downstreamClazzBaseName;
+
+ Class upstreamClazz = null;
+ try {
+ upstreamClazz = Class.forName(upstreamClazzName, true, GLPipelineFactory.class.getClassLoader());
+ } catch (Throwable e) { e.printStackTrace(); }
+
+ return upstreamClazz;
+ }
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
new file mode 100644
index 000000000..17313f770
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -0,0 +1,1609 @@
+/*
+ * 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.
+ */
+
+package javax.media.opengl;
+
+import jogamp.opengl.Debug;
+import jogamp.opengl.GLDrawableFactoryImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.DesktopGLDynamicLookupHelper;
+
+import com.jogamp.common.GlueGenVersion;
+import com.jogamp.common.jvm.JVMUtil;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.nativewindow.NativeWindowVersion;
+import com.jogamp.opengl.JoglVersion;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.opengl.fixedfunc.GLPointerFunc;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Specifies the the OpenGL profile.
+ *
+ * This class static singleton initialization queries the availability of all OpenGL Profiles
+ * and instantiates singleton GLProfile objects for each available profile.
+ *
+ * The platform default profile may be used, using {@link GLProfile#GetProfileDefault()},
+ * or more specialized versions using the other static GetProfile methods.
+ */
+public class GLProfile {
+
+ public static final boolean DEBUG = Debug.debug("GLProfile");
+
+ /**
+ * Static one time initialization of JOGL.
+ * <p>
+ * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking,<br>
+ * see {@link javax.media.nativewindow.NativeWindowFactory#initSingleton(boolean) NativeWindowFactory.initSingleton(firstUIActionOnProcess)}.
+ * </p>
+ * <p>
+ * Applications shall call this methods <b>ASAP</b>, before any other UI invocation.<br>
+ * You may issue the call in your <code>main class</code> static block, which is the earliest point in your application/applet lifecycle,
+ * or within the <code>main function</code>.<br>
+ * In case applications are able to initialize JOGL before any other UI action,<br>
+ * they shall invoke this method with <code>firstUIActionOnProcess=true</code> and benefit from fast native multithreading support on all platforms if possible.</P>
+ * <P>
+ * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL may not be able to initialize JOGL
+ * before the first UI action.<br>
+ * In such case you shall invoke this method with <code>firstUIActionOnProcess=false</code>.<br>
+ * On some platforms, notably X11 with AWT usage, JOGL will utilize special locking mechanisms which may slow down your
+ * application.</P>
+ * <P>
+ * Remark: NEWT is currently not affected by this behavior, ie always uses native multithreading.</P>
+ * <P>
+ * However, in case this method is not invoked, hence GLProfile is not initialized explicitly by the user,<br>
+ * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}, etc, will initialize with <code>firstUIActionOnProcess=false</code>,<br>
+ * hence without the possibility to enable native multithreading.<br>
+ * This is not the recommended way, since it may has a performance impact, but it allows you to run code without explicit initialization.</P>
+ * <P>
+ * In case no explicit initialization was invoked and the implicit initialization didn't happen,<br>
+ * you may encounter the following exception:
+ * <pre>
+ * javax.media.opengl.GLException: No default profile available
+ * </pre></P>
+ *
+ * @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program,
+ * otherwise <code>false</code>.
+ */
+ public static synchronized void initSingleton(final boolean firstUIActionOnProcess) {
+ if(!initialized) {
+ initialized = true;
+ // run the whole static initialization privileged to speed up,
+ // since this skips checking further access
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ initProfilesForDefaultDevices(firstUIActionOnProcess);
+ return null;
+ }
+ });
+ }
+ }
+
+ /**
+ * Trigger eager initialization of GLProfiles for the given device,
+ * in case it isn't done yet.
+ */
+ public static void initProfiles(AbstractGraphicsDevice device) {
+ getProfileMap(device);
+ }
+
+ /**
+ * Manual shutdown method, may be called after your last JOGL use
+ * within the running JVM.<br>
+ * It releases all temporary created resources, ie issues {@link javax.media.opengl.GLDrawableFactory#shutdown()}.<br>
+ * The shutdown implementation is called via the JVM shutdown hook, if not manually invoked here.<br>
+ * Invoke <code>shutdown()</code> manually is recommended, due to the unreliable JVM state within the shutdown hook.<br>
+ */
+ public static synchronized void shutdown() {
+ if(initialized) {
+ initialized = false;
+ GLDrawableFactory.shutdown();
+ }
+ }
+
+ //
+ // Query platform available OpenGL implementation
+ //
+
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL4bc);
+ }
+
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL4);
+ }
+
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL3bc);
+ }
+
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL3);
+ }
+
+ public static boolean isGL2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2);
+ }
+
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GLES2);
+ }
+
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GLES1);
+ }
+
+ public static boolean isGL2ES1Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2ES1);
+ }
+
+ public static boolean isGL2ES2Available(AbstractGraphicsDevice device) {
+ return null != getProfileMap(device).get(GL2ES2);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL4bcAvailable() {
+ return isGL4bcAvailable(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL4Available() {
+ return isGL4Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL3bcAvailable() {
+ return isGL3bcAvailable(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL3Available() {
+ return isGL3Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2Available() {
+ return isGL2Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGLES2Available() {
+ return isGLES2Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGLES1Available() {
+ return isGLES1Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2ES1Available() {
+ return isGL2ES1Available(null);
+ }
+
+ /** Uses the default device */
+ public static boolean isGL2ES2Available() {
+ return isGL2ES2Available(null);
+ }
+
+ public static String glAvailabilityToString(AbstractGraphicsDevice device) {
+ boolean avail;
+ StringBuffer sb = new StringBuffer();
+
+ validateInitialization();
+
+ if(null==device) {
+ device = defaultDevice;
+ }
+
+ sb.append("GLAvailability[Native[GL4bc ");
+ avail=isGL4bcAvailable(device);
+ sb.append(avail);
+ if(avail) {
+ glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_COMPAT);
+ }
+
+ sb.append(", GL4 ");
+ avail=isGL4Available(device);
+ sb.append(avail);
+ if(avail) {
+ glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_CORE);
+ }
+
+ sb.append(", GL3bc ");
+ avail=isGL3bcAvailable(device);
+ sb.append(avail);
+ if(avail) {
+ glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_COMPAT);
+ }
+
+ sb.append(", GL3 ");
+ avail=isGL3Available(device);
+ sb.append(avail);
+ if(avail) {
+ glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_CORE);
+ }
+
+ sb.append(", GL2 ");
+ avail=isGL2Available(device);
+ sb.append(avail);
+ if(avail) {
+ glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_COMPAT);
+ }
+
+ sb.append(", GL2ES1 ");
+ sb.append(isGL2ES1Available(device));
+
+ sb.append(", GLES1 ");
+ avail=isGLES1Available(device);
+ sb.append(avail);
+ if(avail) {
+ glAvailabilityToString(device, sb, 1, GLContext.CTX_PROFILE_ES);
+ }
+
+ sb.append(", GL2ES2 ");
+ sb.append(isGL2ES2Available(device));
+
+ sb.append(", GLES2 ");
+ avail=isGLES2Available(device);
+ sb.append(avail);
+ if(avail) {
+ glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_ES);
+ }
+
+ sb.append("], Profiles[");
+ for(Iterator i=getProfileMap(device).values().iterator(); i.hasNext(); ) {
+ sb.append(((GLProfile)i.next()).toString());
+ sb.append(", ");
+ }
+ sb.append(", default ");
+ sb.append(getDefault(device));
+ sb.append("]]");
+
+ return sb.toString();
+ }
+
+ /** Uses the default device */
+ public static String glAvailabilityToString() {
+ return glAvailabilityToString(null);
+ }
+
+ //
+ // Public (user-visible) profiles
+ //
+
+ /** The desktop OpenGL compatibility profile 4.x, with x >= 0, ie GL2 plus GL4.<br>
+ <code>bc</code> stands for backward compatibility. */
+ public static final String GL4bc = "GL4bc";
+
+ /** The desktop OpenGL core profile 4.x, with x >= 0 */
+ public static final String GL4 = "GL4";
+
+ /** The desktop OpenGL compatibility profile 3.x, with x >= 1, ie GL2 plus GL3.<br>
+ <code>bc</code> stands for backward compatibility. */
+ public static final String GL3bc = "GL3bc";
+
+ /** The desktop OpenGL core profile 3.x, with x >= 1 */
+ public static final String GL3 = "GL3";
+
+ /** The desktop OpenGL profile 1.x up to 3.0 */
+ public static final String GL2 = "GL2";
+
+ /** The embedded OpenGL profile ES 1.x, with x >= 0 */
+ public static final String GLES1 = "GLES1";
+
+ /** The embedded OpenGL profile ES 2.x, with x >= 0 */
+ public static final String GLES2 = "GLES2";
+
+ /** The intersection of the desktop GL2 and embedded ES1 profile */
+ public static final String GL2ES1 = "GL2ES1";
+
+ /** The intersection of the desktop GL3, GL2 and embedded ES2 profile */
+ public static final String GL2ES2 = "GL2ES2";
+
+ /** The intersection of the desktop GL3 and GL2 profile */
+ public static final String GL2GL3 = "GL2GL3";
+
+ /** The default profile, used for the device default profile map */
+ private static final String GL_DEFAULT = "GL_DEFAULT";
+
+ /**
+ * All GL Profiles in the order of default detection.
+ * Desktop compatibility profiles (the one with fixed function pipeline) comes first
+ * from highest to lowest version.
+ *
+ * <ul>
+ * <li> GL4bc
+ * <li> GL3bc
+ * <li> GL2
+ * <li> GL2GL3
+ * <li> GL4
+ * <li> GL3
+ * <li> GL2ES2
+ * <li> GLES2
+ * <li> GL2ES1
+ * <li> GLES1
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL4bc, GL3bc, GL2, GL2GL3, GL4, GL3, GL2ES2, GLES2, GL2ES1, GLES1 };
+
+ /**
+ * Order of maximum profiles.
+ *
+ * <ul>
+ * <li> GL4bc
+ * <li> GL4
+ * <li> GL3bc
+ * <li> GL3
+ * <li> GL2
+ * <li> GL2GL3
+ * <li> GL2ES2
+ * <li> GLES2
+ * <li> GL2ES1
+ * <li> GLES1
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_MAX = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3, GL2ES2, GLES2, GL2ES1, GLES1 };
+
+ /**
+ * Order of minimum original desktop profiles.
+ *
+ * <ul>
+ * <li> GL2
+ * <li> GL3bc
+ * <li> GL4bc
+ * <li> GL3
+ * <li> GL4
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_MIN_DESKTOP = new String[] { GL2, GL3bc, GL4bc, GL3, GL4 };
+
+ /**
+ * Order of maximum fixed function profiles
+ *
+ * <ul>
+ * <li> GL4bc
+ * <li> GL3bc
+ * <li> GL2
+ * <li> GL2ES1
+ * <li> GLES1
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_MAX_FIXEDFUNC = new String[] { GL4bc, GL3bc, GL2, GL2ES1, GLES1 };
+
+ /**
+ * Order of maximum programmable shader profiles
+ *
+ * <ul>
+ * <li> GL4
+ * <li> GL4bc
+ * <li> GL3
+ * <li> GL3bc
+ * <li> GL2
+ * <li> GL2ES2
+ * <li> GLES2
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2ES2, GLES2 };
+
+ /**
+ * All GL2ES2 Profiles in the order of default detection.
+ *
+ * <ul>
+ * <li> GL2ES2
+ * <li> GL2
+ * <li> GL3
+ * <li> GL4
+ * <li> GLES2
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL4, GL3, GL2, GLES2 };
+
+ /**
+ * All GL2ES1 Profiles in the order of default detection.
+ *
+ * <ul>
+ * <li> GL2ES1
+ * <li> GL2
+ * <li> GL3bc
+ * <li> GL4bc
+ * <li> GLES1
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL4bc, GL3bc, GL2, GLES1 };
+
+ /**
+ * All GLES Profiles in the order of default detection.
+ *
+ * <ul>
+ * <li> GLES2
+ * <li> GLES1
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_GLES = new String[] { GLES2, GLES1 };
+
+ /** Returns a default GLProfile object, reflecting the best for the running platform.
+ * It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
+ * @see #GL_PROFILE_LIST_ALL
+ */
+ public static GLProfile getDefault(AbstractGraphicsDevice device) {
+ GLProfile glp = get(device, GL_DEFAULT);
+ return glp;
+ }
+
+ /** Uses the default device */
+ public static GLProfile getDefault() {
+ return getDefault(defaultDevice);
+ }
+
+ /**
+ * Returns the highest profile.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX}
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ * @see #GL_PROFILE_LIST_MAX
+ */
+ public static GLProfile getMaximum(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMaximum()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_MAX);
+ }
+
+ /**
+ * Returns the lowest desktop profile.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MIN_DESKTOP}
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ * @see #GL_PROFILE_LIST_MIN_DESKTOP
+ */
+ public static GLProfile getMinDesktop(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MIN_DESKTOP);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMinDesktop()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_MIN_DESKTOP);
+ }
+
+
+ /**
+ * Returns the highest profile, implementing the fixed function pipeline.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_FIXEDFUNC}
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ * @see #GL_PROFILE_LIST_MAX_FIXEDFUNC
+ */
+ public static GLProfile getMaxFixedFunc(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX_FIXEDFUNC);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMaxFixedFunc()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_MAX_FIXEDFUNC);
+ }
+
+ /**
+ * Returns the highest profile, implementing the programmable shader pipeline.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_PROGSHADER}
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ * @see #GL_PROFILE_LIST_MAX_PROGSHADER
+ */
+ public static GLProfile getMaxProgrammable(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX_PROGSHADER);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMaxProgrammable()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_MAX_PROGSHADER);
+ }
+
+ /**
+ * Returns a profile, implementing the interface GL2ES1.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_GL2ES1}
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ * @see #GL_PROFILE_LIST_GL2ES1
+ */
+ public static GLProfile getGL2ES1(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_GL2ES1);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getGL2ES1()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_GL2ES1);
+ }
+
+ /**
+ * Returns a profile, implementing the interface GL2ES2.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_GL2ES2}
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ * @see #GL_PROFILE_LIST_GL2ES2
+ */
+ public static GLProfile getGL2ES2(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_GL2ES2);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getGL2ES2()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_GL2ES2);
+ }
+
+ /** Returns a GLProfile object.
+ * verifies the given profile and chooses an appropriate implementation.
+ * A generic value of <code>null</code> or <code>GL</code> will result in
+ * the default profile.
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ */
+ public static GLProfile get(AbstractGraphicsDevice device, String profile)
+ throws GLException
+ {
+ if(null==profile || profile.equals("GL")) {
+ profile = GL_DEFAULT;
+ }
+ return (GLProfile) getProfileMap(device).get(profile);
+ }
+
+ /** Uses the default device */
+ public static GLProfile get(String profile)
+ throws GLException
+ {
+ return get(defaultDevice, profile);
+ }
+
+ /**
+ * Returns the first profile from the given list,
+ * where an implementation is available.
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ */
+ public static GLProfile get(AbstractGraphicsDevice device, String[] profiles)
+ throws GLException
+ {
+ HashMap map = getProfileMap(device);
+ for(int i=0; i<profiles.length; i++) {
+ String profile = profiles[i];
+ GLProfile glProfile = (GLProfile) map.get(profile);
+ if(null!=glProfile) {
+ return glProfile;
+ }
+ }
+ throw new GLException("Profiles "+array2String(profiles)+" not available on device "+device);
+ }
+
+ /** Uses the default device */
+ public static GLProfile get(String[] profiles)
+ throws GLException
+ {
+ return get(defaultDevice, profiles);
+ }
+
+ /** Indicates whether the native OpenGL ES1 profile is in use.
+ * This requires an EGL interface.
+ */
+ public static boolean usesNativeGLES1(String profileImpl) {
+ return GLES1.equals(profileImpl);
+ }
+
+ /** Indicates whether the native OpenGL ES2 profile is in use.
+ * This requires an EGL or ES2 compatible interface.
+ */
+ public static boolean usesNativeGLES2(String profileImpl) {
+ return GLES2.equals(profileImpl);
+ }
+
+ /** Indicates whether either of the native OpenGL ES profiles are in use. */
+ public static boolean usesNativeGLES(String profileImpl) {
+ return usesNativeGLES2(profileImpl) || usesNativeGLES1(profileImpl);
+ }
+
+ /** @return {@link javax.media.nativewindow.NativeWindowFactory#isAWTAvailable()} and
+ JOGL's AWT part */
+ public static boolean isAWTAvailable() { return isAWTAvailable; }
+
+ public static String getGLTypeName(int type) {
+ switch (type) {
+ case GL.GL_UNSIGNED_BYTE:
+ return "GL_UNSIGNED_BYTE";
+ case GL.GL_BYTE:
+ return "GL_BYTE";
+ case GL.GL_UNSIGNED_SHORT:
+ return "GL_UNSIGNED_SHORT";
+ case GL.GL_SHORT:
+ return "GL_SHORT";
+ case GL.GL_FLOAT:
+ return "GL_FLOAT";
+ case GL.GL_FIXED:
+ return "GL_FIXED";
+ case javax.media.opengl.GL2ES2.GL_INT:
+ return "GL_INT";
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ return "GL_UNSIGNED_INT";
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ return "GL_DOUBLE";
+ case javax.media.opengl.GL2.GL_2_BYTES:
+ return "GL_2_BYTES";
+ case javax.media.opengl.GL2.GL_3_BYTES:
+ return "GL_3_BYTES";
+ case javax.media.opengl.GL2.GL_4_BYTES:
+ return "GL_4_BYTES";
+ }
+ return null;
+ }
+
+ public static String getGLArrayName(int array) {
+ switch(array) {
+ case GLPointerFunc.GL_VERTEX_ARRAY:
+ return "GL_VERTEX_ARRAY";
+ case GLPointerFunc.GL_NORMAL_ARRAY:
+ return "GL_NORMAL_ARRAY";
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ return "GL_COLOR_ARRAY";
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ return "GL_TEXTURE_COORD_ARRAY";
+ }
+ return null;
+ }
+
+ public final String getGLImplBaseClassName() {
+ return getGLImplBaseClassName(profileImpl);
+ }
+
+ /**
+ * @param o GLProfile object to compare with
+ * @return true if given Object is a GLProfile and
+ * if both, profile and profileImpl is equal with this.
+ */
+ public final boolean equals(Object o) {
+ if(this==o) { return true; }
+ if(o instanceof GLProfile) {
+ GLProfile glp = (GLProfile)o;
+ return profile.equals(glp.getName()) && profileImpl.equals(glp.getImplName()) ;
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ int hash = 5;
+ hash = 97 * hash + (this.profileImpl != null ? this.profileImpl.hashCode() : 0);
+ hash = 97 * hash + (this.profile != null ? this.profile.hashCode() : 0);
+ return hash;
+ }
+
+ /**
+ * @param glp GLProfile to compare with
+ * @throws GLException if given GLProfile and this aren't equal
+ */
+ public final void verifyEquality(GLProfile glp) throws GLException {
+ if(!this.equals(glp)) {
+ throw new GLException("GLProfiles are not equal: "+this+" != "+glp);
+ }
+ }
+
+ public final String getName() {
+ return profile;
+ }
+
+ public final String getImplName() {
+ return profileImpl;
+ }
+
+ /** Indicates whether this profile is capable of GL4bc. */
+ public final boolean isGL4bc() {
+ return GL4bc.equals(profile);
+ }
+
+ /** Indicates whether this profile is capable of GL4. */
+ public final boolean isGL4() {
+ return isGL4bc() || GL4.equals(profile);
+ }
+
+ /** Indicates whether this profile is capable of GL3bc. */
+ public final boolean isGL3bc() {
+ return isGL4bc() || GL3bc.equals(profile);
+ }
+
+ /** Indicates whether this profile is capable of GL3. */
+ public final boolean isGL3() {
+ return isGL4() || isGL3bc() || GL3.equals(profile);
+ }
+
+ /** Indicates whether this context is a GL2 context */
+ public final boolean isGL2() {
+ return isGL3bc() || GL2.equals(profile);
+ }
+
+ /** Indicates whether this profile is capable of GLES1. */
+ public final boolean isGLES1() {
+ return GLES1.equals(profile);
+ }
+
+ /** Indicates whether this profile is capable of GLES2. */
+ public final boolean isGLES2() {
+ return GLES2.equals(profile);
+ }
+
+ /** Indicates whether this profile is capable of GL2ES1. */
+ public final boolean isGL2ES1() {
+ return GL2ES1.equals(profile) || isGL2() || isGLES1() ;
+ }
+
+ /** Indicates whether this profile is capable os GL2ES2. */
+ public final boolean isGL2ES2() {
+ return GL2ES2.equals(profile) || isGL2() || isGL3() || isGLES2() ;
+ }
+
+ /** Indicates whether this profile is capable os GL2GL3. */
+ public final boolean isGL2GL3() {
+ return GL2GL3.equals(profile) || isGL2() || isGL3() ;
+ }
+
+ /** Indicates whether this profile supports GLSL. */
+ public final boolean hasGLSL() {
+ return isGL2ES2() ;
+ }
+
+ /** Indicates whether this profile uses the native OpenGL ES1 implementations. */
+ public final boolean usesNativeGLES1() {
+ return GLES1.equals(profileImpl);
+ }
+
+ /** Indicates whether this profile uses the native OpenGL ES2 implementations. */
+ public final boolean usesNativeGLES2() {
+ return GLES2.equals(profileImpl);
+ }
+
+ /** Indicates whether this profile uses either of the native OpenGL ES implementations. */
+ public final boolean usesNativeGLES() {
+ return usesNativeGLES2() || usesNativeGLES1();
+ }
+
+ /**
+ * General validation if type is a valid GL data type
+ * for the current profile
+ */
+ public boolean isValidDataType(int type, boolean throwException) {
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case GL.GL_FIXED:
+ return true;
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ if( isGL2ES2() ) {
+ return true;
+ }
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ if( isGL3() ) {
+ return true;
+ }
+ case javax.media.opengl.GL2.GL_2_BYTES:
+ case javax.media.opengl.GL2.GL_3_BYTES:
+ case javax.media.opengl.GL2.GL_4_BYTES:
+ if( isGL2() ) {
+ return true;
+ }
+ }
+ if(throwException) {
+ throw new GLException("Illegal data type on profile "+this+": "+type);
+ }
+ return false;
+ }
+
+ public boolean isValidArrayDataType(int index, int comps, int type,
+ boolean isVertexAttribPointer, boolean throwException) {
+ String arrayName = getGLArrayName(index);
+ if(isGLES1()) {
+ if(isVertexAttribPointer) {
+ if(throwException) {
+ throw new GLException("Illegal array type for "+arrayName+" on profile GLES1: VertexAttribPointer");
+ }
+ return false;
+ }
+ switch(index) {
+ case GLPointerFunc.GL_VERTEX_ARRAY:
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerFunc.GL_NORMAL_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_FIXED:
+ case GL.GL_FLOAT:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GLES1: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ }
+ } else if(isGLES2()) {
+ // simply ignore !isVertexAttribPointer case, since it is simulated anyway ..
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case GL.GL_FIXED:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GLES2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ } else if( isGL2ES2() ) {
+ if(isVertexAttribPointer) {
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ } else {
+ switch(index) {
+ case GLPointerFunc.GL_VERTEX_ARRAY:
+ switch(type) {
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerFunc.GL_NORMAL_ARRAY:
+ switch(type) {
+ case GL.GL_BYTE:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GLES1: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerFunc.GL_COLOR_ARRAY:
+ switch(type) {
+ case GL.GL_UNSIGNED_BYTE:
+ case GL.GL_BYTE:
+ case GL.GL_UNSIGNED_SHORT:
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2ES2.GL_UNSIGNED_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ case GLPointerFunc.GL_TEXTURE_COORD_ARRAY:
+ switch(type) {
+ case GL.GL_SHORT:
+ case GL.GL_FLOAT:
+ case javax.media.opengl.GL2ES2.GL_INT:
+ case javax.media.opengl.GL2.GL_DOUBLE:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal data type for "+arrayName+" on profile GL2: "+type);
+ }
+ return false;
+ }
+ switch(comps) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ break;
+ default:
+ if(throwException) {
+ throw new GLException("Illegal component number for "+arrayName+" on profile GL2: "+comps);
+ }
+ return false;
+ }
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ public String toString() {
+ return "GLProfile[" + profile + "/" + profileImpl + "]";
+ }
+
+ static {
+ JVMUtil.initSingleton();
+ }
+
+ private static /*final*/ boolean isAWTAvailable;
+
+ private static /*final*/ boolean hasDesktopGL;
+ private static /*final*/ boolean hasGL234Impl;
+ private static /*final*/ boolean hasGLES2Impl;
+ private static /*final*/ boolean hasGLES1Impl;
+
+ private static /*final*/ GLDrawableFactoryImpl eglFactory;
+ private static /*final*/ GLDrawableFactoryImpl desktopFactory;
+ private static /*final*/ AbstractGraphicsDevice defaultDevice;
+ private static /*final*/ AbstractGraphicsDevice defaultDesktopDevice;
+ private static /*final*/ AbstractGraphicsDevice defaultEGLDevice;
+
+ static boolean initialized = false;
+
+ /**
+ * Tries the profiles implementation and native libraries.
+ * Throws an GLException if no profile could be found at all.
+ */
+ private static void initProfilesForDefaultDevices(boolean firstUIActionOnProcess) {
+ NativeWindowFactory.initSingleton(firstUIActionOnProcess);
+
+ if(DEBUG) {
+ System.err.println("GLProfile.init firstUIActionOnProcess: "+ firstUIActionOnProcess
+ + ", thread: " + Thread.currentThread().getName());
+ System.err.println(VersionUtil.getPlatformInfo());
+ System.err.println(GlueGenVersion.getInstance());
+ System.err.println(NativeWindowVersion.getInstance());
+ System.err.println(JoglVersion.getInstance());
+ }
+
+ ClassLoader classloader = GLProfile.class.getClassLoader();
+
+ isAWTAvailable = NativeWindowFactory.isAWTAvailable() &&
+ ReflectionUtil.isClassAvailable("javax.media.opengl.awt.GLCanvas", classloader) ; // JOGL
+
+ hasGL234Impl = ReflectionUtil.isClassAvailable("jogamp.opengl.gl4.GL4bcImpl", classloader);
+
+ //
+ // Iteration of desktop GL availability detection
+ // utilizing the detected GL version in the shared context.
+ //
+ // - Instantiate GLDrawableFactory incl its shared dummy drawable/context,
+ // which will register at GLContext ..
+ //
+ Throwable t=null;
+ // if successfull it has a shared dummy drawable and context created
+ try {
+ desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
+ if(null != desktopFactory) {
+ DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) desktopFactory.getGLDynamicLookupHelper(0);
+ if(null!=glLookupHelper) {
+ hasDesktopGL = glLookupHelper.hasGLBinding();
+ }
+ }
+ } catch (LinkageError le) {
+ t=le;
+ } catch (RuntimeException re) {
+ t=re;
+ } catch (Throwable tt) {
+ t=tt;
+ }
+ if(DEBUG) {
+ if(null!=t) {
+ t.printStackTrace();
+ }
+ if(null == desktopFactory) {
+ System.err.println("Info: GLProfile.init - Desktop GLDrawable factory not available");
+ }
+ }
+
+ if(null == desktopFactory) {
+ hasDesktopGL = false;
+ hasGL234Impl = false;
+ } else {
+ defaultDesktopDevice = desktopFactory.getDefaultDevice();
+ defaultDevice = defaultDesktopDevice;
+ }
+
+ if ( ReflectionUtil.isClassAvailable("jogamp.opengl.egl.EGLDrawableFactory", classloader) ) {
+ t=null;
+ try {
+ eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
+ if(null != eglFactory) {
+ GLDynamicLookupHelper eglLookupHelper = eglFactory.getGLDynamicLookupHelper(2);
+ if(null!=eglLookupHelper) {
+ hasGLES2Impl = eglLookupHelper.isLibComplete();
+ }
+ eglLookupHelper = eglFactory.getGLDynamicLookupHelper(1);
+ if(null!=eglLookupHelper) {
+ hasGLES1Impl = eglLookupHelper.isLibComplete();
+ }
+ }
+ } catch (LinkageError le) {
+ t=le;
+ } catch (SecurityException se) {
+ t=se;
+ } catch (NullPointerException npe) {
+ t=npe;
+ } catch (RuntimeException re) {
+ t=re;
+ }
+ if(DEBUG) {
+ if(null!=t) {
+ t.printStackTrace();
+ }
+ if(null == eglFactory) {
+ System.err.println("Info: GLProfile.init - EGL GLDrawable factory not available");
+ }
+ }
+ }
+
+ if(null == eglFactory) {
+ hasGLES2Impl = false;
+ hasGLES1Impl = false;
+ } else {
+ defaultEGLDevice = eglFactory.getDefaultDevice();
+ if (null==defaultDevice) {
+ defaultDevice = defaultEGLDevice;
+ }
+ }
+
+ boolean addedAnyProfile = initProfilesForDevice(defaultDesktopDevice) ||
+ initProfilesForDevice(defaultEGLDevice);
+
+ if(DEBUG) {
+ System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
+ System.err.println("GLProfile.init has desktopFactory "+(null!=desktopFactory));
+ System.err.println("GLProfile.init hasDesktopGL "+hasDesktopGL);
+ System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
+ System.err.println("GLProfile.init has eglFactory "+(null!=eglFactory));
+ System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
+ System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl);
+ System.err.println("GLProfile.init defaultDesktopDevice "+defaultDesktopDevice);
+ System.err.println("GLProfile.init defaultEGLDevice "+defaultEGLDevice);
+ System.err.println("GLProfile.init defaultDevice "+defaultDevice);
+ }
+
+ if(!addedAnyProfile) {
+ throw new GLException("No profile available: "+array2String(GL_PROFILE_LIST_ALL)+", "+ glAvailabilityToString());
+ }
+ }
+
+ /**
+ * @param device the device for which profiles shall be initialized
+ * @return true if any profile for the device exists, otherwise false
+ */
+ private static synchronized boolean initProfilesForDevice(AbstractGraphicsDevice device) {
+ if(null == device) {
+ return false;
+ }
+ GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device);
+ factory.enterThreadCriticalZone();
+ try {
+ return initProfilesForDeviceImpl(device);
+ } finally {
+ factory.leaveThreadCriticalZone();
+ }
+ }
+ private static synchronized boolean initProfilesForDeviceImpl(AbstractGraphicsDevice device) {
+ boolean isSet = GLContext.getAvailableGLVersionsSet(device);
+
+ if(DEBUG) {
+ String msg = "Info: GLProfile.initProfilesForDevice: "+device+", isSet "+isSet;
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ // System.err.println(msg);
+ }
+ if(isSet) {
+ return null != GLProfile.getDefault(device);
+ }
+
+ boolean addedDesktopProfile = false;
+ boolean addedEGLProfile = false;
+
+ if( hasDesktopGL && desktopFactory.getIsDeviceCompatible(device)) {
+ // 1st pretend we have all Desktop and EGL profiles ..
+ computeProfileMap(device, true /* desktopCtxUndef*/, true /* eglCtxUndef */);
+
+ // Triggers eager initialization of share context in GLDrawableFactory for the device,
+ // hence querying all available GLProfiles
+ boolean desktopSharedCtxAvail = desktopFactory.getIsSharedContextAvailable(device);
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail);
+ }
+ if( null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 2, GLContext.CTX_PROFILE_COMPAT,
+ 1, 5, GLContext.CTX_PROFILE_COMPAT|GLContext.CTX_OPTION_ANY);
+ }
+ addedDesktopProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
+ } else if( null!=eglFactory && ( hasGLES2Impl || hasGLES1Impl ) && eglFactory.getIsDeviceCompatible(device)) {
+ // 1st pretend we have all EGL profiles ..
+ computeProfileMap(device, false /* desktopCtxUndef*/, true /* eglCtxUndef */);
+
+ // Triggers eager initialization of share context in GLDrawableFactory for the device,
+ // hence querying all available GLProfiles
+ boolean eglSharedCtxAvail = eglFactory.getIsSharedContextAvailable(device);
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
+ }
+ if(hasGLES2Impl && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_ES) ) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 2, GLContext.CTX_PROFILE_ES,
+ 2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+ }
+ if(hasGLES1Impl && null == GLContext.getAvailableGLVersion(device, 1, GLContext.CTX_PROFILE_ES)) {
+ // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
+ // so we have to add the usual suspect
+ GLContext.mapAvailableGLVersion(device,
+ 1, GLContext.CTX_PROFILE_ES,
+ 1, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
+ }
+ addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
+ } else {
+ setProfileMap(device, new HashMap()); // empty
+ if(DEBUG) {
+ System.err.println("GLProfile: EGLFactory - Device is not available: "+device);
+ }
+ }
+
+ if(!GLContext.getAvailableGLVersionsSet(device)) {
+ GLContext.setAvailableGLVersionsSet(device);
+ }
+
+ if (DEBUG) {
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": added profile(s): desktop "+addedDesktopProfile+", egl "+addedEGLProfile);
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device));
+ if(addedDesktopProfile) {
+ dumpGLInfo(desktopFactory, device);
+ List/*<GLCapabilitiesImmutable>*/ availCaps = desktopFactory.getAvailableCapabilities(device);
+ for(int i=0; i<availCaps.size(); i++) {
+ System.err.println(availCaps.get(i));
+ }
+ } else if(addedEGLProfile) {
+ dumpGLInfo(eglFactory, device);
+ List/*<GLCapabilitiesImmutable>*/ availCaps = eglFactory.getAvailableCapabilities(device);
+ for(int i=0; i<availCaps.size(); i++) {
+ System.err.println(availCaps.get(i));
+ }
+ }
+ }
+
+ return addedDesktopProfile || addedEGLProfile;
+ }
+
+ private static void dumpGLInfo(GLDrawableFactoryImpl factory, AbstractGraphicsDevice device) {
+ GLContext ctx = factory.getOrCreateSharedContext(device);
+ if(null != ctx) {
+ System.err.println("GLProfile.dumpGLInfo: "+ctx);
+ ctx.makeCurrent();
+ try {
+ System.err.println(JoglVersion.getGLInfo(ctx.getGL(), null));
+ } finally {
+ ctx.release();
+ }
+ } else {
+ System.err.println("GLProfile.dumpGLInfo: shared context n/a");
+ }
+ }
+
+ public static AbstractGraphicsDevice getDefaultDevice() {
+ validateInitialization();
+ return defaultDevice;
+ }
+
+ public static AbstractGraphicsDevice getDefaultDesktopDevice() {
+ validateInitialization();
+ return defaultDesktopDevice;
+ }
+
+ public static AbstractGraphicsDevice getDefaultEGLDevice() {
+ validateInitialization();
+ return defaultEGLDevice;
+ }
+
+ private static void validateInitialization() {
+ if(!initialized) {
+ synchronized(GLProfile.class) {
+ if(!initialized) {
+ initSingleton(false);
+ }
+ }
+ }
+ }
+
+ private static String array2String(String[] list) {
+ StringBuffer msg = new StringBuffer();
+ msg.append("[");
+ for (int i = 0; i < list.length; i++) {
+ if (i > 0)
+ msg.append(", ");
+ msg.append(list[i]);
+ }
+ msg.append("]");
+ return msg.toString();
+ }
+
+ private static void glAvailabilityToString(AbstractGraphicsDevice device, StringBuffer sb, int major, int profile) {
+ String str = GLContext.getAvailableGLVersionAsString(device, major, profile);
+ if(null==str) {
+ throw new GLException("Internal Error");
+ }
+ sb.append("[");
+ sb.append(str);
+ sb.append("]");
+ }
+
+ private static boolean computeProfileMap(AbstractGraphicsDevice device, boolean desktopCtxUndef, boolean eglCtxUndef) {
+ if (DEBUG) {
+ System.err.println("GLProfile.init map "+device.getConnection()+", desktopCtxUndef "+desktopCtxUndef+", eglCtxUndef "+eglCtxUndef);
+ }
+ GLProfile defaultGLProfile = null;
+ HashMap/*<String, GLProfile>*/ _mappedProfiles = new HashMap(GL_PROFILE_LIST_ALL.length + 1 /* default */);
+ for(int i=0; i<GL_PROFILE_LIST_ALL.length; i++) {
+ String profile = GL_PROFILE_LIST_ALL[i];
+ String profileImpl = computeProfileImpl(device, profile, desktopCtxUndef, eglCtxUndef);
+ if(null!=profileImpl) {
+ GLProfile glProfile = new GLProfile(profile, profileImpl);
+ _mappedProfiles.put(profile, glProfile);
+ if (DEBUG) {
+ System.err.println("GLProfile.init map "+glProfile+" on devide "+device.getConnection());
+ }
+ if(null==defaultGLProfile) {
+ defaultGLProfile=glProfile;
+ if (DEBUG) {
+ System.err.println("GLProfile.init map default "+glProfile+" on device "+device.getConnection());
+ }
+ }
+ } else {
+ if (DEBUG) {
+ System.err.println("GLProfile.init map *** no mapping for "+profile+" on device "+device.getConnection());
+ }
+ }
+ }
+ if(null!=defaultGLProfile) {
+ _mappedProfiles.put(GL_DEFAULT, defaultGLProfile);
+ }
+ setProfileMap(device, _mappedProfiles);
+ return _mappedProfiles.size() > 0;
+ }
+
+ /**
+ * Returns the profile implementation
+ */
+ private static String computeProfileImpl(AbstractGraphicsDevice device, String profile, boolean desktopCtxUndef, boolean eglCtxUndef) {
+ if (GL2ES1.equals(profile)) {
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3bcAvailable(device)) {
+ return GL3bc;
+ } else if(GLContext.isGL4bcAvailable(device)) {
+ return GL4bc;
+ }
+ }
+ if(hasGLES1Impl && ( eglCtxUndef || GLContext.isGLES1Available(device))) {
+ return GLES1;
+ }
+ } else if (GL2ES2.equals(profile)) {
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3Available(device)) {
+ return GL3;
+ } else if(GLContext.isGL4Available(device)) {
+ return GL4;
+ }
+ }
+ if(hasGLES2Impl && ( eglCtxUndef || GLContext.isGLES2Available(device))) {
+ return GLES2;
+ }
+ } else if(GL2GL3.equals(profile)) {
+ if(hasGL234Impl) {
+ if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ return GL2;
+ } else if(GLContext.isGL3bcAvailable(device)) {
+ return GL3bc;
+ } else if(GLContext.isGL4bcAvailable(device)) {
+ return GL4bc;
+ } else if(GLContext.isGL3Available(device)) {
+ return GL3;
+ } else if(GLContext.isGL4Available(device)) {
+ return GL4;
+ }
+ }
+ } else if(GL4bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device))) {
+ return GL4bc;
+ } else if(GL4.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device))) {
+ return GL4;
+ } else if(GL3bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device))) {
+ return GL3bc;
+ } else if(GL3.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device))) {
+ return GL3;
+ } else if(GL2.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device))) {
+ return GL2;
+ } else if(GLES2.equals(profile) && hasGLES2Impl && ( eglCtxUndef || GLContext.isGLES2Available(device))) {
+ return GLES2;
+ } else if(GLES1.equals(profile) && hasGLES1Impl && ( eglCtxUndef || GLContext.isGLES1Available(device))) {
+ return GLES1;
+ }
+ return null;
+ }
+
+ private static String getGLImplBaseClassName(String profileImpl) {
+ if ( GL4bc.equals(profileImpl) ||
+ GL4.equals(profileImpl) ||
+ GL3bc.equals(profileImpl) ||
+ GL3.equals(profileImpl) ||
+ GL2.equals(profileImpl) ) {
+ return "jogamp.opengl.gl4.GL4bc";
+ } else if(GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl)) {
+ return "jogamp.opengl.es1.GLES1";
+ } else if(GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl)) {
+ return "jogamp.opengl.es2.GLES2";
+ } else {
+ throw new GLException("unsupported profile \"" + profileImpl + "\"");
+ }
+ }
+
+ private static /*final*/ HashMap/*<device_connection, HashMap<GL-String, GLProfile>*/ deviceConn2ProfileMap = new HashMap();
+
+ /**
+ * This implementation support lazy initialization, while avoiding recursion/deadlocks.<br>
+ * If no mapping 'device -> GLProfiles-Map' exists yet, it triggers<br>
+ * - create empty mapping device -> GLProfiles-Map <br>
+ * - initialization<br<
+ *
+ * @param device the key 'device -> GLProfiles-Map'
+ * @return the GLProfile HashMap
+ */
+ private static HashMap getProfileMap(AbstractGraphicsDevice device) {
+ validateInitialization();
+ if(null==device) {
+ device = defaultDevice;
+ }
+ String deviceKey = device.getUniqueID();
+ HashMap map = (HashMap) deviceConn2ProfileMap.get(deviceKey);
+ if(null==map) {
+ initProfilesForDevice(device);
+ if( null == deviceConn2ProfileMap.get(deviceKey) ) {
+ throw new InternalError("initProfilesForDevice(..) didn't issue setProfileMap(..) on "+device);
+ }
+ }
+ return map;
+ }
+
+ private static void setProfileMap(AbstractGraphicsDevice device, HashMap/*<GL-String, GLProfile>*/mappedProfiles) {
+ validateInitialization();
+ synchronized ( deviceConn2ProfileMap ) {
+ deviceConn2ProfileMap.put(device.getUniqueID(), mappedProfiles);
+ }
+ }
+
+ private GLProfile(String profile, String profileImpl) {
+ this.profile = profile;
+ this.profileImpl = profileImpl;
+ }
+
+ private String profileImpl = null;
+ private String profile = null;
+}
diff --git a/src/jogl/classes/javax/media/opengl/GLRunnable.java b/src/jogl/classes/javax/media/opengl/GLRunnable.java
new file mode 100644
index 000000000..de0f5df48
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLRunnable.java
@@ -0,0 +1,47 @@
+/**
+ * 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 javax.media.opengl;
+
+/**
+ * <p>
+ * Declares one-shot OpenGL commands usable for injection into a {@link GLAutoDrawable},<br>
+ * via {@link GLAutoDrawable#invoke(boolean, javax.media.opengl.GLRunnable)}.<br>
+ * {@link GLAutoDrawable} executes these commands within it's {@link GLAutoDrawable#display()}
+ * method while the OpenGL context is current.<br>
+ * <p>
+ * This might be useful to inject OpenGL commands from an I/O event listener.
+ */
+public interface GLRunnable {
+ /**
+ * Called by the drawable to initiate one-shot OpenGL commands by the
+ * client, like {@link GLEventListener#display(GLAutoDrawable)}.
+ */
+ void run(GLAutoDrawable drawable);
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/GLUniformData.java b/src/jogl/classes/javax/media/opengl/GLUniformData.java
new file mode 100644
index 000000000..9b0d5f151
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLUniformData.java
@@ -0,0 +1,154 @@
+
+package javax.media.opengl;
+
+import java.nio.*;
+
+public class GLUniformData {
+
+ /**
+ * int atom
+ *
+ * Number of objects is 1
+ *
+ */
+ public GLUniformData(String name, int val) {
+ init(name, 1, new Integer(val));
+ }
+
+ /**
+ * float atom
+ *
+ * Number of objects is 1
+ *
+ */
+ public GLUniformData(String name, float val) {
+ init(name, 1, new Float(val));
+ }
+
+ /**
+ * Multiple IntBuffer Vector
+ *
+ * Number of objects is calculated by data.limit()/components
+ *
+ * @param components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int components, IntBuffer data) {
+ init(name, components, data);
+ }
+
+ /**
+ * Multiple FloatBuffer Vector
+ *
+ * Number of objects is calculated by data.limit()/components
+ *
+ * @param components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int components, FloatBuffer data) {
+ init(name, components, data);
+ }
+
+ /**
+ * Multiple FloatBuffer Matrix
+ *
+ * Number of objects is calculated by data.limit()/(rows*columns)
+ *
+ * @param rows the matrix rows
+ * @param column the matrix column
+ */
+ public GLUniformData(String name, int rows, int columns, FloatBuffer data) {
+ init(name, rows, columns, data);
+ }
+
+ public void setData(int data) { init(new Integer(data)); }
+ public void setData(float data) { init(new Float(data)); }
+ public void setData(IntBuffer data) { init(data); }
+ public void setData(FloatBuffer data) { init(data); }
+
+ public int intValue() { return ((Integer)data).intValue(); };
+ public float floatValue() { return ((Float)data).floatValue(); };
+ public IntBuffer intBufferValue() { return (IntBuffer)data; };
+ public FloatBuffer floatBufferValue() { return (FloatBuffer)data; };
+
+ public String toString() {
+ return "GLUniformData[name "+name+
+ ", location "+location+
+ ", size "+rows+"*"+columns+
+ ", count "+count+
+ ", matrix "+isMatrix+
+ ", data "+data+
+ "]";
+ }
+
+ private void init(String name, int rows, int columns, Object data) {
+ if( 2>rows || rows>4 || 2>columns || columns>4 ) {
+ throw new GLException("rowsXcolumns must be within [2..4]X[2..4], is: "+rows+"X"+columns);
+ }
+ this.name=name;
+ this.rows=rows;
+ this.columns=columns;
+ this.isMatrix=true;
+ this.location=-1;
+ init(data);
+ }
+
+ private void init(String name, int components, Object data) {
+ if( 1>components || components>4 ) {
+ throw new GLException("components must be within [1..4], is: "+components);
+ }
+ this.name=name;
+ this.columns=components;
+ this.rows=1;
+ this.isMatrix=false;
+ this.location=-1;
+ init(data);
+ }
+
+ private void init(Object data) {
+ if(data instanceof Buffer) {
+ int sz = rows*columns;
+ Buffer buffer = (Buffer)data;
+ if(buffer.limit()<sz || 0!=buffer.limit()%sz) {
+ throw new GLException("data buffer size invalid: new buffer limit: "+buffer.limit()+"\n\t"+this);
+ }
+ this.count=buffer.limit()/(rows*columns);
+ } else {
+ if(isMatrix) {
+ throw new GLException("Atom type not allowed for matrix : "+this);
+ }
+ this.count=1;
+ }
+ this.data=data;
+ }
+
+ public String getName() { return name; }
+
+ public int getLocation() { return location; }
+
+ /**
+ * Sets the determined location of the shader uniform.
+ */
+ public void setLocation(int location) { this.location=location; }
+
+ public Object getObject() {
+ return data;
+ }
+ public Buffer getBuffer() {
+ return (data instanceof Buffer)?(Buffer)data:null;
+ }
+ public boolean isBuffer() {
+ return (data instanceof Buffer);
+ }
+ public boolean isMatrix() { return isMatrix; }
+
+ public int count() { return count; }
+ public int components() { return rows*columns; }
+ public int rows() { return rows; }
+ public int columns() { return columns; }
+
+ private String name;
+ private int location;
+ private int rows, columns;
+ private int count;
+ private Object data;
+ private boolean isMatrix;
+}
diff --git a/src/jogl/classes/javax/media/opengl/Threading.java b/src/jogl/classes/javax/media/opengl/Threading.java
new file mode 100644
index 000000000..d0f3ebb93
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/Threading.java
@@ -0,0 +1,166 @@
+/*
+ * 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 javax.media.opengl;
+
+import jogamp.opengl.*;
+
+/** This API provides access to the threading model for the implementation of
+ the classes in this package.
+
+ <P>
+
+ OpenGL is specified as a thread-safe API, but in practice there
+ are multithreading-related issues on most, if not all, of the
+ platforms which support it. For example, some OpenGL
+ implementations do not behave well when one context is made
+ current first on one thread, released, and then made current on a
+ second thread, although this is legal according to the OpenGL
+ specification. On other platforms there are other problems.
+
+ <P>
+
+ Due to these limitations, and due to the inherent multithreading
+ in the Java platform (in particular, in the Abstract Window
+ Toolkit), it is often necessary to limit the multithreading
+ occurring in the typical application using the OpenGL API.
+
+ <P>
+
+ In the current reference implementation, for instance, multithreading
+ has been limited by
+ forcing all OpenGL-related work for GLAutoDrawables on to a single
+ thread. In other words, if an application uses only the
+ GLAutoDrawable and GLEventListener callback mechanism, it is
+ guaranteed to have the most correct single-threaded behavior on
+ all platforms.
+
+ <P>
+
+ Applications using the GLContext makeCurrent/release API directly
+ will inherently break this single-threaded model, as these methods
+ require that the OpenGL context be made current on the current
+ thread immediately. For applications wishing to integrate better
+ with an implementation that uses the single-threaded model, this
+ class provides public access to the mechanism used by the implementation.
+
+ <P>
+
+ Users can execute Runnables on the
+ internal thread used for performing OpenGL work, and query whether
+ the current thread is already this thread. Using these mechanisms
+ the user can move work from the current thread on to the internal
+ OpenGL thread if desired.
+
+ <P>
+
+ This class also provides mechanisms for querying whether this
+ internal serialization of OpenGL work is in effect, and a
+ programmatic way of disabling it. In the current reference
+ implementation it is enabled by default, although it could be
+ disabled in the future if OpenGL drivers become more robust on
+ all platforms.
+
+ <P>
+
+ In addition to specifying programmatically whether the single
+ thread for OpenGL work is enabled, users may switch it on and off
+ using the system property <code>opengl.1thread</code>. Valid values
+ for this system property are:
+
+ <PRE>
+ -Dopengl.1thread=false Disable single-threading of OpenGL work
+ -Dopengl.1thread=true Enable single-threading of OpenGL work (default -- on a newly-created worker thread)
+ -Dopengl.1thread=auto Select default single-threading behavior (currently on)
+ -Dopengl.1thread=awt Enable single-threading of OpenGL work on AWT event dispatch thread (current default on all
+ platforms, and also the default behavior older releases)
+ -Dopengl.1thread=worker Enable single-threading of OpenGL work on newly-created worker thread (not suitable for Mac
+ OS X or X11 platforms, and risky on Windows in applet environments)
+ </PRE>
+*/
+
+public class Threading {
+
+ /** No reason to ever instantiate this class */
+ private Threading() {}
+
+ /** If an implementation of the javax.media.opengl APIs offers a
+ multithreading option but the default behavior is single-threading,
+ this API provides a mechanism for end users to disable single-threading
+ in this implementation. Users are strongly discouraged from
+ calling this method unless they are aware of all of the
+ consequences and are prepared to enforce some amount of
+ threading restrictions in their applications. Disabling
+ single-threading, for example, may have unintended consequences
+ on GLAutoDrawable implementations such as GLCanvas, GLJPanel and
+ GLPbuffer. Currently there is no supported way to re-enable it
+ once disabled, partly to discourage careless use of this
+ method. This method should be called as early as possible in an
+ application. */
+ public static void disableSingleThreading() {
+ ThreadingImpl.disableSingleThreading();
+ }
+
+ /** Indicates whether OpenGL work is being automatically forced to a
+ single thread in this implementation. */
+ public static boolean isSingleThreaded() {
+ return ThreadingImpl.isSingleThreaded();
+ }
+
+ /** Indicates whether the current thread is the single thread on
+ which this implementation of the javax.media.opengl APIs
+ performs all of its OpenGL-related work. This method should only
+ be called if the single-thread model is in effect. */
+ public static boolean isOpenGLThread() throws GLException {
+ return ThreadingImpl.isOpenGLThread();
+ }
+
+ /** Executes the passed Runnable on the single thread used for all
+ OpenGL work in this javax.media.opengl API implementation. It is
+ not specified exactly which thread is used for this
+ purpose. This method should only be called if the single-thread
+ model is in use and if the current thread is not the OpenGL
+ thread (i.e., if <code>isOpenGLThread()</code> returns
+ false). It is up to the end user to check to see whether the
+ current thread is the OpenGL thread and either execute the
+ Runnable directly or perform the work inside it. */
+ public static void invokeOnOpenGLThread(Runnable r) throws GLException {
+ ThreadingImpl.invokeOnOpenGLThread(r);
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java
new file mode 100644
index 000000000..d1e725b00
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java
@@ -0,0 +1,51 @@
+/*
+ * 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 javax.media.opengl.awt;
+
+import javax.media.opengl.*;
+
+public interface AWTGLAutoDrawable extends GLAutoDrawable, ComponentEvents {
+ /** Requests a new width and height for this AWTGLAutoDrawable. */
+ public void setSize(int width, int height);
+
+ /** Schedules a repaint of the component at some point in the
+ future. */
+ public void repaint();
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java b/src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java
new file mode 100644
index 000000000..0c4f63c2d
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java
@@ -0,0 +1,75 @@
+/*
+ * 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 javax.media.opengl.awt;
+
+import javax.media.opengl.*;
+import java.awt.event.*;
+import java.beans.PropertyChangeListener;
+
+/** Factors out the listener manipulation for the events supported by
+ all of the {@link GLDrawable} implementations. Provided to reduce
+ clutter in the documentation for GLDrawable. */
+
+public interface ComponentEvents {
+ public void addComponentListener(ComponentListener l);
+ public void removeComponentListener(ComponentListener l);
+ public void addFocusListener(FocusListener l);
+ public void removeFocusListener(FocusListener l);
+ public void addHierarchyBoundsListener(HierarchyBoundsListener l);
+ public void removeHierarchyBoundsListener(HierarchyBoundsListener l);
+ public void addHierarchyListener(HierarchyListener l);
+ public void removeHierarchyListener(HierarchyListener l);
+ public void addInputMethodListener(InputMethodListener l);
+ public void removeInputMethodListener(InputMethodListener l);
+ public void addKeyListener(KeyListener l);
+ public void removeKeyListener(KeyListener l);
+ public void addMouseListener(MouseListener l);
+ public void removeMouseListener(MouseListener l);
+ public void addMouseMotionListener(MouseMotionListener l);
+ public void removeMouseMotionListener(MouseMotionListener l);
+ public void addMouseWheelListener(MouseWheelListener l);
+ public void removeMouseWheelListener(MouseWheelListener l);
+ public void addPropertyChangeListener(PropertyChangeListener listener);
+ public void removePropertyChangeListener(PropertyChangeListener listener);
+ public void addPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener);
+ public void removePropertyChangeListener(String propertyName,
+ PropertyChangeListener listener);
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
new file mode 100644
index 000000000..4076dac54
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -0,0 +1,1074 @@
+/*
+ * 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 javax.media.opengl.awt;
+
+import java.beans.Beans;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import java.awt.Canvas;
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.geom.Rectangle2D;
+
+import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
+import javax.media.nativewindow.awt.AWTGraphicsDevice;
+import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.Threading;
+
+import com.jogamp.nativewindow.NativeWindowVersion;
+import com.jogamp.common.GlueGenVersion;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.opengl.JoglVersion;
+
+import com.jogamp.common.util.locks.RecursiveLock;
+import jogamp.opengl.Debug;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.ThreadingImpl;
+
+// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
+// context whenever the displayChanged() function is called on our
+// GLEventListeners
+
+/** A heavyweight AWT component which provides OpenGL rendering
+ support. This is the primary implementation of an AWT {@link GLDrawable};
+ {@link GLJPanel} is provided for compatibility with Swing user
+ interfaces when adding a heavyweight doesn't work either because
+ of Z-ordering or LayoutManager problems.
+ *
+ * <h5><A NAME="java2dgl">Java2D OpenGL Remarks</A></h5>
+ *
+ * To avoid any conflicts with a potential Java2D OpenGL context,<br>
+ * you shall consider setting the following JVM properties:<br>
+ * <ul>
+ * <li><pre>sun.java2d.opengl=false</pre></li>
+ * <li><pre>sun.java2d.noddraw=true</pre></li>
+ * </ul>
+ * This is especially true in case you want to utilize a GLProfile other than
+ * {@link GLProfile#GL2}, eg. using {@link GLProfile#getMaxFixedFunc()}.<br>
+ * On the other hand, if you like to experiment with GLJPanel's utilization
+ * of Java2D's OpenGL pipeline, you have to set them to
+ * <ul>
+ * <li><pre>sun.java2d.opengl=true</pre></li>
+ * <li><pre>sun.java2d.noddraw=true</pre></li>
+ * </ul>
+ *
+ * <h5><A NAME="backgrounderase">Disable Background Erase</A></h5>
+ *
+ * GLCanvas tries to disable background erase for the AWT Canvas
+ * before native peer creation (X11) and after it (Windows), <br>
+ * utilizing the optional {@link java.awt.Toolkit} method <code>disableBeackgroundErase(java.awt.Canvas)</code>.<br>
+ * However if this does not give you the desired results, you may want to disable AWT background erase in general:
+ * <ul>
+ * <li><pre>sun.awt.noerasebackground=true</pre></li>
+ * </ul>
+ */
+
+public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol {
+
+ private static final boolean DEBUG;
+
+ static {
+ DEBUG = Debug.debug("GLCanvas");
+ }
+
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private AWTGraphicsConfiguration awtConfig;
+ private GLDrawable drawable;
+ private GLContextImpl context;
+ private boolean sendReshape = false;
+
+ // copy of the cstr args, mainly for recreation
+ private GLCapabilitiesImmutable capsReqUser;
+ private GLCapabilitiesChooser chooser;
+ private GLContext shareWith;
+ private GraphicsDevice device;
+
+ private AWTWindowClosingProtocol awtWindowClosingProtocol =
+ new AWTWindowClosingProtocol(this, new Runnable() {
+ public void run() {
+ GLCanvas.this.destroy();
+ }
+ });
+
+ /** Creates a new GLCanvas component with a default set of OpenGL
+ capabilities, using the default OpenGL capabilities selection
+ mechanism, on the default screen device. */
+ public GLCanvas() {
+ this(null);
+ }
+
+ /** Creates a new GLCanvas component with the requested set of
+ OpenGL capabilities, using the default OpenGL capabilities
+ selection mechanism, on the default screen device.
+ * @see GLCanvas#GLCanvas(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, javax.media.opengl.GLContext, java.awt.GraphicsDevice)
+ */
+ public GLCanvas(GLCapabilitiesImmutable capsReqUser) {
+ this(capsReqUser, null, null, null);
+ }
+
+ /** Creates a new GLCanvas component with the requested set of
+ OpenGL capabilities, using the default OpenGL capabilities
+ selection mechanism, on the default screen device.
+ * This constructor variant also supports using a shared GLContext.
+ *
+ * @see GLCanvas#GLCanvas(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, javax.media.opengl.GLContext, java.awt.GraphicsDevice)
+ */
+ public GLCanvas(GLCapabilitiesImmutable capsReqUser, GLContext shareWith) {
+ this(capsReqUser, null, shareWith, null);
+ }
+
+ /** Creates a new GLCanvas component. The passed GLCapabilities
+ specifies the OpenGL capabilities for the component; if null, a
+ default set of capabilities is used. The GLCapabilitiesChooser
+ specifies the algorithm for selecting one of the available
+ GLCapabilities for the component; a DefaultGLCapabilitesChooser
+ is used if null is passed for this argument. The passed
+ GLContext specifies an OpenGL context with which to share
+ textures, display lists and other OpenGL state, and may be null
+ if sharing is not desired. See the note in the overview
+ documentation on <a
+ href="../../../overview-summary.html#SHARING">context
+ sharing</a>. The passed GraphicsDevice indicates the screen on
+ which to create the GLCanvas; the GLDrawableFactory uses the
+ default screen device of the local GraphicsEnvironment if null
+ is passed for this argument. */
+ public GLCanvas(GLCapabilitiesImmutable capsReqUser,
+ GLCapabilitiesChooser chooser,
+ GLContext shareWith,
+ GraphicsDevice device) {
+ /*
+ * Determination of the native window is made in 'super.addNotify()',
+ * which creates the native peer using AWT's GraphicsConfiguration.
+ * GraphicsConfiguration is returned by this class overwritten
+ * 'getGraphicsConfiguration()', which returns our OpenGL compatible
+ * 'chosen' GraphicsConfiguration.
+ */
+ super();
+
+ if(null==capsReqUser) {
+ capsReqUser = new GLCapabilities(GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()));
+ } else {
+ // don't allow the user to change data
+ capsReqUser = (GLCapabilitiesImmutable) capsReqUser.cloneMutable();
+ }
+
+ if(null==device) {
+ GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ if(null!=gc) {
+ device = gc.getDevice();
+ }
+ }
+
+ // instantiation will be issued in addNotify()
+ this.capsReqUser = capsReqUser;
+ this.chooser = chooser;
+ this.shareWith = shareWith;
+ this.device = device;
+ }
+
+ /**
+ * Overridden to choose a GraphicsConfiguration on a parent container's
+ * GraphicsDevice because both devices
+ */
+ @Override
+ public GraphicsConfiguration getGraphicsConfiguration() {
+ /*
+ * Workaround for problems with Xinerama and java.awt.Component.checkGD
+ * when adding to a container on a different graphics device than the
+ * one that this Canvas is associated with.
+ *
+ * GC will be null unless:
+ * - A native peer has assigned it. This means we have a native
+ * peer, and are already comitted to a graphics configuration.
+ * - This canvas has been added to a component hierarchy and has
+ * an ancestor with a non-null GC, but the native peer has not
+ * yet been created. This means we can still choose the GC on
+ * all platforms since the peer hasn't been created.
+ */
+ final GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ /*
+ * chosen is only non-null on platforms where the GLDrawableFactory
+ * returns a non-null GraphicsConfiguration (in the GLCanvas
+ * constructor).
+ *
+ * if gc is from this Canvas' native peer then it should equal chosen,
+ * otherwise it is from an ancestor component that this Canvas is being
+ * added to, and we go into this block.
+ */
+ GraphicsConfiguration chosen = awtConfig.getGraphicsConfiguration();
+
+ if (gc != null && chosen != null && !chosen.equals(gc)) {
+ /*
+ * Check for compatibility with gc. If they differ by only the
+ * device then return a new GCconfig with the super-class' GDevice
+ * (and presumably the same visual ID in Xinerama).
+ *
+ */
+ if (!chosen.getDevice().getIDstring().equals(gc.getDevice().getIDstring())) {
+ /*
+ * Here we select a GraphicsConfiguration on the alternate
+ * device that is presumably identical to the chosen
+ * configuration, but on the other device.
+ *
+ * Should really check to ensure that we select a configuration
+ * with the same X visual ID for Xinerama screens, otherwise the
+ * GLDrawable may have the wrong visual ID (I don't think this
+ * ever gets updated). May need to add a method to
+ * X11GLDrawableFactory to do this in a platform specific
+ * manner.
+ *
+ * However, on platforms where we can actually get into this
+ * block, both devices should have the same visual list, and the
+ * same configuration should be selected here.
+ */
+ AWTGraphicsConfiguration config = chooseGraphicsConfiguration( (GLCapabilitiesImmutable)awtConfig.getChosenCapabilities(),
+ (GLCapabilitiesImmutable)awtConfig.getRequestedCapabilities(),
+ chooser, gc.getDevice());
+ final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null;
+ boolean equalCaps = config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities());
+ if(DEBUG) {
+ Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName());
+ e.printStackTrace();
+ System.err.println("!!! Created Config (n): HAVE GC "+chosen);
+ System.err.println("!!! Created Config (n): THIS GC "+gc);
+ System.err.println("!!! Created Config (n): Choosen GC "+compatible);
+ System.err.println("!!! Created Config (n): HAVE CF "+awtConfig);
+ System.err.println("!!! Created Config (n): Choosen CF "+config);
+ System.err.println("!!! Created Config (n): EQUALS CAPS "+equalCaps);
+ }
+
+ if (compatible != null) {
+ /*
+ * Save the new GC for equals test above, and to return to
+ * any outside callers of this method.
+ */
+ chosen = compatible;
+
+ awtConfig = config;
+
+ if( !equalCaps && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) {
+ dispose(true);
+ }
+ }
+ }
+
+ /*
+ * If a compatible GC was not found in the block above, this will
+ * return the GC that was selected in the constructor (and might
+ * cause an exception in Component.checkGD when adding to a
+ * container, but in this case that would be the desired behavior).
+ *
+ */
+ return chosen;
+ } else if (gc == null) {
+ /*
+ * The GC is null, which means we have no native peer, and are not
+ * part of a (realized) component hierarchy. So we return the
+ * desired visual that was selected in the constructor (possibly
+ * null).
+ */
+ return chosen;
+ }
+
+ /*
+ * Otherwise we have not explicitly selected a GC in the constructor, so
+ * just return what Canvas would have.
+ */
+ return gc;
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ drawableSync.lock();
+ try {
+ return (null != drawable) ? drawable.createContext(shareWith) : null;
+ } finally {
+ drawableSync.unlock();
+ }
+ }
+
+ public void setRealized(boolean realized) {
+ }
+
+ public boolean isRealized() {
+ drawableSync.lock();
+ try {
+ return ( null != drawable ) ? drawable.isRealized() : false;
+ } finally {
+ drawableSync.unlock();
+ }
+ }
+
+ public int getDefaultCloseOperation() {
+ return awtWindowClosingProtocol.getDefaultCloseOperation();
+ }
+
+ public int setDefaultCloseOperation(int op) {
+ return awtWindowClosingProtocol.setDefaultCloseOperation(op);
+ }
+
+ public void display() {
+ if( !validateGLDrawable() ) {
+ if(DEBUG) {
+ System.err.println("Info: GLCanvas display - skipped GL render, drawable not valid yet");
+ }
+ return; // not yet available ..
+ }
+ maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
+ displayAction);
+
+ awtWindowClosingProtocol.addClosingListenerOneShot();
+ }
+
+ private void dispose(boolean regenerate) {
+ drawableSync.lock();
+ try {
+ if(DEBUG) {
+ Exception ex1 = new Exception("Info: dispose("+regenerate+") - start, hasContext " +
+ (null!=context) + ", hasDrawable " + (null!=drawable));
+ ex1.printStackTrace();
+ }
+
+ if(null!=context) {
+ boolean animatorPaused = false;
+ GLAnimatorControl animator = getAnimator();
+ if(null!=animator) {
+ // can't remove us from animator for recreational addNotify()
+ animatorPaused = animator.pause();
+ }
+
+ disposeRegenerate=regenerate;
+
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ // Workaround for termination issues with applets --
+ // sun.applet.AppletPanel should probably be performing the
+ // remove() call on the EDT rather than on its own thread
+ // Hint: User should run remove from EDT.
+ if (ThreadingImpl.isAWTMode() &&
+ Thread.holdsLock(getTreeLock())) {
+ // The user really should not be invoking remove() from this
+ // thread -- but since he/she is, we can not go over to the
+ // EDT at this point. Try to destroy the context from here.
+ if(context.isCreated()) {
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ }
+ } else if(context.isCreated()) {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else if(context.isCreated()) {
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ }
+
+ if(animatorPaused) {
+ animator.resume();
+ }
+ }
+ if(!regenerate) {
+ disposeAbstractGraphicsDevice();
+ }
+
+ if(DEBUG) {
+ System.err.println("dispose("+regenerate+") - stop");
+ }
+ } finally {
+ drawableSync.unlock();
+ }
+ }
+
+ /**
+ * Just an alias for removeNotify
+ */
+ public void destroy() {
+ removeNotify();
+ }
+
+ /** Overridden to cause OpenGL rendering to be performed during
+ repaint cycles. Subclasses which override this method must call
+ super.paint() in their paint() method in order to function
+ properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>paint</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ @Override
+ public void paint(Graphics g) {
+ if (Beans.isDesignTime()) {
+ // Make GLCanvas behave better in NetBeans GUI builder
+ g.setColor(Color.BLACK);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ FontMetrics fm = g.getFontMetrics();
+ String name = getName();
+ if (name == null) {
+ name = getClass().getName();
+ int idx = name.lastIndexOf('.');
+ if (idx >= 0) {
+ name = name.substring(idx + 1);
+ }
+ }
+ Rectangle2D bounds = fm.getStringBounds(name, g);
+ g.setColor(Color.WHITE);
+ g.drawString(name,
+ (int) ((getWidth() - bounds.getWidth()) / 2),
+ (int) ((getHeight() + bounds.getHeight()) / 2));
+ return;
+ }
+ if( ! this.drawableHelper.isExternalAnimatorAnimating() ) {
+ display();
+ }
+ }
+
+ RecursiveLock drawableSync = new RecursiveLock();
+
+ /** Overridden to track when this component is added to a container.
+ Subclasses which override this method must call
+ super.addNotify() in their addNotify() method in order to
+ function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ @Override
+ public void addNotify() {
+ if(DEBUG) {
+ Exception ex1 = new Exception(Thread.currentThread().getName()+" - Info: addNotify - start, bounds: "+this.getBounds());
+ ex1.printStackTrace();
+ }
+
+ drawableSync.lock();
+ try {
+ /**
+ * 'super.addNotify()' determines the GraphicsConfiguration,
+ * while calling this class's overriden 'getGraphicsConfiguration()' method
+ * after which it creates the native peer.
+ * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
+ * is being used in getGraphicsConfiguration().
+ * This code order also allows recreation, ie re-adding the GLCanvas.
+ */
+ awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
+ if(null==awtConfig) {
+ throw new GLException("Error: NULL AWTGraphicsConfiguration");
+ }
+
+ if (!Beans.isDesignTime()) {
+ // no lock required, since this resource ain't available yet
+ drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
+ .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig));
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setSynchronized(true);
+ }
+
+ // before native peer is valid: X11
+ disableBackgroundErase();
+
+ // issues getGraphicsConfiguration() and creates the native peer
+ super.addNotify();
+
+ // after native peer is valid: Windows
+ disableBackgroundErase();
+
+ // init drawable by paint/display makes the init sequence more equal
+ // for all launch flavors (applet/javaws/..)
+ // validateGLDrawable();
+
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - Info: addNotify - end: peer: "+getPeer());
+ }
+ } finally {
+ drawableSync.unlock();
+ }
+ }
+
+ private boolean validateGLDrawable() {
+ boolean realized = false;
+ if (!Beans.isDesignTime()) {
+ drawableSync.lock();
+ try {
+ if ( null != drawable ) {
+ realized = drawable.isRealized();
+ if ( !realized && 0 < drawable.getWidth() * drawable.getHeight() ) {
+ drawable.setRealized(true);
+ realized = true;
+ sendReshape=true; // ensure a reshape is being send ..
+ if(DEBUG) {
+ String msg = Thread.currentThread().getName()+" - Realized Drawable: "+drawable.toString();
+ // System.err.println(msg);
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ }
+ }
+ }
+ } finally {
+ drawableSync.unlock();
+ }
+ }
+ return realized;
+ }
+
+ /** <p>Overridden to track when this component is removed from a
+ container. Subclasses which override this method must call
+ super.removeNotify() in their removeNotify() method in order to
+ function properly. </p>
+ <p>User shall not call this method outside of EDT, read the AWT/Swing specs
+ about this.</p>
+ <B>Overrides:</B>
+ <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ @Override
+ public void removeNotify() {
+ if(DEBUG) {
+ Exception ex1 = new Exception(Thread.currentThread().getName()+" - Info: removeNotify - start");
+ ex1.printStackTrace();
+ }
+
+ awtWindowClosingProtocol.removeClosingListener();
+
+ if (Beans.isDesignTime()) {
+ super.removeNotify();
+ } else {
+ drawableSync.lock();
+ try {
+ dispose(false);
+ } finally {
+ context=null;
+ drawable=null;
+ awtConfig=null;
+ super.removeNotify();
+ drawableSync.unlock();
+ }
+ }
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - Info: removeNotify - end, peer: "+getPeer());
+ }
+ }
+
+ /** Overridden to cause {@link GLDrawableHelper#reshape} to be
+ called on all registered {@link GLEventListener}s. Subclasses
+ which override this method must call super.reshape() in
+ their reshape() method in order to function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ @Override
+ public void reshape(int x, int y, int width, int height) {
+ super.reshape(x, y, width, height);
+ sendReshape = true;
+ }
+
+ /** <B>Overrides:</B>
+ <DL><DD><CODE>update</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ /**
+ * Overridden from Canvas to prevent the AWT's clearing of the
+ * canvas from interfering with the OpenGL rendering.
+ */
+ @Override
+ public void update(Graphics g) {
+ paint(g);
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void addGLEventListener(int index, GLEventListener listener) {
+ drawableHelper.addGLEventListener(index, listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public void setAnimator(GLAnimatorControl animatorControl) {
+ drawableHelper.setAnimator(animatorControl);
+ }
+
+ public GLAnimatorControl getAnimator() {
+ return drawableHelper.getAnimator();
+ }
+
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ drawableHelper.invoke(this, wait, glRunnable);
+ }
+
+ public void setContext(GLContext ctx) {
+ context=(GLContextImpl)ctx;
+ }
+
+ public GLContext getContext() {
+ return context;
+ }
+
+ public GL getGL() {
+ if (Beans.isDesignTime()) {
+ return null;
+ }
+ GLContext ctx = getContext();
+ return (ctx == null) ? null : ctx.getGL();
+ }
+
+ public GL setGL(GL gl) {
+ GLContext ctx = getContext();
+ if (ctx != null) {
+ ctx.setGL(gl);
+ return gl;
+ }
+ return null;
+ }
+
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ drawableHelper.setAutoSwapBufferMode(onOrOff);
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ return drawableHelper.getAutoSwapBufferMode();
+ }
+
+ public void swapBuffers() {
+ maybeDoSingleThreadedWorkaround(swapBuffersOnEventDispatchThreadAction, swapBuffersAction);
+ }
+
+ public GLProfile getGLProfile() {
+ return capsReqUser.getGLProfile();
+ }
+
+ public GLCapabilitiesImmutable getChosenGLCapabilities() {
+ if (awtConfig == null) {
+ throw new GLException("No AWTGraphicsConfiguration: "+this);
+ }
+
+ return (GLCapabilitiesImmutable)awtConfig.getChosenCapabilities();
+ }
+
+ public GLCapabilitiesImmutable getRequestedGLCapabilities() {
+ if (awtConfig == null) {
+ return capsReqUser;
+ }
+
+ return (GLCapabilitiesImmutable)awtConfig.getRequestedCapabilities();
+ }
+
+ public NativeSurface getNativeSurface() {
+ drawableSync.lock();
+ try {
+ return (null != drawable) ? drawable.getNativeSurface() : null;
+ } finally {
+ drawableSync.unlock();
+ }
+ }
+
+ public long getHandle() {
+ drawableSync.lock();
+ try {
+ return (null != drawable) ? drawable.getHandle() : 0;
+ } finally {
+ drawableSync.unlock();
+ }
+ }
+
+ public GLDrawableFactory getFactory() {
+ drawableSync.lock();
+ try {
+ return (null != drawable) ? drawable.getFactory() : null;
+ } finally {
+ drawableSync.unlock();
+ }
+ }
+
+ @Override
+ public String toString() {
+ final int dw = (null!=drawable) ? drawable.getWidth() : -1;
+ final int dh = (null!=drawable) ? drawable.getHeight() : -1;
+
+ return "AWT-GLCanvas[Realized "+isRealized()+
+ ",\n\t"+((null!=drawable)?drawable.getClass().getName():"null-drawable")+
+ ",\n\tRealized "+isRealized()+
+ ",\n\tFactory "+getFactory()+
+ ",\n\thandle 0x"+Long.toHexString(getHandle())+
+ ",\n\tDrawable size "+dw+"x"+dh+
+ ",\n\tAWT pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
+ ",\n\tvisible "+isVisible()+
+ ",\n\t"+awtConfig+"]";
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void maybeDoSingleThreadedWorkaround(Runnable eventDispatchThreadAction,
+ Runnable invokeGLAction) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(eventDispatchThreadAction);
+ } else {
+ drawableHelper.invokeGL(drawable, context, invokeGLAction, initAction);
+ }
+ }
+
+ class DisposeAction implements Runnable {
+ public void run() {
+ drawableHelper.dispose(GLCanvas.this);
+
+ if(null!=context) {
+ context.makeCurrent(); // implicit wait for lock ..
+ context.destroy();
+ context=null;
+ }
+
+ if(null!=drawable) {
+ drawable.setRealized(false);
+ drawable=null;
+ }
+
+ if(disposeRegenerate) {
+ // recreate GLDrawable to reflect it's new graphics configuration
+ drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
+ .createGLDrawable(NativeWindowFactory.getNativeWindow(GLCanvas.this, awtConfig));
+ if(DEBUG) {
+ System.err.println("GLCanvas.dispose(true): new drawable: "+drawable);
+ }
+ drawable.setRealized(true);
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setSynchronized(true);
+ sendReshape=true; // ensure a reshape is being send ..
+ }
+ }
+ }
+ private boolean disposeRegenerate;
+ private DisposeAction disposeAction = new DisposeAction();
+
+ private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
+ new DisposeOnEventDispatchThreadAction();
+
+ class DisposeOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ }
+ }
+
+ class DisposeAbstractGraphicsDeviceAction implements Runnable {
+ public void run() {
+ AbstractGraphicsConfiguration aconfig = (null!=awtConfig) ? awtConfig.getNativeGraphicsConfiguration() : null;
+ AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
+ AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null;
+ if(null!=adevice) {
+ String adeviceMsg=null;
+ if(DEBUG) {
+ adeviceMsg = adevice.toString();
+ }
+ boolean closed = adevice.close();
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName() + " - GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ }
+ }
+ awtConfig=null;
+ }
+ }
+ private DisposeAbstractGraphicsDeviceAction disposeAbstractGraphicsDeviceAction = new DisposeAbstractGraphicsDeviceAction();
+
+ /**
+ * Disposes the AbstractGraphicsDevice within EDT,
+ * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ *
+ * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
+ */
+ void disposeAbstractGraphicsDevice() {
+ if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
+ disposeAbstractGraphicsDeviceAction.run();
+ } else {
+ try {
+ EventQueue.invokeAndWait(disposeAbstractGraphicsDeviceAction);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ }
+ }
+
+ class InitAction implements Runnable {
+ public void run() {
+ drawableHelper.init(GLCanvas.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ if (sendReshape) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - reshape: "+getWidth()+"x"+getHeight());
+ }
+ // Note: we ignore the given x and y within the parent component
+ // since we are drawing directly into this heavyweight component.
+ drawableHelper.reshape(GLCanvas.this, 0, 0, getWidth(), getHeight());
+ sendReshape = false;
+ }
+
+ drawableHelper.display(GLCanvas.this);
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+
+ class SwapBuffersAction implements Runnable {
+ public void run() {
+ drawable.swapBuffers();
+ }
+ }
+ private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
+
+ // Workaround for ATI driver bugs related to multithreading issues
+ // like simultaneous rendering via Animators to canvases that are
+ // being resized on the AWT event dispatch thread
+ class DisplayOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(drawable, context, displayAction, initAction);
+ }
+ }
+ private DisplayOnEventDispatchThreadAction displayOnEventDispatchThreadAction =
+ new DisplayOnEventDispatchThreadAction();
+ class SwapBuffersOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ }
+ }
+ private SwapBuffersOnEventDispatchThreadAction swapBuffersOnEventDispatchThreadAction =
+ new SwapBuffersOnEventDispatchThreadAction();
+
+ // Disables the AWT's erasing of this Canvas's background on Windows
+ // in Java SE 6. This internal API is not available in previous
+ // releases, but the system property
+ // -Dsun.awt.noerasebackground=true can be specified to get similar
+ // results globally in previous releases.
+ private static boolean disableBackgroundEraseInitialized;
+ private static Method disableBackgroundEraseMethod;
+ private void disableBackgroundErase() {
+ if (!disableBackgroundEraseInitialized) {
+ try {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class clazz = getToolkit().getClass();
+ while (clazz != null && disableBackgroundEraseMethod == null) {
+ try {
+ disableBackgroundEraseMethod =
+ clazz.getDeclaredMethod("disableBackgroundErase",
+ new Class[] { Canvas.class });
+ disableBackgroundEraseMethod.setAccessible(true);
+ } catch (Exception e) {
+ clazz = clazz.getSuperclass();
+ }
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ }
+ disableBackgroundEraseInitialized = true;
+ if(DEBUG) {
+ System.err.println("GLCanvas: TK disableBackgroundErase method found: "+
+ (null!=disableBackgroundEraseMethod));
+ }
+ }
+ if (disableBackgroundEraseMethod != null) {
+ Throwable t=null;
+ try {
+ disableBackgroundEraseMethod.invoke(getToolkit(), new Object[] { this });
+ } catch (Exception e) {
+ t = e;
+ }
+ if(DEBUG) {
+ System.err.println("GLCanvas: TK disableBackgroundErase error: "+t);
+ }
+ }
+ }
+
+ /**
+ * Issues the GraphicsConfigurationFactory's choosing facility within EDT,
+ * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ *
+ * @param capsChosen
+ * @param capsRequested
+ * @param chooser
+ * @param device
+ * @return the chosen AWTGraphicsConfiguration
+ *
+ * @see #disposeAbstractGraphicsDevice()
+ */
+ private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
+ final GLCapabilitiesImmutable capsRequested,
+ final GLCapabilitiesChooser chooser,
+ final GraphicsDevice device) {
+ // Make GLCanvas behave better in NetBeans GUI builder
+ if (Beans.isDesignTime()) {
+ return null;
+ }
+
+ final AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
+ AWTGraphicsConfiguration config = null;
+
+ if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
+ config = (AWTGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+ capsRequested,
+ chooser, aScreen);
+ } else {
+ try {
+ final ArrayList bucket = new ArrayList(1);
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ AWTGraphicsConfiguration c = (AWTGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+ capsRequested,
+ chooser, aScreen);
+ bucket.add(c);
+ }
+ });
+ config = ( bucket.size() > 0 ) ? (AWTGraphicsConfiguration)bucket.get(0) : null ;
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ }
+
+ if (config == null) {
+ throw new GLException("Error: Couldn't fetch AWTGraphicsConfiguration");
+ }
+
+ return config;
+ }
+
+ /**
+ * A most simple JOGL AWT test entry
+ */
+ public static void main(String args[]) {
+ System.err.println(VersionUtil.getPlatformInfo());
+ System.err.println(GlueGenVersion.getInstance());
+ System.err.println(NativeWindowVersion.getInstance());
+ System.err.println(JoglVersion.getInstance());
+
+ GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
+ List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null);
+ for(int i=0; i<availCaps.size(); i++) {
+ System.err.println(availCaps.get(i));
+ }
+
+ GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) );
+ Frame frame = new Frame("JOGL AWT Test");
+
+ GLCanvas glCanvas = new GLCanvas(caps);
+ frame.add(glCanvas);
+ frame.setSize(128, 128);
+
+ glCanvas.addGLEventListener(new GLEventListener() {
+ public void init(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ System.err.println(JoglVersion.getGLInfo(gl, null));
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ }
+ });
+
+ final Frame _frame = frame;
+ final GLCanvas _glCanvas = glCanvas;
+
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ _frame.setVisible(true);
+ }});
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ glCanvas.display();
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ _frame.setVisible(false);
+ _frame.remove(_glCanvas);
+ _frame.dispose();
+ }});
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
new file mode 100644
index 000000000..d58ad0304
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -0,0 +1,1721 @@
+/*
+ * 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 javax.media.opengl.awt;
+
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.beans.Beans;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+
+import java.awt.Color;
+import java.awt.EventQueue;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import javax.swing.JPanel;
+
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.Threading;
+import com.jogamp.opengl.util.FBObject;
+import jogamp.opengl.Debug;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableFactoryImpl;
+import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.ThreadingImpl;
+import jogamp.opengl.awt.Java2D;
+import jogamp.opengl.awt.Java2DGLContext;
+
+// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
+// context whenever the displayChanged() function is called on their
+// GLEventListeners
+
+/** A lightweight Swing component which provides OpenGL rendering
+ support. Provided for compatibility with Swing user interfaces
+ when adding a heavyweight doesn't work either because of
+ Z-ordering or LayoutManager problems.
+ <P>
+ The GLJPanel can be made transparent by creating it with a
+ GLCapabilities object with alpha bits specified and calling {@link
+ #setOpaque}(false). Pixels with resulting OpenGL alpha values less
+ than 1.0 will be overlaid on any underlying Swing rendering. </P>
+ <P>
+ Notes specific to the Reference Implementation: This component
+ attempts to use hardware-accelerated rendering via pbuffers and
+ falls back on to software rendering if problems occur.
+ Note that because this component attempts to use pbuffers for
+ rendering, and because pbuffers can not be resized, somewhat
+ surprising behavior may occur during resize operations; the {@link
+ GLEventListener#init} method may be called multiple times as the
+ pbuffer is resized to be able to cover the size of the GLJPanel.
+ This behavior is correct, as the textures and display lists for
+ the GLJPanel will have been lost during the resize operation. The
+ application should attempt to make its GLEventListener.init()
+ methods as side-effect-free as possible. </P>
+ <P>
+ * Please read <A HREF="GLCanvas.html#java2dgl">Java2D OpenGL Remarks</A>.
+ * </P>
+*/
+
+public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
+ private static final boolean DEBUG = Debug.debug("GLJPanel");
+ private static final boolean VERBOSE = Debug.verbose();
+
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private volatile boolean isInitialized;
+
+ // Data used for either pbuffers or pixmap-based offscreen surfaces
+ private GLCapabilitiesImmutable offscreenCaps;
+ private GLProfile glProfile;
+ private GLDrawableFactoryImpl factory;
+ private GLCapabilitiesChooser chooser;
+ private GLContext shareWith;
+ // Width of the actual GLJPanel
+ private int panelWidth = 0;
+ private int panelHeight = 0;
+ // Lazy reshape notification
+ private boolean handleReshape = false;
+ private boolean sendReshape = true;
+
+ // The backend in use
+ private Backend backend;
+
+ // Used by all backends either directly or indirectly to hook up callbacks
+ private Updater updater = new Updater();
+
+ private static final AccessControlContext localACC = AccessController.getContext();
+
+ // Turns off the pbuffer-based backend (used by default, unless the
+ // Java 2D / OpenGL pipeline is in use)
+ private static boolean hardwareAccelerationDisabled =
+ Debug.isPropertyDefined("jogl.gljpanel.nohw", true, localACC);
+
+ // Turns off the fallback to software-based rendering from
+ // pbuffer-based rendering
+ private static boolean softwareRenderingDisabled =
+ Debug.isPropertyDefined("jogl.gljpanel.nosw", true, localACC);
+
+ // Indicates whether the Java 2D OpenGL pipeline is enabled
+ private boolean oglPipelineEnabled =
+ Java2D.isOGLPipelineActive() &&
+ !Debug.isPropertyDefined("jogl.gljpanel.noogl", true, localACC);
+
+ // For handling reshape events lazily
+ // private int reshapeX;
+ // private int reshapeY;
+ private int reshapeWidth;
+ private int reshapeHeight;
+
+ // These are always set to (0, 0) except when the Java2D / OpenGL
+ // pipeline is active
+ private int viewportX;
+ private int viewportY;
+
+ private AWTWindowClosingProtocol awtWindowClosingProtocol =
+ new AWTWindowClosingProtocol(this, new Runnable() {
+ public void run() {
+ GLJPanel.this.destroy();
+ }
+ });
+
+ static {
+ // Force eager initialization of part of the Java2D class since
+ // otherwise it's likely it will try to be initialized while on
+ // the Queue Flusher Thread, which is not allowed
+ if (Java2D.isOGLPipelineActive() && Java2D.isFBOEnabled()) {
+ Java2D.getShareContext(GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice());
+ }
+ }
+
+ /** Creates a new GLJPanel component with a default set of OpenGL
+ capabilities and using the default OpenGL capabilities selection
+ mechanism. */
+ public GLJPanel() {
+ this(null);
+ }
+
+ /** Creates a new GLJPanel component with the requested set of
+ OpenGL capabilities, using the default OpenGL capabilities
+ selection mechanism. */
+ public GLJPanel(GLCapabilitiesImmutable userCapsRequest) {
+ this(userCapsRequest, null, null);
+ }
+
+ /** Creates a new GLJPanel component. The passed GLCapabilities
+ specifies the OpenGL capabilities for the component; if null, a
+ default set of capabilities is used. The GLCapabilitiesChooser
+ specifies the algorithm for selecting one of the available
+ GLCapabilities for the component; a DefaultGLCapabilitesChooser
+ is used if null is passed for this argument. The passed
+ GLContext specifies an OpenGL context with which to share
+ textures, display lists and other OpenGL state, and may be null
+ if sharing is not desired. See the note in the overview documentation on
+ <a href="../../../overview-summary.html#SHARING">context sharing</a>.
+ <P>
+ Note: Sharing cannot be enabled using J2D OpenGL FBO sharing,
+ since J2D GL Context must be shared and we can only share one context.
+ */
+ public GLJPanel(GLCapabilitiesImmutable userCapsRequest, GLCapabilitiesChooser chooser, GLContext shareWith) {
+ super();
+
+ // Works around problems on many vendors' cards; we don't need a
+ // back buffer for the offscreen surface anyway
+ {
+ GLCapabilities caps;
+ if (userCapsRequest != null) {
+ caps = (GLCapabilities) userCapsRequest.cloneMutable();
+ } else {
+ caps = new GLCapabilities(null);
+ }
+ caps.setDoubleBuffered(false);
+ offscreenCaps = caps;
+ }
+ this.glProfile = offscreenCaps.getGLProfile();
+ this.factory = GLDrawableFactoryImpl.getFactoryImpl(glProfile);
+ this.chooser = ((chooser != null) ? chooser : new DefaultGLCapabilitiesChooser());
+ this.shareWith = shareWith;
+ }
+
+ public void display() {
+ if (EventQueue.isDispatchThread()) {
+ // Want display() to be synchronous, so call paintImmediately()
+ paintImmediately(0, 0, getWidth(), getHeight());
+ } else {
+ // Multithreaded redrawing of Swing components is not allowed,
+ // so do everything on the event dispatch thread
+ try {
+ EventQueue.invokeAndWait(paintImmediatelyAction);
+ } catch (Exception e) {
+ throw new GLException(e);
+ }
+ }
+ }
+
+ protected void dispose(boolean regenerate) {
+ if(DEBUG) {
+ Exception ex1 = new Exception("Info: dispose("+regenerate+") - start");
+ ex1.printStackTrace();
+ }
+
+ if (backend != null) {
+ boolean animatorPaused = false;
+ GLAnimatorControl animator = getAnimator();
+ if(null!=animator) {
+ if(regenerate) {
+ animatorPaused = animator.pause();
+ } else {
+ animator.remove(this);
+ }
+ }
+
+ disposeRegenerate=regenerate;
+ disposeContext=backend.getContext();
+ disposeDrawable=backend.getDrawable();
+
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ // Workaround for termination issues with applets --
+ // sun.applet.AppletPanel should probably be performing the
+ // remove() call on the EDT rather than on its own thread
+ if (ThreadingImpl.isAWTMode() &&
+ Thread.holdsLock(getTreeLock())) {
+ // The user really should not be invoking remove() from this
+ // thread -- but since he/she is, we can not go over to the
+ // EDT at this point. Try to destroy the context from here.
+ if(disposeContext.isCreated()) {
+ drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ }
+ } else if(disposeContext.isCreated()) {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else if(disposeContext.isCreated()) {
+ drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ }
+
+ if(!regenerate) {
+ AbstractGraphicsDevice adevice = disposeDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ String adeviceMsg=null;
+ if(DEBUG) {
+ adeviceMsg = adevice.toString();
+ }
+ // boolean closed = adevice.close();
+ boolean closed = false;
+ if (DEBUG) {
+ System.err.println("GLJPanel.dispose(false): closed GraphicsDevice: " + adeviceMsg + ", result: " + closed);
+ }
+ }
+
+ backend.setContext(disposeContext);
+ if(null==disposeContext) {
+ isInitialized = false;
+ }
+
+ if(animatorPaused) {
+ animator.resume();
+ }
+ }
+
+ if(DEBUG) {
+ System.err.println("dispose("+regenerate+") - stop");
+ }
+ }
+
+ /**
+ * Just an alias for removeNotify
+ */
+ public void destroy() {
+ removeNotify();
+ }
+
+ /** Overridden to cause OpenGL rendering to be performed during
+ repaint cycles. Subclasses which override this method must call
+ super.paintComponent() in their paintComponent() method in order
+ to function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>paintComponent</CODE> in class <CODE>javax.swing.JComponent</CODE></DD></DL> */
+ protected void paintComponent(final Graphics g) {
+ if (Beans.isDesignTime()) {
+ // Make GLJPanel behave better in NetBeans GUI builder
+ g.setColor(Color.BLACK);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ FontMetrics fm = g.getFontMetrics();
+ String name = getName();
+ if (name == null) {
+ name = getClass().getName();
+ int idx = name.lastIndexOf('.');
+ if (idx >= 0) {
+ name = name.substring(idx + 1);
+ }
+ }
+ Rectangle2D bounds = fm.getStringBounds(name, g);
+ g.setColor(Color.WHITE);
+ g.drawString(name,
+ (int) ((getWidth() - bounds.getWidth()) / 2),
+ (int) ((getHeight() + bounds.getHeight()) / 2));
+ return;
+ }
+
+ if (backend == null || !isInitialized) {
+ createAndInitializeBackend();
+ }
+
+ if (!isInitialized) {
+ return;
+ }
+
+ // NOTE: must do this when the context is not current as it may
+ // involve destroying the pbuffer (current context) and
+ // re-creating it -- tricky to do properly while the context is
+ // current
+ if (handleReshape) {
+ handleReshape();
+ }
+
+ updater.setGraphics(g);
+ backend.doPaintComponent(g);
+ }
+
+ /** Overridden to track when this component is added to a container.
+ Subclasses which override this method must call
+ super.addNotify() in their addNotify() method in order to
+ function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void addNotify() {
+ super.addNotify();
+ if (DEBUG) {
+ System.err.println("GLJPanel.addNotify()");
+ }
+ }
+
+ /** Overridden to track when this component is removed from a
+ container. Subclasses which override this method must call
+ super.removeNotify() in their removeNotify() method in order to
+ function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void removeNotify() {
+ if(DEBUG) {
+ Exception ex1 = new Exception("Info: removeNotify - start");
+ ex1.printStackTrace();
+ }
+
+ awtWindowClosingProtocol.removeClosingListener();
+
+ dispose(false);
+ if (backend != null) {
+ backend.destroy();
+ backend = null;
+ }
+ isInitialized = false;
+ super.removeNotify();
+ if(DEBUG) {
+ System.err.println("Info: removeNotify - end");
+ }
+ }
+
+ /** Overridden to cause {@link GLDrawableHelper#reshape} to be
+ called on all registered {@link GLEventListener}s. Subclasses
+ which override this method must call super.reshape() in
+ their reshape() method in order to function properly. <P>
+
+ <B>Overrides:</B>
+ <DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ public void reshape(int x, int y, int width, int height) {
+ super.reshape(x, y, width, height);
+
+ // reshapeX = x;
+ // reshapeY = y;
+ reshapeWidth = width;
+ reshapeHeight = height;
+ handleReshape = true;
+ }
+
+ public void setOpaque(boolean opaque) {
+ if (backend != null) {
+ backend.setOpaque(opaque);
+ }
+ super.setOpaque(opaque);
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void addGLEventListener(int index, GLEventListener listener) {
+ drawableHelper.addGLEventListener(index, listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public void setAnimator(GLAnimatorControl animatorControl) {
+ drawableHelper.setAnimator(animatorControl);
+ }
+
+ public GLAnimatorControl getAnimator() {
+ return drawableHelper.getAnimator();
+ }
+
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ drawableHelper.invoke(this, wait, glRunnable);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return backend.createContext(shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ }
+
+ public boolean isRealized() {
+ return isInitialized;
+ }
+
+ public void setContext(GLContext ctx) {
+ if (backend == null) {
+ return;
+ }
+ backend.setContext(ctx);
+ }
+
+ public GLContext getContext() {
+ if (backend == null) {
+ return null;
+ }
+ return backend.getContext();
+ }
+
+ public GL getGL() {
+ if (Beans.isDesignTime()) {
+ return null;
+ }
+ GLContext context = getContext();
+ return (context == null) ? null : context.getGL();
+ }
+
+ public GL setGL(GL gl) {
+ GLContext context = getContext();
+ if (context != null) {
+ context.setGL(gl);
+ return gl;
+ }
+ return null;
+ }
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ // In the current implementation this is a no-op. Both the pbuffer
+ // and pixmap based rendering paths use a single-buffered surface
+ // so swapping the buffers doesn't do anything. We also don't
+ // currently have the provision to skip copying the data to the
+ // Swing portion of the GLJPanel in any of the rendering paths.
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ // In the current implementation this is a no-op. Both the pbuffer
+ // and pixmap based rendering paths use a single-buffered surface
+ // so swapping the buffers doesn't do anything. We also don't
+ // currently have the provision to skip copying the data to the
+ // Swing portion of the GLJPanel in any of the rendering paths.
+ return true;
+ }
+
+ public void swapBuffers() {
+ // In the current implementation this is a no-op. Both the pbuffer
+ // and pixmap based rendering paths use a single-buffered surface
+ // so swapping the buffers doesn't do anything. We also don't
+ // currently have the provision to skip copying the data to the
+ // Swing portion of the GLJPanel in any of the rendering paths.
+ }
+
+ /** For a translucent GLJPanel (one for which {@link #setOpaque
+ setOpaque}(false) has been called), indicates whether the
+ application should preserve the OpenGL color buffer
+ (GL_COLOR_BUFFER_BIT) for correct rendering of the GLJPanel and
+ underlying widgets which may show through portions of the
+ GLJPanel with alpha values less than 1. Most Swing
+ implementations currently expect the GLJPanel to be completely
+ cleared (e.g., by <code>glClear(GL_COLOR_BUFFER_BIT |
+ GL_DEPTH_BUFFER_BIT)</code>), but for certain optimized Swing
+ implementations which use OpenGL internally, it may be possible
+ to perform OpenGL rendering using the GLJPanel into the same
+ OpenGL drawable as the Swing implementation uses. */
+ public boolean shouldPreserveColorBufferIfTranslucent() {
+ return oglPipelineEnabled;
+ }
+
+ public GLCapabilitiesImmutable getChosenGLCapabilities() {
+ return backend.getChosenGLCapabilities();
+ }
+
+ public final GLProfile getGLProfile() {
+ return glProfile;
+ }
+
+ public NativeSurface getNativeSurface() {
+ throw new GLException("FIXME");
+ }
+
+ public long getHandle() {
+ throw new GLException("FIXME");
+ }
+
+ public final GLDrawableFactory getFactory() {
+ return factory;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private void createAndInitializeBackend() {
+ if (panelWidth == 0 ||
+ panelHeight == 0) {
+ // See whether we have a non-zero size yet and can go ahead with
+ // initialization
+ if (reshapeWidth == 0 ||
+ reshapeHeight == 0) {
+ return;
+ }
+
+ // Pull down reshapeWidth and reshapeHeight into panelWidth and
+ // panelHeight eagerly in order to complete initialization, and
+ // force a reshape later
+ panelWidth = reshapeWidth;
+ panelHeight = reshapeHeight;
+ }
+
+ do {
+ if (backend == null) {
+ if (oglPipelineEnabled) {
+ backend = new J2DOGLBackend();
+ } else {
+ if (!hardwareAccelerationDisabled &&
+ factory.canCreateGLPbuffer(null)) {
+ backend = new PbufferBackend();
+ } else {
+ if (softwareRenderingDisabled) {
+ throw new GLException("Fallback to software rendering disabled by user");
+ }
+ backend = new SoftwareBackend();
+ }
+ }
+ }
+
+ if (!isInitialized) {
+ backend.initialize();
+ }
+ // The backend might set itself to null, indicating it punted to
+ // a different implementation -- try again
+ } while (backend == null);
+
+ awtWindowClosingProtocol.addClosingListenerOneShot();
+ }
+
+ public int getDefaultCloseOperation() {
+ return awtWindowClosingProtocol.getDefaultCloseOperation();
+ }
+
+ public int setDefaultCloseOperation(int op) {
+ return awtWindowClosingProtocol.setDefaultCloseOperation(op);
+ }
+
+ private void handleReshape() {
+ panelWidth = reshapeWidth;
+ panelHeight = reshapeHeight;
+
+ if (DEBUG) {
+ System.err.println("GLJPanel.handleReshape: (w,h) = (" +
+ panelWidth + "," + panelHeight + ")");
+ }
+
+ sendReshape = true;
+ backend.handleReshape();
+ handleReshape = false;
+ }
+
+ // This is used as the GLEventListener for the pbuffer-based backend
+ // as well as the callback mechanism for the other backends
+ class Updater implements GLEventListener {
+ private Graphics g;
+
+ public void setGraphics(Graphics g) {
+ this.g = g;
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ if (!backend.preGL(g)) {
+ return;
+ }
+ drawableHelper.init(GLJPanel.this);
+ backend.postGL(g, false);
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ drawableHelper.dispose(GLJPanel.this);
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ if (!backend.preGL(g)) {
+ return;
+ }
+ if (sendReshape) {
+ if (DEBUG||VERBOSE) {
+ System.err.println("display: reshape(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + ")");
+ }
+ drawableHelper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight);
+ sendReshape = false;
+ }
+
+ drawableHelper.display(GLJPanel.this);
+ backend.postGL(g, true);
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ // This is handled above and dispatched directly to the appropriate context
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+ }
+ }
+
+ public String toString() {
+ return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+"]";
+ }
+
+ private boolean disposeRegenerate;
+ private GLContext disposeContext;
+ private GLDrawable disposeDrawable;
+ private DisposeAction disposeAction = new DisposeAction();
+
+ class DisposeAction implements Runnable {
+ public void run() {
+ updater.dispose(GLJPanel.this);
+
+ if (null != disposeContext) {
+ disposeContext.destroy();
+ disposeContext = null;
+ }
+ if (null != disposeDrawable) {
+ disposeDrawable.setRealized(false);
+ }
+ if (null != disposeDrawable) {
+ if (disposeRegenerate) {
+ disposeDrawable.setRealized(true);
+ disposeContext = (GLContextImpl) disposeDrawable.createContext(shareWith);
+ disposeContext.setSynchronized(true);
+ }
+ }
+ }
+ }
+
+ private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
+ new DisposeOnEventDispatchThreadAction();
+
+ class DisposeOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ }
+ }
+
+
+ class InitAction implements Runnable {
+ public void run() {
+ updater.init(GLJPanel.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ updater.display(GLJPanel.this);
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+
+ class PaintImmediatelyAction implements Runnable {
+ public void run() {
+ paintImmediately(0, 0, getWidth(), getHeight());
+ }
+ }
+ private PaintImmediatelyAction paintImmediatelyAction = new PaintImmediatelyAction();
+
+ private int getNextPowerOf2(int number) {
+ // Workaround for problems where 0 width or height are transiently
+ // seen during layout
+ if (number == 0) {
+ return 2;
+ }
+
+ if (((number-1) & number) == 0) {
+ //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
+ return number;
+ }
+ int power = 0;
+ while (number > 0) {
+ number = number>>1;
+ power++;
+ }
+ return (1<<power);
+ }
+
+ private int getGLInteger(GL gl, int which) {
+ int[] tmp = new int[1];
+ gl.glGetIntegerv(which, tmp, 0);
+ return tmp[0];
+ }
+
+ //----------------------------------------------------------------------
+ // Implementations of the various backends
+ //
+
+ // Abstraction of the different rendering backends: i.e., pure
+ // software / pixmap rendering, pbuffer-based acceleration, Java 2D
+ // / JOGL bridge
+ static interface Backend {
+ // Called each time the backend needs to initialize itself
+ public void initialize();
+
+ // Called when the backend should clean up its resources
+ public void destroy();
+
+ // Called when the opacity of the GLJPanel is changed
+ public void setOpaque(boolean opaque);
+
+ // Called to manually create an additional OpenGL context against
+ // this GLJPanel
+ public GLContext createContext(GLContext shareWith);
+
+ // Called to set the current backend's GLContext
+ public void setContext(GLContext ctx);
+
+ // Called to get the current backend's GLContext
+ public GLContext getContext();
+
+ // Called to get the current backend's GLDrawable
+ public GLDrawable getDrawable();
+
+ // Called to fetch the "real" GLCapabilities for the backend
+ public GLCapabilitiesImmutable getChosenGLCapabilities();
+
+ // Called to fetch the "real" GLProfile for the backend
+ public GLProfile getGLProfile();
+
+ // Called to handle a reshape event. When this is called, the
+ // OpenGL context associated with the backend is not current, to
+ // make it easier to destroy and re-create pbuffers if necessary.
+ public void handleReshape();
+
+ // Called before the OpenGL work is done in init() and display().
+ // If false is returned, this render is aborted.
+ public boolean preGL(Graphics g);
+
+ // Called after the OpenGL work is done in init() and display().
+ // The isDisplay argument indicates whether this was called on
+ // behalf of a call to display() rather than init().
+ public void postGL(Graphics g, boolean isDisplay);
+
+ // Called from within paintComponent() to initiate the render
+ public void doPaintComponent(Graphics g);
+ }
+
+ // Base class used by both the software (pixmap) and pbuffer
+ // backends, both of which rely on reading back the OpenGL frame
+ // buffer and drawing it with a BufferedImage
+ abstract class AbstractReadbackBackend implements Backend {
+ // This image is exactly the correct size to render into the panel
+ protected BufferedImage offscreenImage;
+ // One of these is used to store the read back pixels before storing
+ // in the BufferedImage
+ protected ByteBuffer readBackBytes;
+ protected IntBuffer readBackInts;
+ protected int readBackWidthInPixels;
+ protected int readBackHeightInPixels;
+
+ private int awtFormat;
+ private int glFormat;
+ private int glType;
+
+ // For saving/restoring of OpenGL state during ReadPixels
+ private int[] swapbytes = new int[1];
+ private int[] rowlength = new int[1];
+ private int[] skiprows = new int[1];
+ private int[] skippixels = new int[1];
+ private int[] alignment = new int[1];
+
+ public void setOpaque(boolean opaque) {
+ if (opaque != isOpaque()) {
+ if (offscreenImage != null) {
+ offscreenImage.flush();
+ offscreenImage = null;
+ }
+ }
+ }
+
+ public boolean preGL(Graphics g) {
+ // Empty in this implementation
+ return true;
+ }
+
+ public void postGL(Graphics g, boolean isDisplay) {
+ if (isDisplay) {
+ // Must now copy pixels from offscreen context into surface
+ if (offscreenImage == null) {
+ if (panelWidth > 0 && panelHeight > 0) {
+ // It looks like NVidia's drivers (at least the ones on my
+ // notebook) are buggy and don't allow a sub-rectangle to be
+ // read from a pbuffer...this doesn't really matter because
+ // it's the Graphics.drawImage() calls that are the
+ // bottleneck
+
+ int awtFormat = 0;
+
+ // Should be more flexible in these BufferedImage formats;
+ // perhaps see what the preferred image types are on the
+ // given platform
+ if (isOpaque()) {
+ awtFormat = BufferedImage.TYPE_INT_RGB;
+ } else {
+ awtFormat = BufferedImage.TYPE_INT_ARGB;
+ }
+
+ offscreenImage = new BufferedImage(panelWidth,
+ panelHeight,
+ awtFormat);
+ switch (awtFormat) {
+ case BufferedImage.TYPE_3BYTE_BGR:
+ glFormat = GL2.GL_BGR;
+ glType = GL2.GL_UNSIGNED_BYTE;
+ readBackBytes = ByteBuffer.allocate(readBackWidthInPixels * readBackHeightInPixels * 3);
+ break;
+
+ case BufferedImage.TYPE_INT_RGB:
+ case BufferedImage.TYPE_INT_ARGB:
+ glFormat = GL2.GL_BGRA;
+ glType = getGLPixelType();
+ readBackInts = IntBuffer.allocate(readBackWidthInPixels * readBackHeightInPixels);
+ break;
+
+ default:
+ // FIXME: Support more off-screen image types (current
+ // offscreen context implementations don't use others, and
+ // some of the OpenGL formats aren't supported in the 1.1
+ // headers, which we're currently using)
+ throw new GLException("Unsupported offscreen image type " + awtFormat);
+ }
+ }
+ }
+
+ if (offscreenImage != null) {
+ GL2 gl = getGL().getGL2();
+ // Save current modes
+ gl.glGetIntegerv(GL2.GL_PACK_SWAP_BYTES, swapbytes, 0);
+ gl.glGetIntegerv(GL2.GL_PACK_ROW_LENGTH, rowlength, 0);
+ gl.glGetIntegerv(GL2.GL_PACK_SKIP_ROWS, skiprows, 0);
+ gl.glGetIntegerv(GL2.GL_PACK_SKIP_PIXELS, skippixels, 0);
+ gl.glGetIntegerv(GL2.GL_PACK_ALIGNMENT, alignment, 0);
+
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, GL.GL_FALSE);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, readBackWidthInPixels);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, 1);
+
+ // Actually read the pixels.
+ gl.glReadBuffer(GL2.GL_FRONT);
+ if (readBackBytes != null) {
+ gl.glReadPixels(0, 0, readBackWidthInPixels, readBackHeightInPixels, glFormat, glType, readBackBytes);
+ } else if (readBackInts != null) {
+ gl.glReadPixels(0, 0, readBackWidthInPixels, readBackHeightInPixels, glFormat, glType, readBackInts);
+ }
+
+ // Restore saved modes.
+ gl.glPixelStorei(GL2.GL_PACK_SWAP_BYTES, swapbytes[0]);
+ gl.glPixelStorei(GL2.GL_PACK_ROW_LENGTH, rowlength[0]);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_ROWS, skiprows[0]);
+ gl.glPixelStorei(GL2.GL_PACK_SKIP_PIXELS, skippixels[0]);
+ gl.glPixelStorei(GL2.GL_PACK_ALIGNMENT, alignment[0]);
+
+ if (readBackBytes != null || readBackInts != null) {
+ // Copy temporary data into raster of BufferedImage for faster
+ // blitting Note that we could avoid this copy in the cases
+ // where !offscreenContext.offscreenImageNeedsVerticalFlip(),
+ // but that's the software rendering path which is very slow
+ // anyway
+ Object src = null;
+ Object dest = null;
+ int srcIncr = 0;
+ int destIncr = 0;
+
+ if (readBackBytes != null) {
+ src = readBackBytes.array();
+ dest = ((DataBufferByte) offscreenImage.getRaster().getDataBuffer()).getData();
+ srcIncr = readBackWidthInPixels * 3;
+ destIncr = offscreenImage.getWidth() * 3;
+ } else {
+ src = readBackInts.array();
+ dest = ((DataBufferInt) offscreenImage.getRaster().getDataBuffer()).getData();
+ srcIncr = readBackWidthInPixels;
+ destIncr = offscreenImage.getWidth();
+ }
+
+ if (flipVertically()) {
+ int srcPos = 0;
+ int destPos = (offscreenImage.getHeight() - 1) * destIncr;
+ for (; destPos >= 0; srcPos += srcIncr, destPos -= destIncr) {
+ System.arraycopy(src, srcPos, dest, destPos, destIncr);
+ }
+ } else {
+ int srcPos = 0;
+ int destEnd = destIncr * offscreenImage.getHeight();
+ for (int destPos = 0; destPos < destEnd; srcPos += srcIncr, destPos += destIncr) {
+ System.arraycopy(src, srcPos, dest, destPos, destIncr);
+ }
+ }
+
+ // Note: image will be drawn back in paintComponent() for
+ // correctness on all platforms
+ }
+ }
+ }
+ }
+
+ public void doPaintComponent(Graphics g) {
+ doPaintComponentImpl();
+ if (offscreenImage != null) {
+ // Draw resulting image in one shot
+ g.drawImage(offscreenImage, 0, 0,
+ offscreenImage.getWidth(),
+ offscreenImage.getHeight(),
+ GLJPanel.this);
+ }
+ }
+
+ protected abstract void doPaintComponentImpl();
+ protected abstract int getGLPixelType();
+ protected abstract boolean flipVertically();
+ }
+
+ class SoftwareBackend extends AbstractReadbackBackend {
+ // Implementation using software rendering
+ private GLDrawableImpl offscreenDrawable;
+ private GLContextImpl offscreenContext;
+
+ public void initialize() {
+ // Fall-through path: create an offscreen context instead
+ offscreenDrawable = (GLDrawableImpl) factory.createOffscreenDrawable(
+ null /* default platform device */,
+ offscreenCaps,
+ chooser,
+ Math.max(1, panelWidth),
+ Math.max(1, panelHeight));
+ offscreenContext = (GLContextImpl) offscreenDrawable.createContext(shareWith);
+ offscreenContext.setSynchronized(true);
+ isInitialized = true;
+ }
+
+ public void destroy() {
+ if (offscreenContext != null) {
+ offscreenContext.destroy();
+ offscreenContext = null;
+ }
+ if (offscreenDrawable != null) {
+ offscreenDrawable.destroy();
+ offscreenDrawable = null;
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return offscreenDrawable.createContext(shareWith);
+ }
+
+ public void setContext(GLContext ctx) {
+ offscreenContext=(GLContextImpl)ctx;
+ }
+
+ public GLContext getContext() {
+ return offscreenContext;
+ }
+
+ public GLDrawable getDrawable() {
+ return offscreenDrawable;
+ }
+
+ public GLCapabilitiesImmutable getChosenGLCapabilities() {
+ if (offscreenDrawable == null) {
+ return null;
+ }
+ return offscreenDrawable.getChosenGLCapabilities();
+ }
+
+ public GLProfile getGLProfile() {
+ if (offscreenDrawable == null) {
+ return null;
+ }
+ return offscreenDrawable.getGLProfile();
+ }
+
+ public void handleReshape() {
+ destroy();
+ initialize();
+ readBackWidthInPixels = Math.max(1, panelWidth);
+ readBackHeightInPixels = Math.max(1, panelHeight);
+
+ if (offscreenImage != null) {
+ offscreenImage.flush();
+ offscreenImage = null;
+ }
+ }
+
+ protected void doPaintComponentImpl() {
+ drawableHelper.invokeGL(offscreenDrawable, offscreenContext, displayAction, initAction);
+ }
+
+ protected int getGLPixelType() {
+ return offscreenContext.getOffscreenContextPixelDataType();
+ }
+
+ protected boolean flipVertically() {
+ return offscreenContext.offscreenImageNeedsVerticalFlip();
+ }
+ }
+
+ class PbufferBackend extends AbstractReadbackBackend {
+ private GLPbuffer pbuffer;
+ private int pbufferWidth = 256;
+ private int pbufferHeight = 256;
+
+ public void initialize() {
+ if (pbuffer != null) {
+ throw new InternalError("Creating pbuffer twice without destroying it (memory leak / correctness bug)");
+ }
+ try {
+ pbuffer = factory.createGLPbuffer(null /* default platform device */,
+ offscreenCaps,
+ null,
+ pbufferWidth,
+ pbufferHeight,
+ shareWith);
+ pbuffer.addGLEventListener(updater);
+ isInitialized = true;
+ } catch (GLException e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("Info: GLJPanel: Falling back on software rendering because of problems creating pbuffer");
+ }
+ hardwareAccelerationDisabled = true;
+ backend = null;
+ isInitialized = false;
+ createAndInitializeBackend();
+ }
+ }
+
+ public void destroy() {
+ if (pbuffer != null) {
+ pbuffer.destroy();
+ pbuffer = null;
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return pbuffer.createContext(shareWith);
+ }
+
+ public void setContext(GLContext ctx) {
+ if (pbuffer == null && Beans.isDesignTime()) {
+ return;
+ }
+ pbuffer.setContext(ctx);
+ }
+
+ public GLContext getContext() {
+ // Workaround for crashes in NetBeans GUI builder
+ if (pbuffer == null && Beans.isDesignTime()) {
+ return null;
+ }
+ return pbuffer.getContext();
+ }
+
+ public GLDrawable getDrawable() {
+ return pbuffer;
+ }
+
+ public GLCapabilitiesImmutable getChosenGLCapabilities() {
+ if (pbuffer == null) {
+ return null;
+ }
+ return pbuffer.getChosenGLCapabilities();
+ }
+
+ public GLProfile getGLProfile() {
+ if (pbuffer == null) {
+ return null;
+ }
+ return pbuffer.getGLProfile();
+ }
+
+ public void handleReshape() {
+ // Use factor larger than 2 during shrinks for some hysteresis
+ float shrinkFactor = 2.5f;
+ if ((panelWidth > pbufferWidth) || (panelHeight > pbufferHeight) ||
+ (panelWidth < (pbufferWidth / shrinkFactor)) || (panelHeight < (pbufferHeight / shrinkFactor))) {
+ if (DEBUG) {
+ System.err.println("Resizing pbuffer from (" + pbufferWidth + ", " + pbufferHeight + ") " +
+ " to fit (" + panelWidth + ", " + panelHeight + ")");
+ }
+ // Must destroy and recreate pbuffer to fit
+ if (pbuffer != null) {
+ // Watch for errors during pbuffer destruction (due to
+ // buggy / bad OpenGL drivers, in particular SiS) and fall
+ // back to software rendering
+ try {
+ pbuffer.destroy();
+ } catch (GLException e) {
+ hardwareAccelerationDisabled = true;
+ backend = null;
+ isInitialized = false;
+ // Just disabled hardware acceleration during this resize operation; do a fixup
+ readBackWidthInPixels = Math.max(1, panelWidth);
+ readBackHeightInPixels = Math.max(1, panelHeight);
+ if (DEBUG) {
+ System.err.println("Warning: falling back to software rendering due to bugs in OpenGL drivers");
+ e.printStackTrace();
+ }
+ createAndInitializeBackend();
+ return;
+ }
+ }
+ pbuffer = null;
+ isInitialized = false;
+ pbufferWidth = getNextPowerOf2(panelWidth);
+ pbufferHeight = getNextPowerOf2(panelHeight);
+ if (DEBUG && !hardwareAccelerationDisabled) {
+ System.err.println("New pbuffer size is (" + pbufferWidth + ", " + pbufferHeight + ")");
+ }
+ initialize();
+ }
+
+ // It looks like NVidia's drivers (at least the ones on my
+ // notebook) are buggy and don't allow a rectangle of less than
+ // the pbuffer's width to be read...this doesn't really matter
+ // because it's the Graphics.drawImage() calls that are the
+ // bottleneck. Should probably make the size of the offscreen
+ // image be the exact size of the pbuffer to save some work on
+ // resize operations...
+ readBackWidthInPixels = pbufferWidth;
+ readBackHeightInPixels = panelHeight;
+
+ if (offscreenImage != null) {
+ offscreenImage.flush();
+ offscreenImage = null;
+ }
+ }
+
+ protected void doPaintComponentImpl() {
+ pbuffer.display();
+ }
+
+ protected int getGLPixelType() {
+ // This seems to be a good choice on all platforms
+ return GL2.GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ protected boolean flipVertically() {
+ return true;
+ }
+ }
+
+ class J2DOGLBackend implements Backend {
+ // Opaque Object identifier representing the Java2D surface we are
+ // drawing to; used to determine when to destroy and recreate JOGL
+ // context
+ private Object j2dSurface;
+ // Graphics object being used during Java2D update action
+ // (absolutely essential to cache this)
+ private Graphics cached2DGraphics;
+ // No-op context representing the Java2D OpenGL context
+ private GLContext j2dContext;
+ // Context associated with no-op drawable representing the JOGL
+ // OpenGL context
+ private GLDrawable joglDrawable;
+ // The real OpenGL context JOGL uses to render
+ private GLContext joglContext;
+ // State captured from Java2D OpenGL context necessary in order to
+ // properly render into Java2D back buffer
+ private int[] drawBuffer = new int[1];
+ private int[] readBuffer = new int[1];
+ // This is required when the FBO option of the Java2D / OpenGL
+ // pipeline is active
+ private int[] frameBuffer = new int[1];
+ // Current (as of this writing) NVidia drivers have a couple of bugs
+ // relating to the sharing of framebuffer and renderbuffer objects
+ // between contexts. It appears we have to (a) reattach the color
+ // attachment and (b) actually create new depth buffer storage and
+ // attach it in order for the FBO to behave properly in our context.
+ private boolean checkedForFBObjectWorkarounds;
+ private boolean fbObjectWorkarounds;
+ private int[] frameBufferDepthBuffer;
+ private int[] frameBufferTexture;
+ private boolean createNewDepthBuffer;
+ // Current (as of this writing) ATI drivers have problems when the
+ // same FBO is bound in two different contexts. Here we check for
+ // this case and explicitly release the FBO from Java2D's context
+ // before switching to ours. Java2D will re-bind the FBO when it
+ // makes its context current the next time. Interestingly, if we run
+ // this code path on NVidia hardware, it breaks the rendering
+ // results -- no output is generated. This doesn't appear to be an
+ // interaction with the abovementioned NVidia-specific workarounds,
+ // as even if we disable that code the FBO is still reported as
+ // incomplete in our context.
+ private boolean checkedGLVendor;
+ private boolean vendorIsATI;
+
+ // Holding on to this GraphicsConfiguration is a workaround for a
+ // problem in the Java 2D / JOGL bridge when FBOs are enabled; see
+ // comment related to Issue 274 below
+ private GraphicsConfiguration workaroundConfig;
+
+ public void initialize() {
+ // No-op in this implementation; everything is done lazily
+ isInitialized = true;
+ }
+
+ public void destroy() {
+ Java2D.invokeWithOGLContextCurrent(null, new Runnable() {
+ public void run() {
+ if (joglContext != null) {
+ joglContext.destroy();
+ joglContext = null;
+ }
+ joglDrawable = null;
+ if (j2dContext != null) {
+ j2dContext.destroy();
+ j2dContext = null;
+ }
+ }
+ });
+ }
+
+ public void setOpaque(boolean opaque) {
+ // Empty in this implementation
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ // FIXME: should implement this, but it was not properly
+ // implemented before the refactoring anyway
+ throw new GLException("Not yet implemented");
+ }
+
+ public void setContext(GLContext ctx) {
+ joglContext=ctx;
+ }
+
+ public GLContext getContext() {
+ return joglContext;
+ }
+
+ public GLDrawable getDrawable() {
+ return joglDrawable;
+ }
+
+ public GLCapabilitiesImmutable getChosenGLCapabilities() {
+ // FIXME: should do better than this; is it possible to using only platform-independent code?
+ return new GLCapabilities(null);
+ }
+
+ public GLProfile getGLProfile() {
+ // FIXME: should do better than this; is it possible to using only platform-independent code?
+ return GLProfile.getDefault(GLProfile.getDefaultDesktopDevice());
+ }
+
+ public void handleReshape() {
+ // Empty in this implementation
+ }
+
+ public boolean preGL(Graphics g) {
+ GL2 gl = joglContext.getGL().getGL2();
+ // Set up needed state in JOGL context from Java2D context
+ gl.glEnable(GL2.GL_SCISSOR_TEST);
+ Rectangle r = Java2D.getOGLScissorBox(g);
+
+ if (r == null) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("Java2D.getOGLScissorBox() returned null");
+ }
+ return false;
+ }
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: gl.glScissor(" + r.x + ", " + r.y + ", " + r.width + ", " + r.height + ")");
+ }
+
+ gl.glScissor(r.x, r.y, r.width, r.height);
+ Rectangle oglViewport = Java2D.getOGLViewport(g, panelWidth, panelHeight);
+ // If the viewport X or Y changes, in addition to the panel's
+ // width or height, we need to send a reshape operation to the
+ // client
+ if ((viewportX != oglViewport.x) ||
+ (viewportY != oglViewport.y)) {
+ sendReshape = true;
+ if (DEBUG) {
+ System.err.println("Sending reshape because viewport changed");
+ System.err.println(" viewportX (" + viewportX + ") ?= oglViewport.x (" + oglViewport.x + ")");
+ System.err.println(" viewportY (" + viewportY + ") ?= oglViewport.y (" + oglViewport.y + ")");
+ }
+ }
+ viewportX = oglViewport.x;
+ viewportY = oglViewport.y;
+
+ // If the FBO option is active, bind to the FBO from the Java2D
+ // context.
+ // Note that all of the plumbing in the context sharing stuff will
+ // allow us to bind to this object since it's in our namespace.
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) {
+
+ // The texture target for Java2D's OpenGL pipeline when using FBOs
+ // -- either GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB
+ int fboTextureTarget = Java2D.getOGLTextureType(g);
+
+ if (!checkedForFBObjectWorkarounds) {
+ checkedForFBObjectWorkarounds = true;
+ gl.glBindTexture(fboTextureTarget, 0);
+ gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer[0]);
+ int status = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
+ if (status != GL.GL_FRAMEBUFFER_COMPLETE) {
+ // Need to do workarounds
+ fbObjectWorkarounds = true;
+ createNewDepthBuffer = true;
+ if (DEBUG || VERBOSE) {
+ System.err.println("GLJPanel: ERR GL_FRAMEBUFFER_BINDING: Discovered Invalid J2D FBO("+frameBuffer[0]+"): "+FBObject.getStatusString(status) +
+ ", frame_buffer_object workarounds to be necessary");
+ }
+ } else {
+ // Don't need the frameBufferTexture temporary any more
+ frameBufferTexture = null;
+ if (DEBUG || VERBOSE) {
+ System.err.println("GLJPanel: OK GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]);
+ }
+ }
+ }
+
+ if (fbObjectWorkarounds && createNewDepthBuffer) {
+ if (frameBufferDepthBuffer == null)
+ frameBufferDepthBuffer = new int[1];
+
+ // Create our own depth renderbuffer and associated storage
+ // If we have an old one, delete it
+ if (frameBufferDepthBuffer[0] != 0) {
+ gl.glDeleteRenderbuffers(1, frameBufferDepthBuffer, 0);
+ frameBufferDepthBuffer[0] = 0;
+ }
+
+ gl.glBindTexture(fboTextureTarget, frameBufferTexture[0]);
+ int[] width = new int[1];
+ int[] height = new int[1];
+ gl.glGetTexLevelParameteriv(fboTextureTarget, 0, GL2.GL_TEXTURE_WIDTH, width, 0);
+ gl.glGetTexLevelParameteriv(fboTextureTarget, 0, GL2.GL_TEXTURE_HEIGHT, height, 0);
+
+ gl.glGenRenderbuffers(1, frameBufferDepthBuffer, 0);
+ if (DEBUG) {
+ System.err.println("GLJPanel: Generated frameBufferDepthBuffer " + frameBufferDepthBuffer[0] +
+ " with width " + width[0] + ", height " + height[0]);
+ }
+
+ gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, frameBufferDepthBuffer[0]);
+ // FIXME: may need a loop here like in Java2D
+ gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, GL2GL3.GL_DEPTH_COMPONENT24, width[0], height[0]);
+
+ gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, 0);
+ createNewDepthBuffer = false;
+ }
+
+ gl.glBindTexture(fboTextureTarget, 0);
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, frameBuffer[0]);
+
+ if (fbObjectWorkarounds) {
+ // Hook up the color and depth buffer attachment points for this framebuffer
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0,
+ fboTextureTarget,
+ frameBufferTexture[0],
+ 0);
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: frameBufferDepthBuffer: " + frameBufferDepthBuffer[0]);
+ }
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_DEPTH_ATTACHMENT,
+ GL.GL_RENDERBUFFER,
+ frameBufferDepthBuffer[0]);
+ }
+
+ if (DEBUG) {
+ int status = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
+ if (status != GL.GL_FRAMEBUFFER_COMPLETE) {
+ throw new GLException("Error: framebuffer was incomplete: status = 0x" +
+ Integer.toHexString(status));
+ }
+ }
+ } else {
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: Setting up drawBuffer " + drawBuffer[0] +
+ " and readBuffer " + readBuffer[0]);
+ }
+
+ gl.glDrawBuffer(drawBuffer[0]);
+ gl.glReadBuffer(readBuffer[0]);
+ }
+
+ return true;
+ }
+
+ public void postGL(Graphics g, boolean isDisplay) {
+ // Cause OpenGL pipeline to flush its results because
+ // otherwise it's possible we will buffer up multiple frames'
+ // rendering results, resulting in apparent mouse lag
+ GL gl = getGL();
+ gl.glFinish();
+
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) {
+ // Unbind the framebuffer from our context to work around
+ // apparent driver bugs or at least unspecified behavior causing
+ // OpenGL to run out of memory with certain cards and drivers
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);
+ }
+ }
+
+ public void doPaintComponent(final Graphics g) {
+ // This is a workaround for an issue in the Java 2D / JOGL
+ // bridge (reported by an end user as JOGL Issue 274) where Java
+ // 2D can occasionally leave its internal OpenGL context current
+ // to the on-screen window rather than its internal "scratch"
+ // pbuffer surface to which the FBO is attached. JOGL expects to
+ // find a stable OpenGL drawable (on Windows, an HDC) upon which
+ // it can create another OpenGL context. It turns out that, on
+ // Windows, when Java 2D makes its internal OpenGL context
+ // current against the window in order to put pixels on the
+ // screen, it gets the device context for the window, makes its
+ // context current, and releases the device context. This means
+ // that when JOGL's Runnable gets to run below, the HDC is
+ // already invalid. The workaround for this is to force Java 2D
+ // to make its context current to the scratch surface, which we
+ // can do by executing an empty Runnable with the "shared"
+ // context current. This will be fixed in a Java SE 6 update
+ // release, hopefully 6u2.
+ if (Java2D.isFBOEnabled()) {
+ if (workaroundConfig == null) {
+ workaroundConfig = GraphicsEnvironment.
+ getLocalGraphicsEnvironment().
+ getDefaultScreenDevice().
+ getDefaultConfiguration();
+ }
+ Java2D.invokeWithOGLSharedContextCurrent(workaroundConfig, new Runnable() { public void run() {}});
+ }
+
+ Java2D.invokeWithOGLContextCurrent(g, new Runnable() {
+ public void run() {
+ if (DEBUG && VERBOSE) {
+ System.err.println("-- In invokeWithOGLContextCurrent");
+ }
+
+ // Create no-op context representing Java2D context
+ if (j2dContext == null) {
+ j2dContext = factory.createExternalGLContext();
+ if (DEBUG||VERBOSE) {
+ System.err.println("-- Created External Context: "+j2dContext);
+ }
+ if (DEBUG) {
+// j2dContext.setGL(new DebugGL2(j2dContext.getGL().getGL2()));
+ }
+
+ // Check to see whether we can support the requested
+ // capabilities or need to fall back to a pbuffer
+ // FIXME: add more checks?
+
+ j2dContext.makeCurrent();
+ GL gl = j2dContext.getGL();
+ if ((getGLInteger(gl, GL.GL_RED_BITS) < offscreenCaps.getRedBits()) ||
+ (getGLInteger(gl, GL.GL_GREEN_BITS) < offscreenCaps.getGreenBits()) ||
+ (getGLInteger(gl, GL.GL_BLUE_BITS) < offscreenCaps.getBlueBits()) ||
+ // (getGLInteger(gl, GL.GL_ALPHA_BITS) < offscreenCaps.getAlphaBits()) ||
+ (getGLInteger(gl, GL2.GL_ACCUM_RED_BITS) < offscreenCaps.getAccumRedBits()) ||
+ (getGLInteger(gl, GL2.GL_ACCUM_GREEN_BITS) < offscreenCaps.getAccumGreenBits()) ||
+ (getGLInteger(gl, GL2.GL_ACCUM_BLUE_BITS) < offscreenCaps.getAccumBlueBits()) ||
+ (getGLInteger(gl, GL2.GL_ACCUM_ALPHA_BITS) < offscreenCaps.getAccumAlphaBits()) ||
+ // (getGLInteger(gl, GL2.GL_DEPTH_BITS) < offscreenCaps.getDepthBits()) ||
+ (getGLInteger(gl, GL.GL_STENCIL_BITS) < offscreenCaps.getStencilBits())) {
+ if (DEBUG) {
+ System.err.println("GLJPanel: Falling back to pbuffer-based support because Java2D context insufficient");
+ System.err.println(" Available Required");
+ System.err.println("GL_RED_BITS " + getGLInteger(gl, GL.GL_RED_BITS) + " " + offscreenCaps.getRedBits());
+ System.err.println("GL_GREEN_BITS " + getGLInteger(gl, GL.GL_GREEN_BITS) + " " + offscreenCaps.getGreenBits());
+ System.err.println("GL_BLUE_BITS " + getGLInteger(gl, GL.GL_BLUE_BITS) + " " + offscreenCaps.getBlueBits());
+ System.err.println("GL_ALPHA_BITS " + getGLInteger(gl, GL.GL_ALPHA_BITS) + " " + offscreenCaps.getAlphaBits());
+ System.err.println("GL_ACCUM_RED_BITS " + getGLInteger(gl, GL2.GL_ACCUM_RED_BITS) + " " + offscreenCaps.getAccumRedBits());
+ System.err.println("GL_ACCUM_GREEN_BITS " + getGLInteger(gl, GL2.GL_ACCUM_GREEN_BITS) + " " + offscreenCaps.getAccumGreenBits());
+ System.err.println("GL_ACCUM_BLUE_BITS " + getGLInteger(gl, GL2.GL_ACCUM_BLUE_BITS) + " " + offscreenCaps.getAccumBlueBits());
+ System.err.println("GL_ACCUM_ALPHA_BITS " + getGLInteger(gl, GL2.GL_ACCUM_ALPHA_BITS) + " " + offscreenCaps.getAccumAlphaBits());
+ System.err.println("GL_DEPTH_BITS " + getGLInteger(gl, GL.GL_DEPTH_BITS) + " " + offscreenCaps.getDepthBits());
+ System.err.println("GL_STENCIL_BITS " + getGLInteger(gl, GL.GL_STENCIL_BITS) + " " + offscreenCaps.getStencilBits());
+ }
+ isInitialized = false;
+ backend = null;
+ oglPipelineEnabled = false;
+ handleReshape = true;
+ j2dContext.release();
+ j2dContext.destroy();
+ j2dContext = null;
+ return;
+ }
+ j2dContext.release();
+ }
+
+ j2dContext.makeCurrent();
+ try {
+ captureJ2DState(j2dContext.getGL(), g);
+ Object curSurface = Java2D.getOGLSurfaceIdentifier(g);
+ if (curSurface != null) {
+ if (j2dSurface != curSurface) {
+ if (joglContext != null) {
+ joglContext.destroy();
+ joglContext = null;
+ joglDrawable = null;
+ sendReshape = true;
+ if (DEBUG||VERBOSE) {
+ System.err.println("Sending reshape because surface changed");
+ System.err.println("New surface = " + curSurface);
+ }
+ }
+ j2dSurface = curSurface;
+ if (DEBUG || VERBOSE) {
+ System.err.print("-- Surface type: ");
+ int surfaceType = Java2D.getOGLSurfaceType(g);
+ if (surfaceType == Java2D.UNDEFINED) {
+ System.err.println("UNDEFINED");
+ } else if (surfaceType == Java2D.WINDOW) {
+ System.err.println("WINDOW");
+ } else if (surfaceType == Java2D.PBUFFER) {
+ System.err.println("PBUFFER");
+ } else if (surfaceType == Java2D.TEXTURE) {
+ System.err.println("TEXTURE");
+ } else if (surfaceType == Java2D.FLIP_BACKBUFFER) {
+ System.err.println("FLIP_BACKBUFFER");
+ } else if (surfaceType == Java2D.FBOBJECT) {
+ System.err.println("FBOBJECT");
+ } else {
+ System.err.println("(Unknown surface type " + surfaceType + ")");
+ }
+ }
+ }
+ if (joglContext == null) {
+ AbstractGraphicsDevice device = j2dContext.getGLDrawable().getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ if (factory.canCreateExternalGLDrawable(device)) {
+ joglDrawable = factory.createExternalGLDrawable();
+ // FIXME: Need to share with j2d context, due to FBO resource ..
+ // - ORIG: joglContext = joglDrawable.createContext(shareWith);
+ joglContext = joglDrawable.createContext(j2dContext);
+ if (DEBUG||VERBOSE) {
+ System.err.println("-- Created External Drawable: "+joglDrawable);
+ System.err.println("-- Created Context: "+joglContext);
+ }
+ } else if (factory.canCreateContextOnJava2DSurface(device)) {
+ // Mac OS X code path
+ // FIXME: Need to share with j2d context, due to FBO resource ..
+ // - ORIG: joglContext = factory.createContextOnJava2DSurface(g, shareWith);
+ joglContext = factory.createContextOnJava2DSurface(g, j2dContext);
+ if (DEBUG||VERBOSE) {
+ System.err.println("-- Created Context: "+joglContext);
+ }
+ }
+ /*if (DEBUG) {
+ joglContext.setGL(new DebugGL2(joglContext.getGL().getGL2()));
+ }*/
+
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT &&
+ fbObjectWorkarounds) {
+ createNewDepthBuffer = true;
+ }
+ }
+ if (joglContext instanceof Java2DGLContext) {
+ // Mac OS X code path
+ ((Java2DGLContext) joglContext).setGraphics(g);
+ }
+
+ drawableHelper.invokeGL(joglDrawable, joglContext, displayAction, initAction);
+ }
+ } finally {
+ j2dContext.release();
+ }
+ }
+ });
+ }
+
+ private void captureJ2DState(GL gl, Graphics g) {
+ gl.glGetIntegerv(GL2.GL_DRAW_BUFFER, drawBuffer, 0);
+ gl.glGetIntegerv(GL2.GL_READ_BUFFER, readBuffer, 0);
+ if (Java2D.isFBOEnabled() &&
+ Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) {
+ gl.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, frameBuffer, 0);
+ if(!gl.glIsFramebuffer(frameBuffer[0])) {
+ checkedForFBObjectWorkarounds=true;
+ fbObjectWorkarounds = true;
+ createNewDepthBuffer = true;
+ if (DEBUG || VERBOSE) {
+ System.err.println("GLJPanel: Fetched ERR GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]+" - NOT A FBO"+
+ ", frame_buffer_object workarounds to be necessary");
+ }
+ } else if (DEBUG) {
+ System.err.println("GLJPanel: Fetched OK GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]);
+ }
+
+ if(fbObjectWorkarounds || !checkedForFBObjectWorkarounds) {
+ // See above for description of what we are doing here
+ if (frameBufferTexture == null)
+ frameBufferTexture = new int[1];
+
+ // Query the framebuffer for its color buffer so we can hook
+ // it back up in our context (should not be necessary)
+ gl.glGetFramebufferAttachmentParameteriv(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0,
+ GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
+ frameBufferTexture, 0);
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: FBO COLOR_ATTACHMENT0: " + frameBufferTexture[0]);
+ }
+ }
+
+ if (!checkedGLVendor) {
+ checkedGLVendor = true;
+ String vendor = gl.glGetString(GL.GL_VENDOR);
+
+ if ((vendor != null) &&
+ vendor.startsWith("ATI")) {
+ vendorIsATI = true;
+ }
+ }
+
+ if (vendorIsATI) {
+ // Unbind the FBO from Java2D's context as it appears that
+ // driver bugs on ATI's side are causing problems if the FBO is
+ // simultaneously bound to more than one context. Java2D will
+ // re-bind the FBO during the next validation of its context.
+ // Note: this breaks rendering at least on NVidia hardware
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0);
+ }
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/javax/media/opengl/fixedfunc/GLLightingFunc.java b/src/jogl/classes/javax/media/opengl/fixedfunc/GLLightingFunc.java
new file mode 100644
index 000000000..5563ea9c8
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/fixedfunc/GLLightingFunc.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.fixedfunc;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+
+public interface GLLightingFunc {
+ public static final int GL_LIGHT0 = 0x4000;
+ public static final int GL_LIGHT1 = 0x4001;
+ public static final int GL_LIGHT2 = 0x4002;
+ public static final int GL_LIGHT3 = 0x4003;
+ public static final int GL_LIGHT4 = 0x4004;
+ public static final int GL_LIGHT5 = 0x4005;
+ public static final int GL_LIGHT6 = 0x4006;
+ public static final int GL_LIGHT7 = 0x4007;
+ public static final int GL_LIGHTING = 0xB50;
+ public static final int GL_AMBIENT = 0x1200;
+ public static final int GL_DIFFUSE = 0x1201;
+ public static final int GL_SPECULAR = 0x1202;
+ public static final int GL_POSITION = 0x1203;
+ public static final int GL_SPOT_DIRECTION = 0x1204;
+ public static final int GL_SPOT_EXPONENT = 0x1205;
+ public static final int GL_SPOT_CUTOFF = 0x1206;
+ public static final int GL_CONSTANT_ATTENUATION = 0x1207;
+ public static final int GL_LINEAR_ATTENUATION = 0x1208;
+ public static final int GL_QUADRATIC_ATTENUATION = 0x1209;
+ public static final int GL_EMISSION = 0x1600;
+ public static final int GL_SHININESS = 0x1601;
+ public static final int GL_AMBIENT_AND_DIFFUSE = 0x1602;
+ public static final int GL_COLOR_MATERIAL = 0xB57;
+ public static final int GL_NORMALIZE = 0xBA1;
+
+ public static final int GL_FLAT = 0x1D00;
+ public static final int GL_SMOOTH = 0x1D01;
+
+ public void glLightfv(int light, int pname, java.nio.FloatBuffer params);
+ public void glLightfv(int light, int pname, float[] params, int params_offset);
+ public void glMaterialf(int face, int pname, float param);
+ public void glMaterialfv(int face, int pname, java.nio.FloatBuffer params);
+ public void glMaterialfv(int face, int pname, float[] params, int params_offset);
+ public void glColor4f(float red, float green, float blue, float alpha);
+ public void glShadeModel(int mode);
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java b/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
new file mode 100644
index 000000000..b899f3c0a
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.fixedfunc;
+
+import java.nio.*;
+
+public interface GLMatrixFunc {
+
+ public static final int GL_MATRIX_MODE = 0x0BA0;
+ public static final int GL_MODELVIEW = 0x1700;
+ public static final int GL_PROJECTION = 0x1701;
+ // public static final int GL_TEXTURE = 0x1702; // Use GL.GL_TEXTURE due to ambiguous GL usage
+ public static final int GL_MODELVIEW_MATRIX = 0x0BA6;
+ public static final int GL_PROJECTION_MATRIX = 0x0BA7;
+ public static final int GL_TEXTURE_MATRIX = 0x0BA8;
+
+ /**
+ * glGetFloatv
+ * @param pname GL_MODELVIEW_MATRIX, GL_PROJECTION_MATRIX or GL_TEXTURE_MATRIX
+ * @param params the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glGetFloatv(int pname, java.nio.FloatBuffer params);
+ public void glGetFloatv(int pname, float[] params, int params_offset);
+ /**
+ * glGetIntegerv
+ * @param pname GL_MATRIX_MODE
+ * @param params the FloatBuffer's position remains unchanged
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glGetIntegerv(int pname, IntBuffer params);
+ public void glGetIntegerv(int pname, int[] params, int params_offset);
+
+ /**
+ * sets the current matrix
+ * @param pname GL_MODELVIEW, GL_PROJECTION or GL.GL_TEXTURE
+ */
+ public void glMatrixMode(int mode) ;
+
+ public void glPushMatrix();
+ public void glPopMatrix();
+
+ public void glLoadIdentity() ;
+
+ /**
+ * glLoadMatrixf
+ * @param params the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glLoadMatrixf(java.nio.FloatBuffer m) ;
+ public void glLoadMatrixf(float[] m, int m_offset);
+
+ /**
+ * glMultMatrixf
+ * @param m the FloatBuffer's position remains unchanged,
+ * which is the same behavior than the native JOGL GL impl
+ */
+ public void glMultMatrixf(java.nio.FloatBuffer m) ;
+ public void glMultMatrixf(float[] m, int m_offset);
+
+ public void glTranslatef(float x, float y, float z) ;
+
+ public void glRotatef(float angle, float x, float y, float z);
+
+ public void glScalef(float x, float y, float z) ;
+
+ public void glOrthof(float left, float right, float bottom, float top, float zNear, float zFar) ;
+
+ public void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar);
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFunc.java b/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFunc.java
new file mode 100644
index 000000000..ed7bef5d4
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFunc.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.fixedfunc;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+
+public interface GLPointerFunc {
+ public static final int GL_VERTEX_ARRAY = 0x8074;
+ public static final int GL_NORMAL_ARRAY = 0x8075;
+ public static final int GL_COLOR_ARRAY = 0x8076;
+ public static final int GL_TEXTURE_COORD_ARRAY = 0x8078;
+
+ public void glEnableClientState(int arrayName);
+ public void glDisableClientState(int arrayName);
+
+ public void glVertexPointer(GLArrayData array);
+ public void glVertexPointer(int size, int type, int stride, java.nio.Buffer pointer);
+ public void glVertexPointer(int size, int type, int stride, long pointer_buffer_offset);
+
+ public void glColorPointer(GLArrayData array);
+ public void glColorPointer(int size, int type, int stride, java.nio.Buffer pointer);
+ public void glColorPointer(int size, int type, int stride, long pointer_buffer_offset);
+ public void glColor4f(float red, float green, float blue, float alpha);
+
+ public void glNormalPointer(GLArrayData array);
+ public void glNormalPointer(int type, int stride, java.nio.Buffer pointer);
+ public void glNormalPointer(int type, int stride, long pointer_buffer_offset);
+
+ public void glTexCoordPointer(GLArrayData array);
+ public void glTexCoordPointer(int size, int type, int stride, java.nio.Buffer pointer);
+ public void glTexCoordPointer(int size, int type, int stride, long pointer_buffer_offset);
+
+}
+
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUnurbs.java b/src/jogl/classes/javax/media/opengl/glu/GLUnurbs.java
new file mode 100644
index 000000000..2641115d0
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUnurbs.java
@@ -0,0 +1,8 @@
+package javax.media.opengl.glu;
+
+/**
+ * Wrapper for a GLU NURBS object.
+ */
+
+public interface GLUnurbs {
+}
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUquadric.java b/src/jogl/classes/javax/media/opengl/glu/GLUquadric.java
new file mode 100644
index 000000000..49451a34b
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUquadric.java
@@ -0,0 +1,33 @@
+package javax.media.opengl.glu;
+
+import javax.media.opengl.GL;
+import com.jogamp.opengl.util.ImmModeSink;
+
+/**
+ * Wrapper for a GLU quadric object.
+ */
+
+public interface GLUquadric {
+ // enable/disables the Immediate Mode Sink module.
+ // This defaults to false for GLUgl2,
+ // and is always true for GLUes1.
+ public void enableImmModeSink(boolean val);
+
+ public boolean isImmModeSinkEnabled();
+
+ // set Immediate Mode usage.
+ // This defaults to false at GLU creation time.
+ // If enabled rendering will happen immediately,
+ // otherwise rendering will be hold in the ImmModeSink
+ // object, to be rendered deferred.
+ public void setImmMode(boolean val);
+
+ public boolean getImmMode();
+
+ // creates a new ImmModeSink (VBO Buffers) and
+ // returns the old vbo buffer with it's rendering result
+ public ImmModeSink replaceImmModeSink();
+
+ // gl may be null, then the GL client states are not disabled
+ public void resetImmModeSink(GL gl);
+}
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUtessellator.java b/src/jogl/classes/javax/media/opengl/glu/GLUtessellator.java
new file mode 100644
index 000000000..f98bbe158
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUtessellator.java
@@ -0,0 +1,66 @@
+/*
+* 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 javax.media.opengl.glu;
+
+/**
+ * The <b>GLUtessellator</b> object is used to hold the data, such as the
+ * vertices, edges and callback objects, to describe and tessellate complex
+ * polygons. A <b>GLUtessellator</b> object is used with the
+ * {@link GLU GLU} tessellator methods and
+ * {@link GLUtessellatorCallback GLU callbacks}.
+ *
+ * @author Eric Veach, July 1994
+ * @author Java Port: Pepijn Van Eechhoudt, July 2003
+ * @author Java Port: Nathan Parker Burg, August 2003
+ */
+public interface GLUtessellator {}
diff --git a/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java b/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java
new file mode 100644
index 000000000..0f05619a4
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java
@@ -0,0 +1,356 @@
+/*
+* 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 javax.media.opengl.glu;
+
+/**
+ * <b>GLUtessellatorCallback</b> interface provides methods that the user will
+ * override to define the callbacks for a tessellation object.
+ *
+ * @author Eric Veach, July 1994
+ * @author Java Port: Pepijn Van Eeckhoudt, July 2003
+ * @author Java Port: Nathan Parker Burg, August 2003
+ */
+public interface GLUtessellatorCallback {
+ /**
+ * The <b>begin</b> callback method is invoked like
+ * {@link javax.media.opengl.GL#glBegin glBegin} to indicate the start of a
+ * (triangle) primitive. The method takes a single argument of type int. If
+ * the <b>GLU_TESS_BOUNDARY_ONLY</b> property is set to <b>GL_FALSE</b>, then
+ * the argument is set to either <b>GL_TRIANGLE_FAN</b>,
+ * <b>GL_TRIANGLE_STRIP</b>, or <b>GL_TRIANGLES</b>. If the
+ * <b>GLU_TESS_BOUNDARY_ONLY</b> property is set to <b>GL_TRUE</b>, then the
+ * argument will be set to <b>GL_LINE_LOOP</b>.
+ *
+ * @param type
+ * Specifics the type of begin/end pair being defined. The following
+ * values are valid: <b>GL_TRIANGLE_FAN</b>, <b>GL_TRIANGLE_STRIP</b>,
+ * <b>GL_TRIANGLES</b> or <b>GL_LINE_LOOP</b>.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #end end
+ * @see #begin begin
+ */
+ public void begin(int type);
+
+ /**
+ * The same as the {@link #begin begin} 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 type
+ * Specifics the type of begin/end pair being defined. The following
+ * values are valid: <b>GL_TRIANGLE_FAN</b>, <b>GL_TRIANGLE_STRIP</b>,
+ * <b>GL_TRIANGLES</b> or <b>GL_LINE_LOOP</b>.
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #endData endData
+ * @see #begin begin
+ */
+ public void beginData(int type, Object polygonData);
+
+
+ /**
+ * The <b>edgeFlag</b> callback method is similar to
+ * {@link javax.media.opengl.GL#glEdgeFlag glEdgeFlag}. The method takes
+ * a single boolean boundaryEdge that indicates which edges lie on the
+ * polygon boundary. If the boundaryEdge is <b>GL_TRUE</b>, then each vertex
+ * that follows begins an edge that lies on the polygon boundary, that is,
+ * an edge that separates an interior region from an exterior one. If the
+ * boundaryEdge is <b>GL_FALSE</b>, then each vertex that follows begins an
+ * edge that lies in the polygon interior. The edge flag callback (if
+ * defined) is invoked before the first vertex callback.<P>
+ *
+ * Since triangle fans and triangle strips do not support edge flags, the
+ * begin callback is not called with <b>GL_TRIANGLE_FAN</b> or
+ * <b>GL_TRIANGLE_STRIP</b> if a non-null edge flag callback is provided.
+ * (If the callback is initialized to null, there is no impact on
+ * performance). Instead, the fans and strips are converted to independent
+ * triangles.
+ *
+ * @param boundaryEdge
+ * Specifics which edges lie on the polygon boundary.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #edgeFlagData edgeFlagData
+ */
+ public void edgeFlag(boolean boundaryEdge);
+
+
+ /**
+ * The same as the {@link #edgeFlag edgeFlage} 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 boundaryEdge
+ * Specifics which edges lie on the polygon boundary.
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #edgeFlag edgeFlag
+ */
+ public void edgeFlagData(boolean boundaryEdge, Object polygonData);
+
+
+ /**
+ * The <b>vertex</b> callback method is invoked between the {@link
+ * #begin begin} and {@link #end end} callback methods. It is
+ * similar to {@link javax.media.opengl.GL#glVertex3f glVertex3f},
+ * and it defines the vertices of the triangles created by the
+ * tessellation process. The method takes a reference as its only
+ * argument. This reference is identical to the opaque reference
+ * provided by the user when the vertex was described (see {@link
+ * GLU#gluTessVertex gluTessVertex}).
+ *
+ * @param vertexData
+ * Specifics a reference to the vertices of the triangles created
+ * by the tessellation process.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #vertexData vertexData
+ */
+ public void vertex(Object vertexData);
+
+
+ /**
+ * The same as the {@link #vertex vertex} 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 vertexData
+ * Specifics a reference to the vertices of the triangles created
+ * by the tessellation process.
+ * @param polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #vertex vertex
+ */
+ public void vertexData(Object vertexData, Object polygonData);
+
+
+ /**
+ * The end callback serves the same purpose as
+ * {@link javax.media.opengl.GL#glEnd glEnd}. It indicates the end of a
+ * primitive and it takes no arguments.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #begin begin
+ * @see #endData endData
+ */
+ public void end();
+
+
+ /**
+ * The same as the {@link #end end} 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 polygonData
+ * Specifics a reference to user-defined data.
+ *
+ * @see GLU#gluTessCallback gluTessCallback
+ * @see #beginData beginData
+ * @see #end end
+ */
+ public void endData(Object polygonData);
+
+
+ /**
+ * The <b>combine</b> callback method is called to create a new vertex when
+ * the tessellation detects an intersection, or wishes to merge features. The
+ * method takes four arguments: an array of three elements each of type
+ * double, an array of four references, an array of four elements each of
+ * type float, and a reference to a reference.<P>
+ *
+ * The vertex is defined as a linear combination of up to four existing
+ * vertices, stored in <i>data</i>. The coefficients of the linear combination
+ * are given by <i>weight</i>; these weights always add up to 1. All vertex
+ * pointers are valid even when some of the weights are 0. <i>coords</i> gives
+ * the location of the new vertex.<P>
+ *
+ * The user must allocate another vertex, interpolate parameters using
+ * <i>data</i> and <i>weight</i>, and return the new vertex pointer in
+ * <i>outData</i>. This handle is supplied during rendering callbacks. The
+ * user is responsible for freeing the memory some time after
+ * {@link GLU#gluTessEndPolygon gluTessEndPolygon} is
+ * called.<P>
+ *
+ * For example, if the polygon lies in an arbitrary plane in 3-space, and a
+ * color is associated with each vertex, the <b>GLU_TESS_COMBINE</b>
+ * callback might look like this:
+ * </UL>
+ * <PRE>
+ * 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;
+ * }</PRE>
+ *
+ * @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 <b>error</b> 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 <b>GLU_TESS_MISSING_BEGIN_POLYGON</b>,
+ * <b>GLU_TESS_MISSING_END_POLYGON</b>, <b>GLU_TESS_MISSING_BEGIN_CONTOUR</b>,
+ * <b>GLU_TESS_MISSING_END_CONTOUR</b>, <b>GLU_TESS_COORD_TOO_LARGE</b>,
+ * <b>GLU_TESS_NEED_COMBINE_CALLBACK</b> or <b>GLU_OUT_OF_MEMORY</b>.
+ * Character strings describing these errors can be retrieved with the
+ * {@link GLU#gluErrorString gluErrorString} call.<P>
+ *
+ * The GLU library will recover from the first four errors by inserting the
+ * missing call(s). <b>GLU_TESS_COORD_TOO_LARGE</b> indicates that some
+ * vertex coordinate exceeded the predefined constant
+ * <b>GLU_TESS_MAX_COORD</b> 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.)
+ * <b>GLU_TESS_NEED_COMBINE_CALLBACK</b> indicates that the tessellation
+ * detected an intersection between two edges in the input data, and the
+ * <b>GLU_TESS_COMBINE</b> or <b>GLU_TESS_COMBINE_DATA</b> callback was not
+ * provided. No output is generated. <b>GLU_OUT_OF_MEMORY</b> 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/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java b/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java
new file mode 100644
index 000000000..bd12dfb9d
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java
@@ -0,0 +1,84 @@
+/*
+* 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 javax.media.opengl.glu;
+
+/**
+ * The <b>GLUtessellatorCallbackAdapter</b> 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 {
+ public void begin(int type) {}
+ public void edgeFlag(boolean boundaryEdge) {}
+ public void vertex(Object vertexData) {}
+ public void end() {}
+// public void mesh(jogamp.opengl.tessellator.GLUmesh mesh) {}
+ public void error(int errnum) {}
+ public void combine(double[] coords, Object[] data,
+ float[] weight, Object[] outData) {}
+ public void beginData(int type, Object polygonData) {}
+ public void edgeFlagData(boolean boundaryEdge,
+ Object polygonData) {}
+ public void vertexData(Object vertexData, Object polygonData) {}
+ public void endData(Object polygonData) {}
+ public void errorData(int errnum, Object polygonData) {}
+ public void combineData(double[] coords, Object[] data,
+ float[] weight, Object[] outData,
+ Object polygonData) {}
+}