aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/javax/media/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/javax/media/opengl')
-rw-r--r--src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java239
-rw-r--r--src/jogl/classes/javax/media/opengl/GLArrayData.java114
-rw-r--r--src/jogl/classes/javax/media/opengl/GLAutoDrawable.java211
-rw-r--r--src/jogl/classes/javax/media/opengl/GLBase.java129
-rw-r--r--src/jogl/classes/javax/media/opengl/GLCapabilities.java329
-rw-r--r--src/jogl/classes/javax/media/opengl/GLCapabilitiesChooser.java55
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java261
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawable.java160
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java291
-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/GLProfile.java836
-rw-r--r--src/jogl/classes/javax/media/opengl/GLUniformData.java156
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/Threading.java166
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java52
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/ComponentEvents.java75
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java710
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java1582
-rw-r--r--src/jogl/classes/javax/media/opengl/fixedfunc/GLLightingFunc.java49
-rw-r--r--src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java76
-rw-r--r--src/jogl/classes/javax/media/opengl/fixedfunc/GLPointerFunc.java38
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUnurbs.java8
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUquadric.java33
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUtessellator.java66
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallback.java356
-rwxr-xr-xsrc/jogl/classes/javax/media/opengl/glu/GLUtessellatorCallbackAdapter.java84
27 files changed, 6327 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..782d041a5
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) 2003-2009 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 javax.media.nativewindow.Capabilities;
+import javax.media.nativewindow.NativeWindowException;
+
+/** <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 = false; // FIXME: Debug.debug("DefaultGLCapabilitiesChooser");
+
+ public int chooseCapabilities(Capabilities desired,
+ Capabilities[] available,
+ int windowSystemRecommendedChoice) {
+ GLCapabilities _desired = (GLCapabilities) desired;
+ GLCapabilities[] _available = (GLCapabilities[]) available;
+
+ if (DEBUG) {
+ System.err.println("Desired: " + _desired);
+ for (int i = 0; i < _available.length; i++) {
+ System.err.println("Available " + i + ": " + _available[i]);
+ }
+ System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice);
+ }
+
+ if (windowSystemRecommendedChoice >= 0 &&
+ windowSystemRecommendedChoice < _available.length &&
+ _available[windowSystemRecommendedChoice] != null) {
+ if (DEBUG) {
+ System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice);
+ System.err.println(_available[windowSystemRecommendedChoice]);
+ }
+ return windowSystemRecommendedChoice;
+ }
+
+ // Create score array
+ int[] scores = new int[_available.length];
+ 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 < scores.length; i++) {
+ GLCapabilities cur = _available[i];
+ if (cur == null) {
+ continue;
+ }
+ if (_desired.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()) -
+ (_desired.getRedBits() + _desired.getGreenBits() + _desired.getBlueBits() + _desired.getAlphaBits())));
+ // Compute difference in depth buffer depth
+ score += (DEPTH_MISMATCH_PENALTY_SCALE * sign(score) *
+ Math.abs(cur.getDepthBits() - _desired.getDepthBits()));
+ // Compute difference in accumulation buffer depth
+ score += (ACCUM_MISMATCH_PENALTY_SCALE * sign(score) *
+ Math.abs((cur.getAccumRedBits() + cur.getAccumGreenBits() + cur.getAccumBlueBits() + cur.getAccumAlphaBits()) -
+ (_desired.getAccumRedBits() + _desired.getAccumGreenBits() + _desired.getAccumBlueBits() + _desired.getAccumAlphaBits())));
+ // Compute difference in stencil bits
+ score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - _desired.getStencilBits());
+ if (cur.getDoubleBuffered() != _desired.getDoubleBuffered()) {
+ score += sign(score) * DOUBLE_BUFFER_MISMATCH_PENALTY;
+ }
+ if ((_desired.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 < scores.length; i++) {
+ int score = scores[i];
+ if (score == NO_SCORE) {
+ continue;
+ }
+ GLCapabilities cur = _available[i];
+ if (cur.getHardwareAccelerated()) {
+ int absScore = Math.abs(score);
+ if (!gotHW ||
+ (absScore > maxAbsoluteHWScore)) {
+ gotHW = true;
+ maxAbsoluteHWScore = absScore;
+ }
+ }
+ }
+ if (gotHW) {
+ for (int i = 0; i < scores.length; i++) {
+ int score = scores[i];
+ if (score == NO_SCORE) {
+ continue;
+ }
+ GLCapabilities cur = _available[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 < _available.length; 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 < scores.length; 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[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/GLArrayData.java b/src/jogl/classes/javax/media/opengl/GLArrayData.java
new file mode 100644
index 000000000..d17ee6a06
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLArrayData.java
@@ -0,0 +1,114 @@
+
+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.GL#GL_VERTEX_ARRAY
+ * @see javax.media.opengl.GL#GL_NORMAL_ARRAY
+ * @see javax.media.opengl.GL#GL_COLOR_ARRAY
+ * @see javax.media.opengl.GL#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 javax.media.opengl.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..6b1067701
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java
@@ -0,0 +1,211 @@
+/*
+ * 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 javax.media.opengl.glu.*;
+
+/** 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.NativeWindow NativeWindow} is become visible.
+ 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.NativeWindow NativeWindow}.<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 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 = Boolean.getBoolean("jogl.screenchange.action");
+
+ /** FIXME:
+ ** Invalid state, the resources are not yet ready to render. *
+ public static final int STATE_INVALID = 0;
+
+ ** Valid state, all resources are ready to render,
+ and all registered {@link GLEventListener#init init(..)} are called. *
+ public static final int STATE_VALID = 1;
+
+ ** Destroying state, currently executing the {@link #destroy()} method. *
+ public static final int STATE_DESTROYING = 2; */
+
+ /**
+ * 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 this drawable. If multiple
+ listeners are added to a given drawable, they are notified of
+ events in an arbitrary order. */
+ public void addGLEventListener(GLEventListener listener);
+
+ /** 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);
+
+ /** FIXME: Returns the current state,
+ {@link #STATE_INVALID}, {@link #STATE_VALID} or {@link #STATE_DESTROYING}.
+ Tool to determine, e.g. if a {@link GLEventListener#dispose dispose(..)}
+ event is send in the context of the destruction of this GLAutoDrawable.
+ public int getCurrentState(); */
+
+ /** Destroys all resources associated with this GLAutoDrawable,
+ inclusive the GLContext.
+ If a window is attached to it's implementation, it shall be closed.
+ Causes disposing of all OpenGL resources
+ by calling {@link GLEventListener#dispose dispose(..)} for all
+ registered {@link GLEventListener}s. Called automatically by the
+ window system toolkit upon receiving a destroy notification. This
+ routine may be called manually. */
+ public void destroy();
+
+ /** Causes OpenGL rendering to be performed for this GLAutoDrawable
+ by calling {@link GLEventListener#display display(..)} for all
+ registered {@link GLEventListener}s. Called automatically by the
+ window system toolkit upon receiving a repaint() request. this
+ routine may 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>
+ 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.*/
+ 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. */
+ public void 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..efd2eedd1
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl;
+
+import java.nio.*;
+
+/**
+ * The base interface from which all GL profiles derive, providing
+ * checked conversion down to concrete profiles, and access to the
+ * OpenGL context associated with the GL.
+ */
+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 GL3 profile.
+ * The GL3 profile reflects OpenGL versions greater or equal 3.1
+ * @return whether this GL object conforms to the GL3 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 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 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;
+
+ /**
+ * Returns the GLContext with which this GL object is associated.
+ * @return the GLContext with which this GL object is associated
+ */
+ public GLContext getContext();
+
+ /**
+ * Returns the GLProfile with which this GL object is associated.
+ * @return the GLProfile with which this GL object is associated
+ */
+ public GLProfile getGLProfile();
+}
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..37e35d4f0
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2003-2009 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 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 {
+ private GLProfile glProfile = null;
+ private boolean doubleBuffered = true;
+ private boolean stereo = false;
+ private boolean hardwareAccelerated = true;
+ private int depthBits = 24;
+ 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();
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (RuntimeException e) {
+ throw new GLException(e);
+ }
+ }
+
+ public boolean equals(Object obj) {
+ if(!(obj instanceof GLCapabilities)) {
+ return false;
+ }
+ GLCapabilities other = (GLCapabilities)obj;
+ boolean res = super.equals(obj) &&
+ other.getGLProfile()==glProfile &&
+ other.getDoubleBuffered()==doubleBuffered &&
+ other.getStereo()==stereo &&
+ other.getHardwareAccelerated()==hardwareAccelerated &&
+ other.getDepthBits()==depthBits &&
+ other.getStencilBits()==stencilBits &&
+ other.getAccumRedBits()==accumRedBits &&
+ other.getAccumGreenBits()==accumGreenBits &&
+ other.getAccumBlueBits()==accumBlueBits &&
+ other.getAccumAlphaBits()==accumAlphaBits &&
+ other.getSampleBuffers()==sampleBuffers &&
+ other.getPbufferFloatingPointBuffers()==pbufferFloatingPointBuffers &&
+ other.getPbufferRenderToTexture()==pbufferRenderToTexture &&
+ other.getPbufferRenderToTextureRectangle()==pbufferRenderToTextureRectangle;
+ if(sampleBuffers) {
+ res = res && other.getNumSamples()==numSamples;
+ }
+ return res;
+ }
+
+ /** 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 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;
+ }
+
+ /** Returns a textual representation of this GLCapabilities
+ object. */
+ public String toString() {
+ StringBuffer msg = new StringBuffer();
+ msg.append("GLCapabilities[");
+ msg.append(super.toString());
+ msg.append(", GL profile: " + glProfile +
+ ", DoubleBuffered: " + doubleBuffered +
+ ", Stereo: " + stereo +
+ ", HardwareAccelerated: " + hardwareAccelerated +
+ ", DepthBits: " + depthBits +
+ ", StencilBits: " + stencilBits +
+ ", Red Accum: " + accumRedBits +
+ ", Green Accum: " + accumGreenBits +
+ ", Blue Accum: " + accumBlueBits +
+ ", Alpha Accum: " + accumAlphaBits +
+ ", Multisample: " + sampleBuffers +
+ ", Num samples: "+(sampleBuffers ? numSamples : 0));
+ msg.append(", PBuffer-FloatingPointBuffers: "+pbufferFloatingPointBuffers+
+ ", PBuffer-RenderToTexture: "+pbufferRenderToTexture+
+ ", PBuffer-RenderToTextureRectangle: "+pbufferRenderToTextureRectangle+ "]");
+ 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..38cda8cdf
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilitiesChooser.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003-2009 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 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/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
new file mode 100644
index 000000000..ef7fa8189
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -0,0 +1,261 @@
+/*
+ * 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 com.sun.opengl.impl.Debug;
+import java.util.HashMap;
+
+/** 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 DEBUG = Debug.isPropertyDefined("jogl.debug.GLContext"); // 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;
+
+ private static ThreadLocal currentContext = new ThreadLocal();
+
+ private HashMap/*<int, Object>*/ attachedObjects = new HashMap();
+
+ /**
+ * Returns the GLDrawable to which this context may be used to
+ * draw.
+ */
+ public abstract GLDrawable getGLDrawable();
+
+ /**
+ * 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 GL#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
+ * GL#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
+ * @thows 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();
+ }
+
+ /**
+ * 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) {
+ if(DEBUG) {
+ Exception e = new Exception("setCurrent: "+Thread.currentThread()+", "+currentContext.get()+" -> "+cur);
+ e.printStackTrace();
+ }
+
+ 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.
+ */
+ public abstract GL getGL();
+
+ /**
+ * Sets the GL pipeline object for this GLContext.
+ */
+ public abstract void setGL(GL gl);
+
+ /**
+ * Returns the attached user object for the given name to this GLContext.
+ */
+ public Object getAttachedObject(int name) {
+ return attachedObjects.get(new Integer(name));
+ }
+
+ /**
+ * Returns the attached user object for the given name to this GLContext.
+ */
+ public 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 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 Object putAttachedObject(String name, Object obj) {
+ return attachedObjects.put(name, obj);
+ }
+
+ /**
+ * Classname, GL, GLDrawable
+ */
+ public final String toString() {
+ return getClass().getName()+" ["+getGL()+
+ ",\n\tDrawable: "+ getGLDrawable()+"] ";
+ }
+
+ /** 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();
+}
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..0cde24ff9
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java
@@ -0,0 +1,160 @@
+/*
+ * 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 javax.media.nativewindow.*;
+
+/** 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 NativeWindow#lockSurface() NativeWindow's lockSurface()} and if successfull:
+ * <ul>
+ * <li> Update the {@link GLCapabilities}, which are associated with
+ * the attached {@link NativeWindow}'s {@link AbstractGraphicsConfiguration}.</li>
+ * <li> Release the lock with {@link NativeWindow#unlockSurface() NativeWindow's unlockSurface()}.</li>
+ * </ul><br>
+ * This is important since {@link NativeWindow#lockSurface() NativeWindow'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);
+
+ /** 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 GLCapabilities} 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 NativeWindow}'s
+ {@link AbstractGraphicsConfiguration}, and if changes are necessary,
+ they should reflect those as well.
+ @return A copy of the queried object.
+ */
+ public GLCapabilities getChosenGLCapabilities();
+
+ /** Fetches the {@link GLProfile} for this drawable.
+ Returns the GLProfile object, no copy.
+ */
+ public GLProfile getGLProfile();
+
+ public NativeWindow getNativeWindow();
+
+ 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..5da62c30a
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -0,0 +1,291 @@
+/*
+ * 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 javax.media.nativewindow.*;
+
+import java.lang.reflect.*;
+import java.security.*;
+import com.sun.opengl.impl.*;
+import com.sun.nativewindow.impl.NWReflection;
+
+/** <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 GLCanvas} or {@link
+ GLJPanel} if the capabilities can not be met. Pbuffers are always
+ created immediately and their creation will fail with a {@link
+ 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 {
+ /** Creates a new GLDrawableFactory instance. End users do not need
+ to call this method. */
+ protected GLDrawableFactory() {
+ }
+
+ private static final GLDrawableFactory eglFactory;
+ private static final GLDrawableFactory nativeOSFactory;
+ private static final String nativeOSType;
+
+ /**
+ * Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
+ */
+ static {
+ GLDrawableFactory tmp = null;
+ try {
+ tmp = (GLDrawableFactory) NWReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory");
+ } catch (Throwable t) {
+ if (GLProfile.DEBUG) {
+ System.err.println("GLDrawableFactory.static - EGLDrawableFactory - not available");
+ t.printStackTrace();
+ }
+ }
+ eglFactory = tmp;
+
+ nativeOSType = NativeWindowFactory.getNativeWindowType(false);
+
+ String factoryClassName = null;
+ tmp = null;
+ try {
+ factoryClassName =
+ (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ return System.getProperty("opengl.factory.class.name");
+ }
+ });
+
+ if (null == factoryClassName) {
+ if ( nativeOSType.equals(NativeWindowFactory.TYPE_EGL) ) {
+ // use egl*Factory ..
+ } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_X11) ) {
+ factoryClassName = "com.sun.opengl.impl.x11.glx.X11GLXDrawableFactory";
+ } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_WINDOWS) ) {
+ factoryClassName = "com.sun.opengl.impl.windows.wgl.WindowsWGLDrawableFactory";
+ } else if ( nativeOSType.equals(NativeWindowFactory.TYPE_MACOSX) ) {
+ // FIXME: remove this residual dependence on the AWT
+ factoryClassName = "com.sun.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory";
+ } else {
+ throw new GLException("Unsupported NativeWindow type: "+nativeOSType);
+ }
+ }
+ if (null != factoryClassName) {
+ tmp = (GLDrawableFactory) NWReflection.createInstance(factoryClassName);
+ }
+ } catch (Throwable t) {
+ if (GLProfile.DEBUG) {
+ System.err.println("GLDrawableFactory.static - Native Platform: "+nativeOSType+" - not available: "+factoryClassName);
+ t.printStackTrace();
+ }
+ }
+ nativeOSFactory = tmp;
+ }
+
+ /**
+ * Returns the sole GLDrawableFactory instance.
+ *
+ * @arg 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("GLDrawableFactory unavailable for EGL: "+glProfileImplName);
+ return eglFactory;
+ }
+ if(null==nativeOSFactory) throw new GLException("GLDrawableFactory unavailable for Native Platform "+nativeOSType);
+ return nativeOSFactory;
+ }
+
+ /** Shuts down this GLDrawableFactory, releasing resources
+ associated with it. Before calling this method you should first
+ destroy any GLContexts and GLDrawables that have been created
+ and are still in use. No further OpenGL calls may be made after
+ shutting down the GLDrawableFactory. */
+ public void shutdown() {
+ }
+
+ /**
+ * Returns a GLDrawable that wraps a platform-specific window system
+ * object, such as an AWT or LCDUI Canvas.
+ * On platforms which support pixel format, the NativeWindow's AbstractGraphicsConfiguration
+ * is being used.
+ * support it, selects a pixel format compatible with the supplied
+ * GLCapabilities, or if the passed GLCapabilities object is null,
+ * uses a default set of capabilities. On these platforms, uses
+ * either the supplied GLCapabilitiesChooser object, or if the
+ * passed GLCapabilitiesChooser object is null, uses a
+ * DefaultGLCapabilitiesChooser instance.
+ *
+ * @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(NativeWindow target)
+ throws IllegalArgumentException, GLException;
+
+ //----------------------------------------------------------------------
+ // Methods to create high-level objects
+
+ /**
+ * Returns true if it is possible to create a GLPbuffer. Some older
+ * graphics cards do not have this capability.
+ */
+ public abstract boolean canCreateGLPbuffer();
+
+ /**
+ * 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>.
+ *
+ * @throws GLException if any window system-specific errors caused
+ * the creation of the GLPbuffer to fail.
+ */
+ public abstract GLPbuffer createGLPbuffer(GLCapabilities 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}.
+ */
+ public abstract boolean canCreateExternalGLDrawable();
+
+ /**
+ * <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/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
new file mode 100644
index 000000000..57f4fb46a
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -0,0 +1,836 @@
+/*
+ * 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 javax.media.opengl.fixedfunc.*;
+import java.lang.reflect.*;
+import java.util.HashMap;
+import java.security.*;
+import com.sun.opengl.impl.*;
+import com.sun.nativewindow.impl.NWReflection;
+
+/**
+ * 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 implements Cloneable {
+ public static final boolean DEBUG = Debug.debug("GLProfile");
+
+ //
+ // Public (user-visible) profiles
+ //
+
+ /** The desktop OpenGL 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";
+
+ /**
+ * All GL Profiles in the order of default detection: GL2, GL2ES2, GL2ES1, GLES2, GLES1, GL3
+ */
+ public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL2, GL2ES2, GL2ES1, GLES2, GLES1, GL3 };
+
+ /**
+ * All GL2ES2 Profiles in the order of default detection: GL2ES2, GL2, GLES2, GL3
+ */
+ public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL2, GLES2, GL3 };
+
+ /**
+ * All GL2ES1 Profiles in the order of default detection: GL2ES1, GL2, GLES1
+ */
+ public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL2, 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}
+ */
+ public static final GLProfile getDefault() {
+ if(null==defaultGLProfile) {
+ throw new GLException("No default profile available"); // should never be reached
+ }
+ return defaultGLProfile;
+ }
+
+ /** Returns a GLProfile object.
+ * Verfifies the given profile and chooses an apropriate implementation.
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ */
+ public static final GLProfile get(String profile)
+ throws GLException
+ {
+ if(null==profile) return getDefault();
+ GLProfile glProfile = (GLProfile) mappedProfiles.get(profile);
+ if(null==glProfile) {
+ throw new GLException("No implementation for profile "+profile+" available");
+ }
+ return glProfile;
+ }
+
+ /**
+ * 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.
+ */
+ public static final 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.
+ */
+ public static final GLProfile getGL2ES2()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_GL2ES2);
+ }
+
+ /**
+ * 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 final GLProfile get(String[] profiles)
+ throws GLException
+ {
+ for(int i=0; i<profiles.length; i++) {
+ String profile = profiles[i];
+ GLProfile glProfile = (GLProfile) mappedProfiles.get(profile);
+ if(null!=glProfile) {
+ return glProfile;
+ }
+ }
+ throw new GLException("Profiles "+list2String(profiles)+" not available");
+ }
+
+ /** Indicates whether the native OpenGL ES1 profile is in use.
+ * This requires an EGL interface.
+ */
+ public static final boolean usesNativeGLES1(String profileImpl) {
+ return GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl) ;
+ }
+
+ /** Indicates whether the native OpenGL ES2 profile is in use.
+ * This requires an EGL interface.
+ */
+ public static final boolean usesNativeGLES2(String profileImpl) {
+ return GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl) ;
+ }
+
+ /** Indicates whether either of the native OpenGL ES profiles are in use. */
+ public static final boolean usesNativeGLES(String profileImpl) {
+ return usesNativeGLES2(profileImpl) || usesNativeGLES1(profileImpl);
+ }
+
+ private static final String getGLImplBaseClassName(String profileImpl) {
+ if(GL3.equals(profileImpl)) {
+ return "com.sun.opengl.impl.gl3.GL3";
+ } else if(GL2.equals(profileImpl)) {
+ return "com.sun.opengl.impl.gl2.GL2";
+ } else if(GL2ES12.equals(profileImpl)) {
+ return "com.sun.opengl.impl.gl2es12.GL2ES12";
+ } else if(GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl)) {
+ return "com.sun.opengl.impl.es1.GLES1";
+ } else if(GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl)) {
+ return "com.sun.opengl.impl.es2.GLES2";
+ } else {
+ throw new GLException("unsupported profile \"" + profileImpl + "\"");
+ }
+ }
+
+ public final String getGLImplBaseClassName() {
+ return getGLImplBaseClassName(profileImpl);
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (Exception e) {
+ throw new GLException(e);
+ }
+ }
+
+ /**
+ * @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(o instanceof GLProfile) {
+ GLProfile glp = (GLProfile)o;
+ return profile.equals(glp.getName()) &&
+ profileImpl.equals(glp.getImplName()) ;
+ }
+ return false;
+ }
+
+ /**
+ * @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 GL3. */
+ public final boolean isGL3() {
+ return GL3.equals(profile);
+ }
+
+ /** Indicates whether this profile is capable of GL2. */
+ public final boolean isGL2() {
+ return 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 uses the native OpenGL ES1 implementations. */
+ public final boolean usesNativeGLES1() {
+ return GLES1.equals(profileImpl) || GL2ES1.equals(profileImpl) ;
+ }
+
+ /** Indicates whether this profile uses the native OpenGL ES2 implementations. */
+ public final boolean usesNativeGLES2() {
+ return GLES2.equals(profileImpl) || GL2ES2.equals(profileImpl) ;
+ }
+
+ /** Indicates whether this profile uses either of the native OpenGL ES implementations. */
+ public final boolean usesNativeGLES() {
+ return usesNativeGLES2() || usesNativeGLES1();
+ }
+
+ /** Indicates whether this profile supports GLSL. */
+ public final boolean hasGLSL() {
+ return isGL2ES2() ;
+ }
+
+ /**
+ * 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 + "]";
+ }
+
+ // The intersection between desktop OpenGL and the union of the OpenGL ES profiles
+ // This is here only to avoid having separate GL2ES1Impl and GL2ES2Impl classes
+ private static final String GL2ES12 = "GL2ES12";
+
+ private static final boolean hasGL3Impl;
+ private static final boolean hasGL2Impl;
+ private static final boolean hasGL2ES12Impl;
+ private static final boolean hasGLES2Impl;
+ private static final boolean hasGLES1Impl;
+
+ /** The JVM/process wide default GL profile **/
+ private static GLProfile defaultGLProfile;
+
+ /** All GLProfiles */
+ private static final HashMap/*<String, GLProfile>*/ mappedProfiles;
+
+ /**
+ * Tries the profiles implementation and native libraries.
+ * Throws an GLException if no profile could be found at all.
+ */
+ static {
+ boolean hasDesktopGL = false;
+ boolean hasDesktopGLES12 = false;
+ boolean hasNativeOSFactory = false;
+
+ try {
+ // See DRIHack.java for an explanation of why this is necessary
+ DRIHack.begin();
+ NativeLibLoader.loadGLDesktop();
+ DRIHack.end();
+ hasDesktopGL = true;
+ } catch (Throwable t) {
+ if (DEBUG) {
+ System.err.println("GLProfile.static Desktop GL Library not available");
+ t.printStackTrace();
+ }
+ }
+
+ try {
+ // See DRIHack.java for an explanation of why this is necessary
+ DRIHack.begin();
+ NativeLibLoader.loadGLDesktopES12();
+ DRIHack.end();
+ hasDesktopGLES12 = true;
+ } catch (Throwable t) {
+ if (DEBUG) {
+ System.err.println("GLProfile.static Desktop GL ES12 Library not available");
+ t.printStackTrace();
+ }
+ }
+
+ if(hasDesktopGL||hasDesktopGLES12) {
+ try {
+ hasNativeOSFactory = null!=GLDrawableFactory.getFactoryImpl(GL2);
+ } catch (Throwable t) {
+ if (DEBUG) {
+ System.err.println("GLProfile.static - Native platform GLDrawable factory not available");
+ t.printStackTrace();
+ }
+ }
+ }
+
+ if(!hasNativeOSFactory) {
+ hasDesktopGLES12=false;
+ hasDesktopGL=false;
+ }
+
+ // FIXME: check for real GL3 availability .. ?
+ hasGL3Impl = hasDesktopGL && NWReflection.isClassAvailable("com.sun.opengl.impl.gl3.GL3Impl");
+ hasGL2Impl = hasDesktopGL && NWReflection.isClassAvailable("com.sun.opengl.impl.gl2.GL2Impl");
+
+ hasGL2ES12Impl = hasDesktopGLES12 && NWReflection.isClassAvailable("com.sun.opengl.impl.gl2es12.GL2ES12Impl");
+
+ boolean btest = false;
+
+ boolean hasEGLDynLookup = NWReflection.isClassAvailable("com.sun.opengl.impl.egl.EGLDynamicLookupHelper");
+ boolean hasEGLDrawableFactory = false;
+ try {
+ if(hasEGLDynLookup) {
+ hasEGLDrawableFactory = null!=GLDrawableFactory.getFactoryImpl(GLES2);
+ btest = hasEGLDrawableFactory &&
+ NWReflection.isClassAvailable("com.sun.opengl.impl.es2.GLES2Impl") &&
+ null!=com.sun.opengl.impl.egl.EGLDynamicLookupHelper.getDynamicLookupHelper(2);
+ }
+ } catch (Throwable t) {
+ if (DEBUG) {
+ System.err.println("GLProfile.static - GL ES2 Factory/Library not available");
+ t.printStackTrace();
+ }
+ }
+ hasGLES2Impl = btest;
+
+ btest = false;
+ try {
+ if(hasEGLDynLookup) {
+ btest = hasEGLDrawableFactory &&
+ NWReflection.isClassAvailable("com.sun.opengl.impl.es1.GLES1Impl") &&
+ null!=com.sun.opengl.impl.egl.EGLDynamicLookupHelper.getDynamicLookupHelper(1);
+ }
+ } catch (Throwable t) {
+ if (DEBUG) {
+ System.err.println("GLProfile.static - GL ES1 Factory/Library not available");
+ t.printStackTrace();
+ }
+ }
+ hasGLES1Impl = btest;
+
+ if (DEBUG) {
+ System.err.println("GLProfile.static hasNativeOSFactory "+hasNativeOSFactory);
+ System.err.println("GLProfile.static hasDesktopGLES12 "+hasDesktopGLES12);
+ System.err.println("GLProfile.static hasDesktopGL "+hasDesktopGL);
+ System.err.println("GLProfile.static hasGL3Impl "+hasGL3Impl);
+ System.err.println("GLProfile.static hasGL2Impl "+hasGL2Impl);
+ System.err.println("GLProfile.static hasGL2ES12Impl "+hasGL2ES12Impl);
+ System.err.println("GLProfile.static hasGLES2Impl "+hasGLES2Impl);
+ System.err.println("GLProfile.static hasGLES1Impl "+hasGLES1Impl);
+ }
+
+ HashMap/*<String, GLProfile>*/ _mappedProfiles = new HashMap(GL_PROFILE_LIST_ALL.length);
+ for(int i=0; i<GL_PROFILE_LIST_ALL.length; i++) {
+ String profile = GL_PROFILE_LIST_ALL[i];
+ String profileImpl = computeProfileImpl(profile);
+ if(null!=profileImpl) {
+ GLProfile glProfile = new GLProfile(profile, profileImpl);
+ _mappedProfiles.put(profile, glProfile);
+ if (DEBUG) {
+ System.err.println("GLProfile.static map "+glProfile);
+ }
+ if(null==defaultGLProfile) {
+ defaultGLProfile=glProfile;
+ if (DEBUG) {
+ System.err.println("GLProfile.static default "+glProfile);
+ }
+ }
+ } else {
+ if (DEBUG) {
+ System.err.println("GLProfile.static map *** no mapping for "+profile);
+ }
+ }
+ }
+ mappedProfiles = _mappedProfiles; // final ..
+ if(null==defaultGLProfile) {
+ throw new GLException("No profile available: "+list2String(GL_PROFILE_LIST_ALL));
+ }
+ }
+
+ private static final String list2String(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();
+ }
+
+ /**
+ * Returns the profile implementation
+ */
+ private static String computeProfileImpl(String profile) {
+ if (GL2ES1.equals(profile)) {
+ if(hasGL2Impl) {
+ return GL2;
+ } else if(hasGL2ES12Impl) {
+ return GL2ES12;
+ } else if(hasGLES1Impl) {
+ return GLES1;
+ }
+ } else if (GL2ES2.equals(profile)) {
+ if(hasGL2ES12Impl) {
+ return GL2ES12;
+ } else if(hasGL2Impl) {
+ return GL2;
+ } else if(hasGL3Impl) {
+ return GL3;
+ } else if(hasGLES2Impl) {
+ return GLES2;
+ }
+ } else if(GL3.equals(profile) && hasGL3Impl) {
+ return GL3;
+ } else if(GL2.equals(profile) && hasGL2Impl) {
+ return GL2;
+ } else if(GLES2.equals(profile) && hasGLES2Impl) {
+ return GLES2;
+ } else if(GLES1.equals(profile) && hasGLES1Impl) {
+ return GLES1;
+ }
+ return null;
+ }
+
+ 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;
+ }
+
+ 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/GLUniformData.java b/src/jogl/classes/javax/media/opengl/GLUniformData.java
new file mode 100644
index 000000000..8b5fb1a03
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/GLUniformData.java
@@ -0,0 +1,156 @@
+
+package javax.media.opengl;
+
+import java.nio.*;
+
+public class GLUniformData {
+
+ /**
+ * int atom
+ *
+ * Number of objects is 1
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, int val) {
+ init(name, 1, new Integer(val));
+ }
+
+ /**
+ * float atom
+ *
+ * Number of objects is 1
+ *
+ * @arg components number of elements of one object, ie 4 for GL_FLOAT_VEC4,
+ */
+ public GLUniformData(String name, float val) {
+ init(name, 1, new Float(val));
+ }
+
+ /**
+ * Multiple IntBuffer Vector
+ *
+ * Number of objects is calculated by data.limit()/components
+ *
+ * @arg 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
+ *
+ * @arg 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)
+ *
+ * @arg rows the matrix rows
+ * @arg 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 100755
index 000000000..fecf6c78b
--- /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 com.sun.opengl.impl.*;
+
+/** 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..d92cec389
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java
@@ -0,0 +1,52 @@
+/*
+ * 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 javax.media.opengl.glu.*;
+
+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..4282e9985
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -0,0 +1,710 @@
+/*
+ * 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 javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+
+import com.sun.opengl.impl.*;
+
+import java.awt.Canvas;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.Container;
+import java.awt.Window;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.geom.*;
+import java.beans.*;
+import java.lang.reflect.*;
+import java.security.*;
+
+// 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 {@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. */
+
+public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
+
+ private static final boolean DEBUG = Debug.debug("GLCanvas");
+
+ static private GLProfile defaultGLProfile = GLProfile.getDefault();
+ private GLProfile glProfile;
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private GraphicsConfiguration chosen;
+ private AWTGraphicsConfiguration awtConfig;
+ private GLDrawable drawable;
+ private GLContextImpl context;
+ private boolean autoSwapBufferMode = true;
+ private boolean sendReshape = false;
+
+ // copy of the cstr args ..
+ private GLCapabilities capabilities;
+ private GLCapabilitiesChooser chooser;
+ private GLContext shareWith;
+ private GraphicsDevice device;
+
+ /** 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. */
+ public GLCanvas(GLCapabilities capabilities) {
+ this(capabilities, null, null, 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(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ GLContext shareWith,
+ GraphicsDevice device) {
+ /*
+ * Workaround for Xinerama, always pass null so we can detect whether
+ * super.getGraphicsConfiguration() is returning the Canvas' GC (null),
+ * or an ancestor component's GC (non-null) in the overridden version
+ * below.
+ */
+ super();
+
+ if(null==capabilities) {
+ capabilities = new GLCapabilities(defaultGLProfile);
+ }
+ glProfile = capabilities.getGLProfile();
+
+ this.capabilities = capabilities;
+ this.chooser = chooser;
+ this.shareWith=shareWith;
+ this.device = device;
+ }
+
+ protected interface DestroyMethod {
+ public void destroyMethod();
+ }
+
+ protected final static Object addClosingListener(Component c, final DestroyMethod d) {
+ WindowAdapter cl = null;
+ Window w = getWindow(c);
+ if(null!=w) {
+ cl = new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ // we have to issue this call rigth away,
+ // otherwise the window gets destroyed
+ d.destroyMethod();
+ }
+ };
+ w.addWindowListener(cl);
+ }
+ return cl;
+ }
+
+ protected final static Window getWindow(Component c) {
+ while ( c!=null && ! ( c instanceof Window ) ) {
+ c = c.getParent();
+ }
+ return (Window)c;
+ }
+
+ /**
+ * Overridden to choose a GraphicsConfiguration on a parent container's
+ * GraphicsDevice because both devices
+ */
+ 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.
+ */
+ 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((GLCapabilities)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("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) {
+ return drawable.createContext(shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ }
+
+ private Object closingListener = null;
+ private Object closingListenerLock = new Object();
+
+ public void display() {
+ maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
+ displayAction);
+ if(null==closingListener) {
+ synchronized(closingListenerLock) {
+ if(null==closingListener) {
+ closingListener=addClosingListener(this, new DestroyMethod() {
+ public void destroyMethod() { destroy(); } });
+ }
+ }
+ }
+ }
+
+ protected void dispose(boolean regenerate) {
+ if(DEBUG) {
+ Exception ex1 = new Exception("dispose("+regenerate+") - start");
+ ex1.printStackTrace();
+ }
+ 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
+ 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.
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ } else {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else {
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ }
+
+ 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.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> */
+ 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;
+ }
+
+ display();
+ }
+
+ /** 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 (!Beans.isDesignTime()) {
+ disableBackgroundErase();
+
+ if(null==device) {
+ GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ if(null!=gc) {
+ device = gc.getDevice();
+ }
+ }
+
+ /*
+ * Save the chosen capabilities for use in getGraphicsConfiguration().
+ */
+ awtConfig = chooseGraphicsConfiguration(capabilities, chooser, device);
+ if(DEBUG) {
+ Exception e = new Exception("Created Config: "+awtConfig);
+ e.printStackTrace();
+ }
+ if(null!=awtConfig) {
+ // update ..
+ chosen = awtConfig.getGraphicsConfiguration();
+
+ }
+ if(null==awtConfig) {
+ throw new GLException("Error: AWTGraphicsConfiguration is null");
+ }
+ drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig));
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setSynchronized(true);
+
+ if(DEBUG) {
+ System.err.println("Created Drawable: "+drawable);
+ }
+ drawable.setRealized(true);
+ }
+ }
+
+ /** 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("removeNotify - start");
+ ex1.printStackTrace();
+ }
+
+ if (Beans.isDesignTime()) {
+ super.removeNotify();
+ } else {
+ try {
+ dispose(false);
+ } finally {
+ drawable=null;
+ super.removeNotify();
+ }
+ }
+ if(DEBUG) {
+ System.out.println("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);
+ 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.
+ public void update(Graphics g) {
+ paint(g);
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public void setContext(GLContext ctx) {
+ context=(GLContextImpl)ctx;
+ }
+
+ public GLContext getContext() {
+ return context;
+ }
+
+ public GL getGL() {
+ if (Beans.isDesignTime()) {
+ return null;
+ }
+ GLContext context = getContext();
+ return (context == null) ? null : context.getGL();
+ }
+
+ public void setGL(GL gl) {
+ GLContext context = getContext();
+ if (context != null) {
+ context.setGL(gl);
+ }
+ }
+
+
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ drawableHelper.setAutoSwapBufferMode(onOrOff);
+ }
+
+ public boolean getAutoSwapBufferMode() {
+ return drawableHelper.getAutoSwapBufferMode();
+ }
+
+ public void swapBuffers() {
+ maybeDoSingleThreadedWorkaround(swapBuffersOnEventDispatchThreadAction, swapBuffersAction);
+ }
+
+ public GLProfile getGLProfile() {
+ return glProfile;
+ }
+
+ public GLCapabilities getChosenGLCapabilities() {
+ if (awtConfig == null) {
+ throw new GLException("No AWTGraphicsConfiguration: "+this);
+ }
+
+ return (GLCapabilities)awtConfig.getChosenCapabilities();
+ }
+
+ public GLCapabilities getRequestedGLCapabilities() {
+ if (awtConfig == null) {
+ throw new GLException("No AWTGraphicsConfiguration: "+this);
+ }
+
+ return (GLCapabilities)awtConfig.getRequestedCapabilities();
+ }
+
+ public NativeWindow getNativeWindow() {
+ return drawable.getNativeWindow();
+ }
+
+ public GLDrawableFactory getFactory() {
+ return drawable.getFactory();
+ }
+
+ public String toString() {
+ return "AWT-GLCanvas[ "+awtConfig+", "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+", "+drawableHelper+"]";
+ }
+
+ //----------------------------------------------------------------------
+ // 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);
+ }
+ }
+
+ private boolean disposeRegenerate;
+ private DisposeAction disposeAction = new DisposeAction(this);
+
+ class DisposeAction implements Runnable {
+ private GLCanvas canvas;
+ public DisposeAction(GLCanvas canvas) {
+ this.canvas = canvas;
+ }
+ 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);
+ }
+
+ if(disposeRegenerate) {
+ // recreate GLDrawable to reflect it's new graphics configuration
+ drawable = GLDrawableFactory.getFactory(glProfile).createGLDrawable(NativeWindowFactory.getNativeWindow(canvas, 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 DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
+ new DisposeOnEventDispatchThreadAction();
+
+ class DisposeOnEventDispatchThreadAction implements Runnable {
+ public void run() {
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ }
+ }
+
+ 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) {
+ // Note: we ignore the given x and y within the parent component
+ // since we are drawing directly into this heavyweight component.
+ int width = getWidth();
+ int height = getHeight();
+ getGL().glViewport(0, 0, width, height);
+ drawableHelper.reshape(GLCanvas.this, 0, 0, width, height);
+ 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 (disableBackgroundEraseMethod != null) {
+ try {
+ disableBackgroundEraseMethod.invoke(getToolkit(), new Object[] { this });
+ } catch (Exception e) {
+ // FIXME: workaround for 6504460 (incorrect backport of 6333613 in 5.0u10)
+ // throw new GLException(e);
+ }
+ }
+ }
+
+ private static AWTGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ GraphicsDevice device) {
+ // Make GLCanvas behave better in NetBeans GUI builder
+ if (Beans.isDesignTime()) {
+ return null;
+ }
+
+ AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device);
+ AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capabilities,
+ chooser,
+ aScreen);
+ if (config == null) {
+ throw new GLException("Error: Couldn't fetch AWTGraphicsConfiguration");
+ }
+
+ return config;
+ }
+}
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..5da6a892f
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -0,0 +1,1582 @@
+/*
+ * 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 javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+
+import java.awt.*;
+import java.awt.geom.*;
+import java.awt.image.*;
+import java.beans.*;
+import javax.swing.*;
+import java.nio.*;
+import java.security.*;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import com.sun.opengl.impl.*;
+import com.sun.opengl.impl.awt.*;
+
+// 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>
+
+ 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>
+
+*/
+
+public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
+ 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 GLCapabilities 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();
+
+ // 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");
+
+ // Turns off the fallback to software-based rendering from
+ // pbuffer-based rendering
+ private static boolean softwareRenderingDisabled =
+ Debug.isPropertyDefined("jogl.gljpanel.nosw");
+
+ // Indicates whether the Java 2D OpenGL pipeline is enabled
+ private boolean oglPipelineEnabled =
+ Java2D.isOGLPipelineActive() &&
+ !Debug.isPropertyDefined("jogl.gljpanel.noogl");
+
+ // 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;
+
+ 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(GLCapabilities capabilities) {
+ this(capabilities, 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>.
+ */
+ public GLJPanel(GLCapabilities capabilities, GLCapabilitiesChooser chooser, GLContext shareWith) {
+ super();
+
+ // Works around problems on many vendors' cards; we don't need a
+ // back buffer for the offscreen surface anyway
+ if (capabilities != null) {
+ offscreenCaps = (GLCapabilities) capabilities.clone();
+ } else {
+ offscreenCaps = new GLCapabilities(null);
+ }
+ offscreenCaps.setDoubleBuffered(false);
+ 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("dispose("+regenerate+") - start");
+ ex1.printStackTrace();
+ }
+ if (backend != null) {
+ 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.
+ drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ } else {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else {
+ drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ }
+
+ backend.setContext(disposeContext);
+ if(null==disposeContext) {
+ isInitialized = false;
+ }
+ }
+
+ 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("removeNotify - start");
+ ex1.printStackTrace();
+ }
+ dispose(false);
+ if (backend != null) {
+ backend.destroy();
+ backend = null;
+ }
+ isInitialized = false;
+ super.removeNotify();
+ if(DEBUG) {
+ System.out.println("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 removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return backend.createContext(shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ }
+
+ 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 void setGL(GL gl) {
+ GLContext context = getContext();
+ if (context != null) {
+ context.setGL(gl);
+ }
+ }
+
+ 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 GLCapabilities getChosenGLCapabilities() {
+ return backend.getChosenGLCapabilities();
+ }
+
+ public final GLProfile getGLProfile() {
+ return glProfile;
+ }
+
+ public NativeWindow getNativeWindow() {
+ 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()) {
+ 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);
+
+ if(null==closingListener) {
+ synchronized(closingListenerLock) {
+ if(null==closingListener) {
+ closingListener=GLCanvas.addClosingListener(this, new GLCanvas.DestroyMethod() {
+ public void destroyMethod() { destroy(); } });
+ }
+ }
+ }
+ }
+ private Object closingListener = null;
+ private Object closingListenerLock = new Object();
+
+ 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) {
+ System.err.println("glViewport(" + viewportX + ", " + viewportY + ", " + panelWidth + ", " + panelHeight + ")");
+ }
+ getGL().getGL2().glViewport(viewportX, viewportY, panelWidth, 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")+", "+drawableHelper+"]";
+ }
+
+ 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(disposeRegenerate && null!=disposeDrawable) {
+ 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 GLCapabilities 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 = factory.createOffscreenDrawable(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 GLCapabilities 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(offscreenCaps,
+ null,
+ pbufferWidth,
+ pbufferHeight,
+ shareWith);
+ pbuffer.addGLEventListener(updater);
+ isInitialized = true;
+ } catch (GLException e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ System.err.println("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 GLCapabilities 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 GLCapabilities 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();
+ }
+
+ 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) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: Binding to framebuffer object " + frameBuffer[0]);
+ }
+
+ // 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]);
+ if (gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER) !=
+ GL2.GL_FRAMEBUFFER_COMPLETE) {
+ // Need to do workarounds
+ fbObjectWorkarounds = true;
+ createNewDepthBuffer = true;
+ if (DEBUG) {
+ System.err.println("-- GLJPanel: discovered frame_buffer_object workarounds to be necessary");
+ }
+ } else {
+ // Don't need the frameBufferTexture temporary any more
+ frameBufferTexture = null;
+ }
+ }
+
+ 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(GL2.GL_RENDERBUFFER, frameBufferDepthBuffer[0]);
+ // FIXME: may need a loop here like in Java2D
+ gl.glRenderbufferStorage(GL2.GL_RENDERBUFFER, GL2.GL_DEPTH_COMPONENT24, width[0], height[0]);
+
+ gl.glBindRenderbuffer(GL2.GL_RENDERBUFFER, 0);
+ createNewDepthBuffer = false;
+ }
+
+ gl.glBindTexture(fboTextureTarget, 0);
+ gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer[0]);
+
+ if (fbObjectWorkarounds) {
+ // Hook up the color and depth buffer attachment points for this framebuffer
+ gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER,
+ GL2.GL_COLOR_ATTACHMENT0,
+ fboTextureTarget,
+ frameBufferTexture[0],
+ 0);
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: frameBufferDepthBuffer: " + frameBufferDepthBuffer[0]);
+ }
+ gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER,
+ GL2.GL_DEPTH_ATTACHMENT,
+ GL2.GL_RENDERBUFFER,
+ frameBufferDepthBuffer[0]);
+ }
+
+ if (DEBUG) {
+ int status = gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER);
+ if (status != GL2.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) {
+ 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, GL2.GL_RED_BITS) < offscreenCaps.getRedBits()) ||
+ (getGLInteger(gl, GL2.GL_GREEN_BITS) < offscreenCaps.getGreenBits()) ||
+ (getGLInteger(gl, GL2.GL_BLUE_BITS) < offscreenCaps.getBlueBits()) ||
+ // (getGLInteger(gl, GL2.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, GL2.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, GL2.GL_RED_BITS) + " " + offscreenCaps.getRedBits());
+ System.err.println("GL_GREEN_BITS " + getGLInteger(gl, GL2.GL_GREEN_BITS) + " " + offscreenCaps.getGreenBits());
+ System.err.println("GL_BLUE_BITS " + getGLInteger(gl, GL2.GL_BLUE_BITS) + " " + offscreenCaps.getBlueBits());
+ System.err.println("GL_ALPHA_BITS " + getGLInteger(gl, GL2.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, GL2.GL_DEPTH_BITS) + " " + offscreenCaps.getDepthBits());
+ System.err.println("GL_STENCIL_BITS " + getGLInteger(gl, GL2.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) {
+ System.err.println("Sending reshape because surface changed");
+ System.err.println("New surface = " + curSurface);
+ }
+ }
+ j2dSurface = curSurface;
+ }
+ if (joglContext == null) {
+ if (factory.canCreateExternalGLDrawable()) {
+ joglDrawable = factory.createExternalGLDrawable();
+ joglContext = joglDrawable.createContext(shareWith);
+ } else if (factory.canCreateContextOnJava2DSurface()) {
+ // Mac OS X code path
+ joglContext = factory.createContextOnJava2DSurface(g, shareWith);
+ }
+ 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);
+ }
+
+ if (DEBUG && VERBOSE && Java2D.isFBOEnabled()) {
+ 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 + ")");
+ }
+ }
+
+ 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) {
+ if (DEBUG && VERBOSE) {
+ System.err.println("GLJPanel: Fetching GL_FRAMEBUFFER_BINDING_EXT");
+ }
+ gl.glGetIntegerv(GL2.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(GL2.GL_FRAMEBUFFER,
+ GL2.GL_COLOR_ATTACHMENT0,
+ GL2.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(GL2.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(GL2.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..61757abde
--- /dev/null
+++ b/src/jogl/classes/javax/media/opengl/fixedfunc/GLMatrixFunc.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ */
+
+package javax.media.opengl.fixedfunc;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+
+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 params 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 100755
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 100755
index 000000000..d5a7a11f3
--- /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.sun.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 100755
index 000000000..cb7bd9d76
--- /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 1.1 (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 100755
index 000000000..4b5ec63b7
--- /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 1.1 (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(com.sun.opengl.impl.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 100755
index 000000000..bf6f2d29a
--- /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 1.1 (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(com.sun.opengl.impl.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) {}
+}