From 4cda4b70dbcd21cf57e1e253ddba32b88bcaec18 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Tue, 8 Feb 2011 06:20:35 +0100
Subject: Move implementation private files from com.jogamp.<module>.impl. to
 jogamp.<module> (1/2) - rename task

- com.jogamp.opengl.impl                     -> jogamp.opengl
- com.jogamp.opengl.util.glsl.fixedfunc.impl -> jogamp.opengl.util.glsl.fixedfunc
- com.jogamp.nativewindow.impl               -> jogamp.nativewindow
- com.jogamp.newt.impl                       -> jogamp.newt

This sorts implementation details from the top level, ie skipping the public 'com',
allowing a better seperation of public classes and implementation details
and also reduces strings.

This approach of public/private seperation is also used in the OpenJDK.
---
 .../classes/jogamp/opengl/gl2/ProjectDouble.java   | 1042 ++++++++++++++++++++
 src/jogl/classes/jogamp/opengl/gl2/Util.java       |  244 +++++
 .../jogamp/opengl/gl2/fixme/GLObjectTracker.java   |  835 ++++++++++++++++
 3 files changed, 2121 insertions(+)
 create mode 100644 src/jogl/classes/jogamp/opengl/gl2/ProjectDouble.java
 create mode 100644 src/jogl/classes/jogamp/opengl/gl2/Util.java
 create mode 100644 src/jogl/classes/jogamp/opengl/gl2/fixme/GLObjectTracker.java

(limited to 'src/jogl/classes/jogamp/opengl/gl2')

diff --git a/src/jogl/classes/jogamp/opengl/gl2/ProjectDouble.java b/src/jogl/classes/jogamp/opengl/gl2/ProjectDouble.java
new file mode 100644
index 000000000..98cc3f323
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/gl2/ProjectDouble.java
@@ -0,0 +1,1042 @@
+/*
+** License Applicability. Except to the extent portions of this file are
+** made subject to an alternative license as permitted in the SGI Free
+** Software License B, Version 2.0 (the "License"), the contents of this
+** file are subject only to the provisions of the License. You may not use
+** this file except in compliance with the License. You may obtain a copy
+** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
+** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
+** 
+** http://oss.sgi.com/projects/FreeB
+** 
+** Note that, as provided in the License, the Software is distributed on an
+** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
+** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
+** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
+** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
+**
+** NOTE:  The Original Code (as defined below) has been licensed to Sun
+** Microsystems, Inc. ("Sun") under the SGI Free Software License B
+** (Version 1.1), shown above ("SGI License").   Pursuant to Section
+** 3.2(3) of the SGI License, Sun is distributing the Covered Code to
+** you under an alternative license ("Alternative License").  This
+** Alternative License includes all of the provisions of the SGI License
+** except that Section 2.2 and 11 are omitted.  Any differences between
+** the Alternative License and the SGI License are offered solely by Sun
+** and not by SGI.
+** 
+** Original Code. The Original Code is: OpenGL Sample Implementation,
+** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
+** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
+** Copyright in any portions created by third parties is as indicated
+** elsewhere herein. All Rights Reserved.
+** 
+** Additional Notice Provisions: The application programming interfaces
+** established by SGI in conjunction with the Original Code are The
+** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
+** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
+** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
+** Window System(R) (Version 1.3), released October 19, 1998. This software
+** was created using the OpenGL(R) version 1.2.1 Sample Implementation
+** published by SGI, but has not been independently verified as being
+** compliant with the OpenGL(R) version 1.2.1 Specification.
+**
+** $Date: 2009-03-13 22:20:29 -0700 (Fri, 13 Mar 2009) $ $Revision: 1867 $
+** $Header$
+*/
+
+/* 
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are 
+ * met:
+ * 
+ * * Redistributions of source code must retain the above copyright 
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'LWJGL' nor the names of 
+ *   its contributors may be used to endorse or promote products derived 
+ *   from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * 
+ * - Redistribution in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * 
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * 
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+package com.jogamp.opengl.impl.gl2;
+
+import java.nio.*;
+
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.*;
+import com.jogamp.common.nio.Buffers;
+
+/**
+ * Project.java
+ * <p/>
+ * <p/>
+ * Created 11-jan-2004
+ * 
+ * @author Erik Duijs
+ * @author Kenneth Russell
+ */
+public class ProjectDouble {
+  private static final double[] IDENTITY_MATRIX =
+    new double[] {
+      1.0, 0.0, 0.0, 0.0,
+      0.0, 1.0, 0.0, 0.0,
+      0.0, 0.0, 1.0, 0.0,
+      0.0, 0.0, 0.0, 1.0 };
+
+  // Note that we have cloned parts of the implementation in order to
+  // support incoming Buffers. The reason for this is to avoid loading
+  // non-direct buffer subclasses unnecessarily, because doing so can
+  // cause performance decreases on direct buffer operations, at least
+  // on the current HotSpot JVM. It would be nicer (and make the code
+  // simpler) to simply have the array-based entry points delegate to
+  // the versions taking Buffers by wrapping the arrays.
+
+  // Array-based implementation
+  private final double[] matrix = new double[16];
+
+  private final double[][] tempMatrix = new double[4][4];
+  private final double[] in = new double[4];
+  private final double[] out = new double[4];
+
+  private final double[] forward = new double[3];
+  private final double[] side = new double[3];
+  private final double[] up = new double[3];
+  
+  // Buffer-based implementation
+  private DoubleBuffer locbuf;
+  private final DoubleBuffer matrixBuf;
+
+  private final DoubleBuffer tempMatrixBuf;
+  private final DoubleBuffer inBuf;
+  private final DoubleBuffer outBuf;
+
+  private final DoubleBuffer forwardBuf;
+  private final DoubleBuffer sideBuf;
+  private final DoubleBuffer upBuf;
+
+  public ProjectDouble() {
+    // Use direct buffers to avoid loading indirect buffer
+    // implementations for applications trying to avoid doing so.
+    // Slice up one big buffer because some NIO implementations
+    // allocate a huge amount of memory to back even the smallest of
+    // buffers.
+    DoubleBuffer locbuf = Buffers.newDirectDoubleBuffer(128);
+    int pos = 0;
+    int sz = 16;
+    matrixBuf = slice(locbuf, pos, sz);
+    pos += sz;
+    tempMatrixBuf = slice(locbuf, pos, sz);
+    pos += sz;
+    sz = 4;
+    inBuf = slice(locbuf, pos, sz);
+    pos += sz;
+    outBuf = slice(locbuf, pos, sz);
+    pos += sz;
+    sz = 3;
+    forwardBuf = slice(locbuf, pos, sz);
+    pos += sz;
+    sideBuf = slice(locbuf, pos, sz);
+    pos += sz;
+    upBuf = slice(locbuf, pos, sz);
+  }
+
+  public void destroy() {
+    if(locbuf!=null) {
+        locbuf.clear();
+        locbuf=null;
+    }
+  }
+
+  private static DoubleBuffer slice(DoubleBuffer buf, int pos, int len) {
+    buf.position(pos);
+    buf.limit(pos + len);
+    return buf.slice();
+  }
+
+  /**
+   * Make matrix an identity matrix
+   */
+  private void __gluMakeIdentityd(DoubleBuffer m) {
+    int oldPos = m.position();
+    m.put(IDENTITY_MATRIX);
+    m.position(oldPos);
+  }
+
+  /**
+   * Make matrix an identity matrix
+   */
+  private void __gluMakeIdentityd(double[] m) {
+    for (int i = 0; i < 16; i++) {
+      m[i] = IDENTITY_MATRIX[i];
+    }
+  }
+
+  /**
+   * Method __gluMultMatrixVecd
+   * 
+   * @param matrix
+   * @param in
+   * @param out
+   */
+  private void __gluMultMatrixVecd(double[] matrix, int matrix_offset, double[] in, double[] out) {
+    for (int i = 0; i < 4; i++) {
+      out[i] =
+        in[0] * matrix[0*4+i+matrix_offset] +
+        in[1] * matrix[1*4+i+matrix_offset] +
+        in[2] * matrix[2*4+i+matrix_offset] +
+        in[3] * matrix[3*4+i+matrix_offset];
+    }
+  }
+
+  /**
+   * Method __gluMultMatrixVecd
+   * 
+   * @param matrix
+   * @param in
+   * @param out
+   */
+  private void __gluMultMatrixVecd(DoubleBuffer matrix, DoubleBuffer in, DoubleBuffer out) {
+    int inPos = in.position();
+    int outPos = out.position();
+    int matrixPos = matrix.position();
+    for (int i = 0; i < 4; i++) {
+      out.put(i + outPos,
+              in.get(0+inPos) * matrix.get(0*4+i+matrixPos) +
+              in.get(1+inPos) * matrix.get(1*4+i+matrixPos) +
+              in.get(2+inPos) * matrix.get(2*4+i+matrixPos) +
+              in.get(3+inPos) * matrix.get(3*4+i+matrixPos));
+    }
+  }
+
+  /**
+   * @param src
+   * @param inverse
+   * 
+   * @return
+   */
+  private boolean __gluInvertMatrixd(double[] src, double[] inverse) {
+    int i, j, k, swap;
+    double t;
+    double[][] temp = tempMatrix;
+
+    for (i = 0; i < 4; i++) {
+      for (j = 0; j < 4; j++) {
+        temp[i][j] = src[i*4+j];
+      }
+    }
+    __gluMakeIdentityd(inverse);
+
+    for (i = 0; i < 4; i++) {
+      //
+      // Look for largest element in column
+      //
+      swap = i;
+      for (j = i + 1; j < 4; j++) {
+        if (Math.abs(temp[j][i]) > Math.abs(temp[i][i])) {
+          swap = j;
+        }
+      }
+
+      if (swap != i) {
+        //
+        // Swap rows.
+        //
+        for (k = 0; k < 4; k++) {
+          t = temp[i][k];
+          temp[i][k] = temp[swap][k];
+          temp[swap][k] = t;
+
+          t = inverse[i*4+k];
+          inverse[i*4+k] = inverse[swap*4+k];
+          inverse[swap*4+k] = t;
+        }
+      }
+
+      if (temp[i][i] == 0) {
+        //
+        // No non-zero pivot. The matrix is singular, which shouldn't
+        // happen. This means the user gave us a bad matrix.
+        //
+        return false;
+      }
+
+      t = temp[i][i];
+      for (k = 0; k < 4; k++) {
+        temp[i][k] /= t;
+        inverse[i*4+k] /= t;
+      }
+      for (j = 0; j < 4; j++) {
+        if (j != i) {
+          t = temp[j][i];
+          for (k = 0; k < 4; k++) {
+            temp[j][k] -= temp[i][k] * t;
+            inverse[j*4+k] -= inverse[i*4+k]*t;
+          }
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
+   * @param src
+   * @param inverse
+   * 
+   * @return
+   */
+  private boolean __gluInvertMatrixd(DoubleBuffer src, DoubleBuffer inverse) {
+    int i, j, k, swap;
+    double t;
+
+    int srcPos = src.position();
+    int invPos = inverse.position();
+
+    DoubleBuffer temp = tempMatrixBuf;
+
+    for (i = 0; i < 4; i++) {
+      for (j = 0; j < 4; j++) {
+        temp.put(i*4+j, src.get(i*4+j + srcPos));
+      }
+    }
+    __gluMakeIdentityd(inverse);
+
+    for (i = 0; i < 4; i++) {
+      //
+      // Look for largest element in column
+      //
+      swap = i;
+      for (j = i + 1; j < 4; j++) {
+        if (Math.abs(temp.get(j*4+i)) > Math.abs(temp.get(i*4+i))) {
+          swap = j;
+        }
+      }
+
+      if (swap != i) {
+        //
+        // Swap rows.
+        //
+        for (k = 0; k < 4; k++) {
+          t = temp.get(i*4+k);
+          temp.put(i*4+k, temp.get(swap*4+k));
+          temp.put(swap*4+k, t);
+
+          t = inverse.get(i*4+k + invPos);
+          inverse.put(i*4+k + invPos, inverse.get(swap*4+k + invPos));
+          inverse.put(swap*4+k + invPos, t);
+        }
+      }
+
+      if (temp.get(i*4+i) == 0) {
+        //
+        // No non-zero pivot. The matrix is singular, which shouldn't
+        // happen. This means the user gave us a bad matrix.
+        //
+        return false;
+      }
+
+      t = temp.get(i*4+i);
+      for (k = 0; k < 4; k++) {
+        temp.put(i*4+k, temp.get(i*4+k) / t);
+        inverse.put(i*4+k + invPos, inverse.get(i*4+k + invPos) / t);
+      }
+      for (j = 0; j < 4; j++) {
+        if (j != i) {
+          t = temp.get(j*4+i);
+          for (k = 0; k < 4; k++) {
+            temp.put(j*4+k, temp.get(j*4+k) - temp.get(i*4+k) * t);
+            inverse.put(j*4+k + invPos, inverse.get(j*4+k + invPos) - inverse.get(i*4+k + invPos) * t);
+          }
+        }
+      }
+    }
+    return true;
+  }
+
+
+  /**
+   * @param a
+   * @param b
+   * @param r
+   */
+  private void __gluMultMatricesd(double[] a, int a_offset, double[] b, int b_offset, double[] r) {
+    for (int i = 0; i < 4; i++) {
+      for (int j = 0; j < 4; j++) {
+        r[i*4+j] =
+          a[i*4+0+a_offset]*b[0*4+j+b_offset] +
+          a[i*4+1+a_offset]*b[1*4+j+b_offset] +
+          a[i*4+2+a_offset]*b[2*4+j+b_offset] +
+          a[i*4+3+a_offset]*b[3*4+j+b_offset];
+      }
+    }
+  }
+
+
+  /**
+   * @param a
+   * @param b
+   * @param r
+   */
+  private void __gluMultMatricesd(DoubleBuffer a, DoubleBuffer b, DoubleBuffer r) {
+    int aPos = a.position();
+    int bPos = b.position();
+    int rPos = r.position();
+
+    for (int i = 0; i < 4; i++) {
+      for (int j = 0; j < 4; j++) {
+        r.put(i*4+j + rPos,
+          a.get(i*4+0+aPos)*b.get(0*4+j+bPos) +
+          a.get(i*4+1+aPos)*b.get(1*4+j+bPos) +
+          a.get(i*4+2+aPos)*b.get(2*4+j+bPos) +
+          a.get(i*4+3+aPos)*b.get(3*4+j+bPos));
+      }
+    }
+  }
+
+  /**
+   * Normalize vector
+   *
+   * @param v
+   */
+  private static void normalize(double[] v) {
+    double r;
+
+    r = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
+    if ( r == 0.0 )
+      return;
+
+    r = 1.0 / r;
+
+    v[0] *= r;
+    v[1] *= r;
+    v[2] *= r;
+
+    return;
+  }
+
+  /**
+   * Normalize vector
+   *
+   * @param v
+   */
+  private static void normalize(DoubleBuffer v) {
+    double r;
+
+    int vPos = v.position();
+
+    r = Math.sqrt(v.get(0+vPos) * v.get(0+vPos) +
+                  v.get(1+vPos) * v.get(1+vPos) +
+                  v.get(2+vPos) * v.get(2+vPos));
+    if ( r == 0.0 )
+      return;
+
+    r = 1.0 / r;
+
+    v.put(0+vPos, v.get(0+vPos) * r);
+    v.put(1+vPos, v.get(1+vPos) * r);
+    v.put(2+vPos, v.get(2+vPos) * r);
+
+    return;
+  }
+
+
+  /**
+   * Calculate cross-product
+   *
+   * @param v1
+   * @param v2
+   * @param result
+   */
+  private static void cross(double[] v1, double[] v2, double[] result) {
+    result[0] = v1[1] * v2[2] - v1[2] * v2[1];
+    result[1] = v1[2] * v2[0] - v1[0] * v2[2];
+    result[2] = v1[0] * v2[1] - v1[1] * v2[0];
+  }
+
+  /**
+   * Calculate cross-product
+   *
+   * @param v1
+   * @param v2
+   * @param result
+   */
+  private static void cross(DoubleBuffer v1, DoubleBuffer v2, DoubleBuffer result) {
+    int v1Pos = v1.position();
+    int v2Pos = v2.position();
+    int rPos  = result.position();
+
+    result.put(0+rPos, v1.get(1+v1Pos) * v2.get(2+v2Pos) - v1.get(2+v1Pos) * v2.get(1+v2Pos));
+    result.put(1+rPos, v1.get(2+v1Pos) * v2.get(0+v2Pos) - v1.get(0+v1Pos) * v2.get(2+v2Pos));
+    result.put(2+rPos, v1.get(0+v1Pos) * v2.get(1+v2Pos) - v1.get(1+v1Pos) * v2.get(0+v2Pos));
+  }
+
+  /**
+   * Method gluOrtho2D.
+   * 
+   * @param left
+   * @param right
+   * @param bottom
+   * @param top
+   */
+  public void gluOrtho2D(GL2 gl, double left, double right, double bottom, double top) {
+    gl.glOrtho(left, right, bottom, top, -1, 1);
+  }
+
+  /**
+   * Method gluPerspective.
+   * 
+   * @param fovy
+   * @param aspect
+   * @param zNear
+   * @param zFar
+   */
+  public void gluPerspective(GL2 gl, double fovy, double aspect, double zNear, double zFar) {
+    double sine, cotangent, deltaZ;
+    double radians = fovy / 2 * Math.PI / 180;
+
+    deltaZ = zFar - zNear;
+    sine = Math.sin(radians);
+
+    if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
+      return;
+    }
+
+    cotangent = Math.cos(radians) / sine;
+
+    __gluMakeIdentityd(matrixBuf);
+
+    matrixBuf.put(0 * 4 + 0, cotangent / aspect);
+    matrixBuf.put(1 * 4 + 1, cotangent);
+    matrixBuf.put(2 * 4 + 2, - (zFar + zNear) / deltaZ);
+    matrixBuf.put(2 * 4 + 3, -1);
+    matrixBuf.put(3 * 4 + 2, -2 * zNear * zFar / deltaZ);
+    matrixBuf.put(3 * 4 + 3, 0);
+
+    gl.glMultMatrixd(matrixBuf);
+  }
+
+  /**
+   * Method gluLookAt
+   * 
+   * @param eyex
+   * @param eyey
+   * @param eyez
+   * @param centerx
+   * @param centery
+   * @param centerz
+   * @param upx
+   * @param upy
+   * @param upz
+   */
+  public void gluLookAt(GL2 gl,
+                        double eyex,
+                        double eyey,
+                        double eyez,
+                        double centerx,
+                        double centery,
+                        double centerz,
+                        double upx,
+                        double upy,
+                        double upz) {
+    DoubleBuffer forward = this.forwardBuf;
+    DoubleBuffer side = this.sideBuf;
+    DoubleBuffer up = this.upBuf;
+
+    forward.put(0, centerx - eyex);
+    forward.put(1, centery - eyey);
+    forward.put(2, centerz - eyez);
+
+    up.put(0, upx);
+    up.put(1, upy);
+    up.put(2, upz);
+
+    normalize(forward);
+
+    /* Side = forward x up */
+    cross(forward, up, side);
+    normalize(side);
+
+    /* Recompute up as: up = side x forward */
+    cross(side, forward, up);
+
+    __gluMakeIdentityd(matrixBuf);
+    matrixBuf.put(0 * 4 + 0, side.get(0));
+    matrixBuf.put(1 * 4 + 0, side.get(1));
+    matrixBuf.put(2 * 4 + 0, side.get(2));
+
+    matrixBuf.put(0 * 4 + 1, up.get(0));
+    matrixBuf.put(1 * 4 + 1, up.get(1));
+    matrixBuf.put(2 * 4 + 1, up.get(2));
+
+    matrixBuf.put(0 * 4 + 2, -forward.get(0));
+    matrixBuf.put(1 * 4 + 2, -forward.get(1));
+    matrixBuf.put(2 * 4 + 2, -forward.get(2));
+
+    gl.glMultMatrixd(matrixBuf);
+    gl.glTranslated(-eyex, -eyey, -eyez);
+  }
+
+  /**
+   * Method gluProject
+   * 
+   * @param objx
+   * @param objy
+   * @param objz
+   * @param modelMatrix
+   * @param projMatrix
+   * @param viewport
+   * @param win_pos
+   * 
+   * @return
+   */
+  public boolean gluProject(double objx,
+                            double objy,
+                            double objz,
+                            double[] modelMatrix,
+                            int modelMatrix_offset,
+                            double[] projMatrix,
+                            int projMatrix_offset,
+                            int[] viewport,
+                            int viewport_offset,
+                            double[] win_pos,
+                            int win_pos_offset ) {
+
+    double[] in = this.in;
+    double[] out = this.out;
+
+    in[0] = objx;
+    in[1] = objy;
+    in[2] = objz;
+    in[3] = 1.0;
+
+    __gluMultMatrixVecd(modelMatrix, modelMatrix_offset, in, out);
+    __gluMultMatrixVecd(projMatrix, projMatrix_offset, out, in);
+
+    if (in[3] == 0.0)
+      return false;
+
+    in[3] = (1.0 / in[3]) * 0.5;
+
+    // Map x, y and z to range 0-1
+    in[0] = in[0] * in[3] + 0.5f;
+    in[1] = in[1] * in[3] + 0.5f;
+    in[2] = in[2] * in[3] + 0.5f;
+
+    // Map x,y to viewport
+    win_pos[0+win_pos_offset] = in[0] * viewport[2+viewport_offset] + viewport[0+viewport_offset];
+    win_pos[1+win_pos_offset] = in[1] * viewport[3+viewport_offset] + viewport[1+viewport_offset];
+    win_pos[2+win_pos_offset] = in[2];
+
+    return true;
+  }
+
+  /**
+   * Method gluProject
+   * 
+   * @param objx
+   * @param objy
+   * @param objz
+   * @param modelMatrix
+   * @param projMatrix
+   * @param viewport
+   * @param win_pos
+   * 
+   * @return
+   */
+  public boolean gluProject(double objx,
+                            double objy,
+                            double objz,
+                            DoubleBuffer modelMatrix,
+                            DoubleBuffer projMatrix,
+                            IntBuffer viewport,
+                            DoubleBuffer win_pos) {
+
+    DoubleBuffer in = this.inBuf;
+    DoubleBuffer out = this.outBuf;
+
+    in.put(0, objx);
+    in.put(1, objy);
+    in.put(2, objz);
+    in.put(3, 1.0);
+
+    __gluMultMatrixVecd(modelMatrix, in, out);
+    __gluMultMatrixVecd(projMatrix, out, in);
+
+    if (in.get(3) == 0.0)
+      return false;
+
+    in.put(3, (1.0 / in.get(3)) * 0.5);
+
+    // Map x, y and z to range 0-1
+    in.put(0, in.get(0) * in.get(3) + 0.5f);
+    in.put(1, in.get(1) * in.get(3) + 0.5f);
+    in.put(2, in.get(2) * in.get(3) + 0.5f);
+
+    // Map x,y to viewport
+    int vPos = viewport.position();
+    int wPos = win_pos.position();
+    win_pos.put(0+wPos, in.get(0) * viewport.get(2+vPos) + viewport.get(0+vPos));
+    win_pos.put(1+wPos, in.get(1) * viewport.get(3+vPos) + viewport.get(1+vPos));
+    win_pos.put(2+wPos, in.get(2));
+
+    return true;
+  }
+
+
+  /**
+   * Method gluUnproject
+   * 
+   * @param winx
+   * @param winy
+   * @param winz
+   * @param modelMatrix
+   * @param projMatrix
+   * @param viewport
+   * @param obj_pos
+   * 
+   * @return
+   */
+  public boolean gluUnProject(double winx,
+                              double winy,
+                              double winz,
+                              double[] modelMatrix,
+                              int modelMatrix_offset,
+                              double[] projMatrix,
+                              int projMatrix_offset,
+                              int[] viewport,
+                              int viewport_offset,
+                              double[] obj_pos,
+                              int obj_pos_offset) {
+    double[] in = this.in;
+    double[] out = this.out;
+
+    __gluMultMatricesd(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+    if (!__gluInvertMatrixd(matrix, matrix))
+      return false;
+
+    in[0] = winx;
+    in[1] = winy;
+    in[2] = winz;
+    in[3] = 1.0;
+
+    // Map x and y from window coordinates
+    in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+    in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+
+    // Map to range -1 to 1
+    in[0] = in[0] * 2 - 1;
+    in[1] = in[1] * 2 - 1;
+    in[2] = in[2] * 2 - 1;
+
+    __gluMultMatrixVecd(matrix, 0, in, out);
+
+    if (out[3] == 0.0)
+      return false;
+
+    out[3] = 1.0 / out[3];
+
+    obj_pos[0+obj_pos_offset] = out[0] * out[3];
+    obj_pos[1+obj_pos_offset] = out[1] * out[3];
+    obj_pos[2+obj_pos_offset] = out[2] * out[3];
+
+    return true;
+  }
+
+
+  /**
+   * Method gluUnproject
+   * 
+   * @param winx
+   * @param winy
+   * @param winz
+   * @param modelMatrix
+   * @param projMatrix
+   * @param viewport
+   * @param obj_pos
+   * 
+   * @return
+   */
+  public boolean gluUnProject(double winx,
+                              double winy,
+                              double winz,
+                              DoubleBuffer modelMatrix,
+                              DoubleBuffer projMatrix,
+                              IntBuffer viewport,
+                              DoubleBuffer obj_pos) {
+    DoubleBuffer in = this.inBuf;
+    DoubleBuffer out = this.outBuf;
+
+    __gluMultMatricesd(modelMatrix, projMatrix, matrixBuf);
+
+    if (!__gluInvertMatrixd(matrixBuf, matrixBuf))
+      return false;
+
+    in.put(0, winx);
+    in.put(1, winy);
+    in.put(2, winz);
+    in.put(3, 1.0);
+
+    // Map x and y from window coordinates
+    int vPos = viewport.position();
+    int oPos = obj_pos.position();
+    in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+    in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+
+    // Map to range -1 to 1
+    in.put(0, in.get(0) * 2 - 1);
+    in.put(1, in.get(1) * 2 - 1);
+    in.put(2, in.get(2) * 2 - 1);
+
+    __gluMultMatrixVecd(matrixBuf, in, out);
+
+    if (out.get(3) == 0.0)
+      return false;
+
+    out.put(3, 1.0 / out.get(3));
+
+    obj_pos.put(0+oPos, out.get(0) * out.get(3));
+    obj_pos.put(1+oPos, out.get(1) * out.get(3));
+    obj_pos.put(2+oPos, out.get(2) * out.get(3));
+
+    return true;
+  }
+
+
+  /**
+   * Method gluUnproject4
+   * 
+   * @param winx
+   * @param winy
+   * @param winz
+   * @param clipw
+   * @param modelMatrix
+   * @param projMatrix
+   * @param viewport
+   * @param near
+   * @param far
+   * @param obj_pos
+   * 
+   * @return
+   */
+  public boolean gluUnProject4(double winx,
+                               double winy,
+                               double winz,
+                               double clipw,
+                               double[] modelMatrix,
+                               int modelMatrix_offset,
+                               double[] projMatrix,
+                               int projMatrix_offset,
+                               int[] viewport,
+                               int viewport_offset,
+                               double near,
+                               double far,
+                               double[] obj_pos,
+                               int obj_pos_offset ) {
+    double[] in = this.in;
+    double[] out = this.out;
+
+    __gluMultMatricesd(modelMatrix, modelMatrix_offset, projMatrix, projMatrix_offset, matrix);
+
+    if (!__gluInvertMatrixd(matrix, matrix))
+      return false;
+
+    in[0] = winx;
+    in[1] = winy;
+    in[2] = winz;
+    in[3] = clipw;
+
+    // Map x and y from window coordinates
+    in[0] = (in[0] - viewport[0+viewport_offset]) / viewport[2+viewport_offset];
+    in[1] = (in[1] - viewport[1+viewport_offset]) / viewport[3+viewport_offset];
+    in[2] = (in[2] - near) / (far - near);
+
+    // Map to range -1 to 1
+    in[0] = in[0] * 2 - 1;
+    in[1] = in[1] * 2 - 1;
+    in[2] = in[2] * 2 - 1;
+
+    __gluMultMatrixVecd(matrix, 0, in, out);
+
+    if (out[3] == 0.0)
+      return false;
+
+    obj_pos[0+obj_pos_offset] = out[0];
+    obj_pos[1+obj_pos_offset] = out[1];
+    obj_pos[2+obj_pos_offset] = out[2];
+    obj_pos[3+obj_pos_offset] = out[3];
+    return true;
+  }
+
+  /**
+   * Method gluUnproject4
+   * 
+   * @param winx
+   * @param winy
+   * @param winz
+   * @param clipw
+   * @param modelMatrix
+   * @param projMatrix
+   * @param viewport
+   * @param near
+   * @param far
+   * @param obj_pos
+   * 
+   * @return
+   */
+  public boolean gluUnProject4(double winx,
+                               double winy,
+                               double winz,
+                               double clipw,
+                               DoubleBuffer modelMatrix,
+                               DoubleBuffer projMatrix,
+                               IntBuffer viewport,
+                               double near,
+                               double far,
+                               DoubleBuffer obj_pos) {
+    DoubleBuffer in = this.inBuf;
+    DoubleBuffer out = this.outBuf;
+
+    __gluMultMatricesd(modelMatrix, projMatrix, matrixBuf);
+
+    if (!__gluInvertMatrixd(matrixBuf, matrixBuf))
+      return false;
+
+    in.put(0, winx);
+    in.put(1, winy);
+    in.put(2, winz);
+    in.put(3, clipw);
+
+    // Map x and y from window coordinates
+    int vPos = viewport.position();
+    in.put(0, (in.get(0) - viewport.get(0+vPos)) / viewport.get(2+vPos));
+    in.put(1, (in.get(1) - viewport.get(1+vPos)) / viewport.get(3+vPos));
+    in.put(2, (in.get(2) - near) / (far - near));
+
+    // Map to range -1 to 1
+    in.put(0, in.get(0) * 2 - 1);
+    in.put(1, in.get(1) * 2 - 1);
+    in.put(2, in.get(2) * 2 - 1);
+
+    __gluMultMatrixVecd(matrixBuf, in, out);
+
+    if (out.get(3) == 0.0)
+      return false;
+
+    int oPos = obj_pos.position();
+    obj_pos.put(0+oPos, out.get(0));
+    obj_pos.put(1+oPos, out.get(1));
+    obj_pos.put(2+oPos, out.get(2));
+    obj_pos.put(3+oPos, out.get(3));
+    return true;
+  }
+
+
+  /**
+   * Method gluPickMatrix
+   * 
+   * @param x
+   * @param y
+   * @param deltaX
+   * @param deltaY
+   * @param viewport
+   */
+  public void gluPickMatrix(GL2 gl,
+                            double x,
+                            double y,
+                            double deltaX,
+                            double deltaY,
+                            IntBuffer viewport) {
+    if (deltaX <= 0 || deltaY <= 0) {
+      return;
+    }
+
+    /* Translate and scale the picked region to the entire window */
+    int vPos = viewport.position();
+    gl.glTranslated((viewport.get(2+vPos) - 2 * (x - viewport.get(0+vPos))) / deltaX,
+                    (viewport.get(3+vPos) - 2 * (y - viewport.get(1+vPos))) / deltaY,
+                    0);
+    gl.glScaled(viewport.get(2) / deltaX, viewport.get(3) / deltaY, 1.0);
+  }
+
+  /**
+   * Method gluPickMatrix
+   * 
+   * @param x
+   * @param y
+   * @param deltaX
+   * @param deltaY
+   * @param viewport
+   * @param viewport_offset
+   */
+  public void gluPickMatrix(GL2 gl,
+                            double x,
+                            double y,
+                            double deltaX,
+                            double deltaY,
+                            int[] viewport,
+                            int viewport_offset) {
+    if (deltaX <= 0 || deltaY <= 0) {
+      return;
+    }
+
+    /* Translate and scale the picked region to the entire window */
+    gl.glTranslated((viewport[2+viewport_offset] - 2 * (x - viewport[0+viewport_offset])) / deltaX,
+                    (viewport[3+viewport_offset] - 2 * (y - viewport[1+viewport_offset])) / deltaY,
+                    0);
+    gl.glScaled(viewport[2+viewport_offset] / deltaX, viewport[3+viewport_offset] / deltaY, 1.0);
+  }
+}
diff --git a/src/jogl/classes/jogamp/opengl/gl2/Util.java b/src/jogl/classes/jogamp/opengl/gl2/Util.java
new file mode 100644
index 000000000..a542dcf19
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/gl2/Util.java
@@ -0,0 +1,244 @@
+/* 
+ * Copyright (c) 2002-2004 LWJGL Project
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are 
+ * met:
+ * 
+ * * Redistributions of source code must retain the above copyright 
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'LWJGL' nor the names of 
+ *   its contributors may be used to endorse or promote products derived 
+ *   from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * 
+ * - Redistribution in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * 
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * 
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.opengl.impl.gl2;
+
+import com.jogamp.opengl.impl.*;
+
+import java.nio.IntBuffer;
+import javax.media.opengl.*;
+
+/**
+ * Util.java
+ * <p/>
+ * <p/>
+ * Created 7-jan-2004
+ *
+ * @author Erik Duijs
+ */
+class Util {
+
+  /**
+   * temp int[] of one for getting an int from some GL functions
+   */
+  private int[] scratch = new int[1];
+
+  /**
+   * Return ceiling of integer division
+   *
+   * @param a
+   * @param b
+   *
+   * @return int
+   */
+  protected static int ceil(int a, int b) {
+    return (a % b == 0 ? a / b : a / b + 1);
+  }
+
+  /**
+   * Method compPerPix.
+   *
+   * @param format
+   *
+   * @return int
+   */
+  protected static int compPerPix(int format) {
+    /* Determine number of components per pixel */
+    switch ( format ) {
+    case GL2.GL_COLOR_INDEX:
+    case GL2.GL_STENCIL_INDEX:
+    case GL2.GL_DEPTH_COMPONENT:
+    case GL2.GL_RED:
+    case GL2.GL_GREEN:
+    case GL2.GL_BLUE:
+    case GL2.GL_ALPHA:
+    case GL2.GL_LUMINANCE:
+      return 1;
+    case GL2.GL_LUMINANCE_ALPHA:
+      return 2;
+    case GL2.GL_RGB:
+    case GL2.GL_BGR:
+      return 3;
+    case GL2.GL_RGBA:
+    case GL2.GL_BGRA:
+      return 4;
+    default :
+      return -1;
+    }
+  }
+
+  /**
+   * Method nearestPower.
+   * <p/>
+   * Compute the nearest power of 2 number.  This algorithm is a little strange, but it works quite well.
+   *
+   * @param value
+   *
+   * @return int
+   */
+  protected static int nearestPower(int value) {
+    int i;
+
+    i = 1;
+
+    /* Error! */
+    if ( value == 0 )
+      return -1;
+
+    for ( ; ; ) {
+      if ( value == 1 ) {
+        return i;
+      } else if ( value == 3 ) {
+        return i << 2;
+      }
+      value >>= 1;
+      i <<= 1;
+    }
+  }
+
+  /**
+   * Method bytesPerPixel.
+   *
+   * @param format
+   * @param type
+   *
+   * @return int
+   */
+  protected static int bytesPerPixel(int format, int type) {
+    int n, m;
+
+    switch ( format ) {
+    case GL2.GL_COLOR_INDEX:
+    case GL2.GL_STENCIL_INDEX:
+    case GL2.GL_DEPTH_COMPONENT:
+    case GL2.GL_RED:
+    case GL2.GL_GREEN:
+    case GL2.GL_BLUE:
+    case GL2.GL_ALPHA:
+    case GL2.GL_LUMINANCE:
+      n = 1;
+      break;
+    case GL2.GL_LUMINANCE_ALPHA:
+      n = 2;
+      break;
+    case GL2.GL_RGB:
+    case GL2.GL_BGR:
+      n = 3;
+      break;
+    case GL2.GL_RGBA:
+    case GL2.GL_BGRA:
+      n = 4;
+      break;
+    default :
+      n = 0;
+    }
+
+    switch ( type ) {
+    case GL2.GL_UNSIGNED_BYTE:
+      m = 1;
+      break;
+    case GL2.GL_BYTE:
+      m = 1;
+      break;
+    case GL2.GL_BITMAP:
+      m = 1;
+      break;
+    case GL2.GL_UNSIGNED_SHORT:
+      m = 2;
+      break;
+    case GL2.GL_SHORT:
+      m = 2;
+      break;
+    case GL2.GL_UNSIGNED_INT:
+      m = 4;
+      break;
+    case GL2.GL_INT:
+      m = 4;
+      break;
+    case GL2.GL_FLOAT:
+      m = 4;
+      break;
+    default :
+      m = 0;
+    }
+
+    return n * m;
+  }
+
+  /**
+   * Convenience method for returning an int, rather than getting it out of a buffer yourself.
+   *
+   * @param what
+   *
+   * @return int
+   */
+  protected int glGetIntegerv(GL gl, int what) {
+    gl.glGetIntegerv(what, scratch, 0);
+    return scratch[0];
+  }
+}
diff --git a/src/jogl/classes/jogamp/opengl/gl2/fixme/GLObjectTracker.java b/src/jogl/classes/jogamp/opengl/gl2/fixme/GLObjectTracker.java
new file mode 100644
index 000000000..6ee29b876
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/gl2/fixme/GLObjectTracker.java
@@ -0,0 +1,835 @@
+/*
+ * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ * - Redistribution of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * 
+ * - Redistribution in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * 
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ * 
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ * 
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.opengl.impl.gl2;
+
+import com.jogamp.opengl.impl.*;
+
+import java.nio.*;
+import javax.media.opengl.*;
+
+/** 
+ * Tracks the creation of server-side OpenGL objects which can be
+ * shared between contexts. Ordinarily, when an OpenGL context is
+ * deleted and no other contexts are sharing server-side objects with
+ * it, all of the server-side objects are automatically deleted by the
+ * OpenGL implementation. It is not necessary for the end user to
+ * explicitly delete these objects. However, when the Java2D/OpenGL
+ * pipeline is active and frame buffer objects are being used for
+ * rendering, it is necessary for all OpenGL contexts created by JOGL
+ * to share server-side objects with the Java2D OpenGL context. This
+ * means that these objects "leak" into the namespace used by Java2D.
+ * In order to prevent memory leaks and to present the same
+ * programming model to the end user, it is necessary to track the
+ * creation and destruction of all of these server-side OpenGL objects
+ * and to explicitly release them when all of the JOGL-created
+ * contexts which can see them have been released. <P>
+ *
+ * The {@link #ref ref} and {@link #unref unref} methods should be
+ * used during the creation and destruction of OpenGL contexts by JOGL
+ * in order to update the liveness of the objects being tracked. The
+ * various other methods should be called by the OpenGL binding in the
+ * various named methods.
+ */
+
+public class GLObjectTracker {
+  private static final boolean DEBUG = Debug.debug("GLStatusTracker");
+
+  //----------------------------------------------------------------------
+  // Adders
+  //
+
+  // glGenBuffers
+  public synchronized void addBuffers(int n, IntBuffer ids) {
+    add(getList(BUFFERS), n, ids);
+  }
+
+  // glGenBuffers
+  public synchronized void addBuffers(int n, int[] ids, int ids_offset) {
+    add(getList(BUFFERS), n, ids, ids_offset);
+  }
+
+  // glGenBuffersARB
+  public synchronized void addBuffersARB(int n, IntBuffer ids) {
+    add(getList(BUFFERS_ARB), n, ids);
+  }
+
+  // glGenBuffersARB
+  public synchronized void addBuffersARB(int n, int[] ids, int ids_offset) {
+    add(getList(BUFFERS_ARB), n, ids, ids_offset);
+  }
+
+  // glGenFencesAPPLE
+  public synchronized void addFencesAPPLE(int n, IntBuffer ids) {
+    add(getList(FENCES_APPLE), n, ids);
+  }
+
+  // glGenFencesAPPLE
+  public synchronized void addFencesAPPLE(int n, int[] ids, int ids_offset) {
+    add(getList(FENCES_APPLE), n, ids, ids_offset);
+  }
+
+  // glGenFencesNV
+  public synchronized void addFencesNV(int n, IntBuffer ids) {
+    add(getList(FENCES_NV), n, ids);
+  }
+
+  // glGenFencesNV
+  public synchronized void addFencesNV(int n, int[] ids, int ids_offset) {
+    add(getList(FENCES_NV), n, ids, ids_offset);
+  }
+
+  // glGenFragmentShadersATI
+  public synchronized void addFragmentShadersATI(int start, int n) {
+    add(getList(FRAGMENT_SHADERS_ATI), start, n);
+  }
+
+  // glGenFramebuffersEXT
+  public synchronized void addFramebuffersEXT(int n, IntBuffer ids) {
+    add(getList(FRAMEBUFFERS_EXT), n, ids);
+  }
+
+  // glGenFramebuffersEXT
+  public synchronized void addFramebuffersEXT(int n, int[] ids, int ids_offset) {
+    add(getList(FRAMEBUFFERS_EXT), n, ids, ids_offset);
+  }
+  
+  // glGenLists
+  public synchronized void addLists(int start, int n) {
+    add(getList(LISTS), start, n);
+  }
+
+  // glGenOcclusionQueriesNV
+  public synchronized void addOcclusionQueriesNV(int n, IntBuffer ids) {
+    add(getList(OCCLUSION_QUERIES_NV), n, ids);
+  }
+
+  // glGenOcclusionQueriesNV
+  public synchronized void addOcclusionQueriesNV(int n, int[] ids, int ids_offset) {
+    add(getList(OCCLUSION_QUERIES_NV), n, ids, ids_offset);
+  }
+
+  // glCreateProgram
+  public synchronized void addProgramObject(int obj) {
+    add(getList(PROGRAM_OBJECTS), obj, 1);
+  }
+
+  // glCreateProgramObjectARB
+  public synchronized void addProgramObjectARB(int obj) {
+    add(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+  }
+
+  // glGenProgramsARB
+  public synchronized void addProgramsARB(int n, IntBuffer ids) {
+    add(getList(PROGRAMS_ARB), n, ids);
+  }
+
+  // glGenProgramsARB
+  public synchronized void addProgramsARB(int n, int[] ids, int ids_offset) {
+    add(getList(PROGRAMS_ARB), n, ids, ids_offset);
+  }
+
+  // glGenProgramsNV
+  public synchronized void addProgramsNV(int n, IntBuffer ids) {
+    add(getList(PROGRAMS_NV), n, ids);
+  }
+
+  // glGenProgramsNV
+  public synchronized void addProgramsNV(int n, int[] ids, int ids_offset) {
+    add(getList(PROGRAMS_NV), n, ids, ids_offset);
+  }
+
+  // glGenQueries
+  public synchronized void addQueries(int n, IntBuffer ids) {
+    add(getList(QUERIES), n, ids);
+  }
+
+  // glGenQueries
+  public synchronized void addQueries(int n, int[] ids, int ids_offset) {
+    add(getList(QUERIES), n, ids, ids_offset);
+  }
+
+  // glGenQueriesARB
+  public synchronized void addQueriesARB(int n, IntBuffer ids) {
+    add(getList(QUERIES_ARB), n, ids);
+  }
+
+  // glGenQueriesARB
+  public synchronized void addQueriesARB(int n, int[] ids, int ids_offset) {
+    add(getList(QUERIES_ARB), n, ids, ids_offset);
+  }
+
+  // glGenRenderbuffersEXT
+  public synchronized void addRenderbuffersEXT(int n, IntBuffer ids) {
+    add(getList(RENDERBUFFERS_EXT), n, ids);
+  }
+
+  // glGenRenderbuffersEXT
+  public synchronized void addRenderbuffersEXT(int n, int[] ids, int ids_offset) {
+    add(getList(RENDERBUFFERS_EXT), n, ids, ids_offset);
+  }
+
+  // glCreateShader
+  public synchronized void addShaderObject(int obj) {
+    add(getList(SHADER_OBJECTS), obj, 1);
+  }
+
+  // glCreateShaderObjectARB
+  public synchronized void addShaderObjectARB(int obj) {
+    add(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+  }
+
+  // glGenTextures
+  public synchronized void addTextures(int n, IntBuffer ids) {
+    add(getList(TEXTURES), n, ids);
+  }
+
+  // glGenTextures
+  public synchronized void addTextures(int n, int[] ids, int ids_offset) {
+    add(getList(TEXTURES), n, ids, ids_offset);
+  }
+
+  // glGenVertexArraysAPPLE
+  public synchronized void addVertexArraysAPPLE(int n, IntBuffer ids) {
+    add(getList(VERTEX_ARRAYS_APPLE), n, ids);
+  }
+
+  // glGenVertexArraysAPPLE
+  public synchronized void addVertexArraysAPPLE(int n, int[] ids, int ids_offset) {
+    add(getList(VERTEX_ARRAYS_APPLE), n, ids, ids_offset);
+  }
+
+  // glGenVertexShadersEXT
+  public synchronized void addVertexShadersEXT(int start, int n) {
+    add(getList(VERTEX_SHADERS_EXT), start, n);
+  }
+
+  //----------------------------------------------------------------------
+  // Removers
+  //
+
+  // glDeleteBuffers
+  public synchronized void removeBuffers(int n, IntBuffer ids) {
+    remove(getList(BUFFERS), n, ids);
+  }
+
+  // glDeleteBuffers
+  public synchronized void removeBuffers(int n, int[] ids, int ids_offset) {
+    remove(getList(BUFFERS), n, ids, ids_offset);
+  }
+
+  // glDeleteBuffersARB
+  public synchronized void removeBuffersARB(int n, IntBuffer ids) {
+    remove(getList(BUFFERS_ARB), n, ids);
+  }
+
+  // glDeleteBuffersARB
+  public synchronized void removeBuffersARB(int n, int[] ids, int ids_offset) {
+    remove(getList(BUFFERS_ARB), n, ids, ids_offset);
+  }
+
+  // glDeleteFencesAPPLE
+  public synchronized void removeFencesAPPLE(int n, IntBuffer ids) {
+    remove(getList(FENCES_APPLE), n, ids);
+  }
+
+  // glDeleteFencesAPPLE
+  public synchronized void removeFencesAPPLE(int n, int[] ids, int ids_offset) {
+    remove(getList(FENCES_APPLE), n, ids, ids_offset);
+  }
+
+  // glDeleteFencesNV
+  public synchronized void removeFencesNV(int n, IntBuffer ids) {
+    remove(getList(FENCES_NV), n, ids);
+  }
+
+  // glDeleteFencesNV
+  public synchronized void removeFencesNV(int n, int[] ids, int ids_offset) {
+    remove(getList(FENCES_NV), n, ids, ids_offset);
+  }
+
+  // glDeleteFragmentShaderATI
+  public synchronized void removeFragmentShaderATI(int obj) {
+    remove(getList(FRAGMENT_SHADERS_ATI), obj, 1);
+  }
+
+  // glDeleteFramebuffersEXT
+  public synchronized void removeFramebuffersEXT(int n, IntBuffer ids) {
+    remove(getList(FRAMEBUFFERS_EXT), n, ids);
+  }
+
+  // glDeleteFramebuffersEXT
+  public synchronized void removeFramebuffersEXT(int n, int[] ids, int ids_offset) {
+    remove(getList(FRAMEBUFFERS_EXT), n, ids, ids_offset);
+  }
+  
+  // glDeleteLists
+  public synchronized void removeLists(int start, int n) {
+    remove(getList(LISTS), start, n);
+  }
+
+  // glDeleteOcclusionQueriesNV
+  public synchronized void removeOcclusionQueriesNV(int n, IntBuffer ids) {
+    remove(getList(OCCLUSION_QUERIES_NV), n, ids);
+  }
+
+  // glDeleteOcclusionQueriesNV
+  public synchronized void removeOcclusionQueriesNV(int n, int[] ids, int ids_offset) {
+    remove(getList(OCCLUSION_QUERIES_NV), n, ids, ids_offset);
+  }
+
+  // glDeleteProgram
+  public synchronized void removeProgramObject(int obj) {
+    remove(getList(PROGRAM_OBJECTS), obj, 1);
+  }
+
+  // glDeleteObjectARB
+  public synchronized void removeProgramOrShaderObjectARB(int obj) {
+    remove(getList(PROGRAM_AND_SHADER_OBJECTS_ARB), obj, 1);
+  }
+
+  // glDeleteProgramsARB
+  public synchronized void removeProgramsARB(int n, IntBuffer ids) {
+    remove(getList(PROGRAMS_ARB), n, ids);
+  }
+
+  // glDeleteProgramsARB
+  public synchronized void removeProgramsARB(int n, int[] ids, int ids_offset) {
+    remove(getList(PROGRAMS_ARB), n, ids, ids_offset);
+  }
+
+  // glDeleteProgramsNV
+  public synchronized void removeProgramsNV(int n, IntBuffer ids) {
+    remove(getList(PROGRAMS_NV), n, ids);
+  }
+
+  // glDeleteProgramsNV
+  public synchronized void removeProgramsNV(int n, int[] ids, int ids_offset) {
+    remove(getList(PROGRAMS_NV), n, ids, ids_offset);
+  }
+
+  // glDeleteQueries
+  public synchronized void removeQueries(int n, IntBuffer ids) {
+    remove(getList(QUERIES), n, ids);
+  }
+
+  // glDeleteQueries
+  public synchronized void removeQueries(int n, int[] ids, int ids_offset) {
+    remove(getList(QUERIES), n, ids, ids_offset);
+  }
+
+  // glDeleteQueriesARB
+  public synchronized void removeQueriesARB(int n, IntBuffer ids) {
+    remove(getList(QUERIES_ARB), n, ids);
+  }
+
+  // glDeleteQueriesARB
+  public synchronized void removeQueriesARB(int n, int[] ids, int ids_offset) {
+    remove(getList(QUERIES_ARB), n, ids, ids_offset);
+  }
+
+  // glDeleteRenderbuffersEXT
+  public synchronized void removeRenderbuffersEXT(int n, IntBuffer ids) {
+    remove(getList(RENDERBUFFERS_EXT), n, ids);
+  }
+
+  // glDeleteRenderbuffersEXT
+  public synchronized void removeRenderbuffersEXT(int n, int[] ids, int ids_offset) {
+    remove(getList(RENDERBUFFERS_EXT), n, ids, ids_offset);
+  }
+
+  // glDeleteShader
+  public synchronized void removeShaderObject(int obj) {
+    remove(getList(SHADER_OBJECTS), obj, 1);
+  }
+
+  // glDeleteTextures
+  public synchronized void removeTextures(int n, IntBuffer ids) {
+    remove(getList(TEXTURES), n, ids);
+  }
+
+  // glDeleteTextures
+  public synchronized void removeTextures(int n, int[] ids, int ids_offset) {
+    remove(getList(TEXTURES), n, ids, ids_offset);
+  }
+
+  // glDeleteVertexArraysAPPLE
+  public synchronized void removeVertexArraysAPPLE(int n, IntBuffer ids) {
+    remove(getList(VERTEX_ARRAYS_APPLE), n, ids);
+  }
+
+  // glDeleteVertexArraysAPPLE
+  public synchronized void removeVertexArraysAPPLE(int n, int[] ids, int ids_offset) {
+    remove(getList(VERTEX_ARRAYS_APPLE), n, ids, ids_offset);
+  }
+
+  // glDeleteVertexShaderEXT
+  public synchronized void removeVertexShaderEXT(int obj) {
+    remove(getList(VERTEX_SHADERS_EXT), obj, 1);
+  }
+
+  //----------------------------------------------------------------------
+  // Reference count maintenance and manual deletion
+  //
+
+  public synchronized void transferAll(GLObjectTracker other) {
+    for (int i = 0; i < lists.length; i++) {
+      getList(i).addAll(other.lists[i]);
+      if (other.lists[i] != null) {
+        other.lists[i].clear();
+      }
+    }
+    dirty = true;
+  }
+
+  public synchronized void ref() {
+    ++refCount;
+  }
+
+  public void unref(GLObjectTracker deletedObjectPool) {
+    boolean tryDelete = false;
+    synchronized (this) {
+      if (--refCount == 0) {
+        tryDelete = true;
+      }
+    }
+    if (tryDelete) {
+      // See whether we should try to do the work now or whether we
+      // have to postpone
+      GLContext cur = GLContext.getCurrent();
+      if ((cur != null) &&
+          (cur instanceof GLContextImpl)) {
+        GLContextImpl curImpl = (GLContextImpl) cur;
+        if (deletedObjectPool != null &&
+            deletedObjectPool == curImpl.getDeletedObjectTracker()) {
+          // Should be safe to delete these objects now
+          try {
+            delete((GL2)curImpl.getGL());
+            return;
+          } catch (GLException e) {
+            // Shouldn't happen, but if it does, transfer all objects
+            // to the deleted object pool hoping we can later clean
+            // them up
+            deletedObjectPool.transferAll(this);
+            throw(e);
+          }
+        }
+      }
+      // If we get here, we couldn't attempt to delete the objects
+      // right now; instead try to transfer them to the
+      // deletedObjectPool for later cleanup (FIXME: should consider
+      // throwing an exception if deletedObjectPool is null, since
+      // that shouldn't happen)
+      if (DEBUG) {
+        String s = null;
+        if (cur == null) {
+          s = "current context was null";
+        } else if (!(cur instanceof GLContextImpl)) {
+          s = "current context was not a GLContextImpl";
+        } else if (deletedObjectPool == null) {
+          s = "no current deletedObjectPool";
+        } else if (deletedObjectPool != ((GLContextImpl) cur).getDeletedObjectTracker()) {
+          s = "deletedObjectTracker didn't match";
+          if (((GLContextImpl) cur).getDeletedObjectTracker() == null) {
+            s += " (other was null)";
+          }
+        } else {
+          s = "unknown reason";
+        }
+        System.err.println("Deferred destruction of server-side OpenGL objects into " + deletedObjectPool + ": " + s);
+      }
+
+      if (deletedObjectPool != null) {
+        deletedObjectPool.transferAll(this);
+      }
+    }
+  }
+
+  public void clean(GL2 gl) {
+    if (dirty) {
+      try {
+        delete(gl);
+        dirty = false;
+      } catch (GLException e) {
+        // FIXME: not sure what to do here; probably a bad idea to be
+        // throwing exceptions during an otherwise-successful makeCurrent
+      }
+    }
+  }
+
+
+  //----------------------------------------------------------------------
+  // Internals only below this point
+  //
+
+  // Kinds of sharable server-side OpenGL objects this class tracks
+  private static final int BUFFERS                        = 0;
+  private static final int BUFFERS_ARB                    = 1;
+  private static final int FENCES_APPLE                   = 2;
+  private static final int FENCES_NV                      = 3;
+  private static final int FRAGMENT_SHADERS_ATI           = 4;
+  private static final int FRAMEBUFFERS_EXT               = 5;
+  private static final int LISTS                          = 6;
+  private static final int OCCLUSION_QUERIES_NV           = 7;
+  private static final int PROGRAM_AND_SHADER_OBJECTS_ARB = 8;
+  private static final int PROGRAM_OBJECTS                = 9;
+  private static final int PROGRAMS_ARB                   = 10;
+  private static final int PROGRAMS_NV                    = 11;
+  private static final int QUERIES                        = 12;
+  private static final int QUERIES_ARB                    = 13;
+  private static final int RENDERBUFFERS_EXT              = 14;
+  private static final int SHADER_OBJECTS                 = 15;
+  private static final int TEXTURES                       = 16;
+  private static final int VERTEX_ARRAYS_APPLE            = 17;
+  private static final int VERTEX_SHADERS_EXT             = 18;
+  private static final int NUM_OBJECT_TYPES               = 19;
+
+  static abstract class Deleter {
+    public abstract void delete(GL2 gl, int obj);
+  }
+
+  static class ObjectList {
+    private static final int MIN_CAPACITY = 4;
+
+    private int size;
+    private int capacity;
+    private int[] data;
+    private Deleter deleter;
+    private String name;
+
+    public ObjectList(Deleter deleter) {
+      this.deleter = deleter;
+      clear();
+    }
+
+    public void add(int obj) {
+      if (size == capacity) {
+        int newCapacity = 2 * capacity;
+        int[] newData = new int[newCapacity];
+        System.arraycopy(data, 0, newData, 0, size);
+        data = newData;
+        capacity = newCapacity;
+      }
+
+      data[size++] = obj;
+    }
+
+    public void addAll(ObjectList other) {
+      if (other == null) {
+        return;
+      }
+      for (int i = 0; i < other.size; i++) {
+        add(other.data[i]);
+      }
+    }
+
+    public boolean remove(int value) {
+      for (int i = 0; i < size; i++) {
+        if (data[i] == value) {
+          if (i < size - 1) {
+            System.arraycopy(data, i+1, data, i, size - i - 1);
+          }
+          --size;
+          if ((size < capacity / 4) &&
+              (capacity > MIN_CAPACITY)) {
+            int newCapacity = capacity / 4;
+            if (newCapacity < MIN_CAPACITY) {
+              newCapacity = MIN_CAPACITY;
+            }
+            int[] newData = new int[newCapacity];
+            System.arraycopy(data, 0, newData, 0, size);
+            data = newData;
+            capacity = newCapacity;
+          }
+          return true;
+        }
+      }
+      return false;
+    }
+
+    public void setName(String name) {
+      if (DEBUG) {
+        this.name = name;
+      }
+    }
+
+    public void delete(GL2 gl) {
+      // Just in case we start throwing exceptions during deletion,
+      // make sure we make progress rather than going into an infinite
+      // loop
+      while (size > 0) {
+        int obj = data[size - 1];
+        --size;
+        if (DEBUG) {
+          System.err.println("Deleting server-side OpenGL object " + obj +
+                             ((name != null) ? (" (" + name + ")") : ""));
+        }
+        deleter.delete(gl, obj);
+      }
+    }
+
+    public void clear() {
+      size = 0;
+      capacity = MIN_CAPACITY;
+      data = new int[capacity];
+    }
+  }
+
+  private ObjectList[] lists = new ObjectList[NUM_OBJECT_TYPES];
+  private int refCount;
+  private boolean dirty;
+
+  private void add(ObjectList list, int n, IntBuffer ids) {
+    int pos = ids.position();
+    for (int i = 0; i < n; i++) {
+      list.add(ids.get(pos + i));
+    }
+  }
+
+  private void add(ObjectList list, int n, int[] ids, int ids_offset) {
+    for (int i = 0; i < n; i++) {
+      list.add(ids[i + ids_offset]);
+    }
+  }
+
+  private void add(ObjectList list, int start, int n) {
+    for (int i = 0; i < n; i++) {
+      list.add(start + i);
+    }
+  }
+
+  private void remove(ObjectList list, int n, IntBuffer ids) {
+    int pos = ids.position();
+    for (int i = 0; i < n; i++) {
+      list.remove(ids.get(pos + i));
+    }
+  }
+
+  private void remove(ObjectList list, int n, int[] ids, int ids_offset) {
+    for (int i = 0; i < n; i++) {
+      list.remove(ids[i + ids_offset]);
+    }
+  }
+
+  private void remove(ObjectList list, int start, int n) {
+    for (int i = 0; i < n; i++) {
+      list.remove(start + i);
+    }
+  }
+
+  private ObjectList getList(int which) {
+    ObjectList list = lists[which];
+    if (list == null) {
+      Deleter deleter = null;
+      String name = null;
+      // Figure out which deleter we need
+      switch (which) {
+        case BUFFERS:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteBuffers(1, new int[] { obj }, 0);
+              }
+            };
+          name = "buffer";
+          break;
+        case BUFFERS_ARB:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteBuffersARB(1, new int[] { obj }, 0);
+              }
+            };
+          name = "ARB buffer";
+          break;
+        case FENCES_APPLE:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteFencesAPPLE(1, new int[] { obj }, 0);
+              }
+            };
+          name = "APPLE fence";
+          break;
+        case FENCES_NV:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteFencesNV(1, new int[] { obj }, 0);
+              }
+            };
+          name = "NV fence";
+          break;
+        case FRAGMENT_SHADERS_ATI:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteFragmentShaderATI(obj);
+              }
+            };
+          name = "ATI fragment shader";
+          break;
+        case FRAMEBUFFERS_EXT:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteFramebuffersEXT(1, new int[] { obj }, 0);
+              }
+            };
+          name = "EXT framebuffer";
+          break;
+        case LISTS:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteLists(obj, 1);
+              }
+            };
+          name = "display list";
+          break;
+        case OCCLUSION_QUERIES_NV:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteOcclusionQueriesNV(1, new int[] { obj }, 0);
+              }
+            };
+          name = "NV occlusion query";
+          break;
+        case PROGRAM_AND_SHADER_OBJECTS_ARB:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteObjectARB(obj);
+              }
+            };
+          name = "ARB program or shader object";
+          break;
+        case PROGRAM_OBJECTS:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteProgram(obj);
+              }
+            };
+          name = "program object";
+          break;
+        case PROGRAMS_ARB:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteProgramsARB(1, new int[] { obj }, 0);
+              }
+            };
+          name = "ARB program object";
+          break;
+        case PROGRAMS_NV:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteProgramsNV(1, new int[] { obj }, 0);
+              }
+            };
+          name = "NV program";
+          break;
+        case QUERIES:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteQueries(1, new int[] { obj }, 0);
+              }
+            };
+          name = "query";
+          break;
+        case QUERIES_ARB:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteQueriesARB(1, new int[] { obj }, 0);
+              }
+            };
+          name = "ARB query";
+          break;
+        case RENDERBUFFERS_EXT:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteRenderbuffersEXT(1, new int[] { obj }, 0);
+              }
+            };
+          name = "EXT renderbuffer";
+          break;
+        case SHADER_OBJECTS:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteShader(obj);
+              }
+            };
+          name = "shader object";
+          break;
+        case TEXTURES:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteTextures(1, new int[] { obj }, 0);
+              }
+            };
+          name = "texture";
+          break;
+        case VERTEX_ARRAYS_APPLE:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteVertexArraysAPPLE(1, new int[] { obj }, 0);
+              }
+            };
+          name = "APPLE vertex array";
+          break;
+        case VERTEX_SHADERS_EXT:
+          deleter = new Deleter() {
+              public void delete(GL2 gl, int obj) {
+                gl.glDeleteVertexShaderEXT(obj);
+              }
+            };
+          name = "EXT vertex shader";
+          break;
+        default:
+          throw new InternalError("Unexpected OpenGL object type " + which);
+      }
+
+      list = new ObjectList(deleter);
+      list.setName(name);
+      lists[which] = list;
+    }
+    return list;
+  }
+
+  private void delete(GL2 gl) {
+    for (int i = 0; i < lists.length; i++) {
+      ObjectList list = lists[i];
+      if (list != null) {
+        list.delete(gl);
+        lists[i] = null;
+      }
+    }
+  }
+}
-- 
cgit v1.2.3