aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/games/jogl
diff options
context:
space:
mode:
authordjp <[email protected]>2003-06-08 19:27:01 +0000
committerdjp <[email protected]>2003-06-08 19:27:01 +0000
commitd49fd968963909f181423eae46c613189468fac3 (patch)
treeb231329e6b65fd54aa24b3bcc0a3ecc623daec61 /src/net/java/games/jogl
parent9c8fb046dee5d832bea3f36dcbd43285054f49a0 (diff)
Initial revision
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@3 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/net/java/games/jogl')
-rw-r--r--src/net/java/games/jogl/Animator.java120
-rw-r--r--src/net/java/games/jogl/ComponentEvents.java74
-rw-r--r--src/net/java/games/jogl/DefaultGLCapabilitiesChooser.java216
-rw-r--r--src/net/java/games/jogl/GLCanvas.java177
-rw-r--r--src/net/java/games/jogl/GLCapabilities.java308
-rw-r--r--src/net/java/games/jogl/GLCapabilitiesChooser.java52
-rw-r--r--src/net/java/games/jogl/GLDrawable.java183
-rw-r--r--src/net/java/games/jogl/GLDrawableFactory.java112
-rw-r--r--src/net/java/games/jogl/GLEventListener.java95
-rw-r--r--src/net/java/games/jogl/GLException.java68
-rw-r--r--src/net/java/games/jogl/GLJPanel.java316
-rw-r--r--src/net/java/games/jogl/GLPbuffer.java63
-rw-r--r--src/net/java/games/jogl/impl/FunctionAvailabilityCache.java294
-rw-r--r--src/net/java/games/jogl/impl/GLContext.java400
-rw-r--r--src/net/java/games/jogl/impl/GLContextFactory.java89
-rw-r--r--src/net/java/games/jogl/impl/GLDrawableHelper.java87
-rw-r--r--src/net/java/games/jogl/impl/GLPbufferImpl.java192
-rw-r--r--src/net/java/games/jogl/impl/JAWT_PlatformInfo.java45
-rw-r--r--src/net/java/games/jogl/impl/NativeLibLoader.java50
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java110
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLContext.java365
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java56
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java169
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java203
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java413
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContext.java414
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContextFactory.java56
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java177
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java189
29 files changed, 5093 insertions, 0 deletions
diff --git a/src/net/java/games/jogl/Animator.java b/src/net/java/games/jogl/Animator.java
new file mode 100644
index 000000000..d9f2c6729
--- /dev/null
+++ b/src/net/java/games/jogl/Animator.java
@@ -0,0 +1,120 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+/** <P> An Animator can be attached to a GLDrawable to drive its
+ display() method in a loop. For efficiency, it sets up the
+ rendering thread for the drawable to be its own internal thread,
+ so it can not be combined with manual repaints of the
+ surface. </P>
+
+ <P> The Animator currently contains a workaround for a bug in
+ NVidia's drivers (80174). The current semantics are that once an
+ Animator is created with a given GLDrawable as a target, repaints
+ will likely be suspended for that GLDrawable until the Animator is
+ started. This prevents multithreaded access to the context (which
+ can be problematic) when the application's intent is for
+ single-threaded access within the Animator. It is not guaranteed
+ that repaints will be prevented during this time and applications
+ should not rely on this behavior for correctness. </P>
+*/
+
+public class Animator {
+ private GLDrawable drawable;
+ private Runnable runnable;
+ private Thread thread;
+ private boolean shouldStop;
+
+ public Animator(GLDrawable drawable) {
+ this.drawable = drawable;
+
+ // Workaround for NVidia driver bug 80174
+ if (drawable instanceof GLCanvas) {
+ ((GLCanvas) drawable).willSetRenderingThread();
+ }
+ }
+
+ public synchronized void start() {
+ if (thread != null) {
+ throw new GLException("Already started");
+ }
+ if (runnable == null) {
+ runnable = new Runnable() {
+ public void run() {
+ drawable.setRenderingThread(Thread.currentThread());
+ drawable.setNoAutoRedrawMode(true);
+ boolean noException = false;
+ try {
+ while (!shouldStop) {
+ noException = false;
+ drawable.display();
+ noException = true;
+ }
+ } finally {
+ shouldStop = false;
+ drawable.setNoAutoRedrawMode(false);
+ if (noException) {
+ try {
+ drawable.setRenderingThread(null);
+ } finally {
+ thread = null;
+ synchronized (Animator.this) {
+ Animator.this.notify();
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+ thread = new Thread(runnable);
+ thread.start();
+ }
+
+ public synchronized void stop() {
+ shouldStop = true;
+ while (shouldStop && thread != null) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+}
diff --git a/src/net/java/games/jogl/ComponentEvents.java b/src/net/java/games/jogl/ComponentEvents.java
new file mode 100644
index 000000000..fc3208024
--- /dev/null
+++ b/src/net/java/games/jogl/ComponentEvents.java
@@ -0,0 +1,74 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+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/net/java/games/jogl/DefaultGLCapabilitiesChooser.java b/src/net/java/games/jogl/DefaultGLCapabilitiesChooser.java
new file mode 100644
index 000000000..de7f500b5
--- /dev/null
+++ b/src/net/java/games/jogl/DefaultGLCapabilitiesChooser.java
@@ -0,0 +1,216 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+/** <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.
+
+ </UL>
+*/
+
+public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
+ private static final boolean DEBUG = false;
+
+ public int chooseCapabilities(GLCapabilities desired, GLCapabilities[] available) {
+ if (DEBUG) {
+ for (int i = 0; i < available.length; i++) {
+ System.err.println("Available " + i + ": " + available[i]);
+ }
+ }
+
+ // 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 GLException("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/net/java/games/jogl/GLCanvas.java b/src/net/java/games/jogl/GLCanvas.java
new file mode 100644
index 000000000..21c06ee3f
--- /dev/null
+++ b/src/net/java/games/jogl/GLCanvas.java
@@ -0,0 +1,177 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+import java.awt.Canvas;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import net.java.games.jogl.impl.*;
+
+// 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. This class can not be
+ instantiated directly; use {@link GLDrawableFactory} to construct
+ them. */
+
+public final class GLCanvas extends Canvas implements GLDrawable {
+
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private GLContext context;
+
+ GLCanvas(GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super();
+ context = GLContextFactory.getFactory().createGLContext(this, capabilities, chooser);
+ }
+
+ GLCanvas(GraphicsConfiguration config, GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super(config);
+ context = GLContextFactory.getFactory().createGLContext(this, capabilities, chooser);
+ }
+
+ public void display() {
+ context.invokeGL(displayAction, false, initAction);
+ }
+
+ /** Overridden from Canvas; calls {@link #display}. Should not be
+ invoked by applications directly. */
+ public void paint(Graphics g) {
+ if (!context.getNoAutoRedrawMode()) {
+ display();
+ }
+ }
+
+ /** Overridden from Canvas; causes {@link GLDrawableHelper#reshape}
+ to be called on all registered {@link GLEventListener}s. Called
+ automatically by the AWT; should not be invoked by applications
+ directly. */
+ public void reshape(int x, int y, int width, int height) {
+ super.reshape(x, y, width, height);
+ // Note: we ignore the given x and y within the parent component
+ // since we are drawing directly into this heavyweight component.
+ final int fx = 0;
+ final int fy = 0;
+ final int fwidth = width;
+ final int fheight = height;
+ context.invokeGL(new Runnable() {
+ public void run() {
+ getGL().glViewport(fx, fy, fwidth, fheight);
+ drawableHelper.reshape(GLCanvas.this, fx, fy, fwidth, fheight);
+ }
+ }, true, initAction);
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public GL getGL() {
+ return context.getGL();
+ }
+
+ public void setGL(GL gl) {
+ context.setGL(gl);
+ }
+
+ public GLU getGLU() {
+ return context.getGLU();
+ }
+
+ public void setGLU(GLU glu) {
+ context.setGLU(glu);
+ }
+
+ void willSetRenderingThread() {
+ context.willSetRenderingThread();
+ }
+
+ public void setRenderingThread(Thread currentThreadOrNull) throws GLException {
+ context.setRenderingThread(currentThreadOrNull, initAction);
+ }
+
+ public Thread getRenderingThread() {
+ return context.getRenderingThread();
+ }
+
+ public void setNoAutoRedrawMode(boolean noAutoRedraw) {
+ context.setNoAutoRedrawMode(noAutoRedraw);
+ }
+
+ public boolean getNoAutoRedrawMode() {
+ return context.getNoAutoRedrawMode();
+ }
+
+ public boolean canCreateOffscreenDrawable() {
+ return context.canCreatePbufferContext();
+ }
+
+ public GLPbuffer createOffscreenDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ return new GLPbufferImpl(context.createPbufferContext(capabilities, initialWidth, initialHeight));
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ class InitAction implements Runnable {
+ public void run() {
+ drawableHelper.init(GLCanvas.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ drawableHelper.display(GLCanvas.this);
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+}
diff --git a/src/net/java/games/jogl/GLCapabilities.java b/src/net/java/games/jogl/GLCapabilities.java
new file mode 100644
index 000000000..389617912
--- /dev/null
+++ b/src/net/java/games/jogl/GLCapabilities.java
@@ -0,0 +1,308 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+/** Specifies a set of OpenGL capabilities that a rendering context
+ must support, such as color depth and whether stereo is enabled.
+ It currently contains the minimal number of routines which allow
+ configuration on all supported window systems. */
+
+public class GLCapabilities implements Cloneable {
+ private boolean doubleBuffered = true;
+ private boolean stereo = false;
+ private boolean hardwareAccelerated = true;
+ private int depthBits = 24;
+ private int stencilBits = 0;
+ private int redBits = 8;
+ private int greenBits = 8;
+ private int blueBits = 8;
+ private int alphaBits = 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
+
+ // Bits for pbuffer creation
+ private boolean offscreenFloatingPointBuffers;
+ private boolean offscreenRenderToTexture;
+ private boolean offscreenRenderToTextureRectangle;
+
+ /** Creates a GLCapabilities object. All attributes are in a default
+ state.
+ */
+ public GLCapabilities() {}
+
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+
+ /** 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 color buffer's red
+ component. On some systems only the color depth, which is the
+ sum of the red, green, and blue bits, is considered. */
+ public int getRedBits() {
+ return redBits;
+ }
+
+ /** Sets the number of bits requested for the color buffer's red
+ component. On some systems only the color depth, which is the
+ sum of the red, green, and blue bits, is considered. */
+ public void setRedBits(int redBits) {
+ this.redBits = redBits;
+ }
+
+ /** Returns the number of bits requested for the color buffer's
+ green component. On some systems only the color depth, which is
+ the sum of the red, green, and blue bits, is considered. */
+ public int getGreenBits() {
+ return greenBits;
+ }
+
+ /** Sets the number of bits requested for the color buffer's green
+ component. On some systems only the color depth, which is the
+ sum of the red, green, and blue bits, is considered. */
+ public void setGreenBits(int greenBits) {
+ this.greenBits = greenBits;
+ }
+
+ /** Returns the number of bits requested for the color buffer's blue
+ component. On some systems only the color depth, which is the
+ sum of the red, green, and blue bits, is considered. */
+ public int getBlueBits() {
+ return blueBits;
+ }
+
+ /** Sets the number of bits requested for the color buffer's blue
+ component. On some systems only the color depth, which is the
+ sum of the red, green, and blue bits, is considered. */
+ public void setBlueBits(int blueBits) {
+ this.blueBits = blueBits;
+ }
+
+ /** Returns the number of bits requested for the color buffer's
+ alpha component. On some systems only the color depth, which is
+ the sum of the red, green, and blue bits, is considered. */
+ public int getAlphaBits() {
+ return alphaBits;
+ }
+
+ /** Sets the number of bits requested for the color buffer's alpha
+ component. On some systems only the color depth, which is the
+ sum of the red, green, and blue bits, is considered. */
+ public void setAlphaBits(int alphaBits) {
+ this.alphaBits = alphaBits;
+ }
+
+ /** 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;
+ }
+
+ /** For offscreen surfaces only (pbuffers), indicates whether
+ floating-point buffers should be used if available. Defaults to
+ false. */
+ public void setOffscreenFloatingPointBuffers(boolean onOrOff) {
+ offscreenFloatingPointBuffers = onOrOff;
+ }
+
+ /** For offscreen surfaces only (pbuffers), returns whether
+ floating-point buffers should be used if available. Defaults to
+ false. */
+ public boolean getOffscreenFloatingPointBuffers() {
+ return offscreenFloatingPointBuffers;
+ }
+
+ /** For offscreen surfaces only (pbuffers), indicates whether the
+ render-to-texture extension should be used if available.
+ Defaults to false. */
+ public void setOffscreenRenderToTexture(boolean onOrOff) {
+ offscreenRenderToTexture = onOrOff;
+ }
+
+ /** For offscreen surfaces only (pbuffers), returns whether the
+ render-to-texture extension should be used if available.
+ Defaults to false. */
+ public boolean getOffscreenRenderToTexture() {
+ return offscreenRenderToTexture;
+ }
+
+ /** For offscreen surfaces only (pbuffers), indicates whether the
+ render-to-texture-rectangle extension should be used if
+ available. Defaults to false. */
+ public void setOffscreenRenderToTextureRectangle(boolean onOrOff) {
+ offscreenRenderToTextureRectangle = onOrOff;
+ }
+
+ /** For offscreen surfaces only (pbuffers), returns whether the
+ render-to-texture extension should be used. Defaults to false. */
+ public boolean getOffscreenRenderToTextureRectangle() {
+ return offscreenRenderToTextureRectangle;
+ }
+
+ /** Returns a textual representation of this GLCapabilities
+ object. */
+ public String toString() {
+ return ("GLCapabilities [" +
+ "DoubleBuffered: " + doubleBuffered +
+ ", Stereo: " + stereo +
+ ", HardwareAccelerated: " + hardwareAccelerated +
+ ", DepthBits: " + depthBits +
+ ", StencilBits: " + stencilBits +
+ ", Red: " + redBits +
+ ", Green: " + greenBits +
+ ", Blue: " + blueBits +
+ ", Alpha: " + alphaBits +
+ ", Red Accum: " + accumRedBits +
+ ", Green Accum: " + accumGreenBits +
+ ", Blue Accum: " + accumBlueBits +
+ ", Alpha Accum: " + accumAlphaBits +
+ " ]");
+ }
+}
diff --git a/src/net/java/games/jogl/GLCapabilitiesChooser.java b/src/net/java/games/jogl/GLCapabilitiesChooser.java
new file mode 100644
index 000000000..16b0e2b76
--- /dev/null
+++ b/src/net/java/games/jogl/GLCapabilitiesChooser.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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+/** Provides a mechanism by which applications can customize the
+ window type selection for a given {@link GLCapabilities}. */
+
+public interface GLCapabilitiesChooser {
+ /** Chooses the index (0..available.length - 1) of the {@link
+ GLCapabilities} most closely matching the desired one from the
+ list of all supported. Some of the entries in the
+ <code>available</code> array may be null; the chooser must
+ ignore these. */
+ public int chooseCapabilities(GLCapabilities desired, GLCapabilities[] available);
+}
diff --git a/src/net/java/games/jogl/GLDrawable.java b/src/net/java/games/jogl/GLDrawable.java
new file mode 100644
index 000000000..6197688b1
--- /dev/null
+++ b/src/net/java/games/jogl/GLDrawable.java
@@ -0,0 +1,183 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+import java.awt.Dimension;
+
+// FIXME: We need some way to tell when the device upon which the canvas is
+// being displayed has changed (e.g., the user drags the canvas's parent
+// window from one screen on multi-screen environment to another, when the
+// user changes the display bit depth or screen resolution, etc). When this
+// occurs, we need the canvas to reset the gl function pointer tables for the
+// canvas, because the new device may have different capabilities (e.g.,
+// doesn't support as many opengl extensions) from the original device. This
+// hook would also be useful in other GLDrawables (for example, offscreen
+// buffers such as pbuffers, whose contents may or may not be invalidated when
+// the display mode changes, depending on the vendor's GL implementation).
+//
+// Right now I'm not sure how hook into when this change occurs. There isn't
+// any AWT event corresponding to a device change (as far as I can
+// tell). We could constantly check the GraphicsConfiguration of the canvas's top-level
+// parent to see if it has changed, but this would be very slow (we'd have to
+// do it every time the context is made current). There has got to be a better
+// solution, but I'm not sure what it is.
+
+// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
+// context whenever the displayChanged() function is called on our
+// GLEventListeners
+
+/** Abstracts common functionality among the OpenGL components {@link
+ GLCanvas} and {@link GLJPanel}. */
+
+public interface GLDrawable extends ComponentEvents {
+ /** 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);
+
+ /** Sets the size of this GLDrawable. */
+ public void setSize(int width, int height);
+
+ /** Sets the size of this GLDrawable. */
+ public void setSize(Dimension d);
+
+ /** Returns the size of this GLDrawable as a newly-created Dimension
+ object. */
+ public Dimension getSize();
+
+ /** Stores the size of this GLDrawable into the user-provided
+ Dimension object, returning that object. If the provided
+ Dimension is null a new one will be allocated and returned. */
+ public Dimension getSize(Dimension d);
+
+ /** Returns the {@link GL} pipeline object this GLDrawable uses. */
+ public GL getGL();
+
+ /** Sets the {@link GL} pipeline object this GLDrawable uses. */
+ public void setGL(GL gl);
+
+ /** Returns the {@link GLU} pipeline object this GLDrawable uses. */
+ public GLU getGLU();
+
+ /** Sets the {@link GLU} pipeline object this GLDrawable uses. */
+ public void setGLU(GLU glu);
+
+ /** Causes OpenGL rendering to be performed for this GLDrawable by
+ calling {@link GLEventListener#display} for all registered
+ {@link GLEventListener}s. Called automatically by the window
+ system toolkit upon receiving a repaint() request. When used in
+ conjunction with {@link
+ net.java.games.jogl.GLDrawable#setRenderingThread}, this routine may be
+ called manually by the application's main loop for higher
+ performance and better control over the rendering process. */
+ public void display();
+
+ /** <P> Changes this GLDrawable to allow OpenGL rendering only from
+ the supplied thread, which must either be the current thread or
+ null. Attempts by other threads to perform OpenGL operations
+ like rendering or resizing the window will be ignored as long as
+ the thread is set. Setting up the rendering thread is not
+ required but enables the system to perform additional
+ optimizations, in particular when the application requires
+ control over the rendering loop. Before exiting,
+ <code>setRenderingThread(null)</code> must be called or other
+ threads will be unable to perform OpenGL rendering to this
+ drawable. Throws {@link GLException} if the rendering thread for
+ this drawable has been set and attempts are made to set or clear
+ the rendering thread from another thread, or if the passed
+ thread is not equal to the current thread or null. </P>
+
+ <P> <B>NOTE:</B> Currently this routine is only advisory, which
+ means that on some platforms the underlying optimizations are
+ disabled and setting the rendering thread has no effect.
+ Applications should not rely on setRenderingThread to prevent
+ rendering from other threads. <P>
+
+ @throws GLException if the rendering thread for this drawable has
+ been set by another thread or if the passed thread is not equal
+ to the current thread or null
+ */
+ public void setRenderingThread(Thread currentThreadOrNull) throws GLException;
+
+ /** Returns the rendering thread for this drawable, or null if none
+ has been set. */
+ public Thread getRenderingThread();
+
+ /** Disables automatic redraws of this drawable if possible. This is
+ provided as an overriding mechanism for applications which
+ perform animation on the drawable and for which the (currently
+ advisory) {@link #setRenderingThread} does not provide strict
+ enough guarantees. Its sole purpose is to avoid deadlocks that
+ are unfortunately all too easy to run into when both animating a
+ drawable from a given thread as well as having updates performed
+ by the AWT event thread (repaints, etc.). When it is enabled,
+ repaint requests driven by the AWT will not result in the OpenGL
+ event listeners' display methods being called from the AWT
+ thread, unless (as with GLJPanel) this is the only mechanism by
+ which repaints are done. The necessity of this API may be
+ rethought in a future release. Defaults to false. */
+ public void setNoAutoRedrawMode(boolean noAutoRedraws);
+
+ /** Returns whether automatic redraws are disabled for this
+ drawable. Defaults to false. */
+ public boolean getNoAutoRedrawMode();
+
+ /** Indicates whether this drawable is capable of fabricating a
+ subordinate offscreen drawable for advanced rendering techniques
+ which require offscreen hardware-accelerated surfaces. */
+ public boolean canCreateOffscreenDrawable();
+
+ /** Creates a subordinate offscreen drawable (pbuffer) for this
+ drawable. This routine should only be called if {@link
+ #canCreateOffscreenDrawable} returns true. The passed
+ capabilities are matched according to the platform-dependent
+ pbuffer format selection algorithm, which currently can not be
+ overridden. */
+ public GLPbuffer createOffscreenDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight);
+}
diff --git a/src/net/java/games/jogl/GLDrawableFactory.java b/src/net/java/games/jogl/GLDrawableFactory.java
new file mode 100644
index 000000000..17d5779df
--- /dev/null
+++ b/src/net/java/games/jogl/GLDrawableFactory.java
@@ -0,0 +1,112 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+/** <P> Provides a virtual machine- and operating system-independent
+ mechanism for creating {@link net.java.games.jogl.GLCanvas} and {@link
+ net.java.games.jogl.GLJPanel} objects. </P>
+
+ <P> The {@link net.java.games.jogl.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. </P>
+
+ <P> Because of the multithreaded nature of the Java platform's
+ window system 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. </P>
+*/
+
+public class GLDrawableFactory {
+ private static GLDrawableFactory factory = new GLDrawableFactory();
+
+ private GLDrawableFactory() {}
+
+ /** Returns the sole GLDrawableFactory instance. */
+ public static GLDrawableFactory getFactory() {
+ return factory;
+ }
+
+ /** Creates a {@link GLCanvas} with the specified capabilities using
+ the default capabilities selection algorithm. */
+ public GLCanvas createGLCanvas(GLCapabilities capabilities) {
+ return createGLCanvas(capabilities, null);
+ }
+
+ /** Creates a {@link GLCanvas} with the specified capabilities using
+ the supplied capabilities selection algorithm. A null chooser is
+ equivalent to using the {@link DefaultGLCapabilitiesChooser}. */
+ public GLCanvas createGLCanvas(GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ // FIXME: do we need to select a GraphicsConfiguration here as in
+ // GL4Java? If so, this class will have to be made abstract and
+ // we'll have to provide hooks into this package to get at the
+ // GLCanvas and GLJPanel constructors.
+ if (chooser == null) {
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+ return new GLCanvas(capabilities, chooser);
+ }
+
+ /** Creates a {@link GLJPanel} with the specified capabilities using
+ the default capabilities selection algorithm. */
+ public GLJPanel createGLJPanel(GLCapabilities capabilities) {
+ return createGLJPanel(capabilities, null);
+ }
+
+ /** Creates a {@link GLJPanel} with the specified capabilities using
+ the supplied capabilities selection algorithm. A null chooser is
+ equivalent to using the {@link DefaultGLCapabilitiesChooser}. */
+ public GLJPanel createGLJPanel(GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ if (chooser == null) {
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+ return new GLJPanel(capabilities, chooser);
+ }
+}
diff --git a/src/net/java/games/jogl/GLEventListener.java b/src/net/java/games/jogl/GLEventListener.java
new file mode 100644
index 000000000..8a768af87
--- /dev/null
+++ b/src/net/java/games/jogl/GLEventListener.java
@@ -0,0 +1,95 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+import java.util.EventListener;
+
+/** Declares events which client code can use to manage OpenGL
+ rendering into a {@link GLDrawable}. 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 for the first time. Can be used to perform one-time
+ OpenGL initialization such as setup of lights and display lists.
+ */
+ public void init(GLDrawable 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 necessary.
+ */
+ public void display(GLDrawable 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 net.java.games.jogl.GL#glViewport}; note that for
+ convenience the component has already called {@link
+ net.java.games.jogl.GL#glViewport}(x, y, width, height) when this method
+ is called, so the client may not have to do anything in this
+ method.
+ */
+ public void reshape(GLDrawable drawable, int x, int y, int width, int height);
+
+ /** Called by the drawable when the display mode or the display device
+ associated with the GLDrawable has changed. The two boolean parameters
+ indicate the types of change(s) that have occurred. (<b> !!! CURRENTLY
+ UNIMPLEMENTED !!! </b>)
+ <P>
+
+ An example of a display <i>mode</i> change is when the bit depth changes (e.g.,
+ from 32-bit to 16-bit color) on monitor upon which the GLDrawable is
+ currently being displayed. <p>
+
+ An example of a display <i>device</i> change is when the user drags the
+ window containing the GLDrawable from one monitor to another in a
+ multiple-monitor setup. <p>
+
+ The reason that this function handles both types of changes (instead of
+ handling mode and device changes in separate methods) is so that
+ applications have the opportunity to respond to display changes the most
+ efficient manner. For example, the application may need make fewer
+ adjustments to compensate for a device change if it knows that the mode
+ on the new device is identical the previous mode.
+ */
+ public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged);
+}
diff --git a/src/net/java/games/jogl/GLException.java b/src/net/java/games/jogl/GLException.java
new file mode 100644
index 000000000..6e0d5965f
--- /dev/null
+++ b/src/net/java/games/jogl/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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+/** 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/net/java/games/jogl/GLJPanel.java b/src/net/java/games/jogl/GLJPanel.java
new file mode 100644
index 000000000..787a4a8cc
--- /dev/null
+++ b/src/net/java/games/jogl/GLJPanel.java
@@ -0,0 +1,316 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.Rectangle;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import net.java.games.jogl.impl.*;
+
+// 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. Currently implemented using
+ offscreen (i.e., non-hardware accelerated) rendering, so
+ performance will likely be poor. This class can not be
+ instantiated directly; use {@link GLDrawableFactory} to construct
+ them. */
+
+public final class GLJPanel extends JPanel implements GLDrawable {
+ private GLCapabilities capabilities;
+ private GLCapabilitiesChooser chooser;
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+ private GLContext context;
+ private BufferedImage offscreenImage;
+ private int awtFormat;
+ private int glFormat;
+ private int glType;
+ private int glComps;
+ private DataBufferByte dbByte;
+ private DataBufferInt dbInt;
+ private Object semaphore = new Object();
+ private boolean repaintDone;
+
+ // For saving/restoring of OpenGL state during ReadPixels
+ private int[] swapbytes = new int[1];
+ private int[] lsbfirst = 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];
+
+ GLJPanel(GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super();
+ this.capabilities = capabilities;
+ this.chooser = chooser;
+ }
+
+ public void display() {
+ // Multithreaded redrawing of Swing components is not allowed
+ try {
+ synchronized(semaphore) {
+ repaintDone = false;
+ repaint();
+ while (!repaintDone) {
+ semaphore.wait();
+ }
+ }
+ } catch (InterruptedException e) {
+ }
+ }
+
+ /** Overridden from JComponent; calls {@link #display}. Should not
+ be invoked by applications directly. */
+ public void paintComponent(Graphics g) {
+ displayAction.setGraphics(g);
+ getContext().invokeGL(displayAction, false, initAction);
+ synchronized(semaphore) {
+ repaintDone = true;
+ semaphore.notifyAll();
+ }
+ }
+
+ /** Overridden from Canvas; causes {@link GLDrawableHelper#reshape}
+ to be called on all registered {@link GLEventListener}s. Called
+ automatically by the AWT; should not be invoked by applications
+ directly. */
+ public void reshape(int x, int y, int width, int height) {
+ super.reshape(x, y, width, height);
+ // NOTE: we don't pay attention to the x and y provided since we
+ // are blitting into this component directly
+ final int fx = 0;
+ final int fy = 0;
+ final int fwidth = width;
+ final int fheight = height;
+ getContext().resizeOffscreenContext(width, height);
+ getContext().invokeGL(new Runnable() {
+ public void run() {
+ getGL().glViewport(fx, fy, fwidth, fheight);
+ drawableHelper.reshape(GLJPanel.this, fx, fy, fwidth, fheight);
+ if (offscreenImage != null &&
+ (offscreenImage.getWidth() != getWidth() ||
+ offscreenImage.getHeight() != getHeight())) {
+ offscreenImage.flush();
+ offscreenImage = null;
+ }
+ }
+ }, true, initAction);
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public GL getGL() {
+ // must use getContext() because context is created lazily
+ return getContext().getGL();
+ }
+
+ public void setGL(GL gl) {
+ // must use getContext() because context is created lazily
+ getContext().setGL(gl);
+ }
+
+ public GLU getGLU() {
+ // must use getContext() because context is created lazily
+ return getContext().getGLU();
+ }
+
+ public void setGLU(GLU glu) {
+ // must use getContext() because context is created lazily
+ getContext().setGLU(glu);
+ }
+
+ public void setRenderingThread(Thread currentThreadOrNull) throws GLException {
+ // Not supported for GLJPanel because all repaint requests must be
+ // handled by the AWT thread
+ }
+
+ public Thread getRenderingThread() {
+ return getContext().getRenderingThread();
+ }
+
+ public void setNoAutoRedrawMode(boolean noAutoRedraws) {
+ }
+
+ public boolean getNoAutoRedrawMode() {
+ return false;
+ }
+
+ public boolean canCreateOffscreenDrawable() {
+ // For now let's say no; maybe we can reimplement this class in
+ // terms of pbuffers (though not all vendors support them, and
+ // they seem to require an onscreen context)
+ return false;
+ }
+
+ public GLPbuffer createOffscreenDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ throw new GLException("Not supported");
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private GLContext getContext() {
+ if (context == null) {
+ context = GLContextFactory.getFactory().createGLContext(null, capabilities, chooser);
+ }
+ return context;
+ }
+
+ class InitAction implements Runnable {
+ public void run() {
+ drawableHelper.init(GLJPanel.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ private Graphics g;
+
+ public void setGraphics(Graphics g) {
+ this.g = g;
+ }
+
+ public void run() {
+ drawableHelper.display(GLJPanel.this);
+ // Must now copy pixels from offscreen context into surface
+ if (offscreenImage == null) {
+ int awtFormat = getContext().getOffscreenContextBufferedImageType();
+ offscreenImage = new BufferedImage(getWidth(), getHeight(), awtFormat);
+ switch (awtFormat) {
+ case BufferedImage.TYPE_3BYTE_BGR:
+ glFormat = GL.GL_BGR;
+ glType = GL.GL_UNSIGNED_BYTE;
+ glComps = 3;
+ dbByte = (DataBufferByte) offscreenImage.getRaster().getDataBuffer();
+ break;
+
+ case BufferedImage.TYPE_INT_RGB:
+ glFormat = GL.GL_BGRA;
+ glType = GL.GL_UNSIGNED_BYTE;
+ glComps = 4;
+ dbInt = (DataBufferInt) offscreenImage.getRaster().getDataBuffer();
+ break;
+
+ case BufferedImage.TYPE_INT_ARGB:
+ glFormat = GL.GL_BGRA;
+ glType = GL.GL_UNSIGNED_BYTE;
+ glComps = 4;
+ dbInt = (DataBufferInt) offscreenImage.getRaster().getDataBuffer();
+ 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);
+ }
+ }
+
+ GL gl = getGL();
+ // Save current modes
+ gl.glGetIntegerv(GL.GL_PACK_SWAP_BYTES, swapbytes);
+ gl.glGetIntegerv(GL.GL_PACK_LSB_FIRST, lsbfirst);
+ gl.glGetIntegerv(GL.GL_PACK_ROW_LENGTH, rowlength);
+ gl.glGetIntegerv(GL.GL_PACK_SKIP_ROWS, skiprows);
+ gl.glGetIntegerv(GL.GL_PACK_SKIP_PIXELS, skippixels);
+ gl.glGetIntegerv(GL.GL_PACK_ALIGNMENT, alignment);
+
+ // Little endian machines (DEC Alpha, Intel X86, PPC (in LSB
+ // mode)... for example) could benefit from setting
+ // GL_PACK_LSB_FIRST to GL_TRUE instead of GL_FALSE, but this
+ // would require changing the generated bitmaps too.
+ gl.glPixelStorei(GL.GL_PACK_SWAP_BYTES, GL.GL_FALSE);
+ gl.glPixelStorei(GL.GL_PACK_LSB_FIRST, GL.GL_TRUE);
+ gl.glPixelStorei(GL.GL_PACK_ROW_LENGTH, getWidth());
+ gl.glPixelStorei(GL.GL_PACK_SKIP_ROWS, 0);
+ gl.glPixelStorei(GL.GL_PACK_SKIP_PIXELS, 0);
+ gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
+
+ // Actually read the pixels.
+ gl.glReadBuffer(context.getOffscreenContextReadBuffer());
+ if (dbByte != null) {
+ gl.glReadPixels(0, 0, getWidth(), getHeight(), glFormat, glType, dbByte.getData());
+ } else if (dbInt != null) {
+ gl.glReadPixels(0, 0, getWidth(), getHeight(), glFormat, glType, dbInt.getData());
+ }
+
+ // Restore saved modes.
+ gl.glPixelStorei(GL.GL_PACK_SWAP_BYTES, swapbytes[0]);
+ gl.glPixelStorei(GL.GL_PACK_LSB_FIRST, lsbfirst[0]);
+ gl.glPixelStorei(GL.GL_PACK_ROW_LENGTH, rowlength[0]);
+ gl.glPixelStorei(GL.GL_PACK_SKIP_ROWS, skiprows[0]);
+ gl.glPixelStorei(GL.GL_PACK_SKIP_PIXELS, skippixels[0]);
+ gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, alignment[0]);
+
+ gl.glFlush();
+ gl.glFinish();
+
+ if (context.offscreenImageNeedsVerticalFlip()) {
+ g.drawImage(offscreenImage,
+ 0, 0, getWidth(), getHeight(),
+ 0, getHeight(), getWidth(), 0,
+ GLJPanel.this);
+ } else {
+ g.drawImage(offscreenImage, 0, 0, getWidth(), getHeight(), GLJPanel.this);
+ }
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+}
diff --git a/src/net/java/games/jogl/GLPbuffer.java b/src/net/java/games/jogl/GLPbuffer.java
new file mode 100644
index 000000000..de85f6950
--- /dev/null
+++ b/src/net/java/games/jogl/GLPbuffer.java
@@ -0,0 +1,63 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl;
+
+/** Offscreen rendering support via pbuffers. This class adds very
+ little functionality over the GLDrawable class; the only methods
+ are those which allow access to the pbuffer's contents as a
+ texture map. These methods are currently highly experimental and
+ may be removed in a future release. */
+
+public interface GLPbuffer extends GLDrawable {
+ /** Binds this pbuffer to its internal texture target. Only valid to
+ call if offscreen render-to-texture has been specified in the
+ GLCapabilities 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();
+}
diff --git a/src/net/java/games/jogl/impl/FunctionAvailabilityCache.java b/src/net/java/games/jogl/impl/FunctionAvailabilityCache.java
new file mode 100644
index 000000000..74a3e888d
--- /dev/null
+++ b/src/net/java/games/jogl/impl/FunctionAvailabilityCache.java
@@ -0,0 +1,294 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl;
+
+import net.java.games.jogl.*;
+import java.util.*;
+import java.awt.Canvas;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.lang.reflect.*;
+
+/**
+ * A utility object intended to be used by implementations to act as a cache
+ * of which OpenGL functions are currently available on both the host machine
+ * and display.
+ */
+public final class FunctionAvailabilityCache {
+
+ FunctionAvailabilityCache(GLContext context)
+ {
+ this.context = context;
+ }
+
+ /**
+ * Flush the cache. The cache will be rebuilt lazily as calls to {@link
+ * #isFunctionAvailable(String)} are received.
+ */
+ public void flush()
+ {
+ availabilityCache.clear();
+ availableExtensionCache.clear();
+ }
+
+ public boolean isFunctionAvailable(String glFunctionName)
+ {
+ //System.err.println("!!! CHECKING FOR AVAILABILITY OF: "+glFunctionName);
+
+ Boolean available = (Boolean)availabilityCache.get(glFunctionName);
+
+ if (available == null) // not in availabilityCache
+ {
+ if (isPartOfAvailableExtensions(glFunctionName) ||
+ isPartOfGLCore(context.getGL().glGetString(GL.GL_VERSION), glFunctionName))
+ {
+ available = Boolean.TRUE;
+ }
+ else
+ {
+ available = Boolean.FALSE;
+ }
+
+ availabilityCache.put(glFunctionName, available);
+ }
+
+ return available.booleanValue();
+ }
+
+ public boolean isExtensionAvailable(String glExtensionName) {
+ initAvailableExtensions();
+ return availableExtensionCache.contains(glExtensionName);
+ }
+
+ protected void initAvailableExtensions() {
+ // if hash is empty (meaning it was flushed), pre-cache it with the list
+ // of extensions that are in the GL_EXTENSIONS string
+ if (availableExtensionCache.isEmpty()) {
+ GL gl = context.getGL();
+ //System.err.println("!!! Pre-caching extension availability");
+ String allAvailableExtensions =
+ gl.glGetString(GL.GL_EXTENSIONS) + " " + context.getPlatformExtensionsString();
+ StringTokenizer tok = new StringTokenizer(allAvailableExtensions);
+ while (tok.hasMoreTokens()) {
+ String availableExt = tok.nextToken().trim();
+ availableExt = availableExt.intern();
+ availableExtensionCache.add(availableExt);
+ //System.err.println("!!! Available: " + availableExt);
+ }
+
+ // put a dummy var in here so that the cache is no longer empty even if
+ // no extensions are in the GL_EXTENSIONS string
+ availableExtensionCache.add("<INTERNAL_DUMMY_PLACEHOLDER>");
+ }
+ }
+
+ protected boolean isPartOfAvailableExtensions(String glFunctionName)
+ {
+ initAvailableExtensions();
+
+ // First, find the extension to which the function corresponds
+ String extensionName = getExtensionCorrespondingToFunction(glFunctionName);
+
+ // Now see if that extension is available
+ boolean extensionAvailable = availableExtensionCache.contains(extensionName);
+
+ return extensionAvailable;
+ }
+
+ /**
+ * Returns true if the given OpenGL function is part of the OpenGL core
+ * that corresponds to the give OpenGL version string.
+ *
+ * @param versionString must be of the form "X" or "X.Y" or "X.Y.Z", where
+ * X, Y, and Z are integers
+ @ @exception GLException if the glFunctionName passed in is
+ * not the name of any known OpenGL extension function.
+ */
+ public static boolean isPartOfGLCore(String glVersionString, String glFunctionName)
+ {
+ String funcCoreVersionString =
+ StaticGLInfo.getFunctionAssociation(glFunctionName);
+
+ if (funcCoreVersionString == null) {
+ // No extension string was found in the glext.h/wglext.h/glxext.h
+ // headers when building the StaticGLInfo class. So either it's a new
+ // extension that's not in those headers, or it's not an opengl
+ // extension. Either way it's an illegal argument.
+ throw new GLException(
+ "Function \"" + glFunctionName + "\" does not " +
+ "correspond to any known OpenGL extension or core version.");
+ }
+
+ Version actualVersion;
+ try
+ {
+ actualVersion = new Version(funcCoreVersionString);
+ }
+ catch (IllegalArgumentException e)
+ {
+ // funcCoreVersionString is not an OpenGL version identifier (i.e., not
+ // of the form GL_VERSION_XXX).
+ //
+ // Since the association string returned from
+ // StaticGLInfo.getFunctionAssociation() was not null, this function
+ // must be an OpenGL extension function.
+ //
+ // Therefore this function can't be part of any OpenGL core.
+ return false;
+ }
+
+ Version versionToCheck;
+ try
+ {
+ versionToCheck = new Version(glVersionString);
+ }
+ catch (IllegalArgumentException e)
+ {
+ // user did not supply a valid OpenGL version identifier
+ throw new IllegalArgumentException(
+ "Illegally formatted OpenGL version identifier: \"" + glVersionString + "\"");
+ }
+
+ // See if the version number of glVersionString is less than or equal to
+ // the OpenGL specification number to which the given function actually
+ // belongs.
+ if (actualVersion.compareTo(versionToCheck) <= 0)
+ {
+ System.err.println(
+ glFunctionName + " is in core OpenGL " + glVersionString +
+ " because it is in OpenGL " + funcCoreVersionString);
+ return true;
+ }
+
+ System.err.println(
+ glFunctionName + " is NOT a part of the OpenGL " + glVersionString + " core" +
+ "; it is part of OpenGL " + funcCoreVersionString);
+
+ return false;
+ }
+
+ /** Returns the extension name that corresponds to the given extension
+ * function. For example, it will return "GL_EXT_vertex_array" when the
+ * argument is "glNormalPointerEXT".
+ *
+ * Please see http://oss.sgi.com/projects/ogl-sample/registry/index.html for
+ * a list of extension names and the functions they expose.
+ */
+ protected static String getExtensionCorrespondingToFunction(String glFunctionName)
+ {
+ // HACK: FIXME!!! return something I know is supported so I can test other
+ // functions.
+ return StaticGLInfo.getFunctionAssociation(glFunctionName);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private HashMap availabilityCache = new HashMap(50);
+ private HashSet availableExtensionCache = new HashSet(50);
+ private GLContext context;
+
+ /**
+ * A class for storing and comparing revision version numbers.
+ */
+ private static class Version implements Comparable
+ {
+ private int major, minor, sub;
+ public Version(int majorRev, int minorRev, int subMinorRev)
+ {
+ major = majorRev;
+ minor = minorRev;
+ sub = subMinorRev;
+ }
+
+ /**
+ * @param versionString must be of the form "GL_VERSION_X" or
+ * "GL_VERSION_X_Y" or "GL_VERSION_X_Y_Z", where X, Y, and Z are integers.
+ *
+ * @exception IllegalArgumentException if the argument is not a valid
+ * OpenGL version identifier
+ */
+ public Version(String versionString)
+ {
+ if (! versionString.startsWith("GL_VERSION_"))
+ {
+ // not a version string
+ throw new IllegalArgumentException(
+ "Illegal version identifier \"" + versionString +
+ "\"; does not start with \"GL_VERSION_\"");
+ }
+
+ try
+ {
+ StringTokenizer tok = new StringTokenizer(versionString, "_");
+
+ tok.nextToken(); // GL_
+ tok.nextToken(); // VERSION_
+ if (!tok.hasMoreTokens()) { major = 0; return; }
+ major = Integer.valueOf(tok.nextToken()).intValue();
+ if (!tok.hasMoreTokens()) { minor = 0; return; }
+ minor = Integer.valueOf(tok.nextToken()).intValue();
+ if (!tok.hasMoreTokens()) { sub = 0; return; }
+ sub = Integer.valueOf(tok.nextToken()).intValue();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException(
+ "Illegally formatted version identifier: \"" + versionString + "\"");
+ }
+ }
+
+ public int compareTo(Object o)
+ {
+ Version vo = (Version)o;
+ if (major > vo.major) return 1;
+ else if (major < vo.major) return -1;
+ else if (minor > vo.minor) return 1;
+ else if (minor < vo.minor) return -1;
+ else if (sub > vo.sub) return 1;
+ else if (sub < vo.sub) return -1;
+
+ return 0; // they are equal
+ }
+
+ } // end class Version
+}
+
diff --git a/src/net/java/games/jogl/impl/GLContext.java b/src/net/java/games/jogl/impl/GLContext.java
new file mode 100644
index 000000000..98b1c6065
--- /dev/null
+++ b/src/net/java/games/jogl/impl/GLContext.java
@@ -0,0 +1,400 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl;
+
+import java.awt.Component;
+import java.awt.EventQueue;
+import net.java.games.jogl.*;
+
+public abstract class GLContext {
+ protected static final boolean DEBUG = false;
+
+ static {
+ NativeLibLoader.load();
+ }
+
+ protected Component component;
+
+ // Indicates whether the component (if an onscreen context) has been
+ // realized. Plausibly, before the component is realized the JAWT
+ // should return an error or NULL object from some of its
+ // operations; this appears to be the case on Win32 but is not true
+ // at least with Sun's current X11 implementation (1.4.x), which
+ // crashes with no other error reported if the DrawingSurfaceInfo is
+ // fetched from a locked DrawingSurface during the validation as a
+ // result of calling show() on the main thread. To work around this
+ // we prevent any JAWT or OpenGL operations from being done until
+ // the first event is received from the AWT event dispatch thread.
+ private boolean realized;
+
+ // This avoids (as much as possible) losing the effects of
+ // setRenderingThread, which may need to be deferred if the
+ // component is not realized
+ private boolean deferredSetRenderingThread;
+
+ protected GLCapabilities capabilities;
+ protected GLCapabilitiesChooser chooser;
+ protected GL gl;
+ // All GLU interfaces eventually route calls down to gluRoot. It can be
+ // static because GLU it doesn't actually need to own context, it just makes
+ // GL calls and assumes some context is active.
+ protected static final GLU gluRoot = new GLUImpl();
+ protected static GLU glu = gluRoot; // this is the context's GLU interface
+ protected Thread renderingThread;
+ protected Runnable deferredReshapeAction;
+
+ // This is a workaround for a bug in NVidia's drivers where
+ // vertex_array_range is only safe for single-threaded use; a bug
+ // has been filed, ID 80174. When an Animator is created for a
+ // GLDrawable, the expectation is that the Animator will be started
+ // shortly and that the user doesn't want rendering to occur from
+ // the AWT thread. However, there is a small window between when the
+ // Animator is created and attached to the GLDrawable and when it's
+ // started (and sets the rendering thread) when repaint events can
+ // be issued by the AWT thread if the component is realized. To work
+ // around this problem, we currently specify in the Animator's API
+ // that between the time it's created and started no redraws will
+ // occur.
+ protected volatile boolean willSetRenderingThread;
+
+ // Flag for disabling all repaint and resize processing on the AWT
+ // thread to avoid application-level deadlocks; only really used for
+ // GLCanvas
+ protected boolean noAutoRedraw;
+
+ // Offscreen context handling. Offscreen contexts should handle
+ // these resize requests in makeCurrent and clear the
+ // pendingOffscreenResize flag.
+ protected boolean pendingOffscreenResize;
+ protected int pendingOffscreenWidth;
+ protected int pendingOffscreenHeight;
+
+ // Cache of the functions that are available to be called at the current
+ // moment in time
+ protected FunctionAvailabilityCache functionAvailability;
+
+ public GLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ this.component = component;
+ try {
+ this.capabilities = (GLCapabilities) capabilities.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new GLException(e);
+ }
+ this.chooser = chooser;
+ gl = createGL();
+ functionAvailability = new FunctionAvailabilityCache(this);
+ }
+
+ /** Runs the given runnable with this OpenGL context valid. */
+ public synchronized void invokeGL(Runnable runnable, boolean isReshape, Runnable initAction) throws GLException {
+ Thread currentThread = null;
+
+ // Defer JAWT and OpenGL operations until onscreen components are
+ // realized
+ if (!realized()) {
+ realized = EventQueue.isDispatchThread();
+ }
+
+ if (!realized() ||
+ willSetRenderingThread ||
+ (renderingThread != null &&
+ renderingThread != (currentThread = Thread.currentThread()))) {
+ if (isReshape) {
+ deferredReshapeAction = runnable;
+ }
+ return;
+ }
+
+ if (isReshape && noAutoRedraw) {
+ // Don't process reshape requests on the AWT thread
+ deferredReshapeAction = runnable;
+ return;
+ }
+
+ if (renderingThread == null || deferredSetRenderingThread) {
+ deferredSetRenderingThread = false;
+ if (!makeCurrent(initAction)) {
+ // Couldn't make the thread current because the component has not yet
+ // been visualized, and therefore the context cannot be created.
+ // We'll defer any actions until invokeGL() is called again at a time
+ // when the component has been visualized.
+ if (isReshape) {
+ deferredReshapeAction = runnable;
+ }
+ return;
+ }
+ }
+
+ // At this point the OpenGL context is current. Offscreen contexts
+ // handle resizing the backing bitmap in makeCurrent. Therefore we
+ // may need to free and make the context current again if we
+ // didn't actually make it current above.
+ if (pendingOffscreenResize && renderingThread != null) {
+ free();
+ if (!makeCurrent(initAction)) {
+ throw new GLException("Error while resizing offscreen context");
+ }
+ }
+
+ boolean caughtException = false;
+
+ try {
+ if (deferredReshapeAction != null) {
+ deferredReshapeAction.run();
+ deferredReshapeAction = null;
+ }
+ runnable.run();
+ swapBuffers();
+ } catch (RuntimeException e) {
+ caughtException = true;
+ throw(e);
+ } finally {
+ if (caughtException) {
+ // Disallow setRenderingThread if display action is throwing exceptions
+ renderingThread = null;
+ }
+ if (renderingThread == null) {
+ free();
+ }
+ }
+ }
+
+ public GL getGL() {
+ return gl;
+ }
+
+ public void setGL(GL gl) {
+ this.gl = gl;
+ }
+
+ public GLU getGLU() {
+ return glu;
+ }
+
+ public void setGLU(GLU glu) {
+ this.glu = glu;
+ }
+
+ /** Gives a hint to the context that setRenderingThread will be
+ called in the near future; causes redraws to be halted. This is
+ a workaround for bugs in NVidia's drivers and is used only by
+ the Animator class. */
+ public synchronized void willSetRenderingThread() {
+ this.willSetRenderingThread = true;
+ }
+
+ public synchronized void setRenderingThread(Thread currentThreadOrNull, Runnable initAction) {
+ Thread currentThread = Thread.currentThread();
+ if (currentThreadOrNull != null && currentThreadOrNull != currentThread) {
+ throw new GLException("Argument must be either the current thread or null");
+ }
+ if (renderingThread != null && currentThreadOrNull != null) {
+ throw new GLException("Attempt to re-set or change rendering thread");
+ }
+ if (renderingThread == null && currentThreadOrNull == null) {
+ throw new GLException("Attempt to clear rendering thread when already cleared");
+ }
+ this.willSetRenderingThread = false;
+ if (currentThreadOrNull == null) {
+ renderingThread = null;
+ if (realized()) {
+ // We are guaranteed to own the context
+ free();
+ }
+ } else {
+ renderingThread = currentThreadOrNull;
+ if (realized()) {
+ makeCurrent(initAction);
+ }
+ }
+ }
+
+ public Thread getRenderingThread() {
+ return renderingThread;
+ }
+
+ public void setNoAutoRedrawMode(boolean noAutoRedraw) {
+ this.noAutoRedraw = noAutoRedraw;
+ }
+
+ public boolean getNoAutoRedrawMode() {
+ return noAutoRedraw;
+ }
+
+ /** Routine needed only for offscreen contexts in order to resize
+ the underlying bitmap. Called by GLJPanel. */
+ public void resizeOffscreenContext(int newWidth, int newHeight) {
+ if (!isOffscreen()) {
+ throw new GLException("Should only call for offscreen OpenGL contexts");
+ }
+ pendingOffscreenResize = true;
+ pendingOffscreenWidth = newWidth;
+ pendingOffscreenHeight = newHeight;
+ }
+
+ /** 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();
+
+ /**
+ * Resets the cache of which GL functions are available for calling through this
+ * context. See {@link #isFunctionAvailable(String)} for more information on
+ * the definition of "available".
+ */
+ protected void resetGLFunctionAvailability() {
+ functionAvailability.flush();
+ }
+
+ /**
+ * Returns true if the specified OpenGL core- or extension-function can be
+ * successfully called using this GL context given the current host (OpenGL
+ * <i>client</i>) and display (OpenGL <i>server</i>) configuration.
+ *
+ * See {@link GL#isFunctionAvailable(String)} for more details.
+ *
+ * @param glFunctionName the name of the OpenGL function (e.g., use
+ * "glPolygonOffsetEXT" to check if the {@link
+ * net.java.games.jogl.glPolygonOffsetEXT(float,float)} is available).
+ */
+ protected boolean isFunctionAvailable(String glFunctionName) {
+ return functionAvailability.isFunctionAvailable(mapToRealGLFunctionName(glFunctionName));
+ }
+
+ /**
+ * Returns true if the specified OpenGL extension can be
+ * successfully called using this GL context given the current host (OpenGL
+ * <i>client</i>) and display (OpenGL <i>server</i>) configuration.
+ *
+ * See {@link GL#isExtensionAvailable(String)} for more details.
+ *
+ * @param glExtensionName the name of the OpenGL extension (e.g.,
+ * "GL_VERTEX_PROGRAM_ARB").
+ */
+ public boolean isExtensionAvailable(String glExtensionName) {
+ return functionAvailability.isExtensionAvailable(mapToRealGLExtensionName(glExtensionName));
+ }
+
+ /**
+ * Pbuffer support; indicates whether this context is capable of
+ * creating a subordinate pbuffer context (distinct from an
+ * "offscreen context", which is typically software-rendered on all
+ * platforms).
+ */
+ public abstract boolean canCreatePbufferContext();
+
+ /**
+ * Pbuffer support; creates a subordinate GLContext for a pbuffer
+ * associated with this context.
+ */
+ public abstract GLContext createPbufferContext(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight);
+
+ /**
+ * Pbuffer support; given that this is a GLContext associated with a
+ * pbuffer, binds this pbuffer to its texture target.
+ */
+ public abstract void bindPbufferToTexture();
+
+ /**
+ * Pbuffer support; given that this is a GLContext associated with a
+ * pbuffer, releases this pbuffer from its texture target.
+ */
+ public abstract void releasePbufferFromTexture();
+
+ /** Maps the given "platform-independent" function name to a real function
+ name. Currently this is only used to map "glAllocateMemoryNV" and
+ associated routines to wglAllocateMemoryNV / glXAllocateMemoryNV. */
+ protected abstract String mapToRealGLFunctionName(String glFunctionName);
+
+ /** Maps the given "platform-independent" extension name to a real
+ function name. Currently this is only used to map
+ "GL_ARB_pbuffer" and "GL_ARB_pixel_format" to "WGL_ARB_pbuffer"
+ and "WGL_ARB_pixel_format" (not yet mapped to X11). */
+ protected abstract String mapToRealGLExtensionName(String glExtensionName);
+
+ /** Create the GL for this context. */
+ protected abstract GL createGL();
+
+ /** Hook indicating whether the concrete GLContext implementation is
+ offscreen and therefore whether we need to process resize
+ requests. */
+ protected abstract boolean isOffscreen();
+
+ /** Only called for offscreen contexts; returns the type of
+ BufferedImage required for reading this context's pixels. */
+ public abstract int getOffscreenContextBufferedImageType();
+
+ /** Only called for offscreen contexts; returns the buffer from
+ which to read pixels (GL.GL_FRONT or GL.GL_BACK). */
+ public abstract int getOffscreenContextReadBuffer();
+
+ /** On some platforms the mismatch between OpenGL's coordinate
+ system (origin at bottom left) and the window system's
+ coordinate system (origin at top left) necessitates a vertical
+ flip of pixels read from offscreen contexts. */
+ public abstract boolean offscreenImageNeedsVerticalFlip();
+
+ /** Attempts to make the GL context current. If necessary, creates a
+ context and calls the initAction once the context is current.
+ Most error conditions cause an exception to be thrown, except
+ for the case where the context can not be created because the
+ component has not yet been visualized. In this case makeCurrent
+ returns false and the caller should abort any OpenGL event
+ processing and instead return immediately. */
+ protected abstract boolean makeCurrent(Runnable initAction) throws GLException;
+
+ /** Frees the OpenGL context. All error conditions cause a
+ GLException to be thrown. */
+ protected abstract void free() throws GLException;
+
+ /** Swaps the buffers of the OpenGL context if necessary. All error
+ conditions cause a GLException to be thrown. */
+ protected abstract void swapBuffers() throws GLException;
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+ private boolean realized() {
+ return ((component == null) || realized || component.isDisplayable());
+ }
+}
diff --git a/src/net/java/games/jogl/impl/GLContextFactory.java b/src/net/java/games/jogl/impl/GLContextFactory.java
new file mode 100644
index 000000000..d76648ee8
--- /dev/null
+++ b/src/net/java/games/jogl/impl/GLContextFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl;
+
+import java.awt.Component;
+import net.java.games.jogl.*;
+
+public abstract class GLContextFactory {
+ private static GLContextFactory factory;
+
+ public static GLContextFactory getFactory() {
+ if (factory == null) {
+ try {
+ String osName = System.getProperty("os.name");
+ String osNameLowerCase = osName.toLowerCase();
+ Class factoryClass = null;
+
+ // Because there are some complications with generating all
+ // platforms' Java glue code on all platforms (among them that we
+ // would have to include jawt.h and jawt_md.h in the jogl
+ // sources, which we currently don't have to do) we break the only
+ // static dependencies with platform-specific code here using reflection.
+
+ if (osNameLowerCase.startsWith("wind")) {
+ factoryClass = Class.forName("net.java.games.jogl.impl.windows.WindowsGLContextFactory");
+ } else if (osNameLowerCase.startsWith("darwin")) {
+ } else {
+ // Assume Linux, Solaris, etc. Should probably test for these explicitly.
+ factoryClass = Class.forName("net.java.games.jogl.impl.x11.X11GLContextFactory");
+ }
+
+ if (factoryClass == null) {
+ throw new GLException("OS " + osName + " not yet supported");
+ }
+
+ factory = (GLContextFactory) factoryClass.newInstance();
+ } catch (ClassNotFoundException e) {
+ throw new GLException(e);
+ } catch (InstantiationException e) {
+ throw new GLException(e);
+ } catch (IllegalAccessException e) {
+ throw new GLException(e);
+ }
+ }
+
+ return factory;
+ }
+
+ public abstract GLContext createGLContext(Component component,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser);
+}
diff --git a/src/net/java/games/jogl/impl/GLDrawableHelper.java b/src/net/java/games/jogl/impl/GLDrawableHelper.java
new file mode 100644
index 000000000..d9def672f
--- /dev/null
+++ b/src/net/java/games/jogl/impl/GLDrawableHelper.java
@@ -0,0 +1,87 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl;
+
+import java.util.*;
+import net.java.games.jogl.*;
+
+/** Encapsulates the implementation of most of the GLDrawable's
+ methods to be able to share it between GLCanvas and GLJPanel. */
+
+public class GLDrawableHelper {
+ private List listeners = new ArrayList();
+ private GL gl;
+ // FIXME
+ // private GLU glu;
+
+ public GLDrawableHelper() {
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ listeners.remove(listener);
+ }
+
+ public void init(GLDrawable drawable) {
+ // Note that we don't use iterator() since listeners may
+ // add/remove other listeners during initialization. We don't
+ // guarantee that all listeners will be evaluated if
+ // removeGLEventListener is called.
+ for (int i = 0; i < listeners.size(); i++) {
+ ((GLEventListener) listeners.get(i)).init(drawable);
+ }
+ }
+
+ public void display(GLDrawable drawable) {
+ for (int i = 0; i < listeners.size(); i++) {
+ ((GLEventListener) listeners.get(i)).display(drawable);
+ }
+ }
+
+ public void reshape(GLDrawable drawable,
+ int x, int y, int width, int height) {
+ for (int i = 0; i < listeners.size(); i++) {
+ ((GLEventListener) listeners.get(i)).reshape(drawable, x, y, width, height);
+ }
+ }
+}
diff --git a/src/net/java/games/jogl/impl/GLPbufferImpl.java b/src/net/java/games/jogl/impl/GLPbufferImpl.java
new file mode 100644
index 000000000..d510a9c31
--- /dev/null
+++ b/src/net/java/games/jogl/impl/GLPbufferImpl.java
@@ -0,0 +1,192 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl;
+
+import java.awt.Dimension;
+import java.awt.event.*;
+import java.beans.PropertyChangeListener;
+
+import net.java.games.jogl.*;
+
+/** Platform-independent class exposing pbuffer functionality to
+ applications. This class is not exposed in the public API as it
+ would probably add no value; however it implements the GLDrawable
+ interface so can be interacted with via its display() method. */
+
+public class GLPbufferImpl implements GLPbuffer {
+ // GLPbufferContext
+ private GLContext context;
+ private GLDrawableHelper drawableHelper = new GLDrawableHelper();
+
+ public GLPbufferImpl(GLContext context) {
+ this.context = context;
+ }
+
+ public void display() {
+ context.invokeGL(displayAction, false, initAction);
+ }
+
+ public void setSize(int width, int height) {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public void setSize(Dimension d) {
+ setSize(d.width, d.height);
+ }
+
+ public Dimension getSize() {
+ return getSize(null);
+ }
+
+ public Dimension getSize(Dimension d) {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ drawableHelper.addGLEventListener(listener);
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ drawableHelper.removeGLEventListener(listener);
+ }
+
+ public GL getGL() {
+ return context.getGL();
+ }
+
+ public void setGL(GL gl) {
+ context.setGL(gl);
+ }
+
+ public GLU getGLU() {
+ return context.getGLU();
+ }
+
+ public void setGLU(GLU glu) {
+ context.setGLU(glu);
+ }
+
+ void willSetRenderingThread() {
+ context.willSetRenderingThread();
+ }
+
+ public void setRenderingThread(Thread currentThreadOrNull) throws GLException {
+ // Not supported for pbuffers
+ }
+
+ public Thread getRenderingThread() {
+ // Not supported for pbuffers
+ return null;
+ }
+
+ public void setNoAutoRedrawMode(boolean noAutoRedraws) {
+ }
+
+ public boolean getNoAutoRedrawMode() {
+ return false;
+ }
+
+ public boolean canCreateOffscreenDrawable() {
+ return false;
+ }
+
+ public GLPbuffer createOffscreenDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ throw new GLException("Not supported");
+ }
+
+ public void bindTexture() {
+ context.bindPbufferToTexture();
+ }
+
+ public void releaseTexture() {
+ context.releasePbufferFromTexture();
+ }
+
+ //----------------------------------------------------------------------
+ // No-ops for 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) {}
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ class InitAction implements Runnable {
+ public void run() {
+ drawableHelper.init(GLPbufferImpl.this);
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ drawableHelper.display(GLPbufferImpl.this);
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+}
diff --git a/src/net/java/games/jogl/impl/JAWT_PlatformInfo.java b/src/net/java/games/jogl/impl/JAWT_PlatformInfo.java
new file mode 100644
index 000000000..64da83ec4
--- /dev/null
+++ b/src/net/java/games/jogl/impl/JAWT_PlatformInfo.java
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl;
+
+/** Marker class for all window system-specific JAWT data structures. */
+
+public interface JAWT_PlatformInfo {
+}
diff --git a/src/net/java/games/jogl/impl/NativeLibLoader.java b/src/net/java/games/jogl/impl/NativeLibLoader.java
new file mode 100644
index 000000000..65c199f05
--- /dev/null
+++ b/src/net/java/games/jogl/impl/NativeLibLoader.java
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl;
+
+public class NativeLibLoader {
+ static {
+ System.loadLibrary("jawt");
+ System.loadLibrary("jogl");
+ }
+
+ public static void load() {
+ }
+}
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
new file mode 100644
index 000000000..bcb33e602
--- /dev/null
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
@@ -0,0 +1,110 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.macosx;
+
+import java.awt.Component;
+import java.util.*;
+import net.java.games.gluegen.opengl.*; // for PROCADDRESS_VAR_PREFIX
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public abstract class MacOSXGLContext extends GLContext {
+
+ public MacOSXGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super(component, capabilities, chooser);
+ }
+
+ protected GL createGL()
+ {
+ return new MacOSXGLImpl(this);
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ return glFunctionName;
+ }
+
+ protected abstract boolean isOffscreen();
+
+ public abstract int getOffscreenContextBufferedImageType();
+
+ public abstract int getOffscreenContextReadBuffer();
+
+ public abstract boolean offscreenImageNeedsVerticalFlip();
+
+ /**
+ * Creates and initializes an appropriate OpenGl context. Should only be
+ * called by {@link makeCurrent(Runnable)}.
+ */
+ protected abstract void create();
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException
+ {
+ throw new RuntimeException(" FIXME: not implemented ");
+ }
+
+ protected synchronized void free() throws GLException {
+ throw new RuntimeException(" FIXME: not implemented ");
+ }
+
+ protected abstract void swapBuffers() throws GLException;
+
+
+ protected void resetGLFunctionAvailability() {
+ throw new RuntimeException(" FIXME: not implemented ");
+ }
+
+ protected void resetGLProcAddressTable() {
+ throw new RuntimeException(" FIXME: not implemented ");
+ }
+
+ public net.java.games.jogl.impl.ProcAddressTable getGLProcAddressTable() {
+ throw new RuntimeException(" FIXME: not implemented ");
+ }
+
+ public String getPlatformExtensionsString() {
+ throw new RuntimeException(" FIXME: not implemented ");
+ }
+
+ protected boolean isFunctionAvailable(String glFunctionName)
+ {
+ throw new RuntimeException(" FIXME: not implemented ");
+ }
+
+}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
new file mode 100644
index 000000000..4575b6210
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java
@@ -0,0 +1,365 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.windows;
+
+import java.awt.Component;
+import java.util.*;
+import net.java.games.gluegen.opengl.*; // for PROCADDRESS_VAR_PREFIX
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public abstract class WindowsGLContext extends GLContext {
+ private static JAWT jawt;
+ protected long hglrc;
+ protected long hdc;
+ private boolean wglGetExtensionsStringEXTInitialized;
+ private boolean wglGetExtensionsStringEXTAvailable;
+ private static final Map/*<String, String>*/ functionNameMap;
+ private static final Map/*<String, String>*/ extensionNameMap;
+
+ static {
+ functionNameMap = new HashMap();
+ functionNameMap.put("glAllocateMemoryNV", "wglAllocateMemoryNV");
+ functionNameMap.put("glFreeMemoryNV", "wglFreeMemoryNV");
+
+ extensionNameMap = new HashMap();
+ extensionNameMap.put("GL_ARB_pbuffer", "WGL_ARB_pbuffer");
+ extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format");
+ }
+
+ public WindowsGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super(component, capabilities, chooser);
+ }
+
+ protected GL createGL()
+ {
+ return new WindowsGLImpl(this);
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ String lookup = (String) functionNameMap.get(glFunctionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glFunctionName;
+ }
+
+ protected String mapToRealGLExtensionName(String glExtensionName) {
+ String lookup = (String) extensionNameMap.get(glExtensionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glExtensionName;
+ }
+
+ protected abstract boolean isOffscreen();
+
+ public abstract int getOffscreenContextBufferedImageType();
+
+ public abstract int getOffscreenContextReadBuffer();
+
+ public abstract boolean offscreenImageNeedsVerticalFlip();
+
+ /**
+ * Creates and initializes an appropriate OpenGl context. Should only be
+ * called by {@link makeCurrent(Runnable)}.
+ */
+ protected abstract void create();
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ boolean created = false;
+ if (hglrc == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println("!!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (!WGL.wglMakeCurrent(hdc, hglrc)) {
+ throw new GLException("Error making context current");
+ }
+
+ if (created) {
+ resetGLFunctionAvailability();
+ initAction.run();
+ }
+ return true;
+ }
+
+ protected synchronized void free() throws GLException {
+ if (!WGL.wglMakeCurrent(0, 0)) {
+ throw new GLException("Error freeing OpenGL context");
+ }
+ }
+
+ protected abstract void swapBuffers() throws GLException;
+
+
+ protected void resetGLFunctionAvailability() {
+ super.resetGLFunctionAvailability();
+ resetGLProcAddressTable();
+ }
+
+ protected void resetGLProcAddressTable() {
+
+ if (DEBUG) {
+ System.err.println("!!! Initializing OpenGL extension address table");
+ }
+
+ net.java.games.jogl.impl.ProcAddressTable table = getGLProcAddressTable();
+
+ // if GL is no longer an interface, we'll have to re-implement the code
+ // below so it only iterates through gl methods (a non-interface might
+ // have constructors, custom methods, etc). For now we assume all methods
+ // will be gl methods.
+ GL gl = getGL();
+
+ Class tableClass = table.getClass();
+
+ java.lang.reflect.Field[] fields = tableClass.getDeclaredFields();
+
+ for (int i = 0; i < fields.length; ++i) {
+ String addressFieldName = fields[i].getName();
+ if (!addressFieldName.startsWith(GLEmitter.PROCADDRESS_VAR_PREFIX))
+ {
+ // not a proc address variable
+ continue;
+ }
+ int startOfMethodName = GLEmitter.PROCADDRESS_VAR_PREFIX.length();
+ String glFuncName = addressFieldName.substring(startOfMethodName);
+ try
+ {
+ java.lang.reflect.Field addressField = tableClass.getDeclaredField(addressFieldName);
+ assert(addressField.getType() == Long.TYPE);
+ // get the current value of the proc address variable in the table object
+ long oldProcAddress = addressField.getLong(table);
+ long newProcAddress = WGL.wglGetProcAddress(glFuncName);
+ /*
+ System.err.println(
+ "!!! Address=" + (newProcAddress == 0
+ ? "<NULL> "
+ : ("0x" +
+ Long.toHexString(newProcAddress))) +
+ "\tGL func: " + glFuncName);
+ */
+ // set the current value of the proc address variable in the table object
+ addressField.setLong(gl, newProcAddress);
+ } catch (Exception e) {
+ throw new GLException(
+ "Cannot get GL proc address for method \"" +
+ glFuncName + "\": Couldn't get value of field \"" + addressFieldName +
+ "\" in class " + tableClass.getName(), e);
+ }
+ }
+
+ }
+
+ public net.java.games.jogl.impl.ProcAddressTable getGLProcAddressTable() {
+ if (glProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ glProcAddressTable =
+ new net.java.games.jogl.impl.ProcAddressTable();
+ }
+ return glProcAddressTable;
+ }
+
+ public String getPlatformExtensionsString() {
+ if (!wglGetExtensionsStringEXTInitialized) {
+ wglGetExtensionsStringEXTAvailable = (WGL.wglGetProcAddress("wglGetExtensionsStringEXT") != 0);
+ wglGetExtensionsStringEXTInitialized = true;
+ }
+ if (wglGetExtensionsStringEXTAvailable) {
+ return gl.wglGetExtensionsStringEXT();
+ } else {
+ return "";
+ }
+ }
+
+ protected boolean isFunctionAvailable(String glFunctionName)
+ {
+ boolean available = super.isFunctionAvailable(glFunctionName);
+
+ // Sanity check for implementations that use proc addresses for run-time
+ // linking: if the function IS available, then make sure there's a proc
+ // address for it if it's an extension or not part of the OpenGL 1.1 core
+ // (post GL 1.1 functions are run-time linked on windows).
+ assert(!available ||
+ (getGLProcAddressTable().getAddressFor(mapToRealGLFunctionName(glFunctionName)) != 0 ||
+ FunctionAvailabilityCache.isPartOfGLCore("1.1", mapToRealGLFunctionName(glFunctionName)))
+ );
+
+ return available;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // Table that holds the addresses of the native C-language entry points for
+ // OpenGL functions.
+ private net.java.games.jogl.impl.ProcAddressTable glProcAddressTable;
+
+ protected JAWT getJAWT() {
+ if (jawt == null) {
+ JAWT j = new JAWT();
+ j.version(JAWTFactory.JAWT_VERSION_1_4);
+ if (!JAWTFactory.JAWT_GetAWT(j)) {
+ throw new RuntimeException("Unable to initialize JAWT");
+ }
+ jawt = j;
+ }
+ return jawt;
+ }
+
+ // Helper routine for the overridden create() to call
+ protected void choosePixelFormatAndCreateContext(boolean onscreen) {
+ PIXELFORMATDESCRIPTOR pfd = null;
+ int pixelFormat = 0;
+ if (chooser == null) {
+ // Note: this code path isn't taken any more now that the
+ // DefaultGLCapabilitiesChooser is present. However, it is being
+ // left in place for debugging purposes.
+ pfd = glCapabilities2PFD(capabilities, onscreen);
+ pixelFormat = WGL.ChoosePixelFormat(hdc, pfd);
+ if (pixelFormat == 0) {
+ throw new GLException("Unable to choose appropriate pixel format");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen pixel format from ChoosePixelFormat:");
+ PIXELFORMATDESCRIPTOR tmpPFD = new PIXELFORMATDESCRIPTOR();
+ WGL.DescribePixelFormat(hdc, pixelFormat, tmpPFD.size(), tmpPFD);
+ System.err.println(pfd2GLCapabilities(tmpPFD));
+ }
+ } else {
+ int numFormats = WGL.DescribePixelFormat(hdc, 1, 0, null);
+ if (numFormats == 0) {
+ throw new GLException("Unable to enumerate pixel formats of window for GLCapabilitiesChooser");
+ }
+ GLCapabilities[] availableCaps = new GLCapabilities[numFormats];
+ pfd = new PIXELFORMATDESCRIPTOR();
+ for (int i = 0; i < numFormats; i++) {
+ if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) {
+ throw new GLException("Error describing pixel format " + (1 + i) + " of device context");
+ }
+ availableCaps[i] = pfd2GLCapabilities(pfd);
+ }
+ // Supply information to chooser
+ pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps);
+ if ((pixelFormat < 0) || (pixelFormat >= numFormats)) {
+ throw new GLException("Invalid result " + pixelFormat +
+ " from GLCapabilitiesChooser (should be between 0 and " +
+ (numFormats - 1) + ")");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen pixel format (" + pixelFormat + "):");
+ System.err.println(availableCaps[pixelFormat]);
+ }
+ pixelFormat += 1; // one-base the index
+ if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) {
+ throw new GLException("Error re-describing the chosen pixel format");
+ }
+ }
+ if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) {
+ throw new GLException("Unable to set pixel format");
+ }
+ hglrc = WGL.wglCreateContext(hdc);
+ if (hglrc == 0) {
+ throw new GLException("Unable to create OpenGL context");
+ }
+ }
+
+ static PIXELFORMATDESCRIPTOR glCapabilities2PFD(GLCapabilities caps, boolean onscreen) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ PIXELFORMATDESCRIPTOR pfd = new PIXELFORMATDESCRIPTOR();
+ pfd.nSize((short) pfd.size());
+ pfd.nVersion((short) 1);
+ int pfdFlags = (WGL.PFD_SUPPORT_OPENGL |
+ WGL.PFD_GENERIC_ACCELERATED);
+ if (caps.getDoubleBuffered()) {
+ pfdFlags |= WGL.PFD_DOUBLEBUFFER;
+ if (onscreen) {
+ pfdFlags |= WGL.PFD_SWAP_EXCHANGE;
+ }
+ }
+ if (onscreen) {
+ pfdFlags |= WGL.PFD_DRAW_TO_WINDOW;
+ } else {
+ pfdFlags |= WGL.PFD_DRAW_TO_BITMAP;
+ }
+ pfd.dwFlags(pfdFlags);
+ pfd.iPixelType((byte) WGL.PFD_TYPE_RGBA);
+ pfd.cColorBits((byte) colorDepth);
+ pfd.cRedBits ((byte) caps.getRedBits());
+ pfd.cGreenBits((byte) caps.getGreenBits());
+ pfd.cBlueBits ((byte) caps.getBlueBits());
+ pfd.cDepthBits((byte) caps.getDepthBits());
+ pfd.iLayerType((byte) WGL.PFD_MAIN_PLANE);
+ return pfd;
+ }
+
+ static GLCapabilities pfd2GLCapabilities(PIXELFORMATDESCRIPTOR pfd) {
+ if ((pfd.dwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) {
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities();
+ res.setRedBits (pfd.cRedBits());
+ res.setGreenBits (pfd.cGreenBits());
+ res.setBlueBits (pfd.cBlueBits());
+ res.setAlphaBits (pfd.cAlphaBits());
+ res.setAccumRedBits (pfd.cAccumRedBits());
+ res.setAccumGreenBits(pfd.cAccumGreenBits());
+ res.setAccumBlueBits (pfd.cAccumBlueBits());
+ res.setAccumAlphaBits(pfd.cAccumAlphaBits());
+ res.setDepthBits (pfd.cDepthBits());
+ res.setStencilBits (pfd.cStencilBits());
+ res.setDoubleBuffered((pfd.dwFlags() & WGL.PFD_DOUBLEBUFFER) != 0);
+ res.setStereo ((pfd.dwFlags() & WGL.PFD_STEREO) != 0);
+ res.setHardwareAccelerated(((pfd.dwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) ||
+ ((pfd.dwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0));
+ return res;
+ }
+}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
new file mode 100644
index 000000000..15e622efb
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.windows;
+
+import java.awt.Component;
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class WindowsGLContextFactory extends GLContextFactory {
+ public GLContext createGLContext(Component component,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ if (component != null) {
+ return new WindowsOnscreenGLContext(component, capabilities, chooser);
+ } else {
+ return new WindowsOffscreenGLContext(capabilities, chooser);
+ }
+ }
+}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java
new file mode 100644
index 000000000..727517e63
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java
@@ -0,0 +1,169 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.windows;
+
+import java.awt.image.BufferedImage;
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class WindowsOffscreenGLContext extends WindowsGLContext {
+ private long origbitmap;
+ private long hbitmap;
+ // Width and height of the underlying bitmap
+ private int width;
+ private int height;
+
+ public WindowsOffscreenGLContext(GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super(null, capabilities, chooser);
+ }
+
+ protected GL createGL()
+ {
+ return new WindowsGLImpl(this);
+ }
+
+ protected boolean isOffscreen() {
+ return true;
+ }
+
+ public int getOffscreenContextBufferedImageType() {
+ if (capabilities.getAlphaBits() > 0) {
+ return BufferedImage.TYPE_INT_ARGB;
+ } else {
+ return BufferedImage.TYPE_INT_RGB;
+ }
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ // On Windows these contexts are always single-buffered
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ // We can take care of this in the DIB creation (see below)
+ return false;
+ }
+
+ public boolean canCreatePbufferContext() {
+ // For now say no
+ return false;
+ }
+
+ public synchronized GLContext createPbufferContext(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ throw new GLException("Not supported");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ if (pendingOffscreenResize) {
+ if (pendingOffscreenWidth != width || pendingOffscreenWidth != height) {
+ if (hglrc != 0) {
+ destroy();
+ }
+ width = pendingOffscreenWidth;
+ height = pendingOffscreenHeight;
+ pendingOffscreenResize = false;
+ }
+ }
+ return super.makeCurrent(initAction);
+ }
+
+ protected synchronized void swapBuffers() throws GLException {
+ }
+
+ protected void create() {
+ BITMAPINFO info = new BITMAPINFO();
+ BITMAPINFOHEADER header = info.bmiHeader();
+ int bitsPerPixel = (capabilities.getRedBits() +
+ capabilities.getGreenBits() +
+ capabilities.getBlueBits());
+ header.biSize(header.size());
+ header.biWidth(width);
+ // NOTE: negating the height causes the DIB to be in top-down row
+ // order rather than bottom-up; ends up being correct during pixel
+ // readback
+ header.biHeight(-1 * height);
+ header.biPlanes((short) 1);
+ header.biBitCount((short) bitsPerPixel);
+ header.biXPelsPerMeter(0);
+ header.biYPelsPerMeter(0);
+ header.biClrUsed(0);
+ header.biClrImportant(0);
+ header.biCompression(WGL.BI_RGB);
+ header.biSizeImage(width * height * bitsPerPixel / 8);
+
+ // CreateDIBSection doesn't really need the device context if we are
+ // producing a truecolor bitmap.
+ hbitmap = WGL.CreateDIBSection(0, info, WGL.DIB_RGB_COLORS, 0, 0, 0);
+ if (hbitmap == 0) {
+ throw new GLException("Error creating offscreen bitmap");
+ }
+ hdc = WGL.CreateCompatibleDC(0);
+ if (hdc == 0) {
+ throw new GLException("Error creating device context for offscreen OpenGL context");
+ }
+ if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) {
+ throw new GLException("Error selecting bitmap into new device context");
+ }
+
+ choosePixelFormatAndCreateContext(false);
+ }
+
+ private void destroy() {
+ // Must destroy OpenGL context, bitmap and device context
+ WGL.wglDeleteContext(hglrc);
+ WGL.SelectObject(hdc, origbitmap);
+ WGL.DeleteObject(hbitmap);
+ WGL.DeleteDC(hdc);
+ hglrc = 0;
+ origbitmap = 0;
+ hbitmap = 0;
+ hdc = 0;
+ }
+}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java
new file mode 100644
index 000000000..a5b7519cf
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java
@@ -0,0 +1,203 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.windows;
+
+import java.awt.Component;
+import java.util.*;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class WindowsOnscreenGLContext extends WindowsGLContext {
+ // Variables for lockSurface/unlockSurface
+ JAWT_DrawingSurface ds;
+ JAWT_DrawingSurfaceInfo dsi;
+ JAWT_Win32DrawingSurfaceInfo win32dsi;
+
+ // Variables for pbuffer support
+ List pbuffersToInstantiate = new ArrayList();
+
+ public WindowsOnscreenGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super(component, capabilities, chooser);
+ }
+
+ protected GL createGL()
+ {
+ return new WindowsGLImpl(this);
+ }
+
+ protected boolean isOffscreen() {
+ return false;
+ }
+
+ public int getOffscreenContextBufferedImageType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean canCreatePbufferContext() {
+ return true;
+ }
+
+ public synchronized GLContext createPbufferContext(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ WindowsPbufferGLContext ctx = new WindowsPbufferGLContext(capabilities, initialWidth, initialHeight);
+ pbuffersToInstantiate.add(ctx);
+ return ctx;
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ try {
+ if (!lockSurface()) {
+ return false;
+ }
+ boolean ret = super.makeCurrent(initAction);
+ if (ret) {
+ // Instantiate any pending pbuffers
+ while (!pbuffersToInstantiate.isEmpty()) {
+ WindowsPbufferGLContext ctx =
+ (WindowsPbufferGLContext) pbuffersToInstantiate.remove(pbuffersToInstantiate.size() - 1);
+ ctx.createPbuffer(hdc, hglrc);
+ }
+ }
+ return ret;
+ } catch (RuntimeException e) {
+ try {
+ unlockSurface();
+ } catch (Exception e2) {
+ // do nothing if unlockSurface throws
+ }
+ throw(e);
+ }
+ }
+
+ protected synchronized void free() throws GLException {
+ try {
+ super.free();
+ } finally {
+ unlockSurface();
+ }
+ }
+
+ protected synchronized void swapBuffers() throws GLException {
+ if (!WGL.SwapBuffers(hdc)) {
+ throw new GLException("Error swapping buffers");
+ }
+ }
+
+ private boolean lockSurface() throws GLException {
+ if (hdc != 0) {
+ throw new GLException("Surface already locked");
+ }
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ return false;
+ }
+ int res = ds.Lock();
+ if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) {
+ throw new GLException("Unable to lock surface");
+ }
+ // See whether the surface changed and if so destroy the old
+ // OpenGL context so it will be recreated
+ if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
+ if (hglrc != 0) {
+ if (!WGL.wglDeleteContext(hglrc)) {
+ throw new GLException("Unable to delete old GL context after surface changed");
+ }
+ hglrc = 0;
+ }
+ }
+ dsi = ds.GetDrawingSurfaceInfo();
+ if (dsi == null) {
+ // Widget not yet realized
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ return false;
+ }
+ win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo();
+ hdc = win32dsi.hdc();
+ if (hdc == 0) {
+ // Widget not yet realized
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ win32dsi = null;
+ return false;
+ }
+ return true;
+ }
+
+ private void unlockSurface() {
+ if (hdc == 0) {
+ throw new GLException("Surface already unlocked");
+ }
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ win32dsi = null;
+ hdc = 0;
+ }
+
+ protected void create() {
+ choosePixelFormatAndCreateContext(true);
+ }
+}
diff --git a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java
new file mode 100644
index 000000000..300e9cb85
--- /dev/null
+++ b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java
@@ -0,0 +1,413 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.windows;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class WindowsPbufferGLContext extends WindowsGLContext {
+ private static final boolean DEBUG = false;
+
+ private int initWidth;
+ private int initHeight;
+
+ private long buffer; // pbuffer handle
+ private int width;
+ private int height;
+
+ // FIXME: kept around because we create the OpenGL context lazily to
+ // better integrate with the WindowsGLContext framework
+ private long parentHglrc;
+
+ private static final int MAX_PFORMATS = 256;
+ private static final int MAX_ATTRIBS = 256;
+
+ // State for render-to-texture and render-to-texture-rectangle support
+ private boolean created;
+ private boolean rtt; // render-to-texture?
+ private boolean rect; // render-to-texture-rectangle?
+ private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
+ private int texture; // actual texture object
+
+ public WindowsPbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) {
+ super(null, capabilities, null);
+ this.initWidth = initialWidth;
+ this.initHeight = initialHeight;
+ if (initWidth <= 0 || initHeight <= 0) {
+ throw new GLException("Initial width and height of pbuffer must be positive (were (" +
+ initWidth + ", " + initHeight + "))");
+ }
+ }
+
+ public boolean canCreatePbufferContext() {
+ return false;
+ }
+
+ public GLContext createPbufferContext(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ throw new GLException("Not supported");
+ }
+
+ public void bindPbufferToTexture() {
+ if (!rtt) {
+ throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " +
+ "specified in its GLCapabilities");
+ }
+ GL gl = getGL();
+ gl.glBindTexture(textureTarget, texture);
+ // Note: this test was on the rtt variable in NVidia's code but I
+ // think it doesn't make sense written that way
+ if (rect) {
+ if (!gl.wglBindTexImageARB(buffer, GL.WGL_FRONT_LEFT_ARB)) {
+ throw new GLException("Binding of pbuffer to texture failed: " + wglGetLastError());
+ }
+ }
+ // Note that if the render-to-texture-rectangle extension is not
+ // specified, we perform a glCopyTexImage2D in swapBuffers().
+ }
+
+ public void releasePbufferFromTexture() {
+ if (!rtt) {
+ throw new GLException("Shouldn't try to bind a pbuffer to a texture if render-to-texture hasn't been " +
+ "specified in its GLCapabilities");
+ }
+ if (rect) {
+ GL gl = getGL();
+ if (!gl.wglReleaseTexImageARB(buffer, GL.WGL_FRONT_LEFT_ARB)) {
+ throw new GLException("Releasing of pbuffer from texture failed: " + wglGetLastError());
+ }
+ }
+ }
+
+ public void createPbuffer(long parentHdc, long parentHglrc) {
+ GL gl = getGL();
+
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ float[] fattributes = new float[2*MAX_ATTRIBS];
+ int nfattribs = 0;
+ int niattribs = 0;
+
+ rtt = capabilities.getOffscreenRenderToTexture();
+ rect = capabilities.getOffscreenRenderToTextureRectangle();
+ boolean useFloat = capabilities.getOffscreenFloatingPointBuffers();
+
+ // Since we are trying to create a pbuffer, the pixel format we
+ // request (and subsequently use) must be "p-buffer capable".
+ iattributes[niattribs++] = GL.WGL_DRAW_TO_PBUFFER_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+
+ if (!rtt) {
+ // Currently we don't support non-truecolor visuals in the
+ // GLCapabilities, so we don't offer the option of making
+ // color-index pbuffers.
+ iattributes[niattribs++] = GL.WGL_PIXEL_TYPE_ARB;
+ iattributes[niattribs++] = GL.WGL_TYPE_RGBA_ARB;
+ }
+
+ iattributes[niattribs++] = GL.WGL_DOUBLE_BUFFER_ARB;
+ if (capabilities.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = GL.WGL_DEPTH_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getDepthBits();
+
+ iattributes[niattribs++] = GL.WGL_RED_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getRedBits();
+
+ iattributes[niattribs++] = GL.WGL_GREEN_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getGreenBits();
+
+ iattributes[niattribs++] = GL.WGL_BLUE_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getBlueBits();
+
+ iattributes[niattribs++] = GL.WGL_ALPHA_BITS_ARB;
+ iattributes[niattribs++] = capabilities.getAlphaBits();
+
+ iattributes[niattribs++] = GL.WGL_STENCIL_BITS_ARB;
+ if (capabilities.getStencilBits() > 0) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ if (capabilities.getAccumRedBits() > 0 ||
+ capabilities.getAccumGreenBits() > 0 ||
+ capabilities.getAccumBlueBits() > 0) {
+ iattributes[niattribs++] = GL.WGL_ACCUM_BITS_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ if (useFloat) {
+ iattributes[niattribs++] = GL.WGL_FLOAT_COMPONENTS_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ if (rtt) {
+ if (useFloat) {
+ iattributes[niattribs++] = GL.WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = rect ? GL.WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV : GL.WGL_BIND_TO_TEXTURE_RGB_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+ }
+
+ iattributes[niattribs++] = GL.WGL_SUPPORT_OPENGL_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+
+ int[] pformats = new int[MAX_PFORMATS];
+ int nformats;
+ int[] nformatsTmp = new int[1];
+ if (!gl.wglChoosePixelFormatARB(parentHdc,
+ iattributes,
+ fattributes,
+ MAX_PFORMATS,
+ pformats,
+ nformatsTmp)) {
+ throw new GLException("pbuffer creation error: wglChoosePixelFormatARB() failed");
+ }
+ nformats = nformatsTmp[0];
+ if (nformats <= 0) {
+ throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
+ }
+
+ if (DEBUG) {
+ System.err.println("" + nformats + " suitable pixel formats found");
+ // query pixel format
+ iattributes[0] = GL.WGL_RED_BITS_ARB;
+ iattributes[1] = GL.WGL_GREEN_BITS_ARB;
+ iattributes[2] = GL.WGL_BLUE_BITS_ARB;
+ iattributes[3] = GL.WGL_ALPHA_BITS_ARB;
+ iattributes[4] = GL.WGL_DEPTH_BITS_ARB;
+ iattributes[5] = GL.WGL_FLOAT_COMPONENTS_NV;
+ iattributes[6] = GL.WGL_SAMPLE_BUFFERS_EXT;
+ iattributes[7] = GL.WGL_SAMPLES_EXT;
+ int[] ivalues = new int[8];
+ for (int i = 0; i < nformats; i++) {
+ if (!gl.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 8, iattributes, ivalues)) {
+ throw new GLException("Error while querying pixel format " + pformats[i] +
+ "'s (index " + i + "'s) capabilities for debugging");
+ }
+ System.err.print("pixel format " + pformats[i] + " (index " + i + "): ");
+ System.err.print( "r: " + ivalues[0]);
+ System.err.print(" g: " + ivalues[1]);
+ System.err.print(" b: " + ivalues[2]);
+ System.err.print(" a: " + ivalues[3]);
+ System.err.print(" depth: " + ivalues[4]);
+ System.err.print(" multisample: " + ivalues[6]);
+ System.err.print(" samples: " + ivalues[7]);
+ if (ivalues[5] != 0) {
+ System.err.print(" [float]");
+ }
+ System.err.println();
+ }
+ }
+
+ int format = pformats[0];
+
+ // Create the p-buffer.
+ niattribs = 0;
+
+ if (rtt) {
+ iattributes[niattribs++] = GL.WGL_TEXTURE_FORMAT_ARB;
+ if (useFloat) {
+ iattributes[niattribs++] = GL.WGL_TEXTURE_FLOAT_RGB_NV;
+ } else {
+ iattributes[niattribs++] = GL.WGL_TEXTURE_RGBA_ARB;
+ }
+
+ iattributes[niattribs++] = GL.WGL_TEXTURE_TARGET_ARB;
+ iattributes[niattribs++] = rect ? GL.WGL_TEXTURE_RECTANGLE_NV : GL.WGL_TEXTURE_2D_ARB;
+
+ iattributes[niattribs++] = GL.WGL_MIPMAP_TEXTURE_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+
+ iattributes[niattribs++] = GL.WGL_PBUFFER_LARGEST_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = 0;
+
+ long tmpBuffer = gl.wglCreatePbufferARB(parentHdc, format, initWidth, initHeight, iattributes);
+ if (tmpBuffer == 0) {
+ throw new GLException("pbuffer creation error: wglCreatePbufferARB() failed: " + wglGetLastError());
+ }
+
+ // Get the device context.
+ long tmpHdc = gl.wglGetPbufferDCARB(tmpBuffer);
+ if (tmpHdc == 0) {
+ throw new GLException("pbuffer creation error: wglGetPbufferDCARB() failed");
+ }
+
+ this.parentHglrc = parentHglrc;
+
+ // Set up instance variables
+ buffer = tmpBuffer;
+ hdc = tmpHdc;
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ gl.wglQueryPbufferARB( buffer, GL.WGL_PBUFFER_WIDTH_ARB, tmp );
+ width = tmp[0];
+ gl.wglQueryPbufferARB( buffer, GL.WGL_PBUFFER_HEIGHT_ARB, tmp );
+ height = tmp[0];
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + width + " x " + height);
+ }
+ }
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ created = false;
+
+ if (buffer == 0) {
+ // pbuffer not instantiated yet
+ return false;
+ }
+
+ boolean res = super.makeCurrent(initAction);
+ if (created) {
+ // Initialize render-to-texture support if requested
+ rtt = capabilities.getOffscreenRenderToTexture();
+ rect = capabilities.getOffscreenRenderToTextureRectangle();
+
+ if (rtt) {
+ if (DEBUG) {
+ System.err.println("Initializing render-to-texture support");
+ }
+
+ GL gl = getGL();
+ if (rect && !gl.isExtensionAvailable("GL_NV_texture_rectangle")) {
+ System.err.println("WindowsPbufferGLContext: WARNING: GL_NV_texture_rectangle extension not " +
+ "supported; skipping requested render_to_texture_rectangle support for pbuffer");
+ rect = false;
+ }
+ if (rect) {
+ if (DEBUG) {
+ System.err.println(" Using render-to-texture-rectangle");
+ }
+ textureTarget = GL.GL_TEXTURE_RECTANGLE_NV;
+ } else {
+ if (DEBUG) {
+ System.err.println(" Using vanilla render-to-texture");
+ }
+ textureTarget = GL.GL_TEXTURE_2D;
+ }
+ int[] tmp = new int[1];
+ gl.glGenTextures(1, tmp);
+ texture = tmp[0];
+ gl.glBindTexture(textureTarget, texture);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
+ gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, width, height, 0);
+ }
+ }
+ return res;
+ }
+
+ public void handleModeSwitch(long parentHdc, long parentHglrc) {
+ throw new GLException("Not yet implemented");
+ }
+
+ protected boolean isOffscreen() {
+ // FIXME: currently the only caller of this won't cause proper
+ // resizing of the pbuffer anyway.
+ return false;
+ }
+
+ public int getOffscreenContextBufferedImageType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ protected void create() {
+ created = true;
+ // Create a gl context for the p-buffer.
+ hglrc = WGL.wglCreateContext(hdc);
+ if (hglrc == 0) {
+ throw new GLException("pbuffer creation error: wglCreateContext() failed");
+ }
+
+ // FIXME: provide option to not share display lists with subordinate pbuffer?
+ if (!WGL.wglShareLists(parentHglrc, hglrc)) {
+ throw new GLException("pbuffer: wglShareLists() failed");
+ }
+ }
+
+ protected void swapBuffers() throws GLException {
+ // FIXME: do we need to do anything if the pbuffer is double-buffered?
+ // For now, just grab the pixels for the render-to-texture support.
+ if (rtt && !rect) {
+ if (DEBUG) {
+ System.err.println("Copying pbuffer data to GL_TEXTURE_2D state");
+ }
+
+ GL gl = getGL();
+ gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, width, height, 0);
+ }
+ }
+
+ private String wglGetLastError() {
+ int err = WGL.GetLastError();
+ String detail = null;
+ switch (err) {
+ case WGL.ERROR_INVALID_PIXEL_FORMAT: detail = "ERROR_INVALID_PIXEL_FORMAT"; break;
+ case WGL.ERROR_NO_SYSTEM_RESOURCES: detail = "ERROR_NO_SYSTEM_RESOURCES"; break;
+ case WGL.ERROR_INVALID_DATA: detail = "ERROR_INVALID_DATA"; break;
+ case WGL.ERROR_PROC_NOT_FOUND: detail = "ERROR_PROC_NOT_FOUND"; break;
+ case WGL.ERROR_INVALID_WINDOW_HANDLE:detail = "ERROR_INVALID_WINDOW_HANDLE"; break;
+ default: detail = "(Unknown error code " + err + ")"; break;
+ }
+ return detail;
+ }
+}
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContext.java b/src/net/java/games/jogl/impl/x11/X11GLContext.java
new file mode 100644
index 000000000..8e9804578
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11GLContext.java
@@ -0,0 +1,414 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.x11;
+
+import java.awt.Component;
+import java.util.*;
+import net.java.games.gluegen.opengl.*; // for PROCADDRESS_VAR_PREFIX
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public abstract class X11GLContext extends GLContext {
+ private static JAWT jawt;
+ protected long display;
+ protected long drawable;
+ protected long context;
+ private boolean glXQueryExtensionsStringInitialized;
+ private boolean glXQueryExtensionsStringAvailable;
+ private static final Map/*<String, String>*/ functionNameMap;
+
+ static {
+ functionNameMap = new HashMap();
+ functionNameMap.put("glAllocateMemoryNV", "glXAllocateMemoryNV");
+ functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV");
+ }
+
+ public X11GLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super(component, capabilities, chooser);
+ }
+
+ protected GL createGL()
+ {
+ return new X11GLImpl(this);
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ String lookup = (String) functionNameMap.get(glFunctionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glFunctionName;
+ }
+
+ protected String mapToRealGLExtensionName(String glExtensionName) {
+ return glExtensionName;
+ }
+
+ protected abstract boolean isOffscreen();
+
+ public abstract int getOffscreenContextBufferedImageType();
+
+ public abstract int getOffscreenContextReadBuffer();
+
+ public abstract boolean offscreenImageNeedsVerticalFlip();
+
+ public synchronized void setRenderingThread(Thread currentThreadOrNull, Runnable initAction) {
+ this.willSetRenderingThread = false;
+ // FIXME: the JAWT on X11 grabs the AWT lock while the
+ // DrawingSurface is locked, which means that no other events can
+ // be processed. Currently we handle this by preventing the
+ // effects of setRenderingThread. We should figure out a better
+ // solution that is reasonably robust. Must file a bug to be fixed
+ // in the 1.5 JAWT.
+ }
+
+ /**
+ * Creates and initializes an appropriate OpenGl context. Should only be
+ * called by {@link makeCurrent(Runnable)}.
+ */
+ protected abstract void create();
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ boolean created = false;
+ if (context == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println("!!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+ if (drawable == 0) {
+ throw new GLException("Unable to make context current; drawable was null");
+ }
+
+ // FIXME: this cast to int would be wrong on 64-bit platforms
+ // where the argument type to glXMakeCurrent would change (should
+ // probably make GLXDrawable, and maybe XID, Opaque as long)
+ if (!GLX.glXMakeCurrent(display, (int) drawable, context)) {
+ throw new GLException("Error making context current");
+ }
+
+ if (created) {
+ resetGLFunctionAvailability();
+ initAction.run();
+ }
+ return true;
+ }
+
+ protected synchronized void free() throws GLException {
+ if (!GLX.glXMakeCurrent(display, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context");
+ }
+ }
+
+ protected abstract void swapBuffers() throws GLException;
+
+
+ protected void resetGLFunctionAvailability() {
+ super.resetGLFunctionAvailability();
+ resetGLProcAddressTable();
+ }
+
+ protected void resetGLProcAddressTable() {
+
+ if (DEBUG) {
+ System.err.println("!!! Initializing OpenGL extension address table");
+ }
+
+ net.java.games.jogl.impl.ProcAddressTable table = getGLProcAddressTable();
+
+ // if GL is no longer an interface, we'll have to re-implement the code
+ // below so it only iterates through gl methods (a non-interface might
+ // have constructors, custom methods, etc). For now we assume all methods
+ // will be gl methods.
+ GL gl = getGL();
+
+ Class tableClass = table.getClass();
+
+ java.lang.reflect.Field[] fields = tableClass.getDeclaredFields();
+
+ for (int i = 0; i < fields.length; ++i) {
+ String addressFieldName = fields[i].getName();
+ if (!addressFieldName.startsWith(GLEmitter.PROCADDRESS_VAR_PREFIX))
+ {
+ // not a proc address variable
+ continue;
+ }
+ int startOfMethodName = GLEmitter.PROCADDRESS_VAR_PREFIX.length();
+ String glFuncName = addressFieldName.substring(startOfMethodName);
+ try
+ {
+ java.lang.reflect.Field addressField = tableClass.getDeclaredField(addressFieldName);
+ assert(addressField.getType() == Long.TYPE);
+ // get the current value of the proc address variable in the table object
+ long oldProcAddress = addressField.getLong(table);
+ long newProcAddress = GLX.glXGetProcAddressARB(glFuncName);
+ /*
+ System.err.println(
+ "!!! Address=" + (newProcAddress == 0
+ ? "<NULL> "
+ : ("0x" +
+ Long.toHexString(newProcAddress))) +
+ "\tGL func: " + glFuncName);
+ */
+ // set the current value of the proc address variable in the table object
+ addressField.setLong(gl, newProcAddress);
+ } catch (Exception e) {
+ throw new GLException(
+ "Cannot get GL proc address for method \"" +
+ glFuncName + "\": Couldn't get value of field \"" + addressFieldName +
+ "\" in class " + tableClass.getName(), e);
+ }
+ }
+
+ }
+
+ public net.java.games.jogl.impl.ProcAddressTable getGLProcAddressTable() {
+ if (glProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ glProcAddressTable =
+ new net.java.games.jogl.impl.ProcAddressTable();
+ }
+ return glProcAddressTable;
+ }
+
+ public synchronized String getPlatformExtensionsString() {
+ if (display == 0) {
+ throw new GLException("Context not current");
+ }
+ if (!glXQueryExtensionsStringInitialized) {
+ glXQueryExtensionsStringAvailable = (GLX.glXGetProcAddressARB("glXQueryExtensionsString") != 0);
+ glXQueryExtensionsStringInitialized = true;
+ }
+ if (glXQueryExtensionsStringAvailable) {
+ return GLX.glXQueryExtensionsString(display, GLX.DefaultScreen(display));
+ } else {
+ return "";
+ }
+ }
+
+ protected boolean isFunctionAvailable(String glFunctionName)
+ {
+ boolean available = super.isFunctionAvailable(glFunctionName);
+
+ // Sanity check for implementations that use proc addresses for run-time
+ // linking: if the function IS available, then make sure there's a proc
+ // address for it if it's an extension or not part of the OpenGL 1.1 core
+ // (post GL 1.1 functions are run-time linked on windows).
+ assert(!available ||
+ (getGLProcAddressTable().getAddressFor(mapToRealGLFunctionName(glFunctionName)) != 0 ||
+ FunctionAvailabilityCache.isPartOfGLCore("1.1", mapToRealGLFunctionName(glFunctionName)))
+ );
+
+ return available;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ // Table that holds the addresses of the native C-language entry points for
+ // OpenGL functions.
+ private net.java.games.jogl.impl.ProcAddressTable glProcAddressTable;
+
+ protected JAWT getJAWT() {
+ if (jawt == null) {
+ JAWT j = new JAWT();
+ j.version(JAWTFactory.JAWT_VERSION_1_4);
+ if (!JAWTFactory.JAWT_GetAWT(j)) {
+ throw new RuntimeException("Unable to initialize JAWT");
+ }
+ jawt = j;
+ }
+ return jawt;
+ }
+
+ protected XVisualInfo chooseVisual() {
+ int screen = 0; // FIXME: provide way to specify this?
+ XVisualInfo vis = null;
+ if (chooser == null) {
+ // Note: this code path isn't taken any more now that the
+ // DefaultGLCapabilitiesChooser is present. However, it is being
+ // left in place for debugging purposes.
+ int[] attribs = glCapabilities2AttribList(capabilities);
+ vis = GLX.glXChooseVisual(display, screen, attribs);
+ if (vis == null) {
+ throw new GLException("Unable to find matching visual");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen visual from glXChooseVisual:");
+ System.err.println(xvi2GLCapabilities(vis));
+ }
+ } else {
+ int[] count = new int[1];
+ XVisualInfo template = new XVisualInfo();
+ template.screen(screen);
+ XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualScreenMask, template, count);
+ if (infos == null) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ GLCapabilities[] caps = new GLCapabilities[infos.length];
+ for (int i = 0; i < infos.length; i++) {
+ caps[i] = xvi2GLCapabilities(infos[i]);
+ }
+ int chosen = chooser.chooseCapabilities(capabilities, caps);
+ if (chosen < 0 || chosen >= caps.length) {
+ throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen visual (" + chosen + "):");
+ System.err.println(caps[chosen]);
+ }
+ vis = infos[chosen];
+ if (vis == null) {
+ throw new GLException("GLCapabilitiesChooser chose an invalid visual");
+ }
+ }
+ return vis;
+ }
+
+ protected long createContext(XVisualInfo vis, boolean onscreen) {
+ // FIXME: support sharing of display lists between contexts
+ return GLX.glXCreateContext(display, vis, 0, onscreen);
+ }
+
+ // Helper routine for the overridden create() to call
+ protected void chooseVisualAndCreateContext(boolean onscreen) {
+ XVisualInfo vis = chooseVisual();
+ // FIXME: support sharing of display lists between contexts
+ context = createContext(vis, onscreen);
+ if (context == 0) {
+ throw new GLException("Unable to create OpenGL context");
+ }
+ }
+
+ protected int[] glCapabilities2AttribList(GLCapabilities caps) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ int[] res = new int[22];
+ int idx = 0;
+ res[idx++] = GLX.GLX_RGBA;
+ if (caps.getDoubleBuffered()) {
+ res[idx++] = GLX.GLX_DOUBLEBUFFER;
+ }
+ if (caps.getStereo()) {
+ res[idx++] = GLX.GLX_STEREO;
+ }
+ res[idx++] = GLX.GLX_RED_SIZE;
+ res[idx++] = caps.getRedBits();
+ res[idx++] = GLX.GLX_GREEN_SIZE;
+ res[idx++] = caps.getGreenBits();
+ res[idx++] = GLX.GLX_BLUE_SIZE;
+ res[idx++] = caps.getBlueBits();
+ res[idx++] = GLX.GLX_ALPHA_SIZE;
+ res[idx++] = caps.getAlphaBits();
+ res[idx++] = GLX.GLX_DEPTH_SIZE;
+ res[idx++] = caps.getDepthBits();
+ res[idx++] = GLX.GLX_STENCIL_SIZE;
+ res[idx++] = caps.getStencilBits();
+ res[idx++] = GLX.GLX_ACCUM_RED_SIZE;
+ res[idx++] = caps.getAccumRedBits();
+ res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE;
+ res[idx++] = caps.getAccumGreenBits();
+ res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE;
+ res[idx++] = caps.getAccumBlueBits();
+ res[idx++] = 0;
+ return res;
+ }
+
+ protected GLCapabilities xvi2GLCapabilities(XVisualInfo info) {
+ int[] tmp = new int[1];
+ int val = glXGetConfig(info, GLX.GLX_USE_GL, tmp);
+ if (val == 0) {
+ // Visual does not support OpenGL
+ return null;
+ }
+ val = glXGetConfig(info, GLX.GLX_RGBA, tmp);
+ if (val == 0) {
+ // Visual does not support RGBA
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities();
+ res.setDoubleBuffered(glXGetConfig(info, GLX.GLX_DOUBLEBUFFER, tmp) != 0);
+ res.setStereo (glXGetConfig(info, GLX.GLX_STEREO, tmp) != 0);
+ // Note: use of hardware acceleration is determined by
+ // glXCreateContext, not by the XVisualInfo. Optimistically claim
+ // that all GLCapabilities have the capability to be hardware
+ // accelerated.
+ res.setHardwareAccelerated(true);
+ res.setDepthBits (glXGetConfig(info, GLX.GLX_DEPTH_SIZE, tmp));
+ res.setStencilBits (glXGetConfig(info, GLX.GLX_STENCIL_SIZE, tmp));
+ res.setRedBits (glXGetConfig(info, GLX.GLX_RED_SIZE, tmp));
+ res.setGreenBits (glXGetConfig(info, GLX.GLX_GREEN_SIZE, tmp));
+ res.setBlueBits (glXGetConfig(info, GLX.GLX_BLUE_SIZE, tmp));
+ res.setAlphaBits (glXGetConfig(info, GLX.GLX_ALPHA_SIZE, tmp));
+ res.setAccumRedBits (glXGetConfig(info, GLX.GLX_ACCUM_RED_SIZE, tmp));
+ res.setAccumGreenBits(glXGetConfig(info, GLX.GLX_ACCUM_GREEN_SIZE, tmp));
+ res.setAccumBlueBits (glXGetConfig(info, GLX.GLX_ACCUM_BLUE_SIZE, tmp));
+ res.setAccumAlphaBits(glXGetConfig(info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp));
+ return res;
+ }
+
+ protected String glXGetConfigErrorCode(int err) {
+ switch (err) {
+ case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
+ case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN";
+ case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
+ case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL";
+ default: return "Unknown error code " + err;
+ }
+ }
+
+ protected int glXGetConfig(XVisualInfo info, int attrib, int[] tmp) {
+ if (display == 0) {
+ throw new GLException("No display connection");
+ }
+ int res = GLX.glXGetConfig(display, info, attrib, tmp);
+ if (res != 0) {
+ throw new GLException("glXGetConfig failed: error code " + glXGetConfigErrorCode(res));
+ }
+ return tmp[0];
+ }
+}
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
new file mode 100644
index 000000000..cf1e4be25
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
@@ -0,0 +1,56 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.x11;
+
+import java.awt.Component;
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class X11GLContextFactory extends GLContextFactory {
+ public GLContext createGLContext(Component component,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ if (component != null) {
+ return new X11OnscreenGLContext(component, capabilities, chooser);
+ } else {
+ return new X11OffscreenGLContext(capabilities, chooser);
+ }
+ }
+}
diff --git a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java
new file mode 100644
index 000000000..62fd380ee
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java
@@ -0,0 +1,177 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.x11;
+
+import java.awt.image.BufferedImage;
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class X11OffscreenGLContext extends X11GLContext {
+ private int pixmap;
+ private boolean isDoubleBuffered;
+ // Width and height of the underlying bitmap
+ private int width;
+ private int height;
+
+ // Display connection for use by all offscreen surfaces
+ private long staticDisplay;
+
+ public X11OffscreenGLContext(GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super(null, capabilities, chooser);
+ }
+
+ protected GL createGL()
+ {
+ return new X11GLImpl(this);
+ }
+
+ protected boolean isOffscreen() {
+ return true;
+ }
+
+ public int getOffscreenContextBufferedImageType() {
+ if (capabilities.getAlphaBits() > 0) {
+ return BufferedImage.TYPE_INT_ARGB;
+ } else {
+ return BufferedImage.TYPE_INT_RGB;
+ }
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ if (isDoubleBuffered) {
+ return GL.GL_BACK;
+ }
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ // There doesn't seem to be a way to do this in the construction
+ // of the Pixmap or GLXPixmap
+ return true;
+ }
+
+ public boolean canCreatePbufferContext() {
+ // For now say no
+ return false;
+ }
+
+ public synchronized GLContext createPbufferContext(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ throw new GLException("Not supported");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ ensureDisplayOpened();
+ if (pendingOffscreenResize) {
+ if (pendingOffscreenWidth != width || pendingOffscreenWidth != height) {
+ if (context != 0) {
+ destroy();
+ }
+ width = pendingOffscreenWidth;
+ height = pendingOffscreenHeight;
+ pendingOffscreenResize = false;
+ }
+ }
+ return super.makeCurrent(initAction);
+ }
+
+ protected synchronized void swapBuffers() throws GLException {
+ }
+
+ protected synchronized void free() throws GLException {
+ try {
+ super.free();
+ } finally {
+ display = 0;
+ }
+ }
+
+ protected void create() {
+ XVisualInfo vis = chooseVisual();
+ int bitsPerPixel = vis.depth();
+
+ if (display == 0) {
+ throw new GLException("No active display");
+ }
+ int screen = GLX.DefaultScreen(display);
+ pixmap = GLX.XCreatePixmap(display, (int) GLX.RootWindow(display, screen), width, height, bitsPerPixel);
+ if (pixmap == 0) {
+ throw new GLException("XCreatePixmap failed");
+ }
+ drawable = GLX.glXCreateGLXPixmap(display, vis, pixmap);
+ if (drawable == 0) {
+ throw new GLException("glXCreateGLXPixmap failed");
+ }
+ context = createContext(vis, false);
+ if (context == 0) {
+ throw new GLException("Unable to create OpenGL context");
+ }
+ isDoubleBuffered = (glXGetConfig(vis, GLX.GLX_DOUBLEBUFFER, new int[1]) != 0);
+ }
+
+ private void ensureDisplayOpened() {
+ if (staticDisplay == 0) {
+ staticDisplay = GLX.XOpenDisplay(null);
+ if (staticDisplay == 0) {
+ throw new GLException("Unable to open default display, needed for offscreen surface handling");
+ }
+ }
+ display = staticDisplay;
+ }
+
+ private void destroy() {
+ // Must destroy OpenGL context, pixmap and GLXPixmap
+ GLX.glXDestroyContext(display, context);
+ GLX.glXDestroyGLXPixmap(display, (int) drawable);
+ GLX.XFreePixmap(display, pixmap);
+ context = 0;
+ drawable = 0;
+ pixmap = 0;
+ }
+}
diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
new file mode 100644
index 000000000..496e113a5
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
@@ -0,0 +1,189 @@
+/*
+ * 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
+ * MIDROSYSTEMS, 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 net.java.games.jogl.impl.x11;
+
+import java.awt.Component;
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class X11OnscreenGLContext extends X11GLContext {
+ // Variables for lockSurface/unlockSurface
+ private JAWT_DrawingSurface ds;
+ private JAWT_DrawingSurfaceInfo dsi;
+ private JAWT_X11DrawingSurfaceInfo x11dsi;
+
+ public X11OnscreenGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) {
+ super(component, capabilities, chooser);
+ }
+
+ protected GL createGL()
+ {
+ return new X11GLImpl(this);
+ }
+
+ protected boolean isOffscreen() {
+ return false;
+ }
+
+ public int getOffscreenContextBufferedImageType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean canCreatePbufferContext() {
+ // For now say no
+ return false;
+ }
+
+ public synchronized GLContext createPbufferContext(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ throw new GLException("Not yet supported");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ try {
+ if (!lockSurface()) {
+ return false;
+ }
+ return super.makeCurrent(initAction);
+ } catch (RuntimeException e) {
+ try {
+ unlockSurface();
+ } catch (Exception e2) {
+ // do nothing if unlockSurface throws
+ }
+ throw(e);
+ }
+ }
+
+ protected synchronized void free() throws GLException {
+ try {
+ super.free();
+ } finally {
+ unlockSurface();
+ }
+ }
+
+ protected synchronized void swapBuffers() throws GLException {
+ // FIXME: this cast to int would be wrong on 64-bit platforms
+ // where the argument type to glXMakeCurrent would change (should
+ // probably make GLXDrawable, and maybe XID, Opaque as long)
+ GLX.glXSwapBuffers(display, (int) drawable);
+ }
+
+ private boolean lockSurface() throws GLException {
+ if (drawable != 0) {
+ throw new GLException("Surface already locked");
+ }
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ return false;
+ }
+ int res = ds.Lock();
+ if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) {
+ throw new GLException("Unable to lock surface");
+ }
+ // See whether the surface changed and if so destroy the old
+ // OpenGL context so it will be recreated
+ if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
+ if (context != 0) {
+ GLX.glXDestroyContext(display, context);
+ context = 0;
+ }
+ }
+ dsi = ds.GetDrawingSurfaceInfo();
+ if (dsi == null) {
+ // Widget not yet realized
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ return false;
+ }
+ x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
+ display = x11dsi.display();
+ drawable = x11dsi.drawable();
+ if (display == 0 || drawable == 0) {
+ // Widget not yet realized
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ x11dsi = null;
+ return false;
+ }
+ return true;
+ }
+
+ private void unlockSurface() {
+ if (drawable == 0) {
+ throw new GLException("Surface already unlocked");
+ }
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ x11dsi = null;
+ display = 0;
+ drawable = 0;
+ }
+
+ protected void create() {
+ chooseVisualAndCreateContext(true);
+ }
+}