auto import from //depot/cupcake/@135843
diff --git a/opengl/java/android/opengl/EGLLogWrapper.java b/opengl/java/android/opengl/EGLLogWrapper.java
new file mode 100644
index 0000000..521fc8c
--- /dev/null
+++ b/opengl/java/android/opengl/EGLLogWrapper.java
@@ -0,0 +1,545 @@
+package android.opengl;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import javax.microedition.khronos.egl.EGL;
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGL11;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+
+class EGLLogWrapper implements EGL11 {
+    private EGL10 mEgl10;
+    Writer mLog;
+    boolean mLogArgumentNames;
+    boolean mCheckError;
+    private int mArgCount;
+
+
+    public EGLLogWrapper(EGL egl, int configFlags, Writer log) {
+        mEgl10 = (EGL10) egl;
+        mLog = log;
+        mLogArgumentNames =
+            (GLDebugHelper.CONFIG_LOG_ARGUMENT_NAMES & configFlags) != 0;
+        mCheckError =
+            (GLDebugHelper.CONFIG_CHECK_GL_ERROR & configFlags) != 0;
+    }
+
+    public boolean eglChooseConfig(EGLDisplay display, int[] attrib_list,
+            EGLConfig[] configs, int config_size, int[] num_config) {
+        begin("eglChooseConfig");
+        arg("display", display);
+        arg("attrib_list", attrib_list);
+        arg("config_size", config_size);
+        end();
+
+        boolean result = mEgl10.eglChooseConfig(display, attrib_list, configs,
+                config_size, num_config);
+        arg("configs", configs);
+        arg("num_config", num_config);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglCopyBuffers(EGLDisplay display, EGLSurface surface,
+            Object native_pixmap) {
+        begin("eglCopyBuffers");
+        arg("display", display);
+        arg("surface", surface);
+        arg("native_pixmap", native_pixmap);
+        end();
+
+        boolean result = mEgl10.eglCopyBuffers(display, surface, native_pixmap);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public EGLContext eglCreateContext(EGLDisplay display, EGLConfig config,
+            EGLContext share_context, int[] attrib_list) {
+        begin("eglCreateContext");
+        arg("display", display);
+        arg("config", config);
+        arg("share_context", share_context);
+        arg("attrib_list", attrib_list);
+        end();
+
+        EGLContext result = mEgl10.eglCreateContext(display, config,
+                share_context, attrib_list);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public EGLSurface eglCreatePbufferSurface(EGLDisplay display,
+            EGLConfig config, int[] attrib_list) {
+        begin("eglCreatePbufferSurface");
+        arg("display", display);
+        arg("config", config);
+        arg("attrib_list", attrib_list);
+        end();
+
+        EGLSurface result = mEgl10.eglCreatePbufferSurface(display, config,
+                attrib_list);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public EGLSurface eglCreatePixmapSurface(EGLDisplay display,
+            EGLConfig config, Object native_pixmap, int[] attrib_list) {
+        begin("eglCreatePixmapSurface");
+        arg("display", display);
+        arg("config", config);
+        arg("native_pixmap", native_pixmap);
+        arg("attrib_list", attrib_list);
+        end();
+
+        EGLSurface result = mEgl10.eglCreatePixmapSurface(display, config,
+                native_pixmap, attrib_list);
+        returns(result);
+        checkError();
+        return result;
+        }
+
+    public EGLSurface eglCreateWindowSurface(EGLDisplay display,
+            EGLConfig config, Object native_window, int[] attrib_list) {
+        begin("eglCreateWindowSurface");
+        arg("display", display);
+        arg("config", config);
+        arg("native_window", native_window);
+        arg("attrib_list", attrib_list);
+        end();
+
+        EGLSurface result = mEgl10.eglCreateWindowSurface(display, config,
+                native_window, attrib_list);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglDestroyContext(EGLDisplay display, EGLContext context) {
+        begin("eglDestroyContext");
+        arg("display", display);
+        arg("context", context);
+        end();
+
+        boolean result = mEgl10.eglDestroyContext(display, context);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglDestroySurface(EGLDisplay display, EGLSurface surface) {
+        begin("eglDestroySurface");
+        arg("display", display);
+        arg("surface", surface);
+        end();
+
+        boolean result = mEgl10.eglDestroySurface(display, surface);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglGetConfigAttrib(EGLDisplay display, EGLConfig config,
+            int attribute, int[] value) {
+        begin("eglGetConfigAttrib");
+        arg("display", display);
+        arg("config", config);
+        arg("attribute", attribute);
+        end();
+        boolean result = mEgl10.eglGetConfigAttrib(display, config, attribute,
+                value);
+        arg("value", value);
+        returns(result);
+        checkError();
+        return false;
+    }
+
+    public boolean eglGetConfigs(EGLDisplay display, EGLConfig[] configs,
+            int config_size, int[] num_config) {
+        begin("eglGetConfigs");
+        arg("display", display);
+        arg("config_size", config_size);
+        end();
+
+        boolean result = mEgl10.eglGetConfigs(display, configs, config_size,
+                num_config);
+        arg("configs", configs);
+        arg("num_config", num_config);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public EGLContext eglGetCurrentContext() {
+        begin("eglGetCurrentContext");
+        end();
+
+        EGLContext result = mEgl10.eglGetCurrentContext();
+        returns(result);
+
+        checkError();
+        return result;
+    }
+
+    public EGLDisplay eglGetCurrentDisplay() {
+        begin("eglGetCurrentDisplay");
+        end();
+
+        EGLDisplay result = mEgl10.eglGetCurrentDisplay();
+        returns(result);
+
+        checkError();
+        return result;
+    }
+
+    public EGLSurface eglGetCurrentSurface(int readdraw) {
+        begin("eglGetCurrentSurface");
+        arg("readdraw", readdraw);
+        end();
+
+        EGLSurface result = mEgl10.eglGetCurrentSurface(readdraw);
+        returns(result);
+
+        checkError();
+        return result;
+    }
+
+    public EGLDisplay eglGetDisplay(Object native_display) {
+        begin("eglGetDisplay");
+        arg("native_display", native_display);
+        end();
+
+        EGLDisplay result = mEgl10.eglGetDisplay(native_display);
+        returns(result);
+
+        checkError();
+        return result;
+    }
+
+    public int eglGetError() {
+        begin("eglGetError");
+        end();
+
+        int result = mEgl10.eglGetError();
+        returns(getErrorString(result));
+
+        return result;
+    }
+
+    public boolean eglInitialize(EGLDisplay display, int[] major_minor) {
+        begin("eglInitialize");
+        arg("display", display);
+        end();
+        boolean result = mEgl10.eglInitialize(display, major_minor);
+        returns(result);
+        arg("major_minor", major_minor);
+        checkError();
+        return result;
+    }
+
+    public boolean eglMakeCurrent(EGLDisplay display, EGLSurface draw,
+            EGLSurface read, EGLContext context) {
+        begin("eglMakeCurrent");
+        arg("display", display);
+        arg("draw", draw);
+        arg("read", read);
+        arg("context", context);
+        end();
+        boolean result = mEgl10.eglMakeCurrent(display, draw, read, context);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglQueryContext(EGLDisplay display, EGLContext context,
+            int attribute, int[] value) {
+        begin("eglQueryContext");
+        arg("display", display);
+        arg("context", context);
+        arg("attribute", attribute);
+        end();
+        boolean result = mEgl10.eglQueryContext(display, context, attribute,
+                value);
+        returns(value[0]);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public String eglQueryString(EGLDisplay display, int name) {
+        begin("eglQueryString");
+        arg("display", display);
+        arg("name", name);
+        end();
+        String result = mEgl10.eglQueryString(display, name);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglQuerySurface(EGLDisplay display, EGLSurface surface,
+            int attribute, int[] value) {
+        begin("eglQuerySurface");
+        arg("display", display);
+        arg("surface", surface);
+        arg("attribute", attribute);
+        end();
+        boolean result = mEgl10.eglQuerySurface(display, surface, attribute,
+                value);
+        returns(value[0]);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglSwapBuffers(EGLDisplay display, EGLSurface surface) {
+        begin("eglInitialize");
+        arg("display", display);
+        arg("surface", surface);
+        end();
+        boolean result = mEgl10.eglSwapBuffers(display, surface);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglTerminate(EGLDisplay display) {
+        begin("eglTerminate");
+        arg("display", display);
+        end();
+        boolean result = mEgl10.eglTerminate(display);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglWaitGL() {
+        begin("eglWaitGL");
+        end();
+        boolean result = mEgl10.eglWaitGL();
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    public boolean eglWaitNative(int engine, Object bindTarget) {
+        begin("eglWaitNative");
+        arg("engine", engine);
+        arg("bindTarget", bindTarget);
+        end();
+        boolean result = mEgl10.eglWaitNative(engine, bindTarget);
+        returns(result);
+        checkError();
+        return result;
+    }
+
+    private void checkError() {
+        int eglError;
+        if ((eglError = mEgl10.eglGetError()) != EGL_SUCCESS) {
+            String errorMessage = "eglError: " + getErrorString(eglError);
+            logLine(errorMessage);
+            if (mCheckError) {
+                throw new GLException(eglError, errorMessage);
+            }
+        }
+    }
+
+    private void logLine(String message) {
+        log(message + '\n');
+    }
+
+    private void log(String message) {
+        try {
+            mLog.write(message);
+        } catch (IOException e) {
+            // Ignore exception, keep on trying
+        }
+    }
+
+    private void begin(String name) {
+        log(name + '(');
+        mArgCount = 0;
+    }
+
+    private void arg(String name, String value) {
+        if (mArgCount++ > 0) {
+            log(", ");
+        }
+        if (mLogArgumentNames) {
+            log(name + "=");
+        }
+        log(value);
+    }
+
+    private void end() {
+        log(");\n");
+        flush();
+    }
+
+    private void flush() {
+        try {
+            mLog.flush();
+        } catch (IOException e) {
+            mLog = null;
+        }
+    }
+
+    private void arg(String name, int value) {
+        arg(name, Integer.toString(value));
+    }
+
+    private void arg(String name, Object object) {
+        arg(name, toString(object));
+    }
+
+    private void arg(String name, EGLDisplay object) {
+        if (object == EGL10.EGL_DEFAULT_DISPLAY) {
+            arg(name, "EGL10.EGL_DEFAULT_DISPLAY");
+        } else if (object == EGL_NO_DISPLAY) {
+            arg(name, "EGL10.EGL_NO_DISPLAY");
+        } else {
+            arg(name, toString(object));
+        }
+    }
+
+    private void arg(String name, EGLContext object) {
+        if (object == EGL10.EGL_NO_CONTEXT) {
+            arg(name, "EGL10.EGL_NO_CONTEXT");
+        } else {
+            arg(name, toString(object));
+        }
+    }
+
+    private void arg(String name, EGLSurface object) {
+        if (object == EGL10.EGL_NO_SURFACE) {
+            arg(name, "EGL10.EGL_NO_SURFACE");
+        } else {
+            arg(name, toString(object));
+        }
+    }
+
+    private void returns(String result) {
+        log(" returns " + result + ";\n");
+        flush();
+    }
+
+    private void returns(int result) {
+        returns(Integer.toString(result));
+    }
+
+    private void returns(boolean result) {
+        returns(Boolean.toString(result));
+    }
+
+    private void returns(Object result) {
+        returns(toString(result));
+    }
+
+    private String toString(Object obj) {
+        if (obj == null) {
+            return "null";
+        } else {
+            return obj.toString();
+        }
+    }
+
+    private void arg(String name, int[] arr) {
+        if (arr == null) {
+            arg(name, "null");
+        } else {
+            arg(name, toString(arr.length, arr, 0));
+        }
+    }
+
+    private void arg(String name, Object[] arr) {
+        if (arr == null) {
+            arg(name, "null");
+        } else {
+            arg(name, toString(arr.length, arr, 0));
+        }
+    }
+
+    private String toString(int n, int[] arr, int offset) {
+        StringBuilder buf = new StringBuilder();
+        buf.append("{\n");
+        int arrLen = arr.length;
+        for (int i = 0; i < n; i++) {
+            int index = offset + i;
+            buf.append(" [" + index + "] = ");
+            if (index < 0 || index >= arrLen) {
+                buf.append("out of bounds");
+            } else {
+                buf.append(arr[index]);
+            }
+            buf.append('\n');
+        }
+        buf.append("}");
+        return buf.toString();
+    }
+
+    private String toString(int n, Object[] arr, int offset) {
+        StringBuilder buf = new StringBuilder();
+        buf.append("{\n");
+        int arrLen = arr.length;
+        for (int i = 0; i < n; i++) {
+            int index = offset + i;
+            buf.append(" [" + index + "] = ");
+            if (index < 0 || index >= arrLen) {
+                buf.append("out of bounds");
+            } else {
+                buf.append(arr[index]);
+            }
+            buf.append('\n');
+        }
+        buf.append("}");
+        return buf.toString();
+    }
+
+    private static String getHex(int value) {
+        return "0x" + Integer.toHexString(value);
+    }
+
+    public static String getErrorString(int error) {
+        switch (error) {
+        case EGL_SUCCESS:
+            return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:
+            return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:
+            return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:
+            return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:
+            return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:
+            return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:
+            return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE:
+            return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:
+            return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:
+            return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP:
+            return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW:
+            return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:
+            return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:
+            return "EGL_BAD_SURFACE";
+        case EGL11.EGL_CONTEXT_LOST:
+            return "EGL_CONTEXT_LOST";
+        default:
+            return getHex(error);
+        }
+    }
+}
diff --git a/opengl/java/android/opengl/GLDebugHelper.java b/opengl/java/android/opengl/GLDebugHelper.java
new file mode 100644
index 0000000..18a1e73
--- /dev/null
+++ b/opengl/java/android/opengl/GLDebugHelper.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.io.Writer;
+
+import javax.microedition.khronos.egl.EGL;
+import javax.microedition.khronos.opengles.GL;
+
+/**
+ * A helper class for debugging OpenGL ES applications.
+ *
+ * Wraps the supplied GL interface with a new GL interface that adds support for
+ * error checking and logging.
+ *
+ */
+public class GLDebugHelper {
+
+    /**
+     * Wrap an existing GL interface in a new GL interface that adds support for
+     * error checking and/or logging.
+     * <p>
+     * Wrapping means that the GL instance that is passed in to this method is
+     * wrapped inside a new GL instance that optionally performs additional
+     * operations before and after calling the wrapped GL instance.
+     * <p>
+     * Error checking means that the wrapper will automatically call
+     * glError after each GL operation,
+     * and throw a GLException if an error occurs. (By design, calling glError
+     * itself will not cause an exception to be thrown.) Enabling error checking
+     * is an alternative to manually calling glError after every GL operation.
+     * <p>
+     * Logging means writing a text representation of each GL method call to
+     * a log.
+     * <p>
+     * @param gl the existing GL interface. Must implement GL and GL10. May
+     * optionally implement GL11 as well.
+     * @param configFlags A bitmask of error checking flags.
+     * @param log - null to disable logging, non-null to enable logging.
+     * @return the wrapped GL instance.
+     */
+
+    /**
+     * Check glError() after every call.
+     */
+    public static final int CONFIG_CHECK_GL_ERROR = (1 << 0);
+
+    /**
+     * Check if all calls are on the same thread.
+     */
+    public static final int CONFIG_CHECK_THREAD = (1 << 1);
+
+    /**
+     * Print argument names when logging GL Calls.
+     */
+    public static final int CONFIG_LOG_ARGUMENT_NAMES = (1 << 2);
+
+    /**
+     * The Error number used in the GLException that is thrown if
+     * CONFIG_CHECK_THREAD is enabled and you call OpenGL ES on the
+     * a different thread.
+     */
+    public static final int ERROR_WRONG_THREAD = 0x7000;
+
+    public static GL wrap(GL gl, int configFlags, Writer log) {
+        if ( configFlags != 0 ) {
+            gl = new GLErrorWrapper(gl, configFlags);
+        }
+        if ( log != null ) {
+            boolean logArgumentNames =
+                (CONFIG_LOG_ARGUMENT_NAMES & configFlags) != 0;
+            gl = new GLLogWrapper(gl, log, logArgumentNames);
+        }
+        return gl;
+    }
+
+    /**
+     * Wrap an existing EGL interface in a new EGL interface that adds
+     * support for error checking and/or logging.
+     * @param egl the existing GL interface. Must implement EGL and EGL10. May
+     * optionally implement EGL11 as well.
+     * @param configFlags A bitmask of error checking flags.
+     * @param log - null to disable logging, non-null to enable logging.
+     * @return the wrapped EGL interface.
+     */
+    public static EGL wrap(EGL egl, int configFlags, Writer log) {
+        if (log != null) {
+            egl = new EGLLogWrapper(egl, configFlags, log);
+        }
+        return egl;
+    }
+}
+
diff --git a/opengl/java/android/opengl/GLErrorWrapper.java b/opengl/java/android/opengl/GLErrorWrapper.java
new file mode 100644
index 0000000..884a1a0
--- /dev/null
+++ b/opengl/java/android/opengl/GLErrorWrapper.java
@@ -0,0 +1,961 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.nio.Buffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.ShortBuffer;
+
+import javax.microedition.khronos.opengles.GL;
+
+/**
+ * Implement an error checking wrapper. The wrapper will automatically call
+     * glError after each GL operation, and throw a GLException if an error
+     * occurs. (By design, calling glError itself will not cause an exception
+     * to be thrown.) Enabling error checking is an alternative to manually
+     *  calling glError after every GL operation.
+ */
+class GLErrorWrapper extends GLWrapperBase {
+    boolean mCheckError;
+    boolean mCheckThread;
+    Thread mOurThread;
+
+    public GLErrorWrapper(GL gl, int configFlags) {
+        super(gl);
+        mCheckError = (configFlags & GLDebugHelper.CONFIG_CHECK_GL_ERROR) != 0;
+        mCheckThread = (configFlags & GLDebugHelper.CONFIG_CHECK_THREAD) != 0;
+    }
+
+    private void checkThread() {
+        if (mCheckThread) {
+            Thread currentThread = Thread.currentThread();
+            if (mOurThread == null) {
+                mOurThread = currentThread;
+            } else {
+                if (!mOurThread.equals(currentThread)) {
+                    throw new GLException(GLDebugHelper.ERROR_WRONG_THREAD,
+                            "OpenGL method called from wrong thread.");
+                }
+            }
+        }
+    }
+
+    private void checkError() {
+        if (mCheckError) {
+            int glError;
+            if ((glError = mgl.glGetError()) != 0) {
+                throw new GLException(glError);
+            }
+        }
+    }
+
+    // ---------------------------------------------------------------------
+    // GL10 methods:
+
+    public void glActiveTexture(int texture) {
+        checkThread();
+        mgl.glActiveTexture(texture);
+        checkError();
+    }
+
+    public void glAlphaFunc(int func, float ref) {
+        checkThread();
+        mgl.glAlphaFunc(func, ref);
+        checkError();
+    }
+
+    public void glAlphaFuncx(int func, int ref) {
+        checkThread();
+        mgl.glAlphaFuncx(func, ref);
+        checkError();
+    }
+
+    public void glBindTexture(int target, int texture) {
+        checkThread();
+        mgl.glBindTexture(target, texture);
+        checkError();
+    }
+
+    public void glBlendFunc(int sfactor, int dfactor) {
+        checkThread();
+        mgl.glBlendFunc(sfactor, dfactor);
+        checkError();
+    }
+
+    public void glClear(int mask) {
+        checkThread();
+        mgl.glClear(mask);
+        checkError();
+    }
+
+    public void glClearColor(float red, float green, float blue, float alpha) {
+        checkThread();
+        mgl.glClearColor(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glClearColorx(int red, int green, int blue, int alpha) {
+        checkThread();
+        mgl.glClearColorx(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glClearDepthf(float depth) {
+        checkThread();
+        mgl.glClearDepthf(depth);
+        checkError();
+    }
+
+    public void glClearDepthx(int depth) {
+        checkThread();
+        mgl.glClearDepthx(depth);
+        checkError();
+    }
+
+    public void glClearStencil(int s) {
+        checkThread();
+        mgl.glClearStencil(s);
+        checkError();
+    }
+
+    public void glClientActiveTexture(int texture) {
+        checkThread();
+        mgl.glClientActiveTexture(texture);
+        checkError();
+    }
+
+    public void glColor4f(float red, float green, float blue, float alpha) {
+        checkThread();
+        mgl.glColor4f(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glColor4x(int red, int green, int blue, int alpha) {
+        checkThread();
+        mgl.glColor4x(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glColorMask(boolean red, boolean green, boolean blue,
+            boolean alpha) {
+        checkThread();
+        mgl.glColorMask(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glColorPointer(int size, int type, int stride, Buffer pointer) {
+        checkThread();
+        mgl.glColorPointer(size, type, stride, pointer);
+        checkError();
+    }
+
+    public void glCompressedTexImage2D(int target, int level,
+            int internalformat, int width, int height, int border,
+            int imageSize, Buffer data) {
+        checkThread();
+        mgl.glCompressedTexImage2D(target, level, internalformat, width,
+                height, border, imageSize, data);
+        checkError();
+    }
+
+    public void glCompressedTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int width, int height, int format, int imageSize,
+            Buffer data) {
+        checkThread();
+        mgl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width,
+                height, format, imageSize, data);
+        checkError();
+    }
+
+    public void glCopyTexImage2D(int target, int level, int internalformat,
+            int x, int y, int width, int height, int border) {
+        checkThread();
+        mgl.glCopyTexImage2D(target, level, internalformat, x, y, width,
+                height, border);
+        checkError();
+    }
+
+    public void glCopyTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int x, int y, int width, int height) {
+        checkThread();
+        mgl.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
+                height);
+        checkError();
+    }
+
+    public void glCullFace(int mode) {
+        checkThread();
+        mgl.glCullFace(mode);
+        checkError();
+    }
+
+    public void glDeleteTextures(int n, int[] textures, int offset) {
+        checkThread();
+        mgl.glDeleteTextures(n, textures, offset);
+        checkError();
+    }
+
+    public void glDeleteTextures(int n, IntBuffer textures) {
+        checkThread();
+        mgl.glDeleteTextures(n, textures);
+        checkError();
+    }
+
+    public void glDepthFunc(int func) {
+        checkThread();
+        mgl.glDepthFunc(func);
+        checkError();
+    }
+
+    public void glDepthMask(boolean flag) {
+        checkThread();
+        mgl.glDepthMask(flag);
+        checkError();
+    }
+
+    public void glDepthRangef(float near, float far) {
+        checkThread();
+        mgl.glDepthRangef(near, far);
+        checkError();
+    }
+
+    public void glDepthRangex(int near, int far) {
+        checkThread();
+        mgl.glDepthRangex(near, far);
+        checkError();
+    }
+
+    public void glDisable(int cap) {
+        checkThread();
+        mgl.glDisable(cap);
+        checkError();
+    }
+
+    public void glDisableClientState(int array) {
+        checkThread();
+        mgl.glDisableClientState(array);
+        checkError();
+    }
+
+    public void glDrawArrays(int mode, int first, int count) {
+        checkThread();
+        mgl.glDrawArrays(mode, first, count);
+        checkError();
+    }
+
+    public void glDrawElements(int mode, int count, int type, Buffer indices) {
+        checkThread();
+        mgl.glDrawElements(mode, count, type, indices);
+        checkError();
+    }
+
+    public void glEnable(int cap) {
+        checkThread();
+        mgl.glEnable(cap);
+        checkError();
+    }
+
+    public void glEnableClientState(int array) {
+        checkThread();
+        mgl.glEnableClientState(array);
+        checkError();
+    }
+
+    public void glFinish() {
+        checkThread();
+        mgl.glFinish();
+        checkError();
+    }
+
+    public void glFlush() {
+        checkThread();
+        mgl.glFlush();
+        checkError();
+    }
+
+    public void glFogf(int pname, float param) {
+        checkThread();
+        mgl.glFogf(pname, param);
+        checkError();
+    }
+
+    public void glFogfv(int pname, float[] params, int offset) {
+        checkThread();
+        mgl.glFogfv(pname, params, offset);
+        checkError();
+    }
+
+    public void glFogfv(int pname, FloatBuffer params) {
+        checkThread();
+        mgl.glFogfv(pname, params);
+        checkError();
+    }
+
+    public void glFogx(int pname, int param) {
+        checkThread();
+        mgl.glFogx(pname, param);
+        checkError();
+    }
+
+    public void glFogxv(int pname, int[] params, int offset) {
+        checkThread();
+        mgl.glFogxv(pname, params, offset);
+        checkError();
+    }
+
+    public void glFogxv(int pname, IntBuffer params) {
+        checkThread();
+        mgl.glFogxv(pname, params);
+        checkError();
+    }
+
+    public void glFrontFace(int mode) {
+        checkThread();
+        mgl.glFrontFace(mode);
+        checkError();
+    }
+
+    public void glFrustumf(float left, float right, float bottom, float top,
+            float near, float far) {
+        checkThread();
+        mgl.glFrustumf(left, right, bottom, top, near, far);
+        checkError();
+    }
+
+    public void glFrustumx(int left, int right, int bottom, int top, int near,
+            int far) {
+        checkThread();
+        mgl.glFrustumx(left, right, bottom, top, near, far);
+        checkError();
+    }
+
+    public void glGenTextures(int n, int[] textures, int offset) {
+        checkThread();
+        mgl.glGenTextures(n, textures, offset);
+        checkError();
+    }
+
+    public void glGenTextures(int n, IntBuffer textures) {
+        checkThread();
+        mgl.glGenTextures(n, textures);
+        checkError();
+    }
+
+    public int glGetError() {
+        checkThread();
+        int result = mgl.glGetError();
+        return result;
+    }
+
+    public void glGetIntegerv(int pname, int[] params, int offset) {
+        checkThread();
+        mgl.glGetIntegerv(pname, params, offset);
+        checkError();
+    }
+
+    public void glGetIntegerv(int pname, IntBuffer params) {
+        checkThread();
+        mgl.glGetIntegerv(pname, params);
+        checkError();
+    }
+
+    public String glGetString(int name) {
+        checkThread();
+        String result = mgl.glGetString(name);
+        checkError();
+        return result;
+    }
+
+    public void glHint(int target, int mode) {
+        checkThread();
+        mgl.glHint(target, mode);
+        checkError();
+    }
+
+    public void glLightModelf(int pname, float param) {
+        checkThread();
+        mgl.glLightModelf(pname, param);
+        checkError();
+    }
+
+    public void glLightModelfv(int pname, float[] params, int offset) {
+        checkThread();
+        mgl.glLightModelfv(pname, params, offset);
+        checkError();
+    }
+
+    public void glLightModelfv(int pname, FloatBuffer params) {
+        checkThread();
+        mgl.glLightModelfv(pname, params);
+        checkError();
+    }
+
+    public void glLightModelx(int pname, int param) {
+        checkThread();
+        mgl.glLightModelx(pname, param);
+        checkError();
+    }
+
+    public void glLightModelxv(int pname, int[] params, int offset) {
+        checkThread();
+        mgl.glLightModelxv(pname, params, offset);
+        checkError();
+    }
+
+    public void glLightModelxv(int pname, IntBuffer params) {
+        checkThread();
+        mgl.glLightModelxv(pname, params);
+        checkError();
+    }
+
+    public void glLightf(int light, int pname, float param) {
+        checkThread();
+        mgl.glLightf(light, pname, param);
+        checkError();
+    }
+
+    public void glLightfv(int light, int pname, float[] params, int offset) {
+        checkThread();
+        mgl.glLightfv(light, pname, params, offset);
+        checkError();
+    }
+
+    public void glLightfv(int light, int pname, FloatBuffer params) {
+        checkThread();
+        mgl.glLightfv(light, pname, params);
+        checkError();
+    }
+
+    public void glLightx(int light, int pname, int param) {
+        checkThread();
+        mgl.glLightx(light, pname, param);
+        checkError();
+    }
+
+    public void glLightxv(int light, int pname, int[] params, int offset) {
+        checkThread();
+        mgl.glLightxv(light, pname, params, offset);
+        checkError();
+    }
+
+    public void glLightxv(int light, int pname, IntBuffer params) {
+        checkThread();
+        mgl.glLightxv(light, pname, params);
+        checkError();
+    }
+
+    public void glLineWidth(float width) {
+        checkThread();
+        mgl.glLineWidth(width);
+        checkError();
+    }
+
+    public void glLineWidthx(int width) {
+        checkThread();
+        mgl.glLineWidthx(width);
+        checkError();
+    }
+
+    public void glLoadIdentity() {
+        checkThread();
+        mgl.glLoadIdentity();
+        checkError();
+    }
+
+    public void glLoadMatrixf(float[] m, int offset) {
+        checkThread();
+        mgl.glLoadMatrixf(m, offset);
+        checkError();
+    }
+
+    public void glLoadMatrixf(FloatBuffer m) {
+        checkThread();
+        mgl.glLoadMatrixf(m);
+        checkError();
+    }
+
+    public void glLoadMatrixx(int[] m, int offset) {
+        checkThread();
+        mgl.glLoadMatrixx(m, offset);
+        checkError();
+    }
+
+    public void glLoadMatrixx(IntBuffer m) {
+        checkThread();
+        mgl.glLoadMatrixx(m);
+        checkError();
+    }
+
+    public void glLogicOp(int opcode) {
+        checkThread();
+        mgl.glLogicOp(opcode);
+        checkError();
+    }
+
+    public void glMaterialf(int face, int pname, float param) {
+        checkThread();
+        mgl.glMaterialf(face, pname, param);
+        checkError();
+    }
+
+    public void glMaterialfv(int face, int pname, float[] params, int offset) {
+        checkThread();
+        mgl.glMaterialfv(face, pname, params, offset);
+        checkError();
+    }
+
+    public void glMaterialfv(int face, int pname, FloatBuffer params) {
+        checkThread();
+        mgl.glMaterialfv(face, pname, params);
+        checkError();
+    }
+
+    public void glMaterialx(int face, int pname, int param) {
+        checkThread();
+        mgl.glMaterialx(face, pname, param);
+        checkError();
+    }
+
+    public void glMaterialxv(int face, int pname, int[] params, int offset) {
+        checkThread();
+        mgl.glMaterialxv(face, pname, params, offset);
+        checkError();
+    }
+
+    public void glMaterialxv(int face, int pname, IntBuffer params) {
+        checkThread();
+        mgl.glMaterialxv(face, pname, params);
+        checkError();
+    }
+
+    public void glMatrixMode(int mode) {
+        checkThread();
+        mgl.glMatrixMode(mode);
+        checkError();
+    }
+
+    public void glMultMatrixf(float[] m, int offset) {
+        checkThread();
+        mgl.glMultMatrixf(m, offset);
+        checkError();
+    }
+
+    public void glMultMatrixf(FloatBuffer m) {
+        checkThread();
+        mgl.glMultMatrixf(m);
+        checkError();
+    }
+
+    public void glMultMatrixx(int[] m, int offset) {
+        checkThread();
+        mgl.glMultMatrixx(m, offset);
+        checkError();
+    }
+
+    public void glMultMatrixx(IntBuffer m) {
+        checkThread();
+        mgl.glMultMatrixx(m);
+        checkError();
+    }
+
+    public void glMultiTexCoord4f(int target,
+            float s, float t, float r, float q) {
+        checkThread();
+        mgl.glMultiTexCoord4f(target, s, t, r, q);
+        checkError();
+    }
+
+    public void glMultiTexCoord4x(int target, int s, int t, int r, int q) {
+        checkThread();
+        mgl.glMultiTexCoord4x(target, s, t, r, q);
+        checkError();
+    }
+
+    public void glNormal3f(float nx, float ny, float nz) {
+        checkThread();
+        mgl.glNormal3f(nx, ny, nz);
+        checkError();
+    }
+
+    public void glNormal3x(int nx, int ny, int nz) {
+        checkThread();
+        mgl.glNormal3x(nx, ny, nz);
+        checkError();
+    }
+
+    public void glNormalPointer(int type, int stride, Buffer pointer) {
+        checkThread();
+        mgl.glNormalPointer(type, stride, pointer);
+        checkError();
+    }
+
+    public void glOrthof(float left, float right, float bottom, float top,
+            float near, float far) {
+        checkThread();
+        mgl.glOrthof(left, right, bottom, top, near, far);
+        checkError();
+    }
+
+    public void glOrthox(int left, int right, int bottom, int top, int near,
+            int far) {
+        checkThread();
+        mgl.glOrthox(left, right, bottom, top, near, far);
+        checkError();
+    }
+
+    public void glPixelStorei(int pname, int param) {
+        checkThread();
+        mgl.glPixelStorei(pname, param);
+        checkError();
+    }
+
+    public void glPointSize(float size) {
+        checkThread();
+        mgl.glPointSize(size);
+        checkError();
+    }
+
+    public void glPointSizex(int size) {
+        checkThread();
+        mgl.glPointSizex(size);
+        checkError();
+    }
+
+    public void glPolygonOffset(float factor, float units) {
+        checkThread();
+        mgl.glPolygonOffset(factor, units);
+        checkError();
+    }
+
+    public void glPolygonOffsetx(int factor, int units) {
+        checkThread();
+        mgl.glPolygonOffsetx(factor, units);
+        checkError();
+    }
+
+    public void glPopMatrix() {
+        checkThread();
+        mgl.glPopMatrix();
+        checkError();
+    }
+
+    public void glPushMatrix() {
+        checkThread();
+        mgl.glPushMatrix();
+        checkError();
+    }
+
+    public void glReadPixels(int x, int y, int width, int height, int format,
+            int type, Buffer pixels) {
+        checkThread();
+        mgl.glReadPixels(x, y, width, height, format, type, pixels);
+        checkError();
+    }
+
+    public void glRotatef(float angle, float x, float y, float z) {
+        checkThread();
+        mgl.glRotatef(angle, x, y, z);
+        checkError();
+    }
+
+    public void glRotatex(int angle, int x, int y, int z) {
+        checkThread();
+        mgl.glRotatex(angle, x, y, z);
+        checkError();
+    }
+
+    public void glSampleCoverage(float value, boolean invert) {
+        checkThread();
+        mgl.glSampleCoverage(value, invert);
+        checkError();
+    }
+
+    public void glSampleCoveragex(int value, boolean invert) {
+        checkThread();
+        mgl.glSampleCoveragex(value, invert);
+        checkError();
+    }
+
+    public void glScalef(float x, float y, float z) {
+        checkThread();
+        mgl.glScalef(x, y, z);
+        checkError();
+    }
+
+    public void glScalex(int x, int y, int z) {
+        checkThread();
+        mgl.glScalex(x, y, z);
+        checkError();
+    }
+
+    public void glScissor(int x, int y, int width, int height) {
+        checkThread();
+        mgl.glScissor(x, y, width, height);
+        checkError();
+    }
+
+    public void glShadeModel(int mode) {
+        checkThread();
+        mgl.glShadeModel(mode);
+        checkError();
+    }
+
+    public void glStencilFunc(int func, int ref, int mask) {
+        checkThread();
+        mgl.glStencilFunc(func, ref, mask);
+        checkError();
+    }
+
+    public void glStencilMask(int mask) {
+        checkThread();
+        mgl.glStencilMask(mask);
+        checkError();
+    }
+
+    public void glStencilOp(int fail, int zfail, int zpass) {
+        checkThread();
+        mgl.glStencilOp(fail, zfail, zpass);
+        checkError();
+    }
+
+    public void glTexCoordPointer(int size, int type,
+            int stride, Buffer pointer) {
+        checkThread();
+        mgl.glTexCoordPointer(size, type, stride, pointer);
+        checkError();
+    }
+
+    public void glTexEnvf(int target, int pname, float param) {
+        checkThread();
+        mgl.glTexEnvf(target, pname, param);
+        checkError();
+    }
+
+    public void glTexEnvfv(int target, int pname, float[] params, int offset) {
+        checkThread();
+        mgl.glTexEnvfv(target, pname, params, offset);
+        checkError();
+    }
+
+    public void glTexEnvfv(int target, int pname, FloatBuffer params) {
+        checkThread();
+        mgl.glTexEnvfv(target, pname, params);
+        checkError();
+    }
+
+    public void glTexEnvx(int target, int pname, int param) {
+        checkThread();
+        mgl.glTexEnvx(target, pname, param);
+        checkError();
+    }
+
+    public void glTexEnvxv(int target, int pname, int[] params, int offset) {
+        checkThread();
+        mgl.glTexEnvxv(target, pname, params, offset);
+        checkError();
+    }
+
+    public void glTexEnvxv(int target, int pname, IntBuffer params) {
+        checkThread();
+        mgl.glTexEnvxv(target, pname, params);
+        checkError();
+    }
+
+    public void glTexImage2D(int target, int level, int internalformat,
+            int width, int height, int border, int format, int type,
+            Buffer pixels) {
+        checkThread();
+        mgl.glTexImage2D(target, level, internalformat, width, height, border,
+                format, type, pixels);
+        checkError();
+    }
+
+    public void glTexParameterf(int target, int pname, float param) {
+        checkThread();
+        mgl.glTexParameterf(target, pname, param);
+        checkError();
+    }
+
+    public void glTexParameterx(int target, int pname, int param) {
+        checkThread();
+        mgl.glTexParameterx(target, pname, param);
+        checkError();
+    }
+
+    public void glTexParameteriv(int target, int pname, int[] params, int offset) {
+        checkThread();
+        mgl11.glTexParameteriv(target, pname, params, offset);
+        checkError();
+    }
+
+    public void glTexParameteriv(int target, int pname, IntBuffer params) {
+        checkThread();
+        mgl11.glTexParameteriv(target, pname, params);
+        checkError();
+    }
+
+    public void glTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int width, int height, int format, int type,
+            Buffer pixels) {
+        checkThread();
+        mgl.glTexSubImage2D(target, level, xoffset, yoffset, width, height,
+                format, type, pixels);
+        checkError();
+    }
+
+    public void glTranslatef(float x, float y, float z) {
+        checkThread();
+        mgl.glTranslatef(x, y, z);
+        checkError();
+    }
+
+    public void glTranslatex(int x, int y, int z) {
+        checkThread();
+        mgl.glTranslatex(x, y, z);
+        checkError();
+    }
+
+    public void glVertexPointer(int size, int type,
+            int stride, Buffer pointer) {
+        checkThread();
+        mgl.glVertexPointer(size, type, stride, pointer);
+        checkError();
+    }
+
+    public void glViewport(int x, int y, int width, int height) {
+        checkThread();
+        mgl.glViewport(x, y, width, height);
+        checkError();
+    }
+
+    public void glClipPlanef(int plane, float[] equation, int offset) {
+        checkThread();
+        mgl11.glClipPlanef(plane, equation, offset);
+        checkError();
+    }
+
+    public void glClipPlanef(int plane, FloatBuffer equation) {
+        checkThread();
+        mgl11.glClipPlanef(plane, equation);
+        checkError();
+    }
+
+    public void glClipPlanex(int plane, int[] equation, int offset) {
+        checkThread();
+        mgl11.glClipPlanex(plane, equation, offset);
+        checkError();
+    }
+
+    public void glClipPlanex(int plane, IntBuffer equation) {
+        checkThread();
+        mgl11.glClipPlanex(plane, equation);
+        checkError();
+    }
+
+    // Draw Texture Extension
+
+    public void glDrawTexfOES(float x, float y, float z,
+        float width, float height) {
+        checkThread();
+        mgl11Ext.glDrawTexfOES(x, y, z, width, height);
+        checkError();
+    }
+
+    public void glDrawTexfvOES(float[] coords, int offset) {
+        checkThread();
+        mgl11Ext.glDrawTexfvOES(coords, offset);
+        checkError();
+    }
+
+    public void glDrawTexfvOES(FloatBuffer coords) {
+        checkThread();
+        mgl11Ext.glDrawTexfvOES(coords);
+        checkError();
+    }
+
+    public void glDrawTexiOES(int x, int y, int z, int width, int height) {
+        checkThread();
+        mgl11Ext.glDrawTexiOES(x, y, z, width, height);
+        checkError();
+    }
+
+    public void glDrawTexivOES(int[] coords, int offset) {
+        checkThread();
+        mgl11Ext.glDrawTexivOES(coords, offset);
+        checkError();
+    }
+
+    public void glDrawTexivOES(IntBuffer coords) {
+        checkThread();
+        mgl11Ext.glDrawTexivOES(coords);
+        checkError();
+    }
+
+    public void glDrawTexsOES(short x, short y, short z,
+        short width, short height) {
+        checkThread();
+        mgl11Ext.glDrawTexsOES(x, y, z, width, height);
+        checkError();
+    }
+
+    public void glDrawTexsvOES(short[] coords, int offset) {
+        checkThread();
+        mgl11Ext.glDrawTexsvOES(coords, offset);
+        checkError();
+    }
+
+    public void glDrawTexsvOES(ShortBuffer coords) {
+        checkThread();
+        mgl11Ext.glDrawTexsvOES(coords);
+        checkError();
+    }
+
+    public void glDrawTexxOES(int x, int y, int z, int width, int height) {
+        checkThread();
+        mgl11Ext.glDrawTexxOES(x, y, z, width, height);
+        checkError();
+    }
+
+    public void glDrawTexxvOES(int[] coords, int offset) {
+        checkThread();
+        mgl11Ext.glDrawTexxvOES(coords, offset);
+        checkError();
+    }
+
+    public void glDrawTexxvOES(IntBuffer coords) {
+        checkThread();
+        mgl11Ext.glDrawTexxvOES(coords);
+        checkError();
+    }
+
+    public int glQueryMatrixxOES(int[] mantissa, int mantissaOffset,
+        int[] exponent, int exponentOffset) {
+        checkThread();
+        int valid = mgl10Ext.glQueryMatrixxOES(mantissa, mantissaOffset,
+            exponent, exponentOffset);
+        checkError();
+        return valid;
+    }
+
+    public int glQueryMatrixxOES(IntBuffer mantissa, IntBuffer exponent) {
+        checkThread();
+        int valid = mgl10Ext.glQueryMatrixxOES(mantissa, exponent);
+        checkError();
+        return valid;
+    }
+}
diff --git a/opengl/java/android/opengl/GLException.java b/opengl/java/android/opengl/GLException.java
new file mode 100644
index 0000000..762fccf
--- /dev/null
+++ b/opengl/java/android/opengl/GLException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+/**
+ * An exception class for OpenGL errors.
+ *
+ */
+@SuppressWarnings("serial")
+public class GLException extends RuntimeException {
+    public GLException(final int error) {
+        super(getErrorString(error));
+        mError = error;
+    }
+
+    public GLException(final int error, final String string) {
+        super(string);
+        mError = error;
+    }
+
+    private static String getErrorString(int error) {
+        String errorString = GLU.gluErrorString(error);
+        if ( errorString == null ) {
+            errorString = "Unknown error 0x" + Integer.toHexString(error);
+        }
+        return errorString;
+    }
+
+    int getError() {
+        return mError;
+    }
+
+    private final int mError;
+}
+
diff --git a/opengl/java/android/opengl/GLLogWrapper.java b/opengl/java/android/opengl/GLLogWrapper.java
new file mode 100644
index 0000000..4119bf8
--- /dev/null
+++ b/opengl/java/android/opengl/GLLogWrapper.java
@@ -0,0 +1,3065 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.DoubleBuffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.LongBuffer;
+import java.nio.ShortBuffer;
+import java.util.Arrays;
+
+import javax.microedition.khronos.opengles.GL;
+
+/**
+ * A wrapper that logs all GL calls (and results) in human-readable form.
+ *
+ */
+class GLLogWrapper extends GLWrapperBase {
+    private static final int FORMAT_INT = 0;
+    private static final int FORMAT_FLOAT = 1;
+    private static final int FORMAT_FIXED = 2;
+
+    public GLLogWrapper(GL gl, Writer log, boolean logArgumentNames) {
+        super(gl);
+        mLog = log;
+        mLogArgumentNames = logArgumentNames;
+    }
+
+    private void checkError() {
+        int glError;
+        if ((glError = mgl.glGetError()) != 0) {
+            String errorMessage = "glError: " + Integer.toString(glError);
+            logLine(errorMessage);
+        }
+    }
+
+    private void logLine(String message) {
+        log(message + '\n');
+    }
+
+    private void log(String message) {
+        try {
+            mLog.write(message);
+        } catch (IOException e) {
+            // Ignore exception, keep on trying
+        }
+    }
+
+    private void begin(String name) {
+        log(name + '(');
+        mArgCount = 0;
+    }
+
+    private void arg(String name, String value) {
+        if (mArgCount++ > 0) {
+            log(", ");
+        }
+        if (mLogArgumentNames) {
+            log(name + "=");
+        }
+        log(value);
+    }
+
+    private void end() {
+        log(");\n");
+        flush();
+    }
+
+    private void flush() {
+        try {
+            mLog.flush();
+        } catch (IOException e) {
+            mLog = null;
+        }
+    }
+
+    private void arg(String name, boolean value) {
+        arg(name, Boolean.toString(value));
+    }
+
+    private void arg(String name, int value) {
+        arg(name, Integer.toString(value));
+    }
+
+    private void arg(String name, float value) {
+        arg(name, Float.toString(value));
+    }
+
+    private void returns(String result) {
+        log(") returns " + result + ";\n");
+        flush();
+    }
+
+    private void returns(int result) {
+        returns(Integer.toString(result));
+    }
+
+    private void arg(String name, int n, int[] arr, int offset) {
+        arg(name, toString(n, FORMAT_INT, arr, offset));
+    }
+
+    private void arg(String name, int n, short[] arr, int offset) {
+        arg(name, toString(n, arr, offset));
+    }
+
+    private void arg(String name, int n, float[] arr, int offset) {
+        arg(name, toString(n, arr, offset));
+    }
+
+    private void formattedAppend(StringBuilder buf, int value, int format) {
+        switch (format) {
+        case FORMAT_INT:
+            buf.append(value);
+            break;
+        case FORMAT_FLOAT:
+            buf.append(Float.intBitsToFloat(value));
+            break;
+        case FORMAT_FIXED:
+            buf.append(value / 65536.0f);
+            break;
+        }
+    }
+
+    private String toString(int n, int format, int[] arr, int offset) {
+        StringBuilder buf = new StringBuilder();
+        buf.append("{\n");
+        int arrLen = arr.length;
+        for (int i = 0; i < n; i++) {
+            int index = offset + i;
+            buf.append(" [" + index + "] = ");
+            if (index < 0 || index >= arrLen) {
+                buf.append("out of bounds");
+            } else {
+                formattedAppend(buf, arr[index], format);
+            }
+            buf.append('\n');
+        }
+        buf.append("}");
+        return buf.toString();
+    }
+
+    private String toString(int n, short[] arr, int offset) {
+        StringBuilder buf = new StringBuilder();
+        buf.append("{\n");
+        int arrLen = arr.length;
+        for (int i = 0; i < n; i++) {
+            int index = offset + i;
+            buf.append(" [" + index + "] = ");
+            if (index < 0 || index >= arrLen) {
+                buf.append("out of bounds");
+            } else {
+                buf.append(arr[index]);
+            }
+            buf.append('\n');
+        }
+        buf.append("}");
+        return buf.toString();
+    }
+
+    private String toString(int n, float[] arr, int offset) {
+        StringBuilder buf = new StringBuilder();
+        buf.append("{\n");
+        int arrLen = arr.length;
+        for (int i = 0; i < n; i++) {
+            int index = offset + i;
+            buf.append("[" + index + "] = ");
+            if (index < 0 || index >= arrLen) {
+                buf.append("out of bounds");
+            } else {
+                buf.append(arr[index]);
+            }
+            buf.append('\n');
+        }
+        buf.append("}");
+        return buf.toString();
+    }
+
+    private String toString(int n, FloatBuffer buf) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("{\n");
+        for (int i = 0; i < n; i++) {
+            builder.append(" [" + i + "] = " + buf.get(i) + '\n');
+        }
+        builder.append("}");
+        return builder.toString();
+    }
+
+    private String toString(int n, int format, IntBuffer buf) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("{\n");
+        for (int i = 0; i < n; i++) {
+            builder.append(" [" + i + "] = ");
+            formattedAppend(builder, buf.get(i), format);
+            builder.append('\n');
+        }
+        builder.append("}");
+        return builder.toString();
+    }
+
+    private String toString(int n, ShortBuffer buf) {
+        StringBuilder builder = new StringBuilder();
+        builder.append("{\n");
+        for (int i = 0; i < n; i++) {
+            builder.append(" [" + i + "] = " + buf.get(i) + '\n');
+        }
+        builder.append("}");
+        return builder.toString();
+    }
+
+    private void arg(String name, int n, FloatBuffer buf) {
+        arg(name, toString(n, buf));
+    }
+
+    private void arg(String name, int n, IntBuffer buf) {
+        arg(name, toString(n, FORMAT_INT, buf));
+    }
+
+    private void arg(String name, int n, ShortBuffer buf) {
+        arg(name, toString(n, buf));
+    }
+
+    private void argPointer(int size, int type, int stride, Buffer pointer) {
+        arg("size", size);
+        arg("type", getPointerTypeName(type));
+        arg("stride", stride);
+        arg("pointer", pointer.toString());
+    }
+
+    private static String getHex(int value) {
+        return "0x" + Integer.toHexString(value);
+    }
+
+    public static String getErrorString(int error) {
+        switch (error) {
+        case GL_NO_ERROR:
+            return "GL_NO_ERROR";
+        case GL_INVALID_ENUM:
+            return "GL_INVALID_ENUM";
+        case GL_INVALID_VALUE:
+            return "GL_INVALID_VALUE";
+        case GL_INVALID_OPERATION:
+            return "GL_INVALID_OPERATION";
+        case GL_STACK_OVERFLOW:
+            return "GL_STACK_OVERFLOW";
+        case GL_STACK_UNDERFLOW:
+            return "GL_STACK_UNDERFLOW";
+        case GL_OUT_OF_MEMORY:
+            return "GL_OUT_OF_MEMORY";
+        default:
+            return getHex(error);
+        }
+    }
+
+    private String getClearBufferMask(int mask) {
+        StringBuilder b = new StringBuilder();
+        if ((mask & GL_DEPTH_BUFFER_BIT) != 0) {
+            b.append("GL_DEPTH_BUFFER_BIT");
+            mask &= ~GL_DEPTH_BUFFER_BIT;
+        }
+        if ((mask & GL_STENCIL_BUFFER_BIT) != 0) {
+            if (b.length() > 0) {
+                b.append(" | ");
+            }
+            b.append("GL_STENCIL_BUFFER_BIT");
+            mask &= ~GL_STENCIL_BUFFER_BIT;
+        }
+        if ((mask & GL_COLOR_BUFFER_BIT) != 0) {
+            if (b.length() > 0) {
+                b.append(" | ");
+            }
+            b.append("GL_COLOR_BUFFER_BIT");
+            mask &= ~GL_COLOR_BUFFER_BIT;
+        }
+        if (mask != 0) {
+            if (b.length() > 0) {
+                b.append(" | ");
+            }
+            b.append(getHex(mask));
+        }
+        return b.toString();
+    }
+
+    private String getFactor(int factor) {
+        switch(factor) {
+        case GL_ZERO:
+            return "GL_ZERO";
+        case GL_ONE:
+            return "GL_ONE";
+        case GL_SRC_COLOR:
+            return "GL_SRC_COLOR";
+        case GL_ONE_MINUS_SRC_COLOR:
+            return "GL_ONE_MINUS_SRC_COLOR";
+        case GL_DST_COLOR:
+            return "GL_DST_COLOR";
+        case GL_ONE_MINUS_DST_COLOR:
+            return "GL_ONE_MINUS_DST_COLOR";
+        case GL_SRC_ALPHA:
+            return "GL_SRC_ALPHA";
+        case GL_ONE_MINUS_SRC_ALPHA:
+            return "GL_ONE_MINUS_SRC_ALPHA";
+        case GL_DST_ALPHA:
+            return "GL_DST_ALPHA";
+        case GL_ONE_MINUS_DST_ALPHA:
+            return "GL_ONE_MINUS_DST_ALPHA";
+        case GL_SRC_ALPHA_SATURATE:
+            return "GL_SRC_ALPHA_SATURATE";
+
+        default:
+            return getHex(factor);
+        }
+    }
+
+    private String getShadeModel(int model) {
+        switch(model) {
+        case GL_FLAT:
+            return "GL_FLAT";
+        case GL_SMOOTH:
+            return "GL_SMOOTH";
+        default:
+            return getHex(model);
+        }
+    }
+
+    private String getTextureTarget(int target) {
+        switch (target) {
+        case GL_TEXTURE_2D:
+            return "GL_TEXTURE_2D";
+        default:
+            return getHex(target);
+        }
+    }
+
+    private String getTextureEnvTarget(int target) {
+        switch (target) {
+        case GL_TEXTURE_ENV:
+            return "GL_TEXTURE_ENV";
+        default:
+            return getHex(target);
+        }
+    }
+
+    private String getTextureEnvPName(int pname) {
+        switch (pname) {
+        case GL_TEXTURE_ENV_MODE:
+            return "GL_TEXTURE_ENV_MODE";
+        case GL_TEXTURE_ENV_COLOR:
+            return "GL_TEXTURE_ENV_COLOR";
+        default:
+            return getHex(pname);
+        }
+    }
+
+    private int getTextureEnvParamCount(int pname) {
+        switch (pname) {
+        case GL_TEXTURE_ENV_MODE:
+            return 1;
+        case GL_TEXTURE_ENV_COLOR:
+            return 4;
+        default:
+            return 0;
+        }
+    }
+
+    private String getTextureEnvParamName(float param) {
+        int iparam = (int) param;
+        if (param == (float) iparam) {
+            switch (iparam) {
+            case GL_REPLACE:
+                return "GL_REPLACE";
+            case GL_MODULATE:
+                return "GL_MODULATE";
+            case GL_DECAL:
+                return "GL_DECAL";
+            case GL_BLEND:
+                return "GL_BLEND";
+            case GL_ADD:
+                return "GL_ADD";
+            case GL_COMBINE:
+                return "GL_COMBINE";
+            default:
+                return getHex(iparam);
+            }
+        }
+        return Float.toString(param);
+    }
+
+    private String getMatrixMode(int matrixMode) {
+        switch (matrixMode) {
+        case GL_MODELVIEW:
+            return "GL_MODELVIEW";
+        case GL_PROJECTION:
+            return "GL_PROJECTION";
+        case GL_TEXTURE:
+            return "GL_TEXTURE";
+        default:
+            return getHex(matrixMode);
+        }
+    }
+
+    private String getClientState(int clientState) {
+        switch (clientState) {
+        case GL_COLOR_ARRAY:
+            return "GL_COLOR_ARRAY";
+        case GL_VERTEX_ARRAY:
+            return "GL_VERTEX_ARRAY";
+        case GL_NORMAL_ARRAY:
+            return "GL_NORMAL_ARRAY";
+        case GL_TEXTURE_COORD_ARRAY:
+            return "GL_TEXTURE_COORD_ARRAY";
+        default:
+            return getHex(clientState);
+        }
+    }
+
+    private String getCap(int cap) {
+        switch (cap) {
+        case GL_FOG:
+            return "GL_FOG";
+        case GL_LIGHTING:
+            return "GL_LIGHTING";
+        case GL_TEXTURE_2D:
+            return "GL_TEXTURE_2D";
+        case GL_CULL_FACE:
+            return "GL_CULL_FACE";
+        case GL_ALPHA_TEST:
+            return "GL_ALPHA_TEST";
+        case GL_BLEND:
+            return "GL_BLEND";
+        case GL_COLOR_LOGIC_OP:
+            return "GL_COLOR_LOGIC_OP";
+        case GL_DITHER:
+            return "GL_DITHER";
+        case GL_STENCIL_TEST:
+            return "GL_STENCIL_TEST";
+        case GL_DEPTH_TEST:
+            return "GL_DEPTH_TEST";
+        case GL_LIGHT0:
+            return "GL_LIGHT0";
+        case GL_LIGHT1:
+            return "GL_LIGHT1";
+        case GL_LIGHT2:
+            return "GL_LIGHT2";
+        case GL_LIGHT3:
+            return "GL_LIGHT3";
+        case GL_LIGHT4:
+            return "GL_LIGHT4";
+        case GL_LIGHT5:
+            return "GL_LIGHT5";
+        case GL_LIGHT6:
+            return "GL_LIGHT6";
+        case GL_LIGHT7:
+            return "GL_LIGHT7";
+        case GL_POINT_SMOOTH:
+            return "GL_POINT_SMOOTH";
+        case GL_LINE_SMOOTH:
+            return "GL_LINE_SMOOTH";
+        case GL_COLOR_MATERIAL:
+            return "GL_COLOR_MATERIAL";
+        case GL_NORMALIZE:
+            return "GL_NORMALIZE";
+        case GL_RESCALE_NORMAL:
+            return "GL_RESCALE_NORMAL";
+        case GL_VERTEX_ARRAY:
+            return "GL_VERTEX_ARRAY";
+        case GL_NORMAL_ARRAY:
+            return "GL_NORMAL_ARRAY";
+        case GL_COLOR_ARRAY:
+            return "GL_COLOR_ARRAY";
+        case GL_TEXTURE_COORD_ARRAY:
+            return "GL_TEXTURE_COORD_ARRAY";
+        case GL_MULTISAMPLE:
+            return "GL_MULTISAMPLE";
+        case GL_SAMPLE_ALPHA_TO_COVERAGE:
+            return "GL_SAMPLE_ALPHA_TO_COVERAGE";
+        case GL_SAMPLE_ALPHA_TO_ONE:
+            return "GL_SAMPLE_ALPHA_TO_ONE";
+        case GL_SAMPLE_COVERAGE:
+            return "GL_SAMPLE_COVERAGE";
+        case GL_SCISSOR_TEST:
+            return "GL_SCISSOR_TEST";
+        default:
+            return getHex(cap);
+        }
+    }
+
+    private String getTexturePName(int pname) {
+        switch (pname) {
+        case GL_TEXTURE_MAG_FILTER:
+            return "GL_TEXTURE_MAG_FILTER";
+        case GL_TEXTURE_MIN_FILTER:
+            return "GL_TEXTURE_MIN_FILTER";
+        case GL_TEXTURE_WRAP_S:
+            return "GL_TEXTURE_WRAP_S";
+        case GL_TEXTURE_WRAP_T:
+            return "GL_TEXTURE_WRAP_T";
+        case GL_GENERATE_MIPMAP:
+            return "GL_GENERATE_MIPMAP";
+        case GL_TEXTURE_CROP_RECT_OES:
+            return "GL_TEXTURE_CROP_RECT_OES";
+        default:
+            return getHex(pname);
+        }
+    }
+
+    private String getTextureParamName(float param) {
+        int iparam = (int) param;
+        if (param == (float) iparam) {
+            switch (iparam) {
+            case GL_CLAMP_TO_EDGE:
+                return "GL_CLAMP_TO_EDGE";
+            case GL_REPEAT:
+                return "GL_REPEAT";
+            case GL_NEAREST:
+                return "GL_NEAREST";
+            case GL_LINEAR:
+                return "GL_LINEAR";
+            case GL_NEAREST_MIPMAP_NEAREST:
+                return "GL_NEAREST_MIPMAP_NEAREST";
+            case GL_LINEAR_MIPMAP_NEAREST:
+                return "GL_LINEAR_MIPMAP_NEAREST";
+            case GL_NEAREST_MIPMAP_LINEAR:
+                return "GL_NEAREST_MIPMAP_LINEAR";
+            case GL_LINEAR_MIPMAP_LINEAR:
+                return "GL_LINEAR_MIPMAP_LINEAR";
+            default:
+                return getHex(iparam);
+            }
+        }
+        return Float.toString(param);
+    }
+
+    private String getFogPName(int pname) {
+        switch (pname) {
+        case GL_FOG_DENSITY:
+            return "GL_FOG_DENSITY";
+        case GL_FOG_START:
+            return "GL_FOG_START";
+        case GL_FOG_END:
+            return "GL_FOG_END";
+        case GL_FOG_MODE:
+            return "GL_FOG_MODE";
+        case GL_FOG_COLOR:
+            return "GL_FOG_COLOR";
+        default:
+            return getHex(pname);
+        }
+    }
+
+    private int getFogParamCount(int pname) {
+        switch (pname) {
+        case GL_FOG_DENSITY:
+            return 1;
+        case GL_FOG_START:
+            return 1;
+        case GL_FOG_END:
+            return 1;
+        case GL_FOG_MODE:
+            return 1;
+        case GL_FOG_COLOR:
+            return 4;
+        default:
+            return 0;
+        }
+    }
+
+    private String getBeginMode(int mode) {
+        switch (mode) {
+        case GL_POINTS:
+            return "GL_POINTS";
+        case GL_LINES:
+            return "GL_LINES";
+        case GL_LINE_LOOP:
+            return "GL_LINE_LOOP";
+        case GL_LINE_STRIP:
+            return "GL_LINE_STRIP";
+        case GL_TRIANGLES:
+            return "GL_TRIANGLES";
+        case GL_TRIANGLE_STRIP:
+            return "GL_TRIANGLE_STRIP";
+        case GL_TRIANGLE_FAN:
+            return "GL_TRIANGLE_FAN";
+        default:
+            return getHex(mode);
+        }
+    }
+
+    private String getIndexType(int type) {
+        switch (type) {
+        case GL_UNSIGNED_SHORT:
+            return "GL_UNSIGNED_SHORT";
+        case GL_UNSIGNED_BYTE:
+            return "GL_UNSIGNED_BYTE";
+        default:
+            return getHex(type);
+        }
+    }
+
+    private String getIntegerStateName(int pname) {
+        switch (pname) {
+        case GL_ALPHA_BITS:
+            return "GL_ALPHA_BITS";
+        case GL_ALIASED_LINE_WIDTH_RANGE:
+            return "GL_ALIASED_LINE_WIDTH_RANGE";
+        case GL_ALIASED_POINT_SIZE_RANGE:
+            return "GL_ALIASED_POINT_SIZE_RANGE";
+        case GL_BLUE_BITS:
+            return "GL_BLUE_BITS";
+        case GL_COMPRESSED_TEXTURE_FORMATS:
+            return "GL_COMPRESSED_TEXTURE_FORMATS";
+        case GL_DEPTH_BITS:
+            return "GL_DEPTH_BITS";
+        case GL_GREEN_BITS:
+            return "GL_GREEN_BITS";
+        case GL_MAX_ELEMENTS_INDICES:
+            return "GL_MAX_ELEMENTS_INDICES";
+        case GL_MAX_ELEMENTS_VERTICES:
+            return "GL_MAX_ELEMENTS_VERTICES";
+        case GL_MAX_LIGHTS:
+            return "GL_MAX_LIGHTS";
+        case GL_MAX_TEXTURE_SIZE:
+            return "GL_MAX_TEXTURE_SIZE";
+        case GL_MAX_VIEWPORT_DIMS:
+            return "GL_MAX_VIEWPORT_DIMS";
+        case GL_MAX_MODELVIEW_STACK_DEPTH:
+            return "GL_MAX_MODELVIEW_STACK_DEPTH";
+        case GL_MAX_PROJECTION_STACK_DEPTH:
+            return "GL_MAX_PROJECTION_STACK_DEPTH";
+        case GL_MAX_TEXTURE_STACK_DEPTH:
+            return "GL_MAX_TEXTURE_STACK_DEPTH";
+        case GL_MAX_TEXTURE_UNITS:
+            return "GL_MAX_TEXTURE_UNITS";
+        case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+            return "GL_NUM_COMPRESSED_TEXTURE_FORMATS";
+        case GL_RED_BITS:
+            return "GL_RED_BITS";
+        case GL_SMOOTH_LINE_WIDTH_RANGE:
+            return "GL_SMOOTH_LINE_WIDTH_RANGE";
+        case GL_SMOOTH_POINT_SIZE_RANGE:
+            return "GL_SMOOTH_POINT_SIZE_RANGE";
+        case GL_STENCIL_BITS:
+            return "GL_STENCIL_BITS";
+        case GL_SUBPIXEL_BITS:
+            return "GL_SUBPIXEL_BITS";
+
+        case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
+            return "GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES";
+        case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
+            return "GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES";
+        case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
+            return "GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES";
+
+        default:
+            return getHex(pname);
+        }
+    }
+
+    private int getIntegerStateSize(int pname) {
+        switch (pname) {
+        case GL_ALPHA_BITS:
+            return 1;
+        case GL_ALIASED_LINE_WIDTH_RANGE:
+            return 2;
+        case GL_ALIASED_POINT_SIZE_RANGE:
+            return 2;
+        case GL_BLUE_BITS:
+            return 1;
+        case GL_COMPRESSED_TEXTURE_FORMATS:
+            // Have to ask the implementation for the size
+        {
+            int[] buffer = new int[1];
+            mgl.glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, buffer, 0);
+            return buffer[0];
+        }
+        case GL_DEPTH_BITS:
+            return 1;
+        case GL_GREEN_BITS:
+            return 1;
+        case GL_MAX_ELEMENTS_INDICES:
+            return 1;
+        case GL_MAX_ELEMENTS_VERTICES:
+            return 1;
+        case GL_MAX_LIGHTS:
+            return 1;
+        case GL_MAX_TEXTURE_SIZE:
+            return 1;
+        case GL_MAX_VIEWPORT_DIMS:
+            return 2;
+        case GL_MAX_MODELVIEW_STACK_DEPTH:
+            return 1;
+        case GL_MAX_PROJECTION_STACK_DEPTH:
+            return 1;
+        case GL_MAX_TEXTURE_STACK_DEPTH:
+            return 1;
+        case GL_MAX_TEXTURE_UNITS:
+            return 1;
+        case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+            return 1;
+        case GL_RED_BITS:
+            return 1;
+        case GL_SMOOTH_LINE_WIDTH_RANGE:
+            return 2;
+        case GL_SMOOTH_POINT_SIZE_RANGE:
+            return 2;
+        case GL_STENCIL_BITS:
+            return 1;
+        case GL_SUBPIXEL_BITS:
+            return 1;
+
+        case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
+        case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
+        case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
+            return 16;
+
+        default:
+            return 0;
+        }
+    }
+
+    private int getIntegerStateFormat(int pname) {
+        switch (pname) {
+        case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
+        case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
+        case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
+            return FORMAT_FLOAT;
+
+        default:
+            return FORMAT_INT;
+        }
+    }
+
+    private String getHintTarget(int target) {
+        switch (target) {
+        case GL_FOG_HINT:
+            return "GL_FOG_HINT";
+        case GL_LINE_SMOOTH_HINT:
+            return "GL_LINE_SMOOTH_HINT";
+        case GL_PERSPECTIVE_CORRECTION_HINT:
+            return "GL_PERSPECTIVE_CORRECTION_HINT";
+        case GL_POINT_SMOOTH_HINT:
+            return "GL_POINT_SMOOTH_HINT";
+        case GL_POLYGON_SMOOTH_HINT:
+            return "GL_POLYGON_SMOOTH_HINT";
+        case GL_GENERATE_MIPMAP_HINT:
+            return "GL_GENERATE_MIPMAP_HINT";
+        default:
+            return getHex(target);
+        }
+    }
+
+    private String getHintMode(int mode) {
+        switch (mode) {
+        case GL_FASTEST:
+            return "GL_FASTEST";
+        case GL_NICEST:
+            return "GL_NICEST";
+        case GL_DONT_CARE:
+            return "GL_DONT_CARE";
+        default:
+            return getHex(mode);
+        }
+    }
+
+    private String getFaceName(int face) {
+        switch (face) {
+        case GL_FRONT_AND_BACK:
+            return "GL_FRONT_AND_BACK";
+        default:
+            return getHex(face);
+        }
+    }
+
+    private String getMaterialPName(int pname) {
+        switch (pname) {
+        case GL_AMBIENT:
+            return "GL_AMBIENT";
+        case GL_DIFFUSE:
+            return "GL_DIFFUSE";
+        case GL_SPECULAR:
+            return "GL_SPECULAR";
+        case GL_EMISSION:
+            return "GL_EMISSION";
+        case GL_SHININESS:
+            return "GL_SHININESS";
+        case GL_AMBIENT_AND_DIFFUSE:
+            return "GL_AMBIENT_AND_DIFFUSE";
+        default:
+            return getHex(pname);
+        }
+    }
+
+    private int getMaterialParamCount(int pname) {
+        switch (pname) {
+        case GL_AMBIENT:
+            return 4;
+        case GL_DIFFUSE:
+            return 4;
+        case GL_SPECULAR:
+            return 4;
+        case GL_EMISSION:
+            return 4;
+        case GL_SHININESS:
+            return 1;
+        case GL_AMBIENT_AND_DIFFUSE:
+            return 4;
+        default:
+            return 0;
+        }
+    }
+
+    private String getLightName(int light) {
+        if (light >= GL_LIGHT0 && light <= GL_LIGHT7) {
+            return "GL_LIGHT" + Integer.toString(light);
+        }
+        return getHex(light);
+    }
+
+    private String getLightPName(int pname) {
+        switch (pname) {
+        case GL_AMBIENT:
+            return "GL_AMBIENT";
+        case GL_DIFFUSE:
+            return "GL_DIFFUSE";
+        case GL_SPECULAR:
+            return "GL_SPECULAR";
+        case GL_POSITION:
+            return "GL_POSITION";
+        case GL_SPOT_DIRECTION:
+            return "GL_SPOT_DIRECTION";
+        case GL_SPOT_EXPONENT:
+            return "GL_SPOT_EXPONENT";
+        case GL_SPOT_CUTOFF:
+            return "GL_SPOT_CUTOFF";
+        case GL_CONSTANT_ATTENUATION:
+            return "GL_CONSTANT_ATTENUATION";
+        case GL_LINEAR_ATTENUATION:
+            return "GL_LINEAR_ATTENUATION";
+        case GL_QUADRATIC_ATTENUATION:
+            return "GL_QUADRATIC_ATTENUATION";
+        default:
+            return getHex(pname);
+        }
+    }
+
+    private int getLightParamCount(int pname) {
+        switch (pname) {
+        case GL_AMBIENT:
+            return 4;
+        case GL_DIFFUSE:
+            return 4;
+        case GL_SPECULAR:
+            return 4;
+        case GL_POSITION:
+            return 4;
+        case GL_SPOT_DIRECTION:
+            return 3;
+        case GL_SPOT_EXPONENT:
+            return 1;
+        case GL_SPOT_CUTOFF:
+            return 1;
+        case GL_CONSTANT_ATTENUATION:
+            return 1;
+        case GL_LINEAR_ATTENUATION:
+            return 1;
+        case GL_QUADRATIC_ATTENUATION:
+            return 1;
+        default:
+            return 0;
+        }
+    }
+
+    private String getLightModelPName(int pname) {
+        switch (pname) {
+        case GL_LIGHT_MODEL_AMBIENT:
+            return "GL_LIGHT_MODEL_AMBIENT";
+        case GL_LIGHT_MODEL_TWO_SIDE:
+            return "GL_LIGHT_MODEL_TWO_SIDE";
+        default:
+            return getHex(pname);
+        }
+    }
+
+    private int getLightModelParamCount(int pname) {
+        switch (pname) {
+        case GL_LIGHT_MODEL_AMBIENT:
+            return 4;
+        case GL_LIGHT_MODEL_TWO_SIDE:
+            return 1;
+        default:
+            return 0;
+        }
+    }
+
+    private String getPointerTypeName(int type) {
+        switch (type) {
+        case GL_BYTE:
+            return "GL_BYTE";
+        case GL_UNSIGNED_BYTE:
+            return "GL_UNSIGNED_BYTE";
+        case GL_SHORT:
+            return "GL_SHORT";
+        case GL_FIXED:
+            return "GL_FIXED";
+        case GL_FLOAT:
+            return "GL_FLOAT";
+        default:
+            return getHex(type);
+        }
+    }
+
+    private ByteBuffer toByteBuffer(int byteCount, Buffer input) {
+        ByteBuffer result = null;
+        boolean convertWholeBuffer = (byteCount < 0);
+        if (input instanceof ByteBuffer) {
+            ByteBuffer input2 = (ByteBuffer) input;
+            if (convertWholeBuffer) {
+                byteCount = input2.limit();
+            }
+            result = ByteBuffer.allocate(byteCount).order(input2.order());
+            int position = input2.position();
+            for (int i = 0; i < byteCount; i++) {
+                result.put(input2.get());
+            }
+            input2.position(position);
+        } else if (input instanceof CharBuffer) {
+            CharBuffer input2 = (CharBuffer) input;
+            if (convertWholeBuffer) {
+                byteCount = input2.limit() * 2;
+            }
+            result = ByteBuffer.allocate(byteCount).order(input2.order());
+            CharBuffer result2 = result.asCharBuffer();
+            int position = input2.position();
+            for (int i = 0; i < byteCount / 2; i++) {
+                result2.put(input2.get());
+            }
+            input2.position(position);
+        } else if (input instanceof ShortBuffer) {
+            ShortBuffer input2 = (ShortBuffer) input;
+            if (convertWholeBuffer) {
+                byteCount = input2.limit() * 2;
+            }
+            result = ByteBuffer.allocate(byteCount).order(input2.order());
+            ShortBuffer result2 = result.asShortBuffer();
+            int position = input2.position();
+            for (int i = 0; i < byteCount / 2; i++) {
+                result2.put(input2.get());
+            }
+            input2.position(position);
+        } else if (input instanceof IntBuffer) {
+            IntBuffer input2 = (IntBuffer) input;
+            if (convertWholeBuffer) {
+                byteCount = input2.limit() * 4;
+            }
+            result = ByteBuffer.allocate(byteCount).order(input2.order());
+            IntBuffer result2 = result.asIntBuffer();
+            int position = input2.position();
+            for (int i = 0; i < byteCount / 4; i++) {
+                result2.put(input2.get());
+            }
+            input2.position(position);
+        } else if (input instanceof FloatBuffer) {
+            FloatBuffer input2 = (FloatBuffer) input;
+            if (convertWholeBuffer) {
+                byteCount = input2.limit() * 4;
+            }
+            result = ByteBuffer.allocate(byteCount).order(input2.order());
+            FloatBuffer result2 = result.asFloatBuffer();
+            int position = input2.position();
+            for (int i = 0; i < byteCount / 4; i++) {
+                result2.put(input2.get());
+            }
+            input2.position(position);
+        } else if (input instanceof DoubleBuffer) {
+            DoubleBuffer input2 = (DoubleBuffer) input;
+            if (convertWholeBuffer) {
+                byteCount = input2.limit() * 8;
+            }
+            result = ByteBuffer.allocate(byteCount).order(input2.order());
+            DoubleBuffer result2 = result.asDoubleBuffer();
+            int position = input2.position();
+            for (int i = 0; i < byteCount / 8; i++) {
+                result2.put(input2.get());
+            }
+            input2.position(position);
+        } else if (input instanceof LongBuffer) {
+            LongBuffer input2 = (LongBuffer) input;
+            if (convertWholeBuffer) {
+                byteCount = input2.limit() * 8;
+            }
+            result = ByteBuffer.allocate(byteCount).order(input2.order());
+            LongBuffer result2 = result.asLongBuffer();
+            int position = input2.position();
+            for (int i = 0; i < byteCount / 8; i++) {
+                result2.put(input2.get());
+            }
+            input2.position(position);
+        } else {
+            throw new RuntimeException("Unimplemented Buffer subclass.");
+        }
+        result.rewind();
+        // The OpenGL API will interpret the result in hardware byte order,
+        // so we better do that as well:
+        result.order(ByteOrder.nativeOrder());
+        return result;
+    }
+
+    private char[] toCharIndices(int count, int type, Buffer indices) {
+        char[] result = new char[count];
+        switch (type) {
+        case GL_UNSIGNED_BYTE: {
+            ByteBuffer byteBuffer = toByteBuffer(count, indices);
+            byte[] array = byteBuffer.array();
+            int offset = byteBuffer.arrayOffset();
+            for (int i = 0; i < count; i++) {
+                result[i] = (char) (0xff & array[offset + i]);
+            }
+        }
+            break;
+        case GL_UNSIGNED_SHORT: {
+            CharBuffer charBuffer;
+            if (indices instanceof CharBuffer) {
+                charBuffer = (CharBuffer) indices;
+            } else {
+                ByteBuffer byteBuffer = toByteBuffer(count * 2, indices);
+                charBuffer = byteBuffer.asCharBuffer();
+            }
+            int oldPosition = charBuffer.position();
+            charBuffer.position(0);
+            charBuffer.get(result);
+            charBuffer.position(oldPosition);
+        }
+            break;
+        default:
+            // Don't throw an exception, because we don't want logging to
+            // change the behavior.
+            break;
+        }
+        return result;
+    }
+
+    private void doArrayElement(StringBuilder builder, boolean enabled,
+            String name, PointerInfo pointer, int index) {
+        if (!enabled) {
+            return;
+        }
+        builder.append(" ");
+        builder.append(name + ":{");
+        if (pointer == null) {
+            builder.append("undefined");
+            return;
+        }
+        if (pointer.mStride < 0) {
+            builder.append("invalid stride");
+            return;
+        }
+
+        int stride = pointer.getStride();
+        ByteBuffer byteBuffer = pointer.mTempByteBuffer;
+        int size = pointer.mSize;
+        int type = pointer.mType;
+        int sizeofType = pointer.sizeof(type);
+        int byteOffset = stride * index;
+        for (int i = 0; i < size; i++) {
+            if (i > 0) {
+                builder.append(", ");
+            }
+            switch (type) {
+            case GL_BYTE: {
+                byte d = byteBuffer.get(byteOffset);
+                builder.append(Integer.toString(d));
+            }
+                break;
+            case GL_UNSIGNED_BYTE: {
+                byte d = byteBuffer.get(byteOffset);
+                builder.append(Integer.toString(0xff & d));
+            }
+                break;
+            case GL_SHORT: {
+                ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
+                short d = shortBuffer.get(byteOffset / 2);
+                builder.append(Integer.toString(d));
+            }
+                break;
+            case GL_FIXED: {
+                IntBuffer intBuffer = byteBuffer.asIntBuffer();
+                int d = intBuffer.get(byteOffset / 4);
+                builder.append(Integer.toString(d));
+            }
+                break;
+            case GL_FLOAT: {
+                FloatBuffer intBuffer = byteBuffer.asFloatBuffer();
+                float d = intBuffer.get(byteOffset / 4);
+                builder.append(Float.toString(d));
+            }
+                break;
+            default:
+                builder.append("?");
+                break;
+            }
+            byteOffset += sizeofType;
+        }
+        builder.append("}");
+    }
+
+    private void doElement(StringBuilder builder, int ordinal, int vertexIndex) {
+        builder.append(" [" + ordinal + " : " + vertexIndex + "] =");
+        doArrayElement(builder, mVertexArrayEnabled, "v", mVertexPointer,
+                vertexIndex);
+        doArrayElement(builder, mNormalArrayEnabled, "n", mNormalPointer,
+                vertexIndex);
+        doArrayElement(builder, mColorArrayEnabled, "c", mColorPointer,
+                vertexIndex);
+        doArrayElement(builder, mTextureCoordArrayEnabled, "t",
+                mTexCoordPointer, vertexIndex);
+        builder.append("\n");
+        // Vertex
+        // Normal
+        // Color
+        // TexCoord
+    }
+
+    private void bindArrays() {
+        if (mColorArrayEnabled)
+            mColorPointer.bindByteBuffer();
+        if (mNormalArrayEnabled)
+            mNormalPointer.bindByteBuffer();
+        if (mTextureCoordArrayEnabled)
+            mTexCoordPointer.bindByteBuffer();
+        if (mVertexArrayEnabled)
+            mVertexPointer.bindByteBuffer();
+    }
+
+    private void unbindArrays() {
+        if (mColorArrayEnabled)
+            mColorPointer.unbindByteBuffer();
+        if (mNormalArrayEnabled)
+            mNormalPointer.unbindByteBuffer();
+        if (mTextureCoordArrayEnabled)
+            mTexCoordPointer.unbindByteBuffer();
+        if (mVertexArrayEnabled)
+            mVertexPointer.unbindByteBuffer();
+    }
+
+    private void startLogIndices() {
+        mStringBuilder = new StringBuilder();
+        mStringBuilder.append("\n");
+        bindArrays();
+    }
+
+    private void endLogIndices() {
+        log(mStringBuilder.toString());
+        unbindArrays();
+    }
+
+    // ---------------------------------------------------------------------
+    // GL10 methods:
+
+    public void glActiveTexture(int texture) {
+        begin("glActiveTexture");
+        arg("texture", texture);
+        end();
+        mgl.glActiveTexture(texture);
+        checkError();
+    }
+
+    public void glAlphaFunc(int func, float ref) {
+        begin("glAlphaFunc");
+        arg("func", func);
+        arg("ref", ref);
+        end();
+        mgl.glAlphaFunc(func, ref);
+        checkError();
+    }
+
+    public void glAlphaFuncx(int func, int ref) {
+        begin("glAlphaFuncx");
+        arg("func", func);
+        arg("ref", ref);
+        end();
+        mgl.glAlphaFuncx(func, ref);
+        checkError();
+    }
+
+    public void glBindTexture(int target, int texture) {
+        begin("glBindTexture");
+        arg("target", getTextureTarget(target));
+        arg("texture", texture);
+        end();
+        mgl.glBindTexture(target, texture);
+        checkError();
+    }
+
+    public void glBlendFunc(int sfactor, int dfactor) {
+        begin("glBlendFunc");
+        arg("sfactor", getFactor(sfactor));
+        arg("dfactor", getFactor(dfactor));
+        end();
+
+        mgl.glBlendFunc(sfactor, dfactor);
+        checkError();
+    }
+
+    public void glClear(int mask) {
+        begin("glClear");
+        arg("mask", getClearBufferMask(mask));
+        end();
+
+        mgl.glClear(mask);
+        checkError();
+    }
+
+    public void glClearColor(float red, float green, float blue, float alpha) {
+        begin("glClearColor");
+        arg("red", red);
+        arg("green", green);
+        arg("blue", blue);
+        arg("alpha", alpha);
+        end();
+
+        mgl.glClearColor(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glClearColorx(int red, int green, int blue, int alpha) {
+        begin("glClearColor");
+        arg("red", red);
+        arg("green", green);
+        arg("blue", blue);
+        arg("alpha", alpha);
+        end();
+
+        mgl.glClearColorx(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glClearDepthf(float depth) {
+        begin("glClearDepthf");
+        arg("depth", depth);
+        end();
+
+        mgl.glClearDepthf(depth);
+        checkError();
+    }
+
+    public void glClearDepthx(int depth) {
+        begin("glClearDepthx");
+        arg("depth", depth);
+        end();
+
+        mgl.glClearDepthx(depth);
+        checkError();
+    }
+
+    public void glClearStencil(int s) {
+        begin("glClearStencil");
+        arg("s", s);
+        end();
+
+        mgl.glClearStencil(s);
+        checkError();
+    }
+
+    public void glClientActiveTexture(int texture) {
+        begin("glClientActiveTexture");
+        arg("texture", texture);
+        end();
+
+        mgl.glClientActiveTexture(texture);
+        checkError();
+    }
+
+    public void glColor4f(float red, float green, float blue, float alpha) {
+        begin("glColor4f");
+        arg("red", red);
+        arg("green", green);
+        arg("blue", blue);
+        arg("alpha", alpha);
+        end();
+
+        mgl.glColor4f(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glColor4x(int red, int green, int blue, int alpha) {
+        begin("glColor4x");
+        arg("red", red);
+        arg("green", green);
+        arg("blue", blue);
+        arg("alpha", alpha);
+        end();
+
+        mgl.glColor4x(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glColorMask(boolean red, boolean green, boolean blue,
+            boolean alpha) {
+        begin("glColorMask");
+        arg("red", red);
+        arg("green", green);
+        arg("blue", blue);
+        arg("alpha", alpha);
+        end();
+
+        mgl.glColorMask(red, green, blue, alpha);
+        checkError();
+    }
+
+    public void glColorPointer(int size, int type, int stride, Buffer pointer) {
+        begin("glColorPointer");
+        argPointer(size, type, stride, pointer);
+        end();
+        mColorPointer = new PointerInfo(size, type, stride, pointer);
+
+        mgl.glColorPointer(size, type, stride, pointer);
+        checkError();
+    }
+
+    public void glCompressedTexImage2D(int target, int level,
+            int internalformat, int width, int height, int border,
+            int imageSize, Buffer data) {
+        begin("glCompressedTexImage2D");
+        arg("target", getTextureTarget(target));
+        arg("level", level);
+        arg("internalformat", internalformat);
+        arg("width", width);
+        arg("height", height);
+        arg("border", border);
+        arg("imageSize", imageSize);
+        arg("data", data.toString());
+        end();
+
+        mgl.glCompressedTexImage2D(target, level, internalformat, width,
+                height, border, imageSize, data);
+        checkError();
+    }
+
+    public void glCompressedTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int width, int height, int format, int imageSize,
+            Buffer data) {
+        begin("glCompressedTexSubImage2D");
+        arg("target", getTextureTarget(target));
+        arg("level", level);
+        arg("xoffset", xoffset);
+        arg("yoffset", yoffset);
+        arg("width", width);
+        arg("height", height);
+        arg("format", format);
+        arg("imageSize", imageSize);
+        arg("data", data.toString());
+        end();
+
+        mgl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width,
+                height, format, imageSize, data);
+        checkError();
+    }
+
+    public void glCopyTexImage2D(int target, int level, int internalformat,
+            int x, int y, int width, int height, int border) {
+        begin("glCopyTexImage2D");
+        arg("target", getTextureTarget(target));
+        arg("level", level);
+        arg("internalformat", internalformat);
+        arg("x", x);
+        arg("y", y);
+        arg("width", width);
+        arg("height", height);
+        arg("border", border);
+        end();
+
+        mgl.glCopyTexImage2D(target, level, internalformat, x, y, width,
+                height, border);
+        checkError();
+    }
+
+    public void glCopyTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int x, int y, int width, int height) {
+        begin("glCopyTexSubImage2D");
+        arg("target", getTextureTarget(target));
+        arg("level", level);
+        arg("xoffset", xoffset);
+        arg("yoffset", yoffset);
+        arg("x", x);
+        arg("y", y);
+        arg("width", width);
+        arg("height", height);
+        end();
+
+        mgl.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width,
+                height);
+        checkError();
+    }
+
+    public void glCullFace(int mode) {
+        begin("glCullFace");
+        arg("mode", mode);
+        end();
+
+        mgl.glCullFace(mode);
+        checkError();
+    }
+
+    public void glDeleteTextures(int n, int[] textures, int offset) {
+        begin("glDeleteTextures");
+        arg("n", n);
+        arg("textures", n, textures, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glDeleteTextures(n, textures, offset);
+        checkError();
+    }
+
+    public void glDeleteTextures(int n, IntBuffer textures) {
+        begin("glDeleteTextures");
+        arg("n", n);
+        arg("textures", n, textures);
+        end();
+
+        mgl.glDeleteTextures(n, textures);
+        checkError();
+    }
+
+    public void glDepthFunc(int func) {
+        begin("glDepthFunc");
+        arg("func", func);
+        end();
+
+        mgl.glDepthFunc(func);
+        checkError();
+    }
+
+    public void glDepthMask(boolean flag) {
+        begin("glDepthMask");
+        arg("flag", flag);
+        end();
+
+        mgl.glDepthMask(flag);
+        checkError();
+    }
+
+    public void glDepthRangef(float near, float far) {
+        begin("glDepthRangef");
+        arg("near", near);
+        arg("far", far);
+        end();
+
+        mgl.glDepthRangef(near, far);
+        checkError();
+    }
+
+    public void glDepthRangex(int near, int far) {
+        begin("glDepthRangex");
+        arg("near", near);
+        arg("far", far);
+        end();
+
+        mgl.glDepthRangex(near, far);
+        checkError();
+    }
+
+    public void glDisable(int cap) {
+        begin("glDisable");
+        arg("cap", getCap(cap));
+        end();
+
+        mgl.glDisable(cap);
+        checkError();
+    }
+
+    public void glDisableClientState(int array) {
+        begin("glDisableClientState");
+        arg("array", getClientState(array));
+        end();
+
+        switch (array) {
+        case GL_COLOR_ARRAY:
+            mColorArrayEnabled = false;
+            break;
+        case GL_NORMAL_ARRAY:
+            mNormalArrayEnabled = false;
+            break;
+        case GL_TEXTURE_COORD_ARRAY:
+            mTextureCoordArrayEnabled = false;
+            break;
+        case GL_VERTEX_ARRAY:
+            mVertexArrayEnabled = false;
+            break;
+        }
+        mgl.glDisableClientState(array);
+        checkError();
+    }
+
+    public void glDrawArrays(int mode, int first, int count) {
+        begin("glDrawArrays");
+        arg("mode", mode);
+        arg("first", first);
+        arg("count", count);
+        startLogIndices();
+        for (int i = 0; i < count; i++) {
+            doElement(mStringBuilder, i, first + count);
+        }
+        endLogIndices();
+        end();
+
+        mgl.glDrawArrays(mode, first, count);
+        checkError();
+    }
+
+    public void glDrawElements(int mode, int count, int type, Buffer indices) {
+        begin("glDrawElements");
+        arg("mode", getBeginMode(mode));
+        arg("count", count);
+        arg("type", getIndexType(type));
+        char[] indexArray = toCharIndices(count, type, indices);
+        int indexArrayLength = indexArray.length;
+        startLogIndices();
+        for (int i = 0; i < indexArrayLength; i++) {
+            doElement(mStringBuilder, i, indexArray[i]);
+        }
+        endLogIndices();
+        end();
+
+        mgl.glDrawElements(mode, count, type, indices);
+        checkError();
+    }
+
+    public void glEnable(int cap) {
+        begin("glEnable");
+        arg("cap", getCap(cap));
+        end();
+
+        mgl.glEnable(cap);
+        checkError();
+    }
+
+    public void glEnableClientState(int array) {
+        begin("glEnableClientState");
+        arg("array", getClientState(array));
+        end();
+
+        switch (array) {
+        case GL_COLOR_ARRAY:
+            mColorArrayEnabled = true;
+            break;
+        case GL_NORMAL_ARRAY:
+            mNormalArrayEnabled = true;
+            break;
+        case GL_TEXTURE_COORD_ARRAY:
+            mTextureCoordArrayEnabled = true;
+            break;
+        case GL_VERTEX_ARRAY:
+            mVertexArrayEnabled = true;
+            break;
+        }
+        mgl.glEnableClientState(array);
+        checkError();
+    }
+
+    public void glFinish() {
+        begin("glFinish");
+        end();
+
+        mgl.glFinish();
+        checkError();
+    }
+
+    public void glFlush() {
+        begin("glFlush");
+        end();
+
+        mgl.glFlush();
+        checkError();
+    }
+
+    public void glFogf(int pname, float param) {
+        begin("glFogf");
+        arg("pname", pname);
+        arg("param", param);
+        end();
+
+        mgl.glFogf(pname, param);
+        checkError();
+    }
+
+    public void glFogfv(int pname, float[] params, int offset) {
+        begin("glFogfv");
+        arg("pname", getFogPName(pname));
+        arg("params", getFogParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glFogfv(pname, params, offset);
+        checkError();
+    }
+
+    public void glFogfv(int pname, FloatBuffer params) {
+        begin("glFogfv");
+        arg("pname", getFogPName(pname));
+        arg("params", getFogParamCount(pname), params);
+        end();
+
+        mgl.glFogfv(pname, params);
+        checkError();
+    }
+
+    public void glFogx(int pname, int param) {
+        begin("glFogx");
+        arg("pname", getFogPName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glFogx(pname, param);
+        checkError();
+    }
+
+    public void glFogxv(int pname, int[] params, int offset) {
+        begin("glFogxv");
+        arg("pname", getFogPName(pname));
+        arg("params", getFogParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glFogxv(pname, params, offset);
+        checkError();
+    }
+
+    public void glFogxv(int pname, IntBuffer params) {
+        begin("glFogxv");
+        arg("pname", getFogPName(pname));
+        arg("params", getFogParamCount(pname), params);
+        end();
+
+        mgl.glFogxv(pname, params);
+        checkError();
+    }
+
+    public void glFrontFace(int mode) {
+        begin("glFrontFace");
+        arg("mode", mode);
+        end();
+
+        mgl.glFrontFace(mode);
+        checkError();
+    }
+
+    public void glFrustumf(float left, float right, float bottom, float top,
+            float near, float far) {
+        begin("glFrustumf");
+        arg("left", left);
+        arg("right", right);
+        arg("bottom", bottom);
+        arg("top", top);
+        arg("near", near);
+        arg("far", far);
+        end();
+
+        mgl.glFrustumf(left, right, bottom, top, near, far);
+        checkError();
+    }
+
+    public void glFrustumx(int left, int right, int bottom, int top, int near,
+            int far) {
+        begin("glFrustumx");
+        arg("left", left);
+        arg("right", right);
+        arg("bottom", bottom);
+        arg("top", top);
+        arg("near", near);
+        arg("far", far);
+        end();
+
+        mgl.glFrustumx(left, right, bottom, top, near, far);
+        checkError();
+    }
+
+    public void glGenTextures(int n, int[] textures, int offset) {
+        begin("glGenTextures");
+        arg("n", n);
+        arg("textures", Arrays.toString(textures));
+        arg("offset", offset);
+
+        mgl.glGenTextures(n, textures, offset);
+
+        returns(toString(n, FORMAT_INT, textures, offset));
+
+        checkError();
+    }
+
+    public void glGenTextures(int n, IntBuffer textures) {
+        begin("glGenTextures");
+        arg("n", n);
+        arg("textures", textures.toString());
+
+        mgl.glGenTextures(n, textures);
+
+        returns(toString(n, FORMAT_INT, textures));
+
+        checkError();
+    }
+
+    public int glGetError() {
+        begin("glGetError");
+
+        int result = mgl.glGetError();
+
+        returns(result);
+
+        return result;
+    }
+
+    public void glGetIntegerv(int pname, int[] params, int offset) {
+        begin("glGetIntegerv");
+        arg("pname", getIntegerStateName(pname));
+        arg("params", Arrays.toString(params));
+        arg("offset", offset);
+
+        mgl.glGetIntegerv(pname, params, offset);
+
+        returns(toString(getIntegerStateSize(pname),
+                getIntegerStateFormat(pname), params, offset));
+
+        checkError();
+    }
+
+    public void glGetIntegerv(int pname, IntBuffer params) {
+        begin("glGetIntegerv");
+        arg("pname", getIntegerStateName(pname));
+        arg("params", params.toString());
+
+        mgl.glGetIntegerv(pname, params);
+
+        returns(toString(getIntegerStateSize(pname),
+                getIntegerStateFormat(pname), params));
+
+        checkError();
+    }
+
+    public String glGetString(int name) {
+        begin("glGetString");
+        arg("name", name);
+
+        String result = mgl.glGetString(name);
+
+        returns(result);
+
+        checkError();
+        return result;
+    }
+
+    public void glHint(int target, int mode) {
+        begin("glHint");
+        arg("target", getHintTarget(target));
+        arg("mode", getHintMode(mode));
+        end();
+
+        mgl.glHint(target, mode);
+        checkError();
+    }
+
+    public void glLightModelf(int pname, float param) {
+        begin("glLightModelf");
+        arg("pname", getLightModelPName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glLightModelf(pname, param);
+        checkError();
+    }
+
+    public void glLightModelfv(int pname, float[] params, int offset) {
+        begin("glLightModelfv");
+        arg("pname", getLightModelPName(pname));
+        arg("params", getLightModelParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glLightModelfv(pname, params, offset);
+        checkError();
+    }
+
+    public void glLightModelfv(int pname, FloatBuffer params) {
+        begin("glLightModelfv");
+        arg("pname", getLightModelPName(pname));
+        arg("params", getLightModelParamCount(pname), params);
+        end();
+
+        mgl.glLightModelfv(pname, params);
+        checkError();
+    }
+
+    public void glLightModelx(int pname, int param) {
+        begin("glLightModelx");
+        arg("pname", getLightModelPName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glLightModelx(pname, param);
+        checkError();
+    }
+
+    public void glLightModelxv(int pname, int[] params, int offset) {
+        begin("glLightModelxv");
+        arg("pname", getLightModelPName(pname));
+        arg("params", getLightModelParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glLightModelxv(pname, params, offset);
+        checkError();
+    }
+
+    public void glLightModelxv(int pname, IntBuffer params) {
+        begin("glLightModelfv");
+        arg("pname", getLightModelPName(pname));
+        arg("params", getLightModelParamCount(pname), params);
+        end();
+
+        mgl.glLightModelxv(pname, params);
+        checkError();
+    }
+
+    public void glLightf(int light, int pname, float param) {
+        begin("glLightf");
+        arg("light", getLightName(light));
+        arg("pname", getLightPName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glLightf(light, pname, param);
+        checkError();
+    }
+
+    public void glLightfv(int light, int pname, float[] params, int offset) {
+        begin("glLightfv");
+        arg("light", getLightName(light));
+        arg("pname", getLightPName(pname));
+        arg("params", getLightParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glLightfv(light, pname, params, offset);
+        checkError();
+    }
+
+    public void glLightfv(int light, int pname, FloatBuffer params) {
+        begin("glLightfv");
+        arg("light", getLightName(light));
+        arg("pname", getLightPName(pname));
+        arg("params", getLightParamCount(pname), params);
+        end();
+
+        mgl.glLightfv(light, pname, params);
+        checkError();
+    }
+
+    public void glLightx(int light, int pname, int param) {
+        begin("glLightx");
+        arg("light", getLightName(light));
+        arg("pname", getLightPName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glLightx(light, pname, param);
+        checkError();
+    }
+
+    public void glLightxv(int light, int pname, int[] params, int offset) {
+        begin("glLightxv");
+        arg("light", getLightName(light));
+        arg("pname", getLightPName(pname));
+        arg("params", getLightParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glLightxv(light, pname, params, offset);
+        checkError();
+    }
+
+    public void glLightxv(int light, int pname, IntBuffer params) {
+        begin("glLightxv");
+        arg("light", getLightName(light));
+        arg("pname", getLightPName(pname));
+        arg("params", getLightParamCount(pname), params);
+        end();
+
+        mgl.glLightxv(light, pname, params);
+        checkError();
+    }
+
+    public void glLineWidth(float width) {
+        begin("glLineWidth");
+        arg("width", width);
+        end();
+
+        mgl.glLineWidth(width);
+        checkError();
+    }
+
+    public void glLineWidthx(int width) {
+        begin("glLineWidthx");
+        arg("width", width);
+        end();
+
+        mgl.glLineWidthx(width);
+        checkError();
+    }
+
+    public void glLoadIdentity() {
+        begin("glLoadIdentity");
+        end();
+
+        mgl.glLoadIdentity();
+        checkError();
+    }
+
+    public void glLoadMatrixf(float[] m, int offset) {
+        begin("glLoadMatrixf");
+        arg("m", 16, m, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glLoadMatrixf(m, offset);
+        checkError();
+    }
+
+    public void glLoadMatrixf(FloatBuffer m) {
+        begin("glLoadMatrixf");
+        arg("m", 16, m);
+        end();
+
+        mgl.glLoadMatrixf(m);
+        checkError();
+    }
+
+    public void glLoadMatrixx(int[] m, int offset) {
+        begin("glLoadMatrixx");
+        arg("m", 16, m, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glLoadMatrixx(m, offset);
+        checkError();
+    }
+
+    public void glLoadMatrixx(IntBuffer m) {
+        begin("glLoadMatrixx");
+        arg("m", 16, m);
+        end();
+
+        mgl.glLoadMatrixx(m);
+        checkError();
+    }
+
+    public void glLogicOp(int opcode) {
+        begin("glLogicOp");
+        arg("opcode", opcode);
+        end();
+
+        mgl.glLogicOp(opcode);
+        checkError();
+    }
+
+    public void glMaterialf(int face, int pname, float param) {
+        begin("glMaterialf");
+        arg("face", getFaceName(face));
+        arg("pname", getMaterialPName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glMaterialf(face, pname, param);
+        checkError();
+    }
+
+    public void glMaterialfv(int face, int pname, float[] params, int offset) {
+        begin("glMaterialfv");
+        arg("face", getFaceName(face));
+        arg("pname", getMaterialPName(pname));
+        arg("params", getMaterialParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glMaterialfv(face, pname, params, offset);
+        checkError();
+    }
+
+    public void glMaterialfv(int face, int pname, FloatBuffer params) {
+        begin("glMaterialfv");
+        arg("face", getFaceName(face));
+        arg("pname", getMaterialPName(pname));
+        arg("params", getMaterialParamCount(pname), params);
+        end();
+
+        mgl.glMaterialfv(face, pname, params);
+        checkError();
+    }
+
+    public void glMaterialx(int face, int pname, int param) {
+        begin("glMaterialx");
+        arg("face", getFaceName(face));
+        arg("pname", getMaterialPName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glMaterialx(face, pname, param);
+        checkError();
+    }
+
+    public void glMaterialxv(int face, int pname, int[] params, int offset) {
+        begin("glMaterialxv");
+        arg("face", getFaceName(face));
+        arg("pname", getMaterialPName(pname));
+        arg("params", getMaterialParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glMaterialxv(face, pname, params, offset);
+        checkError();
+    }
+
+    public void glMaterialxv(int face, int pname, IntBuffer params) {
+        begin("glMaterialxv");
+        arg("face", getFaceName(face));
+        arg("pname", getMaterialPName(pname));
+        arg("params", getMaterialParamCount(pname), params);
+        end();
+
+        mgl.glMaterialxv(face, pname, params);
+        checkError();
+    }
+
+    public void glMatrixMode(int mode) {
+        begin("glMatrixMode");
+        arg("mode", getMatrixMode(mode));
+        end();
+
+        mgl.glMatrixMode(mode);
+        checkError();
+    }
+
+    public void glMultMatrixf(float[] m, int offset) {
+        begin("glMultMatrixf");
+        arg("m", 16, m, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glMultMatrixf(m, offset);
+        checkError();
+    }
+
+    public void glMultMatrixf(FloatBuffer m) {
+        begin("glMultMatrixf");
+        arg("m", 16, m);
+        end();
+
+        mgl.glMultMatrixf(m);
+        checkError();
+    }
+
+    public void glMultMatrixx(int[] m, int offset) {
+        begin("glMultMatrixx");
+        arg("m", 16, m, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glMultMatrixx(m, offset);
+        checkError();
+    }
+
+    public void glMultMatrixx(IntBuffer m) {
+        begin("glMultMatrixx");
+        arg("m", 16, m);
+        end();
+
+        mgl.glMultMatrixx(m);
+        checkError();
+    }
+
+    public void glMultiTexCoord4f(int target, float s, float t, float r, float q) {
+        begin("glMultiTexCoord4f");
+        arg("target", target);
+        arg("s", s);
+        arg("t", t);
+        arg("r", r);
+        arg("q", q);
+        end();
+
+        mgl.glMultiTexCoord4f(target, s, t, r, q);
+        checkError();
+    }
+
+    public void glMultiTexCoord4x(int target, int s, int t, int r, int q) {
+        begin("glMultiTexCoord4x");
+        arg("target", target);
+        arg("s", s);
+        arg("t", t);
+        arg("r", r);
+        arg("q", q);
+        end();
+
+        mgl.glMultiTexCoord4x(target, s, t, r, q);
+        checkError();
+    }
+
+    public void glNormal3f(float nx, float ny, float nz) {
+        begin("glNormal3f");
+        arg("nx", nx);
+        arg("ny", ny);
+        arg("nz", nz);
+        end();
+
+        mgl.glNormal3f(nx, ny, nz);
+        checkError();
+    }
+
+    public void glNormal3x(int nx, int ny, int nz) {
+        begin("glNormal3x");
+        arg("nx", nx);
+        arg("ny", ny);
+        arg("nz", nz);
+        end();
+
+        mgl.glNormal3x(nx, ny, nz);
+        checkError();
+    }
+
+    public void glNormalPointer(int type, int stride, Buffer pointer) {
+        begin("glNormalPointer");
+        arg("type", type);
+        arg("stride", stride);
+        arg("pointer", pointer.toString());
+        end();
+        mNormalPointer = new PointerInfo(3, type, stride, pointer);
+
+        mgl.glNormalPointer(type, stride, pointer);
+        checkError();
+    }
+
+    public void glOrthof(float left, float right, float bottom, float top,
+            float near, float far) {
+        begin("glOrthof");
+        arg("left", left);
+        arg("right", right);
+        arg("bottom", bottom);
+        arg("top", top);
+        arg("near", near);
+        arg("far", far);
+        end();
+
+        mgl.glOrthof(left, right, bottom, top, near, far);
+        checkError();
+    }
+
+    public void glOrthox(int left, int right, int bottom, int top, int near,
+            int far) {
+        begin("glOrthox");
+        arg("left", left);
+        arg("right", right);
+        arg("bottom", bottom);
+        arg("top", top);
+        arg("near", near);
+        arg("far", far);
+        end();
+
+        mgl.glOrthox(left, right, bottom, top, near, far);
+        checkError();
+    }
+
+    public void glPixelStorei(int pname, int param) {
+        begin("glPixelStorei");
+        arg("pname", pname);
+        arg("param", param);
+        end();
+
+        mgl.glPixelStorei(pname, param);
+        checkError();
+    }
+
+    public void glPointSize(float size) {
+        begin("glPointSize");
+        arg("size", size);
+        end();
+
+        mgl.glPointSize(size);
+        checkError();
+    }
+
+    public void glPointSizex(int size) {
+        begin("glPointSizex");
+        arg("size", size);
+        end();
+
+        mgl.glPointSizex(size);
+        checkError();
+    }
+
+    public void glPolygonOffset(float factor, float units) {
+        begin("glPolygonOffset");
+        arg("factor", factor);
+        arg("units", units);
+        end();
+        mgl.glPolygonOffset(factor, units);
+        checkError();
+    }
+
+    public void glPolygonOffsetx(int factor, int units) {
+        begin("glPolygonOffsetx");
+        arg("factor", factor);
+        arg("units", units);
+        end();
+
+        mgl.glPolygonOffsetx(factor, units);
+        checkError();
+    }
+
+    public void glPopMatrix() {
+        begin("glPopMatrix");
+        end();
+
+        mgl.glPopMatrix();
+        checkError();
+    }
+
+    public void glPushMatrix() {
+        begin("glPushMatrix");
+        end();
+
+        mgl.glPushMatrix();
+        checkError();
+    }
+
+    public void glReadPixels(int x, int y, int width, int height, int format,
+            int type, Buffer pixels) {
+        begin("glReadPixels");
+        arg("x", x);
+        arg("y", y);
+        arg("width", width);
+        arg("height", height);
+        arg("format", format);
+        arg("type", type);
+        arg("pixels", pixels.toString());
+        end();
+
+        mgl.glReadPixels(x, y, width, height, format, type, pixels);
+        checkError();
+    }
+
+    public void glRotatef(float angle, float x, float y, float z) {
+        begin("glRotatef");
+        arg("angle", angle);
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        end();
+
+        mgl.glRotatef(angle, x, y, z);
+        checkError();
+    }
+
+    public void glRotatex(int angle, int x, int y, int z) {
+        begin("glRotatex");
+        arg("angle", angle);
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        end();
+
+        mgl.glRotatex(angle, x, y, z);
+        checkError();
+    }
+
+    public void glSampleCoverage(float value, boolean invert) {
+        begin("glSampleCoveragex");
+        arg("value", value);
+        arg("invert", invert);
+        end();
+
+        mgl.glSampleCoverage(value, invert);
+        checkError();
+    }
+
+    public void glSampleCoveragex(int value, boolean invert) {
+        begin("glSampleCoveragex");
+        arg("value", value);
+        arg("invert", invert);
+        end();
+
+        mgl.glSampleCoveragex(value, invert);
+        checkError();
+    }
+
+    public void glScalef(float x, float y, float z) {
+        begin("glScalef");
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        end();
+
+        mgl.glScalef(x, y, z);
+        checkError();
+    }
+
+    public void glScalex(int x, int y, int z) {
+        begin("glScalex");
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        end();
+
+        mgl.glScalex(x, y, z);
+        checkError();
+    }
+
+    public void glScissor(int x, int y, int width, int height) {
+        begin("glScissor");
+        arg("x", x);
+        arg("y", y);
+        arg("width", width);
+        arg("height", height);
+        end();
+
+        mgl.glScissor(x, y, width, height);
+        checkError();
+    }
+
+    public void glShadeModel(int mode) {
+        begin("glShadeModel");
+        arg("mode", getShadeModel(mode));
+        end();
+
+        mgl.glShadeModel(mode);
+        checkError();
+    }
+
+    public void glStencilFunc(int func, int ref, int mask) {
+        begin("glStencilFunc");
+        arg("func", func);
+        arg("ref", ref);
+        arg("mask", mask);
+        end();
+
+        mgl.glStencilFunc(func, ref, mask);
+        checkError();
+    }
+
+    public void glStencilMask(int mask) {
+        begin("glStencilMask");
+        arg("mask", mask);
+        end();
+
+        mgl.glStencilMask(mask);
+        checkError();
+    }
+
+    public void glStencilOp(int fail, int zfail, int zpass) {
+        begin("glStencilOp");
+        arg("fail", fail);
+        arg("zfail", zfail);
+        arg("zpass", zpass);
+        end();
+
+        mgl.glStencilOp(fail, zfail, zpass);
+        checkError();
+    }
+
+    public void glTexCoordPointer(int size, int type, int stride, Buffer pointer) {
+        begin("glTexCoordPointer");
+        argPointer(size, type, stride, pointer);
+        end();
+        mTexCoordPointer = new PointerInfo(size, type, stride, pointer);
+
+        mgl.glTexCoordPointer(size, type, stride, pointer);
+        checkError();
+    }
+
+    public void glTexEnvf(int target, int pname, float param) {
+        begin("glTexEnvf");
+        arg("target", getTextureEnvTarget(target));
+        arg("pname", getTextureEnvPName(pname));
+        arg("param", getTextureEnvParamName(param));
+        end();
+
+        mgl.glTexEnvf(target, pname, param);
+        checkError();
+    }
+
+    public void glTexEnvfv(int target, int pname, float[] params, int offset) {
+        begin("glTexEnvfv");
+        arg("target", getTextureEnvTarget(target));
+        arg("pname", getTextureEnvPName(pname));
+        arg("params", getTextureEnvParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glTexEnvfv(target, pname, params, offset);
+        checkError();
+    }
+
+    public void glTexEnvfv(int target, int pname, FloatBuffer params) {
+        begin("glTexEnvfv");
+        arg("target", getTextureEnvTarget(target));
+        arg("pname", getTextureEnvPName(pname));
+        arg("params", getTextureEnvParamCount(pname), params);
+        end();
+
+        mgl.glTexEnvfv(target, pname, params);
+        checkError();
+    }
+
+    public void glTexEnvx(int target, int pname, int param) {
+        begin("glTexEnvx");
+        arg("target", getTextureEnvTarget(target));
+        arg("pname", getTextureEnvPName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glTexEnvx(target, pname, param);
+        checkError();
+    }
+
+    public void glTexEnvxv(int target, int pname, int[] params, int offset) {
+        begin("glTexEnvxv");
+        arg("target", getTextureEnvTarget(target));
+        arg("pname", getTextureEnvPName(pname));
+        arg("params", getTextureEnvParamCount(pname), params, offset);
+        arg("offset", offset);
+        end();
+
+        mgl.glTexEnvxv(target, pname, params, offset);
+        checkError();
+    }
+
+    public void glTexEnvxv(int target, int pname, IntBuffer params) {
+        begin("glTexEnvxv");
+        arg("target", getTextureEnvTarget(target));
+        arg("pname", getTextureEnvPName(pname));
+        arg("params", getTextureEnvParamCount(pname), params);
+        end();
+
+        mgl.glTexEnvxv(target, pname, params);
+        checkError();
+    }
+
+    public void glTexImage2D(int target, int level, int internalformat,
+            int width, int height, int border, int format, int type,
+            Buffer pixels) {
+        begin("glTexImage2D");
+        arg("target", target);
+        arg("level", level);
+        arg("internalformat", internalformat);
+        arg("width", width);
+        arg("height", height);
+        arg("border", border);
+        arg("format", format);
+        arg("type", type);
+        arg("pixels", pixels.toString());
+        end();
+
+        mgl.glTexImage2D(target, level, internalformat, width, height, border,
+                format, type, pixels);
+        checkError();
+    }
+
+    public void glTexParameterf(int target, int pname, float param) {
+        begin("glTexParameterf");
+        arg("target", getTextureTarget(target));
+        arg("pname", getTexturePName(pname));
+        arg("param", getTextureParamName(param));
+        end();
+
+        mgl.glTexParameterf(target, pname, param);
+        checkError();
+    }
+
+    public void glTexParameterx(int target, int pname, int param) {
+        begin("glTexParameterx");
+        arg("target", getTextureTarget(target));
+        arg("pname", getTexturePName(pname));
+        arg("param", param);
+        end();
+
+        mgl.glTexParameterx(target, pname, param);
+        checkError();
+    }
+
+    public void glTexParameteriv(int target, int pname, int[] params, int offset) {
+        begin("glTexParameteriv");
+        arg("target", getTextureTarget(target));
+        arg("pname", getTexturePName(pname));
+        arg("params", 4, params, offset);
+        end();
+
+        mgl11.glTexParameteriv(target, pname, params, offset);
+        checkError();
+    }
+
+    public void glTexParameteriv(int target, int pname, IntBuffer params) {
+        begin("glTexParameteriv");
+        arg("target", getTextureTarget(target));
+        arg("pname", getTexturePName(pname));
+        arg("params", 4, params);
+        end();
+
+        mgl11.glTexParameteriv(target, pname, params);
+        checkError();
+    }
+
+    public void glTexSubImage2D(int target, int level, int xoffset,
+            int yoffset, int width, int height, int format, int type,
+            Buffer pixels) {
+        begin("glTexSubImage2D");
+        arg("target", getTextureTarget(target));
+        arg("level", level);
+        arg("xoffset", xoffset);
+        arg("yoffset", yoffset);
+        arg("width", width);
+        arg("height", height);
+        arg("format", format);
+        arg("type", type);
+        arg("pixels", pixels.toString());
+        end();
+        mgl.glTexSubImage2D(target, level, xoffset, yoffset, width, height,
+                format, type, pixels);
+        checkError();
+    }
+
+    public void glTranslatef(float x, float y, float z) {
+        begin("glTranslatef");
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        end();
+        mgl.glTranslatef(x, y, z);
+        checkError();
+    }
+
+    public void glTranslatex(int x, int y, int z) {
+        begin("glTranslatex");
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        end();
+        mgl.glTranslatex(x, y, z);
+        checkError();
+    }
+
+    public void glVertexPointer(int size, int type, int stride, Buffer pointer) {
+        begin("glVertexPointer");
+        argPointer(size, type, stride, pointer);
+        end();
+        mVertexPointer = new PointerInfo(size, type, stride, pointer);
+        mgl.glVertexPointer(size, type, stride, pointer);
+        checkError();
+    }
+
+    public void glViewport(int x, int y, int width, int height) {
+        begin("glViewport");
+        arg("x", x);
+        arg("y", y);
+        arg("width", width);
+        arg("height", height);
+        end();
+        mgl.glViewport(x, y, width, height);
+        checkError();
+    }
+
+    public void glClipPlanef(int plane, float[] equation, int offset) {
+        begin("glClipPlanef");
+        arg("plane", plane);
+        arg("equation", 4, equation, offset);
+        arg("offset", offset);
+        end();
+        mgl11.glClipPlanef(plane, equation, offset);
+        checkError();
+    }
+
+    public void glClipPlanef(int plane, FloatBuffer equation) {
+        begin("glClipPlanef");
+        arg("plane", plane);
+        arg("equation", 4, equation);
+        end();
+        mgl11.glClipPlanef(plane, equation);
+        checkError();
+    }
+
+    public void glClipPlanex(int plane, int[] equation, int offset) {
+        begin("glClipPlanex");
+        arg("plane", plane);
+        arg("equation", 4, equation, offset);
+        arg("offset", offset);
+        end();
+        mgl11.glClipPlanex(plane, equation, offset);
+        checkError();
+    }
+
+    public void glClipPlanex(int plane, IntBuffer equation) {
+        begin("glClipPlanef");
+        arg("plane", plane);
+        arg("equation", 4, equation);
+        end();
+        mgl11.glClipPlanex(plane, equation);
+        checkError();
+    }
+
+    // Draw Texture Extension
+
+    public void glDrawTexfOES(float x, float y, float z,
+        float width, float height) {
+        begin("glDrawTexfOES");
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        arg("width", width);
+        arg("height", height);
+        end();
+        mgl11Ext.glDrawTexfOES(x, y, z, width, height);
+        checkError();
+    }
+
+    public void glDrawTexfvOES(float[] coords, int offset) {
+        begin("glDrawTexfvOES");
+        arg("coords", 5, coords, offset);
+        arg("offset", offset);
+        end();
+        mgl11Ext.glDrawTexfvOES(coords, offset);
+        checkError();
+    }
+
+    public void glDrawTexfvOES(FloatBuffer coords) {
+        begin("glDrawTexfvOES");
+        arg("coords", 5, coords);
+        end();
+        mgl11Ext.glDrawTexfvOES(coords);
+        checkError();
+    }
+
+    public void glDrawTexiOES(int x, int y, int z, int width, int height) {
+        begin("glDrawTexiOES");
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        arg("width", width);
+        arg("height", height);
+        end();
+        mgl11Ext.glDrawTexiOES(x, y, z, width, height);
+        checkError();
+    }
+
+    public void glDrawTexivOES(int[] coords, int offset) {
+        begin("glDrawTexivOES");
+        arg("coords", 5, coords, offset);
+        arg("offset", offset);
+        end();
+        mgl11Ext.glDrawTexivOES(coords, offset);
+        checkError();
+    }
+
+    public void glDrawTexivOES(IntBuffer coords) {
+        begin("glDrawTexivOES");
+        arg("coords", 5, coords);
+        end();
+        mgl11Ext.glDrawTexivOES(coords);
+        checkError();
+    }
+
+    public void glDrawTexsOES(short x, short y, short z,
+        short width, short height) {
+        begin("glDrawTexsOES");
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        arg("width", width);
+        arg("height", height);
+        end();
+        mgl11Ext.glDrawTexsOES(x, y, z, width, height);
+        checkError();
+    }
+
+    public void glDrawTexsvOES(short[] coords, int offset) {
+        begin("glDrawTexsvOES");
+        arg("coords", 5, coords, offset);
+        arg("offset", offset);
+        end();
+        mgl11Ext.glDrawTexsvOES(coords, offset);
+        checkError();
+    }
+
+    public void glDrawTexsvOES(ShortBuffer coords) {
+        begin("glDrawTexsvOES");
+        arg("coords", 5, coords);
+        end();
+        mgl11Ext.glDrawTexsvOES(coords);
+        checkError();
+    }
+
+    public void glDrawTexxOES(int x, int y, int z, int width, int height) {
+        begin("glDrawTexxOES");
+        arg("x", x);
+        arg("y", y);
+        arg("z", z);
+        arg("width", width);
+        arg("height", height);
+        end();
+        mgl11Ext.glDrawTexxOES(x, y, z, width, height);
+        checkError();
+    }
+
+    public void glDrawTexxvOES(int[] coords, int offset) {
+        begin("glDrawTexxvOES");
+        arg("coords", 5, coords, offset);
+        arg("offset", offset);
+        end();
+        mgl11Ext.glDrawTexxvOES(coords, offset);
+        checkError();
+    }
+
+    public void glDrawTexxvOES(IntBuffer coords) {
+        begin("glDrawTexxvOES");
+        arg("coords", 5, coords);
+        end();
+        mgl11Ext.glDrawTexxvOES(coords);
+        checkError();
+    }
+
+    public int glQueryMatrixxOES(int[] mantissa, int mantissaOffset,
+        int[] exponent, int exponentOffset) {
+        begin("glQueryMatrixxOES");
+        arg("mantissa", Arrays.toString(mantissa));
+        arg("exponent", Arrays.toString(exponent));
+        end();
+        int valid = mgl10Ext.glQueryMatrixxOES(mantissa, mantissaOffset,
+            exponent, exponentOffset);
+        returns(toString(16, FORMAT_FIXED, mantissa, mantissaOffset));
+        returns(toString(16, FORMAT_INT, exponent, exponentOffset));
+        checkError();
+        return valid;
+    }
+
+    public int glQueryMatrixxOES(IntBuffer mantissa, IntBuffer exponent) {
+        begin("glQueryMatrixxOES");
+        arg("mantissa", mantissa.toString());
+        arg("exponent", exponent.toString());
+        end();
+        int valid = mgl10Ext.glQueryMatrixxOES(mantissa, exponent);
+        returns(toString(16, FORMAT_FIXED, mantissa));
+        returns(toString(16, FORMAT_INT, exponent));
+        checkError();
+        return valid;
+    }
+
+    // Unsupported GL11 methods
+
+    public void glBindBuffer(int target, int buffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBufferData(int target, int size, Buffer data, int usage) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBufferSubData(int target, int offset, int size, Buffer data) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glColor4ub(byte red, byte green, byte blue, byte alpha) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteBuffers(int n, int[] buffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteBuffers(int n, IntBuffer buffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenBuffers(int n, int[] buffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenBuffers(int n, IntBuffer buffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBooleanv(int pname, boolean[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBooleanv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBufferParameteriv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBufferParameteriv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanef(int pname, float[] eqn, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanef(int pname, FloatBuffer eqn) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanex(int pname, int[] eqn, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanex(int pname, IntBuffer eqn) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFixedv(int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFixedv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFloatv(int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFloatv(int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightfv(int light, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightfv(int light, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightxv(int light, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightxv(int light, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialfv(int face, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialfv(int face, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialxv(int face, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialxv(int face, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnviv(int env, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnviv(int env, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnvxv(int env, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnvxv(int env, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterfv(int target, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterfv(int target, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameteriv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameteriv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterxv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterxv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsBuffer(int buffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsEnabled(int cap) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsTexture(int texture) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterf(int pname, float param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterfv(int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterfv(int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterx(int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterxv(int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterxv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointSizePointerOES(int type, int stride, Buffer pointer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnvi(int target, int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnviv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnviv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterfv(int target, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterfv(int target, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameteri(int target, int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterxv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterxv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    private class PointerInfo {
+        /**
+         * The number of coordinates per vertex. 1..4
+         */
+        public int mSize;
+        /**
+         * The type of each coordinate.
+         */
+        public int mType;
+        /**
+         * The byte offset between consecutive vertices. 0 means mSize *
+         * sizeof(mType)
+         */
+        public int mStride;
+        public Buffer mPointer;
+        public ByteBuffer mTempByteBuffer; // Only valid during glDrawXXX calls
+
+        public PointerInfo(int size, int type, int stride, Buffer pointer) {
+            mSize = size;
+            mType = type;
+            mStride = stride;
+            mPointer = pointer;
+        }
+
+        public int sizeof(int type) {
+            switch (type) {
+            case GL_UNSIGNED_BYTE:
+                return 1;
+            case GL_BYTE:
+                return 1;
+            case GL_SHORT:
+                return 2;
+            case GL_FIXED:
+                return 4;
+            case GL_FLOAT:
+                return 4;
+            default:
+                return 0;
+            }
+        }
+
+        public int getStride() {
+            return mStride > 0 ? mStride : sizeof(mType) * mSize;
+        }
+
+        public void bindByteBuffer() {
+            mTempByteBuffer = toByteBuffer(-1, mPointer);
+        }
+
+        public void unbindByteBuffer() {
+            mTempByteBuffer = null;
+        }
+    }
+
+    private Writer mLog;
+    private boolean mLogArgumentNames;
+    private int mArgCount;
+
+    private PointerInfo mColorPointer;
+    private PointerInfo mNormalPointer;
+    private PointerInfo mTexCoordPointer;
+    private PointerInfo mVertexPointer;
+
+    boolean mColorArrayEnabled;
+    boolean mNormalArrayEnabled;
+    boolean mTextureCoordArrayEnabled;
+    boolean mVertexArrayEnabled;
+
+    StringBuilder mStringBuilder;
+}
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
new file mode 100644
index 0000000..42c53f9
--- /dev/null
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -0,0 +1,661 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.concurrent.Semaphore;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGL11;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+/**
+ * An implementation of SurfaceView that uses the dedicated surface for
+ * displaying an OpenGL animation.  This allows the animation to run in a
+ * separate thread, without requiring that it be driven by the update mechanism
+ * of the view hierarchy.
+ *
+ * The application-specific rendering code is delegated to a GLView.Renderer
+ * instance.
+ */
+public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
+    public final static int RENDERMODE_WHEN_DIRTY = 0;
+    public final static int RENDERMODE_CONTUOUSLY = 1;
+
+    /**
+     * Check glError() after every GL call.
+     */
+    public final static int DEBUG_CHECK_GL_ERROR = 1;
+
+    /**
+     * Log GL calls to the system log at "verbose" level with tag "GLSurfaceView".
+     */
+    public final static int DEBUG_LOG_GL_CALLS = 2;
+
+    public GLSurfaceView(Context context) {
+        super(context);
+        init();
+    }
+
+    public GLSurfaceView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        // Install a SurfaceHolder.Callback so we get notified when the
+        // underlying surface is created and destroyed
+        SurfaceHolder holder = getHolder();
+        holder.addCallback(this);
+        holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
+    }
+
+    /**
+     * Set the glWrapper to a new value. The current glWrapper is used
+     * whenever a surface is created. The default value is null.
+     * @param glWrapper the new GLWrapper
+     */
+    public void setGLWrapper(GLWrapper glWrapper) {
+        mGLWrapper = glWrapper;
+    }
+
+    /**
+     * Set the debug flags to a new value. The debug flags take effect
+     * whenever a surface is created. The default value is zero.
+     * @param debugFlags the new debug flags
+     * @see #DEBUG_CHECK_GL_ERROR
+     * @see #DEBUG_LOG_GL_CALLS
+     */
+    public void setDebugFlags(int debugFlags) {
+        mDebugFlags = debugFlags;
+    }
+
+    public int getDebugFlags() {
+        return mDebugFlags;
+    }
+
+    /**
+     * Set the renderer associated with this view. Can only be called once.
+     * @param renderer
+     */
+    public void setRenderer(Renderer renderer) {
+        if (mGLThread != null) {
+            throw new IllegalStateException("setRenderer has already been called for this instance.");
+        }
+        mGLThread = new GLThread(renderer);
+        mGLThread.start();
+    }
+
+    /**
+     * Set the rendering mode. When the renderMode is
+     * RENDERMODE_CONTINUOUSLY, the renderer is called
+     * repeatedly to re-render the scene. When the rendermode
+     * is RENDERMODE_WHEN_DIRTY, the renderer only rendered when the surface
+     * is created, or when requestRender is called. Defaults to RENDERMODE_CONTINUOUSLY.
+     * @param renderMode one of the RENDERMODE_X constants
+     */
+    public void setRenderMode(int renderMode) {
+        mGLThread.setRenderMode(renderMode);
+    }
+
+    /**
+     * Get the current rendering mode. May be called
+     * from any thread. Must not be called before a renderer has been set.
+     * @return true if the renderer will render continuously.
+     */
+    public int getRenderMode() {
+        return mGLThread.getRenderMode();
+    }
+
+    /**
+     * Request that the renderer render a frame. May be called
+     * from any thread. Must not be called before a renderer has been set.
+     * This method is typically used when the render mode has been set to
+     * false, so that frames are only rendered on demand.
+     */
+    public void requestRender() {
+        mGLThread.requestRender();
+    }
+
+    public void surfaceCreated(SurfaceHolder holder) {
+        mGLThread.surfaceCreated();
+    }
+
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // Surface will be destroyed when we return
+        mGLThread.surfaceDestroyed();
+    }
+
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        mGLThread.onWindowResize(w, h);
+    }
+
+    /**
+     * Inform the view that the activity is paused. The owner of this view must
+     * call this method when the activity is paused.
+     */
+    public void onPause() {
+        mGLThread.onPause();
+    }
+
+    /**
+     * Inform the view that the activity is resumed. The owner of this view must
+     * call this method when the activity is resumed.
+     */
+    public void onResume() {
+        mGLThread.onResume();
+    }
+
+    /**
+     * Queue an "event" to be run on the GL rendering thread.
+     * @param r the runnable to be run on the GL rendering thread.
+     */
+    public void queueEvent(Runnable r) {
+        mGLThread.queueEvent(r);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mGLThread.requestExitAndWait();
+    }
+
+    // ----------------------------------------------------------------------
+
+    public interface GLWrapper {
+      GL wrap(GL gl);
+    }
+
+    // ----------------------------------------------------------------------
+
+    /**
+     * A generic renderer interface.
+     */
+    public interface Renderer {
+        /**
+         * @return the EGL configuration specification desired by the renderer.
+         */
+        int[] getConfigSpec();
+
+        /**
+         * Surface created.
+         * Called when the surface is created. Called when the application
+         * starts, and whenever the GPU is reinitialized. This will
+         * typically happen when the device awakes after going to sleep.
+         * Set your textures here.
+         * @param gl the GL interface. Use <code>instanceof</code> to
+         * test if the interface supports GL11 or higher interfaces.
+         * @param config the EGLConfig of the created surface. Can be used
+         * to create matching pbuffers.
+         */
+        void onSurfaceCreated(GL10 gl, EGLConfig config);
+        /**
+         * Surface changed size.
+         * Called after the surface is created and whenever
+         * the OpenGL ES surface size changes. Set your viewport here.
+         * @param gl the GL interface. Use <code>instanceof</code> to
+         * test if the interface supports GL11 or higher interfaces.
+         * @param width
+         * @param height
+         */
+        void onSurfaceChanged(GL10 gl, int width, int height);
+        /**
+         * Draw the current frame.
+         * @param gl the GL interface. Use <code>instanceof</code> to
+         * test if the interface supports GL11 or higher interfaces.
+         */
+        void onDrawFrame(GL10 gl);
+    }
+
+    /**
+     * An EGL helper class.
+     */
+
+    private class EglHelper {
+        public EglHelper() {
+
+        }
+
+        /**
+         * Initialize EGL for a given configuration spec.
+         * @param configSpec
+         */
+        public void start(int[] configSpec){
+            /*
+             * Get an EGL instance
+             */
+            mEgl = (EGL10) EGLContext.getEGL();
+
+            /*
+             * Get to the default display.
+             */
+            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
+            /*
+             * We can now initialize EGL for that display
+             */
+            int[] version = new int[2];
+            mEgl.eglInitialize(mEglDisplay, version);
+
+            EGLConfig[] configs = new EGLConfig[1];
+            int[] num_config = new int[1];
+            mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1,
+                    num_config);
+            mEglConfig = configs[0];
+
+            /*
+            * Create an OpenGL ES context. This must be done only once, an
+            * OpenGL context is a somewhat heavy object.
+            */
+            mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig,
+                    EGL10.EGL_NO_CONTEXT, null);
+
+            mEglSurface = null;
+        }
+
+        /*
+         * React to the creation of a new surface by creating and returning an
+         * OpenGL interface that renders to that surface.
+         */
+        public GL createSurface(SurfaceHolder holder) {
+            /*
+             *  The window size has changed, so we need to create a new
+             *  surface.
+             */
+            if (mEglSurface != null) {
+
+                /*
+                 * Unbind and destroy the old EGL surface, if
+                 * there is one.
+                 */
+                mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
+                        EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+                mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+            }
+
+            /*
+             * Create an EGL surface we can render into.
+             */
+            mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay,
+                    mEglConfig, holder, null);
+
+            /*
+             * Before we can issue GL commands, we need to make sure
+             * the context is current and bound to a surface.
+             */
+            mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
+                    mEglContext);
+
+
+            GL gl = mEglContext.getGL();
+            if (mGLWrapper != null) {
+                gl = mGLWrapper.wrap(gl);
+            }
+
+            if ((mDebugFlags & (DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS))!= 0) {
+                int configFlags = 0;
+                Writer log = null;
+                if ((mDebugFlags & DEBUG_CHECK_GL_ERROR) != 0) {
+                    configFlags |= GLDebugHelper.CONFIG_CHECK_GL_ERROR;
+                }
+                if ((mDebugFlags & DEBUG_LOG_GL_CALLS) != 0) {
+                    log = new LogWriter();
+                }
+                gl = GLDebugHelper.wrap(gl, configFlags, log);
+            }
+            return gl;
+        }
+
+        /**
+         * Display the current render surface.
+         * @return false if the context has been lost.
+         */
+        public boolean swap() {
+            mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
+
+            /*
+             * Always check for EGL_CONTEXT_LOST, which means the context
+             * and all associated data were lost (For instance because
+             * the device went to sleep). We need to sleep until we
+             * get a new surface.
+             */
+            return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST;
+        }
+
+        public void finish() {
+            if (mEglSurface != null) {
+                mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
+                        EGL10.EGL_NO_SURFACE,
+                        EGL10.EGL_NO_CONTEXT);
+                mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+                mEglSurface = null;
+            }
+            if (mEglContext != null) {
+                mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+                mEglContext = null;
+            }
+            if (mEglDisplay != null) {
+                mEgl.eglTerminate(mEglDisplay);
+                mEglDisplay = null;
+            }
+        }
+
+        EGL10 mEgl;
+        EGLDisplay mEglDisplay;
+        EGLSurface mEglSurface;
+        EGLConfig mEglConfig;
+        EGLContext mEglContext;
+    }
+
+    /**
+     * A generic GL Thread. Takes care of initializing EGL and GL. Delegates
+     * to a Renderer instance to do the actual drawing. Can be configured to
+     * render continuously or on request.
+     *
+     */
+    class GLThread extends Thread {
+        GLThread(Renderer renderer) {
+            super();
+            mDone = false;
+            mWidth = 0;
+            mHeight = 0;
+            mRequestRender = true;
+            mRenderMode = RENDERMODE_CONTUOUSLY;
+            mRenderer = renderer;
+            setName("GLThread");
+        }
+
+        @Override
+        public void run() {
+            /*
+             * When the android framework launches a second instance of
+             * an activity, the new instance's onCreate() method may be
+             * called before the first instance returns from onDestroy().
+             *
+             * This semaphore ensures that only one instance at a time
+             * accesses EGL.
+             */
+            try {
+                try {
+                sEglSemaphore.acquire();
+                } catch (InterruptedException e) {
+                    return;
+                }
+                guardedRun();
+            } catch (InterruptedException e) {
+                // fall thru and exit normally
+            } finally {
+                sEglSemaphore.release();
+            }
+        }
+
+        private void guardedRun() throws InterruptedException {
+            mEglHelper = new EglHelper();
+            /*
+             * Specify a configuration for our opengl session
+             * and grab the first configuration that matches is
+             */
+            int[] configSpec = mRenderer.getConfigSpec();
+            mEglHelper.start(configSpec);
+
+            GL10 gl = null;
+            boolean tellRendererSurfaceCreated = true;
+            boolean tellRendererSurfaceChanged = true;
+
+            /*
+             * This is our main activity thread's loop, we go until
+             * asked to quit.
+             */
+            while (!mDone) {
+
+                /*
+                 *  Update the asynchronous state (window size)
+                 */
+                int w, h;
+                boolean changed;
+                boolean needStart = false;
+                synchronized (this) {
+                    Runnable r;
+                    while ((r = getEvent()) != null) {
+                        r.run();
+                    }
+                    if (mPaused) {
+                        mEglHelper.finish();
+                        needStart = true;
+                    }
+                    while (needToWait()) {
+                        wait();
+                    }
+                    if (mDone) {
+                        break;
+                    }
+                    changed = mSizeChanged;
+                    w = mWidth;
+                    h = mHeight;
+                    mSizeChanged = false;
+                    mRequestRender = false;
+                }
+                if (needStart) {
+                    mEglHelper.start(configSpec);
+                    tellRendererSurfaceCreated = true;
+                    changed = true;
+                }
+                if (changed) {
+                    gl = (GL10) mEglHelper.createSurface(getHolder());
+                    tellRendererSurfaceChanged = true;
+                }
+                if (tellRendererSurfaceCreated) {
+                    mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);
+                    tellRendererSurfaceCreated = false;
+                }
+                if (tellRendererSurfaceChanged) {
+                    mRenderer.onSurfaceChanged(gl, w, h);
+                    tellRendererSurfaceChanged = false;
+                }
+                if ((w > 0) && (h > 0)) {
+                    /* draw a frame here */
+                    mRenderer.onDrawFrame(gl);
+
+                    /*
+                     * Once we're done with GL, we need to call swapBuffers()
+                     * to instruct the system to display the rendered frame
+                     */
+                    mEglHelper.swap();
+                }
+             }
+
+            /*
+             * clean-up everything...
+             */
+            mEglHelper.finish();
+        }
+
+        private boolean needToWait() {
+            if (mDone) {
+                return false;
+            }
+
+            if (mPaused || (! mHasSurface)) {
+                return true;
+            }
+
+            if ((mWidth > 0) && (mHeight > 0) && (mRequestRender || (mRenderMode == RENDERMODE_CONTUOUSLY))) {
+                return false;
+            }
+
+            return true;
+        }
+
+        public void setRenderMode(int renderMode) {
+            if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTUOUSLY)) ) {
+                throw new IllegalArgumentException("renderMode");
+            }
+            synchronized(this) {
+                mRenderMode = renderMode;
+                if (renderMode == RENDERMODE_CONTUOUSLY) {
+                    notify();
+                }
+            }
+        }
+
+        public int getRenderMode() {
+            synchronized(this) {
+                return mRenderMode;
+            }
+        }
+
+        public void requestRender() {
+            synchronized(this) {
+                mRequestRender = true;
+                notify();
+            }
+        }
+
+        public void surfaceCreated() {
+            synchronized(this) {
+                mHasSurface = true;
+                notify();
+            }
+        }
+
+        public void surfaceDestroyed() {
+            synchronized(this) {
+                mHasSurface = false;
+                notify();
+            }
+        }
+
+        public void onPause() {
+            synchronized (this) {
+                mPaused = true;
+            }
+        }
+
+        public void onResume() {
+            synchronized (this) {
+                mPaused = false;
+                notify();
+            }
+        }
+
+        public void onWindowResize(int w, int h) {
+            synchronized (this) {
+                mWidth = w;
+                mHeight = h;
+                mSizeChanged = true;
+                notify();
+            }
+        }
+
+        public void requestExitAndWait() {
+            // don't call this from GLThread thread or it is a guaranteed
+            // deadlock!
+            synchronized(this) {
+                mDone = true;
+                notify();
+            }
+            try {
+                join();
+            } catch (InterruptedException ex) {
+                Thread.currentThread().interrupt();
+            }
+        }
+
+        /**
+         * Queue an "event" to be run on the GL rendering thread.
+         * @param r the runnable to be run on the GL rendering thread.
+         */
+        public void queueEvent(Runnable r) {
+            synchronized(this) {
+                mEventQueue.add(r);
+            }
+        }
+
+        private Runnable getEvent() {
+            synchronized(this) {
+                if (mEventQueue.size() > 0) {
+                    return mEventQueue.remove(0);
+                }
+
+            }
+            return null;
+        }
+
+        private boolean mDone;
+        private boolean mPaused;
+        private boolean mHasSurface;
+        private int mWidth;
+        private int mHeight;
+        private int mRenderMode;
+        private boolean mRequestRender;
+        private Renderer mRenderer;
+        private ArrayList<Runnable> mEventQueue = new ArrayList<Runnable>();
+        private EglHelper mEglHelper;
+    }
+
+    static class LogWriter extends Writer {
+
+        @Override public void close() {
+            flushBuilder();
+        }
+
+        @Override public void flush() {
+            flushBuilder();
+        }
+
+        @Override public void write(char[] buf, int offset, int count) {
+            for(int i = 0; i < count; i++) {
+                char c = buf[offset + i];
+                if ( c == '\n') {
+                    flushBuilder();
+                }
+                else {
+                    mBuilder.append(c);
+                }
+            }
+        }
+
+        private void flushBuilder() {
+            if (mBuilder.length() > 0) {
+                Log.v("GLSurfaceView", mBuilder.toString());
+                mBuilder.delete(0, mBuilder.length());
+            }
+        }
+
+        private StringBuilder mBuilder = new StringBuilder();
+    }
+
+    private static final Semaphore sEglSemaphore = new Semaphore(1);
+    private boolean mSizeChanged = true;
+
+    private GLThread mGLThread;
+    private GLWrapper mGLWrapper;
+    private int mDebugFlags;
+}
diff --git a/opengl/java/android/opengl/GLU.java b/opengl/java/android/opengl/GLU.java
new file mode 100644
index 0000000..0152f42
--- /dev/null
+++ b/opengl/java/android/opengl/GLU.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * A set of GL utilities inspired by the OpenGL Utility Toolkit.
+ * 
+ */
+
+public class GLU {
+
+    /**
+     * Return an error string from a GL or GLU error code.
+     * 
+     * @param error - a GL or GLU error code.
+     * @return the error string for the input error code, or NULL if the input
+     *         was not a valid GL or GLU error code.
+     */
+    public static String gluErrorString(int error) {
+        switch (error) {
+        case GL10.GL_NO_ERROR:
+            return "no error";
+        case GL10.GL_INVALID_ENUM:
+            return "invalid enum";
+        case GL10.GL_INVALID_VALUE:
+            return "invalid value";
+        case GL10.GL_INVALID_OPERATION:
+            return "invalid operation";
+        case GL10.GL_STACK_OVERFLOW:
+            return "stack overflow";
+        case GL10.GL_STACK_UNDERFLOW:
+            return "stack underflow";
+        case GL10.GL_OUT_OF_MEMORY:
+            return "out of memory";
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * Define a viewing transformation in terms of an eye point, a center of
+     * view, and an up vector.
+     * 
+     * @param gl a GL10 interface
+     * @param eyeX eye point X
+     * @param eyeY eye point Y
+     * @param eyeZ eye point Z
+     * @param centerX center of view X
+     * @param centerY center of view Y
+     * @param centerZ center of view Z
+     * @param upX up vector X
+     * @param upY up vector Y
+     * @param upZ up vector Z
+     */
+    public static void gluLookAt(GL10 gl, float eyeX, float eyeY, float eyeZ,
+            float centerX, float centerY, float centerZ, float upX, float upY,
+            float upZ) {
+
+        // See the OpenGL GLUT documentation for gluLookAt for a description
+        // of the algorithm. We implement it in a straightforward way:
+
+        float fx = centerX - eyeX;
+        float fy = centerY - eyeY;
+        float fz = centerZ - eyeZ;
+
+        // Normalize f
+        float rlf = 1.0f / Matrix.length(fx, fy, fz);
+        fx *= rlf;
+        fy *= rlf;
+        fz *= rlf;
+
+        // compute s = f x up (x means "cross product")
+        float sx = fy * upZ - fz * upY;
+        float sy = fz * upX - fx * upZ;
+        float sz = fx * upY - fy * upX;
+        
+        // and normalize s
+        float rls = 1.0f / Matrix.length(sx, sy, sz);
+        sx *= rls;
+        sy *= rls;
+        sz *= rls;
+        
+        // compute u = s x f
+        float ux = sy * fz - sz * fy;
+        float uy = sz * fx - sx * fz;
+        float uz = sx * fy - sy * fx;
+
+        float[] m = new float[16];
+        m[0] = sx;
+        m[1] = ux;
+        m[2] = -fx;
+        m[3] = 0.0f;
+
+        m[4] = sy;
+        m[5] = uy;
+        m[6] = -fy;
+        m[7] = 0.0f;
+
+        m[8] = sz;
+        m[9] = uz;
+        m[10] = -fz;
+        m[11] = 0.0f;
+
+        m[12] = 0.0f;
+        m[13] = 0.0f;
+        m[14] = 0.0f;
+        m[15] = 1.0f;
+
+        gl.glMultMatrixf(m, 0);
+        gl.glTranslatef(-eyeX, -eyeY, -eyeZ);
+    }
+
+    /**
+     * Set up a 2D orthographic projection matrix
+     * 
+     * @param gl
+     * @param left
+     * @param right
+     * @param bottom
+     * @param top
+     */
+    public static void gluOrtho2D(GL10 gl, float left, float right,
+            float bottom, float top) {
+        gl.glOrthof(left, right, bottom, top, -1.0f, 1.0f);
+    }
+
+    /**
+     * Set up a perspective projection matrix
+     * 
+     * @param gl a GL10 interface
+     * @param fovy specifies the field of view angle, in degrees, in the Y
+     *        direction.
+     * @param aspect specifies the aspect ration that determins the field of
+     *        view in the x direction. The aspect ratio is the ratio of x
+     *        (width) to y (height).
+     * @param zNear specifies the distance from the viewer to the near clipping
+     *        plane (always positive).
+     * @param zFar specifies the distance from the viewer to the far clipping
+     *        plane (always positive).
+     */
+    public static void gluPerspective(GL10 gl, float fovy, float aspect,
+            float zNear, float zFar) {
+        float top = zNear * (float) Math.tan(fovy * (Math.PI / 360.0));
+        float bottom = -top;
+        float left = bottom * aspect;
+        float right = top * aspect;
+        gl.glFrustumf(left, right, bottom, top, zNear, zFar);
+    }
+
+    /**
+     * Map object coordinates into window coordinates. gluProject transforms the
+     * specified object coordinates into window coordinates using model, proj,
+     * and view. The result is stored in win.
+     * <p>
+     * Note that you can use the OES_matrix_get extension, if present, to get
+     * the current modelView and projection matrices.
+     * 
+     * @param objX object coordinates X
+     * @param objY object coordinates Y
+     * @param objZ object coordinates Z
+     * @param model the current modelview matrix
+     * @param modelOffset the offset into the model array where the modelview
+     *        maxtrix data starts.
+     * @param project the current projection matrix
+     * @param projectOffset the offset into the project array where the project
+     *        matrix data starts.
+     * @param view the current view, {x, y, width, height}
+     * @param viewOffset the offset into the view array where the view vector
+     *        data starts.
+     * @param win the output vector {winX, winY, winZ}, that returns the
+     *        computed window coordinates.
+     * @param winOffset the offset into the win array where the win vector data
+     *        starts.
+     * @return A return value of GL_TRUE indicates success, a return value of
+     *         GL_FALSE indicates failure.
+     */
+    public static int gluProject(float objX, float objY, float objZ,
+            float[] model, int modelOffset, float[] project, int projectOffset,
+            int[] view, int viewOffset, float[] win, int winOffset) {
+        float[] m = new float[16];
+        Matrix.multiplyMM(m, 0, project, projectOffset, model, modelOffset);
+
+        float[] v = new float[4];
+
+        v[0] = objX;
+        v[1] = objY;
+        v[2] = objZ;
+        v[3] = 1.0f;
+
+        float[] v2 = new float[4];
+
+        Matrix.multiplyMV(v2, 0, m, 0, v, 0);
+
+        float w = v2[3];
+        if (w == 0.0f) {
+            return GL10.GL_FALSE;
+        }
+
+        float rw = 1.0f / w;
+
+        win[winOffset] =
+                view[viewOffset] + view[viewOffset + 2] * (v2[0] * rw + 1.0f)
+                        * 0.5f;
+        win[winOffset + 1] =
+                view[viewOffset + 1] + view[viewOffset + 3]
+                        * (v2[1] * rw + 1.0f) * 0.5f;
+        win[winOffset + 2] = (v2[2] * rw + 1.0f) * 0.5f;
+
+        return GL10.GL_TRUE;
+    }
+
+    /**
+     * Map window coordinates to object coordinates. gluUnProject maps the
+     * specified window coordinates into object coordinates using model, proj,
+     * and view. The result is stored in obj.
+     * <p>
+     * Note that you can use the OES_matrix_get extension, if present, to get
+     * the current modelView and projection matrices.
+     * 
+     * @param winX window coordinates X
+     * @param winY window coordinates Y
+     * @param winZ window coordinates Z
+     * @param model the current modelview matrix
+     * @param modelOffset the offset into the model array where the modelview
+     *        maxtrix data starts.
+     * @param project the current projection matrix
+     * @param projectOffset the offset into the project array where the project
+     *        matrix data starts.
+     * @param view the current view, {x, y, width, height}
+     * @param viewOffset the offset into the view array where the view vector
+     *        data starts.
+     * @param obj the output vector {objX, objY, objZ}, that returns the
+     *        computed object coordinates.
+     * @param objOffset the offset into the obj array where the obj vector data
+     *        starts.
+     * @return A return value of GL10.GL_TRUE indicates success, a return value
+     *         of GL10.GL_FALSE indicates failure.
+     */
+    public static int gluUnProject(float winX, float winY, float winZ,
+            float[] model, int modelOffset, float[] project, int projectOffset,
+            int[] view, int viewOffset, float[] obj, int objOffset) {
+        float[] pm = new float[16];
+        Matrix.multiplyMM(pm, 0, project, projectOffset, model, modelOffset);
+
+        float[] invPM = new float[16];
+        if (!Matrix.invertM(invPM, 0, pm, 0)) {
+            return GL10.GL_FALSE;
+        }
+
+        float[] v = new float[4];
+
+        v[0] =
+                2.0f * (winX - view[viewOffset + 0]) / view[viewOffset + 2]
+                        - 1.0f;
+        v[1] =
+                2.0f * (winY - view[viewOffset + 1]) / view[viewOffset + 3]
+                        - 1.0f;
+        v[2] = 2.0f * winZ - 1.0f;
+        v[3] = 1.0f;
+
+        float[] v2 = new float[4];
+
+        Matrix.multiplyMV(v2, 0, invPM, 0, v, 0);
+
+        obj[objOffset] = v2[0];
+        obj[objOffset + 1] = v2[1];
+        obj[objOffset + 2] = v2[2];
+
+        return GL10.GL_TRUE;
+    }
+
+ }
diff --git a/opengl/java/android/opengl/GLUtils.java b/opengl/java/android/opengl/GLUtils.java
new file mode 100644
index 0000000..df6c557
--- /dev/null
+++ b/opengl/java/android/opengl/GLUtils.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import javax.microedition.khronos.opengles.GL10;
+import android.graphics.Bitmap;
+
+/**
+ *
+ * Utility class to help bridging OpenGL ES and Android APIs.
+ *
+ */
+
+public final class GLUtils {
+
+    /*
+     * We use a class initializer to allow the native code to cache some
+     * field offsets.
+     */
+    static {
+        nativeClassInit();
+    }
+
+    private GLUtils() {
+    }
+
+    /**
+     * return the internal format as defined by OpenGL ES of the supplied bitmap.
+     *
+     * @param bitmap
+     * @return the internal format of the bitmap.
+     */
+    public static int getInternalFormat(Bitmap bitmap) {
+        if (bitmap == null) {
+            throw new NullPointerException("getInternalFormat can't be used with a null Bitmap");
+        }
+        switch (bitmap.getConfig()) {
+            case ALPHA_8:
+                return GL10.GL_ALPHA;
+            case ARGB_4444:
+            case ARGB_8888:
+                return GL10.GL_RGBA;
+            case RGB_565:
+                return GL10.GL_RGB;
+        }
+        throw new IllegalArgumentException("Unknown internalformat");
+    }
+
+    /**
+     * Return the type as defined by OpenGL ES of the supplied bitmap.
+     */
+    public static int getType(Bitmap bitmap) {
+        if (bitmap == null) {
+            throw new NullPointerException("getType can't be used with a null Bitmap");
+        }
+        int type;
+        switch(bitmap.getConfig()) {
+            case ARGB_4444:
+                type = GL10.GL_UNSIGNED_SHORT_4_4_4_4;
+                break;
+            case RGB_565:
+                type = GL10.GL_UNSIGNED_SHORT_5_6_5;
+                break;
+            case ALPHA_8:
+            case ARGB_8888:
+            default:
+                type = GL10.GL_UNSIGNED_BYTE;
+                break;
+        }
+        return type;
+    }
+
+    /**
+     * Calls glTexImage2D() on the current OpenGL context. If no context is
+     * current the behavior is the same as calling glTexImage2D() with  no
+     * current context, that is, eglGetError() will return the appropriate
+     * error.
+     * Unlike glTexImage2D() bitmap cannot be null and will raise an exception
+     * in that case.
+     * All other parameters are identical to those used for glTexImage2D().
+     *
+     * NOTE: this method doesn't change GL_UNPACK_ALIGNMENT, you must make
+     * sure to set it properly according to the supplied bitmap.
+     *
+     * Whether or not bitmap can have non power of two dimensions depends on
+     * the current OpenGL context. Always check glGetError() some time
+     * after calling this method, just like when using OpenGL directly.
+     *
+     * @param target
+     * @param level
+     * @param internalformat
+     * @param bitmap
+     * @param border
+     */
+    public static void texImage2D(int target, int level, int internalformat,
+            Bitmap bitmap, int border) {
+        if (bitmap == null) {
+            throw new NullPointerException("texImage2D can't be used with a null Bitmap");
+        }
+        int type = getType(bitmap);
+        if (native_texImage2D(target, level, internalformat, bitmap, type, border)!=0) {
+            throw new IllegalArgumentException("invalid Bitmap format");
+        }
+    }
+
+    /**
+     * A version of texImage2D() that takes an explicit type parameter
+     * as defined by the OpenGL ES specification.
+     *
+     * @param target
+     * @param level
+     * @param internalformat
+     * @param bitmap
+     * @param type
+     * @param border
+     */
+    public static void texImage2D(int target, int level, int internalformat,
+            Bitmap bitmap, int type, int border) {
+        if (bitmap == null) {
+            throw new NullPointerException("texImage2D can't be used with a null Bitmap");
+        }
+        if (native_texImage2D(target, level, internalformat, bitmap, type, border)!=0) {
+            throw new IllegalArgumentException("invalid Bitmap format");
+        }
+    }
+
+    /**
+     * A version of texImage2D that determines the internalFormat automatically.
+     *
+     * @param target
+     * @param level
+     * @param bitmap
+     * @param border
+     */
+    public static void texImage2D(int target, int level, Bitmap bitmap,
+            int border) {
+        if (bitmap == null) {
+            throw new NullPointerException("texImage2D can't be used with a null Bitmap");
+        }
+        int type = getType(bitmap);
+        if (native_texImage2D(target, level, -1, bitmap, type, border)!=0) {
+            throw new IllegalArgumentException("invalid Bitmap format");
+        }
+    }
+
+    /**
+     * Calls glTexSubImage2D() on the current OpenGL context. If no context is
+     * current the behavior is the same as calling glTexSubImage2D() with  no
+     * current context, that is, eglGetError() will return the appropriate
+     * error.
+     * Unlike glTexSubImage2D() bitmap cannot be null and will raise an exception
+     * in that case.
+     * All other parameters are identical to those used for glTexSubImage2D().
+     *
+     * NOTE: this method doesn't change GL_UNPACK_ALIGNMENT, you must make
+     * sure to set it properly according to the supplied bitmap.
+     *
+     * Whether or not bitmap can have non power of two dimensions depends on
+     * the current OpenGL context. Always check glGetError() some time
+     * after calling this method, just like when using OpenGL directly.
+     *
+     * @param target
+     * @param level
+     * @param xoffset
+     * @param yoffset
+     * @param bitmap
+     */
+    public static void texSubImage2D(int target, int level, int xoffset, int yoffset,
+            Bitmap bitmap) {
+        if (bitmap == null) {
+            throw new NullPointerException("texSubImage2D can't be used with a null Bitmap");
+        }
+        int type = getType(bitmap);
+        if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap, -1, type)!=0) {
+            throw new IllegalArgumentException("invalid Bitmap format");
+        }
+    }
+
+    /**
+     * A version of texSubImage2D() that takes an explicit type parameter
+     * as defined by the OpenGL ES specification.
+     *
+     * @param target
+     * @param level
+     * @param xoffset
+     * @param yoffset
+     * @param bitmap
+     * @param type
+     */
+    public static void texSubImage2D(int target, int level, int xoffset, int yoffset,
+            Bitmap bitmap, int format, int type) {
+        if (bitmap == null) {
+            throw new NullPointerException("texSubImage2D can't be used with a null Bitmap");
+        }
+        if (native_texSubImage2D(target, level, xoffset, yoffset, bitmap, format, type)!=0) {
+            throw new IllegalArgumentException("invalid Bitmap format");
+        }
+    }
+
+    native private static void nativeClassInit();
+
+    native private static int native_texImage2D(int target, int level, int internalformat,
+            Bitmap bitmap, int type, int border);
+    native private static int native_texSubImage2D(int target, int level, int xoffset, int yoffset,
+            Bitmap bitmap, int format, int type);
+}
diff --git a/opengl/java/android/opengl/GLWrapperBase.java b/opengl/java/android/opengl/GLWrapperBase.java
new file mode 100644
index 0000000..067f95f
--- /dev/null
+++ b/opengl/java/android/opengl/GLWrapperBase.java
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.nio.Buffer;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL10Ext;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+/**
+ * The abstract base class for a GL wrapper. Provides
+ * some convenient instance variables and default implementations.
+ */
+abstract class GLWrapperBase
+    implements GL, GL10, GL10Ext, GL11, GL11Ext {
+	public GLWrapperBase(GL gl) {
+		mgl = (GL10) gl;
+		if (gl instanceof GL10Ext) {
+			mgl10Ext = (GL10Ext) gl;
+		}
+		if (gl instanceof GL11) {
+			mgl11 = (GL11) gl;
+		}
+		if (gl instanceof GL11Ext) {
+			mgl11Ext = (GL11Ext) gl;
+		}
+		if (gl instanceof GL11ExtensionPack) {
+			mgl11ExtensionPack = (GL11ExtensionPack) gl;
+		}
+	}
+	
+	protected GL10 mgl;
+	protected GL10Ext mgl10Ext;
+	protected GL11 mgl11;
+	protected GL11Ext mgl11Ext;
+	protected GL11ExtensionPack mgl11ExtensionPack;
+
+    // Unsupported GL11 methods
+
+    public void glGetPointerv(int pname, java.nio.Buffer[] params) {
+        throw new UnsupportedOperationException();
+    }
+
+    // VBO versions of *Pointer and *Elements methods
+    public void glColorPointer(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glNormalPointer(int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexCoordPointer(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glVertexPointer(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDrawElements(int mode, int count, int type, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBindBuffer(int target, int buffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBufferData(int target, int size, Buffer data, int usage) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBufferSubData(int target, int offset, int size, Buffer data) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glColor4ub(byte red, byte green, byte blue, byte alpha) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteBuffers(int n, int[] buffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteBuffers(int n, IntBuffer buffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenBuffers(int n, int[] buffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenBuffers(int n, IntBuffer buffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBooleanv(int pname, boolean[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBooleanv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBufferParameteriv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetBufferParameteriv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanef(int pname, float[] eqn, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanef(int pname, FloatBuffer eqn) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanex(int pname, int[] eqn, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetClipPlanex(int pname, IntBuffer eqn) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFixedv(int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFixedv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFloatv(int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFloatv(int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightfv(int light, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightfv(int light, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightxv(int light, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetLightxv(int light, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialfv(int face, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialfv(int face, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialxv(int face, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetMaterialxv(int face, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnviv(int env, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnviv(int env, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnvxv(int env, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexEnvxv(int env, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterfv(int target, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterfv(int target, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameteriv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameteriv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterxv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexParameterxv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsBuffer(int buffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsEnabled(int cap) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsTexture(int texture) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterf(int pname, float param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterfv(int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterfv(int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterx(int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterxv(int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointParameterxv(int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glPointSizePointerOES(int type, int stride, Buffer pointer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnvi(int target, int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnviv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexEnviv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterfv(int target, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterfv(int target, int pname, FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameteri(int target, int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterxv(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexParameterxv(int target, int pname, IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    // Unsupported GL11Ext methods
+
+    public void glCurrentPaletteMatrixOES(int matrixpaletteindex) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glLoadPaletteFromModelViewMatrixOES() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glMatrixIndexPointerOES(int size, int type, int stride, Buffer pointer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glMatrixIndexPointerOES(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glWeightPointerOES(int size, int type, int stride, Buffer pointer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glWeightPointerOES(int size, int type, int stride, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    // Unsupported GL11ExtensionPack methods
+
+    public void glBindFramebufferOES(int target, int framebuffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBindRenderbufferOES(int target, int renderbuffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBlendEquation(int mode) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBlendEquationSeparate(int modeRGB, int modeAlpha) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glBlendFuncSeparate(int srcRGB, int dstRGB, int srcAlpha, int dstAlpha) {
+        throw new UnsupportedOperationException();
+    }
+
+    int glCheckFramebufferStatusOES(int target) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glCompressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, int imageSize) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteFramebuffersOES(int n, int[] framebuffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteFramebuffersOES(int n, java.nio.IntBuffer framebuffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteRenderbuffersOES(int n, int[] renderbuffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glDeleteRenderbuffersOES(int n, java.nio.IntBuffer renderbuffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glFramebufferRenderbufferOES(int target, int attachment, int renderbuffertarget, int renderbuffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glFramebufferTexture2DOES(int target, int attachment, int textarget, int texture, int level) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenerateMipmapOES(int target) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenFramebuffersOES(int n, int[] framebuffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenFramebuffersOES(int n, java.nio.IntBuffer framebuffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenRenderbuffersOES(int n, int[] renderbuffers, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGenRenderbuffersOES(int n, java.nio.IntBuffer renderbuffers) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFramebufferAttachmentParameterivOES(int target, int attachment, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetFramebufferAttachmentParameterivOES(int target, int attachment, int pname, java.nio.IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetRenderbufferParameterivOES(int target, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetRenderbufferParameterivOES(int target, int pname, java.nio.IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexGenfv(int coord, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexGenfv(int coord, int pname, java.nio.FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexGeniv(int coord, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexGeniv(int coord, int pname, java.nio.IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexGenxv(int coord, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glGetTexGenxv(int coord, int pname, java.nio.IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsFramebufferOES(int framebuffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean glIsRenderbufferOES(int renderbuffer) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glRenderbufferStorageOES(int target, int internalformat, int width, int height) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGenf(int coord, int pname, float param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGenfv(int coord, int pname, float[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGenfv(int coord, int pname, java.nio.FloatBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGeni(int coord, int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGeniv(int coord, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGeniv(int coord, int pname, java.nio.IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGenx(int coord, int pname, int param) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGenxv(int coord, int pname, int[] params, int offset) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void glTexGenxv(int coord, int pname, java.nio.IntBuffer params) {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/opengl/java/android/opengl/Group.java b/opengl/java/android/opengl/Group.java
new file mode 100644
index 0000000..1ef2953
--- /dev/null
+++ b/opengl/java/android/opengl/Group.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.ShortBuffer;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Iterator;
+import javax.microedition.khronos.opengles.*;
+
+class MaterialIndices {
+
+    private Material material = null;
+    private ShortBuffer indexBuffer = null;
+
+    public MaterialIndices(Material material, ShortBuffer indexBuffer) {
+        this.material = material;
+        this.indexBuffer = indexBuffer;
+    }
+
+    public Material getMaterial() {
+        return material;
+    }
+
+    public ShortBuffer getIndexBuffer() {
+        return indexBuffer;
+    }
+}
+
+/**
+ * {@hide}
+ */
+public class Group {
+
+    private Object3D parent;
+    private String name;
+
+    private List<MaterialIndices> materialIndices =
+        new ArrayList<MaterialIndices>();
+
+    public Group(Object3D parent) {
+        this.parent = parent;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void load(DataInputStream dis) throws IOException {
+        dis.readInt(); // name length
+        this.name = dis.readUTF();
+
+        int numMaterials = dis.readInt();
+
+        for (int i = 0; i < numMaterials; i++) {
+            dis.readInt(); // material name length
+            String matName = dis.readUTF();
+            Material material = parent.getMaterial(matName);
+
+            int numIndices = dis.readInt();
+            byte[] indicesBytes = new byte[numIndices * 2];
+            dis.readFully(indicesBytes);
+
+            // Swap bytes from network to native order if necessary
+            if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
+                int idx = 0;
+                for (int j = 0; j < numIndices; j++) {
+                    byte b0 = indicesBytes[idx];
+                    byte b1 = indicesBytes[idx + 1];
+                    indicesBytes[idx] = b1;
+                    indicesBytes[idx + 1] = b0;
+                    idx += 2;
+                }
+            }
+
+            ByteBuffer ibb = ByteBuffer.allocateDirect(2*numIndices);
+            ibb.order(ByteOrder.nativeOrder());
+            ibb.put(indicesBytes);
+            ibb.position(0);
+
+            ShortBuffer sb = ibb.asShortBuffer();
+            materialIndices.add(new MaterialIndices(material, sb));
+        }
+    }
+
+    public int getNumTriangles() {
+        int numTriangles = 0;
+        Iterator<MaterialIndices> iter = materialIndices.iterator();
+        while (iter.hasNext()) {
+            MaterialIndices matIdx = iter.next();
+            ShortBuffer indexBuffer = matIdx.getIndexBuffer();
+            numTriangles += indexBuffer.capacity()/3;
+        }
+        return numTriangles;
+    }
+
+    public void draw(GL10 gl) {
+        gl.glDisableClientState(gl.GL_COLOR_ARRAY);
+
+        gl.glVertexPointer(3, gl.GL_FIXED, 0, parent.getVertexBuffer());
+        gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
+
+        gl.glNormalPointer(gl.GL_FIXED, 0, parent.getNormalBuffer());
+        gl.glEnableClientState(gl.GL_NORMAL_ARRAY);
+
+        if (parent.hasTexcoords()) {
+            gl.glTexCoordPointer(2, gl.GL_FIXED, 0, parent.getTexcoordBuffer());
+            gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY);
+            gl.glEnable(gl.GL_TEXTURE_2D);
+        } else {
+            gl.glDisable(gl.GL_TEXTURE_2D);
+        }
+
+        Iterator<MaterialIndices> iter = materialIndices.iterator();
+        while (iter.hasNext()) {
+            MaterialIndices matIdx = iter.next();
+            ShortBuffer indexBuffer = matIdx.getIndexBuffer();
+            Material mat = matIdx.getMaterial();
+            mat.setMaterialParameters(gl);
+            if (parent.hasTexcoords() && mat.getMap_Kd().length() > 0) {
+                Texture texture = parent.getTexture(mat.getMap_Kd());
+                texture.setTextureParameters(gl);
+            }
+
+            gl.glDrawElements(gl.GL_TRIANGLES,
+                    indexBuffer.capacity(),
+                    gl.GL_UNSIGNED_SHORT,
+                    indexBuffer);
+        }
+    }
+
+    public String toString() {
+        return "Group[" +
+        "name=" + name +
+        "]";
+    }
+}
diff --git a/opengl/java/android/opengl/Material.java b/opengl/java/android/opengl/Material.java
new file mode 100644
index 0000000..60a3e72
--- /dev/null
+++ b/opengl/java/android/opengl/Material.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ * {@hide}
+ */
+public class Material {
+
+    private Object3D parent;
+    private String name;
+    private String map_kd;
+    private float[] ka = new float[4];
+    private float[] kd = new float[4];
+    private float[] ks = new float[4];
+    private float ns;
+    private int illum;
+    private float d;
+
+    private static float[] black = { 0.0f, 0.0f, 0.0f, 1.0f };
+
+    public Material(Object3D parent) {
+        this.parent = parent;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getMap_Kd() {
+        return map_kd;
+    }
+
+    public void setMaterialParameters(GL10 gl) {
+        gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, kd, 0);
+        gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_DIFFUSE, kd, 0);
+        gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_SPECULAR, ks, 0);
+        gl.glMaterialf(gl.GL_FRONT_AND_BACK, gl.GL_SHININESS,
+                Math.min(Math.max(ns, 0), 128));
+
+//      if (illum == 0) {
+//      gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, kd, 0);
+//      } else {
+//      gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, ka, 0);
+//      gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_DIFFUSE, kd, 0);
+//      }
+
+//      if (illum > 1) {
+//      gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_SPECULAR, ks, 0);
+//      gl.glMaterialf(gl.GL_FRONT_AND_BACK, gl.GL_SHININESS,
+//      Math.min(Math.max(ns, 0), 128));
+//      } else {
+//      gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_SPECULAR, black, 0);
+//      }
+    }
+
+    public void load(DataInputStream dis) throws IOException {
+        dis.readInt(); // name length
+        this.name = dis.readUTF();
+
+        dis.readInt(); // map_kdLength
+        this.map_kd = dis.readUTF();
+
+        if (parent.hasTexcoords() && map_kd.length() > 0) {
+            parent.loadTexture(map_kd);
+        }
+
+        this.ka[0] = dis.readFloat();
+        this.ka[1] = dis.readFloat();
+        this.ka[2] = dis.readFloat();
+        this.ka[3] = dis.readFloat();
+
+        this.kd[0] = dis.readFloat();
+        this.kd[1] = dis.readFloat();
+        this.kd[2] = dis.readFloat();
+        this.kd[3] = dis.readFloat();
+
+        this.ks[0] = dis.readFloat();
+        this.ks[1] = dis.readFloat();
+        this.ks[2] = dis.readFloat();
+        this.ks[3] = dis.readFloat();
+
+        this.ns = dis.readFloat();
+        this.illum = dis.readInt();
+        this.d = dis.readFloat();
+    }
+
+    public String toString() {
+        return "Material[" +
+        "name=\"" + name + "\"," +
+        "ka={" + ka[0] + "," + ka[1] + "," + ka[2] + "}," +
+        "kd={" + kd[0] + "," + kd[1] + "," + kd[2] + "}," +
+        "ks={" + ks[0] + "," + ks[1] + "," + ks[2] + "}," +
+        "ns=" + ns + "," +
+        "map_kd=\"" + 
+        (map_kd == null ? "" : map_kd) +
+        "\"," +
+        "illum=" + illum + "," +
+        "d=" + d +
+        "]";
+    }
+}
diff --git a/opengl/java/android/opengl/Matrix.java b/opengl/java/android/opengl/Matrix.java
new file mode 100644
index 0000000..13ba36e
--- /dev/null
+++ b/opengl/java/android/opengl/Matrix.java
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+/**
+ * Matrix math utilities. These methods operate on OpenGL ES format
+ * matrices and vectors stored in float arrays.
+ *
+ * Matrices are 4 x 4 column-vector matrices stored in column-major
+ * order:
+ * <pre>
+ *  m[offset +  0] m[offset +  4] m[offset +  8] m[offset + 12]
+ *  m[offset +  1] m[offset +  5] m[offset +  9] m[offset + 13]
+ *  m[offset +  2] m[offset +  6] m[offset + 10] m[offset + 14]
+ *  m[offset +  3] m[offset +  7] m[offset + 11] m[offset + 15]
+ * </pre>
+ *
+ * Vectors are 4 row x 1 column column-vectors stored in order:
+ * <pre>
+ * v[offset + 0]
+ * v[offset + 1]
+ * v[offset + 2]
+ * v[offset + 3]
+ * </pre>
+ *
+ */
+public class Matrix {
+    /**
+     * Multiply two 4x4 matrices together and store the result in a third 4x4
+     * matrix. In matrix notation: result = lhs x rhs. Due to the way
+     * matrix multiplication works, the result matrix will have the same
+     * effect as first multiplying by the rhs matrix, then multiplying by
+     * the lhs matrix. This is the opposite of what you might expect.
+     *
+     * The same float array may be passed for result, lhs, and/or rhs. However,
+     * the result element values are undefined if the result elements overlap
+     * either the lhs or rhs elements.
+     *
+     * @param result The float array that holds the result.
+     * @param resultOffset The offset into the result array where the result is
+     *        stored.
+     * @param lhs The float array that holds the left-hand-side matrix.
+     * @param lhsOffset The offset into the lhs array where the lhs is stored
+     * @param rhs The float array that holds the right-hand-side matrix.
+     * @param rhsOffset The offset into the rhs array where the rhs is stored.
+     *
+     * @throws IllegalArgumentException if result, lhs, or rhs are null, or if
+     * resultOffset + 16 > result.length or lhsOffset + 16 > lhs.length or
+     * rhsOffset + 16 > rhs.length.
+     */
+    public static native void multiplyMM(float[] result, int resultOffset,
+            float[] lhs, int lhsOffset, float[] rhs, int rhsOffset);
+
+    /**
+     * Multiply a 4 element vector by a 4x4 matrix and store the result in a 4
+     * element column vector. In matrix notation: result = lhs x rhs
+     *
+     * The same float array may be passed for resultVec, lhsMat, and/or rhsVec.
+     * However, the resultVec element values are undefined if the resultVec
+     * elements overlap either the lhsMat or rhsVec elements.
+     *
+     * @param resultVec The float array that holds the result vector.
+     * @param resultVecOffset The offset into the result array where the result
+     *        vector is stored.
+     * @param lhsMat The float array that holds the left-hand-side matrix.
+     * @param lhsMatOffset The offset into the lhs array where the lhs is stored
+     * @param rhsVec The float array that holds the right-hand-side vector.
+     * @param rhsVecOffset The offset into the rhs vector where the rhs vector
+     *        is stored.
+     *
+     * @throws IllegalArgumentException if resultVec, lhsMat,
+     * or rhsVec are null, or if resultVecOffset + 4 > resultVec.length
+     * or lhsMatOffset + 16 > lhsMat.length or
+     * rhsVecOffset + 4 > rhsVec.length.
+     */
+    public static native void multiplyMV(float[] resultVec,
+            int resultVecOffset, float[] lhsMat, int lhsMatOffset,
+            float[] rhsVec, int rhsVecOffset);
+
+    /**
+     * Transposes a 4 x 4 matrix.
+     *
+     * @param mTrans the array that holds the output inverted matrix
+     * @param mTransOffset an offset into mInv where the inverted matrix is
+     *        stored.
+     * @param m the input array
+     * @param mOffset an offset into m where the matrix is stored.
+     */
+    public static void transposeM(float[] mTrans, int mTransOffset, float[] m,
+            int mOffset) {
+        for (int i = 0; i < 4; i++) {
+            int mBase = i * 4 + mOffset;
+            mTrans[i + mTransOffset] = m[mBase];
+            mTrans[i + 4 + mTransOffset] = m[mBase + 1];
+            mTrans[i + 8 + mTransOffset] = m[mBase + 2];
+            mTrans[i + 12 + mTransOffset] = m[mBase + 3];
+        }
+    }
+
+    /**
+     * Inverts a 4 x 4 matrix.
+     *
+     * @param mInv the array that holds the output inverted matrix
+     * @param mInvOffset an offset into mInv where the inverted matrix is
+     *        stored.
+     * @param m the input array
+     * @param mOffset an offset into m where the matrix is stored.
+     * @return true if the matrix could be inverted, false if it could not.
+     */
+    public static boolean invertM(float[] mInv, int mInvOffset, float[] m,
+            int mOffset) {
+        // Invert a 4 x 4 matrix using Cramer's Rule
+
+        // array of transpose source matrix
+        float[] src = new float[16];
+
+        // transpose matrix
+        transposeM(src, 0, m, mOffset);
+
+        // temp array for pairs
+        float[] tmp = new float[12];
+
+        // calculate pairs for first 8 elements (cofactors)
+        tmp[0] = src[10] * src[15];
+        tmp[1] = src[11] * src[14];
+        tmp[2] = src[9] * src[15];
+        tmp[3] = src[11] * src[13];
+        tmp[4] = src[9] * src[14];
+        tmp[5] = src[10] * src[13];
+        tmp[6] = src[8] * src[15];
+        tmp[7] = src[11] * src[12];
+        tmp[8] = src[8] * src[14];
+        tmp[9] = src[10] * src[12];
+        tmp[10] = src[8] * src[13];
+        tmp[11] = src[9] * src[12];
+
+        // Holds the destination matrix while we're building it up.
+        float[] dst = new float[16];
+
+        // calculate first 8 elements (cofactors)
+        dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7];
+        dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7];
+        dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7];
+        dst[1] -= tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7];
+        dst[2] = tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7];
+        dst[2] -= tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7];
+        dst[3] = tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6];
+        dst[3] -= tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6];
+        dst[4] = tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3];
+        dst[4] -= tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3];
+        dst[5] = tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3];
+        dst[5] -= tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3];
+        dst[6] = tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3];
+        dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3];
+        dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2];
+        dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2];
+
+        // calculate pairs for second 8 elements (cofactors)
+        tmp[0] = src[2] * src[7];
+        tmp[1] = src[3] * src[6];
+        tmp[2] = src[1] * src[7];
+        tmp[3] = src[3] * src[5];
+        tmp[4] = src[1] * src[6];
+        tmp[5] = src[2] * src[5];
+        tmp[6] = src[0] * src[7];
+        tmp[7] = src[3] * src[4];
+        tmp[8] = src[0] * src[6];
+        tmp[9] = src[2] * src[4];
+        tmp[10] = src[0] * src[5];
+        tmp[11] = src[1] * src[4];
+
+        // calculate second 8 elements (cofactors)
+        dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15];
+        dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15];
+        dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15];
+        dst[9] -= tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15];
+        dst[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15];
+        dst[10] -= tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15];
+        dst[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14];
+        dst[11] -= tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14];
+        dst[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9];
+        dst[12] -= tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10];
+        dst[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10];
+        dst[13] -= tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8];
+        dst[14] = tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8];
+        dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9];
+        dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9];
+        dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8];
+
+        // calculate determinant
+        float det =
+                src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3]
+                        * dst[3];
+
+        if (det == 0.0f) {
+
+        }
+
+        // calculate matrix inverse
+        det = 1 / det;
+        for (int j = 0; j < 16; j++)
+            mInv[j + mInvOffset] = dst[j] * det;
+
+        return true;
+    }
+
+    /**
+     * Computes an orthographic projection matrix.
+     *
+     * @param m returns the result
+     * @param mOffset
+     * @param left
+     * @param right
+     * @param bottom
+     * @param top
+     * @param near
+     * @param far
+     */
+    public static void orthoM(float[] m, int mOffset,
+        float left, float right, float bottom, float top,
+        float near, float far) {
+        if (left == right) {
+            throw new IllegalArgumentException("left == right");
+        }
+        if (bottom == top) {
+            throw new IllegalArgumentException("bottom == top");
+        }
+        if (near == far) {
+            throw new IllegalArgumentException("near == far");
+        }
+
+        final float r_width  = 1.0f / (right - left);
+        final float r_height = 1.0f / (top - bottom);
+        final float r_depth  = 1.0f / (far - near);
+        final float x =  2.0f * (r_width);
+        final float y =  2.0f * (r_height);
+        final float z = -2.0f * (r_depth);
+        final float tx = -(right + left) * r_width;
+        final float ty = -(top + bottom) * r_height;
+        final float tz = -(far + near) * r_depth;
+        m[mOffset + 0] = x;
+        m[mOffset + 5] = y;
+        m[mOffset +10] = z;
+        m[mOffset +12] = tx;
+        m[mOffset +13] = ty;
+        m[mOffset +14] = tz;
+        m[mOffset +15] = 1.0f;
+        m[mOffset + 1] = 0.0f;
+        m[mOffset + 2] = 0.0f;
+        m[mOffset + 3] = 0.0f;
+        m[mOffset + 4] = 0.0f;
+        m[mOffset + 6] = 0.0f;
+        m[mOffset + 7] = 0.0f;
+        m[mOffset + 8] = 0.0f;
+        m[mOffset + 9] = 0.0f;
+        m[mOffset + 11] = 0.0f;
+    }
+
+
+    /**
+     * Define a projection matrix in terms of six clip planes
+     * @param m the float array that holds the perspective matrix
+     * @param offset the offset into float array m where the perspective
+     * matrix data is written
+     * @param left
+     * @param right
+     * @param bottom
+     * @param top
+     * @param near
+     * @param far
+     */
+
+    public static void frustumM(float[] m, int offset,
+            float left, float right, float bottom, float top,
+            float near, float far) {
+        if (left == right) {
+            throw new IllegalArgumentException("left == right");
+        }
+        if (top == bottom) {
+            throw new IllegalArgumentException("top == bottom");
+        }
+        if (near == far) {
+            throw new IllegalArgumentException("near == far");
+        }
+        if (near <= 0.0f) {
+            throw new IllegalArgumentException("near <= 0.0f");
+        }
+        if (far <= 0.0f) {
+            throw new IllegalArgumentException("far <= 0.0f");
+        }
+        final float r_width  = 1.0f / (right - left);
+        final float r_height = 1.0f / (top - bottom);
+        final float r_depth  = 1.0f / (near - far);
+        final float x = 2.0f * (near * r_width);
+        final float y = 2.0f * (near * r_height);
+        final float A = 2.0f * ((right + left) * r_width);
+        final float B = (top + bottom) * r_height;
+        final float C = (far + near) * r_depth;
+        final float D = 2.0f * (far * near * r_depth);
+        m[offset + 0] = x;
+        m[offset + 5] = y;
+        m[offset + 8] = A;
+        m[offset +  9] = B;
+        m[offset + 10] = C;
+        m[offset + 14] = D;
+        m[offset + 11] = -1.0f;
+        m[offset +  1] = 0.0f;
+        m[offset +  2] = 0.0f;
+        m[offset +  3] = 0.0f;
+        m[offset +  4] = 0.0f;
+        m[offset +  6] = 0.0f;
+        m[offset +  7] = 0.0f;
+        m[offset + 12] = 0.0f;
+        m[offset + 13] = 0.0f;
+        m[offset + 15] = 0.0f;
+    }
+
+    /**
+     * Computes the length of a vector
+     *
+     * @param x x coordinate of a vector
+     * @param y y coordinate of a vector
+     * @param z z coordinate of a vector
+     * @return the length of a vector
+     */
+    public static float length(float x, float y, float z) {
+        return (float) Math.sqrt(x * x + y * y + z * z);
+    }
+
+    /**
+     * Sets matrix m to the identity matrix.
+     * @param sm returns the result
+     * @param smOffset index into sm where the result matrix starts
+     */
+    public static void setIdentityM(float[] sm, int smOffset) {
+        for (int i=0 ; i<16 ; i++) {
+            sm[smOffset + i] = 0;
+        }
+        for(int i = 0; i < 16; i += 5) {
+            sm[smOffset + i] = 1.0f;
+        }
+    }
+
+    /**
+     * Scales matrix  m by x, y, and z, putting the result in sm
+     * @param sm returns the result
+     * @param smOffset index into sm where the result matrix starts
+     * @param m source matrix
+     * @param mOffset index into m where the source matrix starts
+     * @param x scale factor x
+     * @param y scale factor y
+     * @param z scale factor z
+     */
+    public static void scaleM(float[] sm, int smOffset,
+            float[] m, int mOffset,
+            float x, float y, float z) {
+        for (int i=0 ; i<4 ; i++) {
+            int smi = smOffset + i;
+            int mi = mOffset + i;
+            sm[     smi] = m[     mi] * x;
+            sm[ 4 + smi] = m[ 4 + mi] * y;
+            sm[ 8 + smi] = m[ 8 + mi] * z;
+            sm[12 + smi] = m[12 + mi];
+        }
+    }
+
+    /**
+     * Scales matrix m in place by sx, sy, and sz
+     * @param m matrix to scale
+     * @param mOffset index into m where the matrix starts
+     * @param x scale factor x
+     * @param y scale factor y
+     * @param z scale factor z
+     */
+    public static void scaleM(float[] m, int mOffset,
+            float x, float y, float z) {
+        for (int i=0 ; i<4 ; i++) {
+            int mi = mOffset + i;
+            m[     mi] *= x;
+            m[ 4 + mi] *= y;
+            m[ 8 + mi] *= z;
+        }
+    }
+
+    /**
+     * Translates matrix m by x, y, and z, putting the result in tm
+     * @param tm returns the result
+     * @param tmOffset index into sm where the result matrix starts
+     * @param m source matrix
+     * @param mOffset index into m where the source matrix starts
+     * @param x translation factor x
+     * @param y translation factor y
+     * @param z translation factor z
+     */
+    public static void translateM(float[] tm, int tmOffset,
+            float[] m, int mOffset,
+            float x, float y, float z) {
+        for (int i=0 ; i<12 ; i++) {
+            tm[tmOffset + i] = m[mOffset + i];
+        }
+        for (int i=0 ; i<4 ; i++) {
+            int tmi = tmOffset + i;
+            int mi = mOffset + i;
+            tm[12 + tmi] = m[mi] * x + m[4 + mi] * y + m[8 + mi] * z +
+                m[12 + mi];
+        }
+    }
+
+    /**
+     * Translates matrix m by x, y, and z in place.
+     * @param m matrix
+     * @param mOffset index into m where the matrix starts
+     * @param x translation factor x
+     * @param y translation factor y
+     * @param z translation factor z
+     */
+    public static void translateM(
+            float[] m, int mOffset,
+            float x, float y, float z) {
+        for (int i=0 ; i<4 ; i++) {
+            int mi = mOffset + i;
+            m[12 + mi] += m[mi] * x + m[4 + mi] * y + m[8 + mi] * z;
+        }
+    }
+
+    /**
+     * Rotates matrix m by angle a (in degrees) around the axis (x, y, z)
+     * @param rm returns the result
+     * @param rmOffset index into rm where the result matrix starts
+     * @param m source matrix
+     * @param mOffset index into m where the source matrix starts
+     * @param a angle to rotate in degrees
+     * @param x scale factor x
+     * @param y scale factor y
+     * @param z scale factor z
+     */
+    public static void rotateM(float[] rm, int rmOffset,
+            float[] m, int mOffset,
+            float a, float x, float y, float z) {
+        float[] r = new float[16];
+        setRotateM(r, 0, a, x, y, z);
+        multiplyMM(rm, rmOffset, m, mOffset, r, 0);
+    }
+
+    /**
+     * Rotates matrix m in place by angle a (in degrees)
+     * around the axis (x, y, z)
+     * @param m source matrix
+     * @param mOffset index into m where the matrix starts
+     * @param a angle to rotate in degrees
+     * @param x scale factor x
+     * @param y scale factor y
+     * @param z scale factor z
+     */
+    public static void rotateM(float[] m, int mOffset,
+            float a, float x, float y, float z) {
+        float[] temp = new float[32];
+        setRotateM(temp, 0, a, x, y, z);
+        multiplyMM(temp, 16, m, mOffset, temp, 0);
+        System.arraycopy(temp, 16, m, mOffset, 16);
+    }
+
+    /**
+     * Rotates matrix m by angle a (in degrees) around the axis (x, y, z)
+     * @param rm returns the result
+     * @param rmOffset index into rm where the result matrix starts
+     * @param a angle to rotate in degrees
+     * @param x scale factor x
+     * @param y scale factor y
+     * @param z scale factor z
+     */
+    public static void setRotateM(float[] rm, int rmOffset,
+            float a, float x, float y, float z) {
+        rm[rmOffset + 3] = 0;
+        rm[rmOffset + 7] = 0;
+        rm[rmOffset + 11]= 0;
+        rm[rmOffset + 12]= 0;
+        rm[rmOffset + 13]= 0;
+        rm[rmOffset + 14]= 0;
+        rm[rmOffset + 15]= 1;
+        a *= (float) (Math.PI / 180.0f);
+        float s = (float) Math.sin(a);
+        float c = (float) Math.cos(a);
+        if (1.0f == x && 0.0f == y && 0.0f == z) {
+            rm[rmOffset + 5] = c;   rm[rmOffset + 10]= c;
+            rm[rmOffset + 6] = s;   rm[rmOffset + 9] = -s;
+            rm[rmOffset + 1] = 0;   rm[rmOffset + 2] = 0;
+            rm[rmOffset + 4] = 0;   rm[rmOffset + 8] = 0;
+            rm[rmOffset + 0] = 1;
+        } else if (0.0f == x && 1.0f == y && 0.0f == z) {
+            rm[rmOffset + 0] = c;   rm[rmOffset + 10]= c;
+            rm[rmOffset + 8] = s;   rm[rmOffset + 2] = -s;
+            rm[rmOffset + 1] = 0;   rm[rmOffset + 4] = 0;
+            rm[rmOffset + 6] = 0;   rm[rmOffset + 9] = 0;
+            rm[rmOffset + 5] = 1;
+        } else if (0.0f == x && 0.0f == y && 1.0f == z) {
+            rm[rmOffset + 0] = c;   rm[rmOffset + 5] = c;
+            rm[rmOffset + 1] = s;   rm[rmOffset + 4] = -s;
+            rm[rmOffset + 2] = 0;   rm[rmOffset + 6] = 0;
+            rm[rmOffset + 8] = 0;   rm[rmOffset + 9] = 0;
+            rm[rmOffset + 10]= 1;
+        } else {
+            float len = length(x, y, z);
+            if (1.0f != len) {
+                float recipLen = 1.0f / len;
+                x *= recipLen;
+                y *= recipLen;
+                z *= recipLen;
+            }
+            float nc = 1.0f - c;
+            float xy = x * y;
+            float yz = y * z;
+            float zx = z * x;
+            float xs = x * s;
+            float ys = y * s;
+            float zs = z * s;
+            rm[rmOffset +  0] = x*x*nc +  c;
+            rm[rmOffset +  4] =  xy*nc - zs;
+            rm[rmOffset +  8] =  zx*nc + ys;
+            rm[rmOffset +  1] =  xy*nc + zs;
+            rm[rmOffset +  5] = y*y*nc +  c;
+            rm[rmOffset +  9] =  yz*nc - xs;
+            rm[rmOffset +  2] =  zx*nc - ys;
+            rm[rmOffset +  6] =  yz*nc + xs;
+            rm[rmOffset + 10] = z*z*nc +  c;
+        }
+    }
+
+    /**
+     * Converts Euler angles to a rotation matrix
+     * @param rm returns the result
+     * @param rmOffset index into rm where the result matrix starts
+     * @param x angle of rotation, in degrees
+     * @param y angle of rotation, in degrees
+     * @param z angle of rotation, in degrees
+     */
+    public static void setRotateEulerM(float[] rm, int rmOffset,
+            float x, float y, float z) {
+        x *= (float) (Math.PI / 180.0f);
+        y *= (float) (Math.PI / 180.0f);
+        z *= (float) (Math.PI / 180.0f);
+        float cx = (float) Math.cos(x);
+        float sx = (float) Math.sin(x);
+        float cy = (float) Math.cos(y);
+        float sy = (float) Math.sin(y);
+        float cz = (float) Math.cos(z);
+        float sz = (float) Math.sin(z);
+        float cxsy = cx * sy;
+        float sxsy = sx * sy;
+
+        rm[rmOffset + 0]  =   cy * cz;
+        rm[rmOffset + 1]  =  -cy * sz;
+        rm[rmOffset + 2]  =   sy;
+        rm[rmOffset + 3]  =  0.0f;
+
+        rm[rmOffset + 4]  =  cxsy * cz + cx * sz;
+        rm[rmOffset + 5]  = -cxsy * sz + cx * cz;
+        rm[rmOffset + 6]  =  -sx * cy;
+        rm[rmOffset + 7]  =  0.0f;
+
+        rm[rmOffset + 8]  = -sxsy * cz + sx * sz;
+        rm[rmOffset + 9]  =  sxsy * sz + sx * cz;
+        rm[rmOffset + 10] =  cx * cy;
+        rm[rmOffset + 11] =  0.0f;
+
+        rm[rmOffset + 12] =  0.0f;
+        rm[rmOffset + 13] =  0.0f;
+        rm[rmOffset + 14] =  0.0f;
+        rm[rmOffset + 15] =  1.0f;
+    }
+}
diff --git a/opengl/java/android/opengl/Object3D.java b/opengl/java/android/opengl/Object3D.java
new file mode 100644
index 0000000..340c6a7
--- /dev/null
+++ b/opengl/java/android/opengl/Object3D.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import javax.microedition.khronos.opengles.*;
+
+/**
+ * {@hide}
+ */
+public abstract class Object3D {
+
+    private boolean mHasTexcoords = false;
+
+    private float mBoundsMinX = Float.MAX_VALUE;
+    private float mBoundsMaxX = Float.MIN_VALUE;
+    private float mBoundsMinY = Float.MAX_VALUE;
+    private float mBoundsMaxY = Float.MIN_VALUE;
+    private float mBoundsMinZ = Float.MAX_VALUE;
+    private float mBoundsMaxZ = Float.MIN_VALUE;
+
+    private IntBuffer mVertexBuffer;
+    private IntBuffer mNormalBuffer;
+    private IntBuffer mTexcoordBuffer;
+
+    // All groups, by name
+    private Map<String, Group> mGroups;
+
+    // All materials, by name
+    private Map<String, Material> mMaterials;
+
+    // All texture maps, by name
+    private Map<String, Texture> mTextures;
+
+    public Object3D() {
+        reset();
+    }
+
+    /**
+     * Override this method with an implementation that contructs
+     * and InputStream from the given filename.  For example, if the
+     * source files are to be retrieved using an AssetManager,
+     * the implementation would use AssetManager.load() to
+     * get the input stream.
+     */
+    public abstract InputStream readFile(String filename) throws IOException;
+
+    private void reset() {
+        mVertexBuffer = mNormalBuffer = mTexcoordBuffer = null;
+
+        mGroups = new HashMap<String,Group>();
+        mMaterials = new HashMap<String,Material>();
+        mTextures = new HashMap<String,Texture>();
+    }
+
+    public Material getMaterial(String name) {
+        Material mat = mMaterials.get(name);
+        return mat;
+    }
+
+    public Texture getTexture(String name) {
+        return mTextures.get(name);
+    }
+
+    public IntBuffer getVertexBuffer() {
+        return mVertexBuffer;
+    }
+
+    public IntBuffer getNormalBuffer() {
+        return mNormalBuffer;
+    }
+
+    public IntBuffer getTexcoordBuffer() {
+        return mTexcoordBuffer;
+    }
+
+    public int getNumTriangles() {
+        int numTriangles = 0;
+        Iterator<Group> iter = mGroups.values().iterator();
+        while (iter.hasNext()) {
+            numTriangles += iter.next().getNumTriangles();
+        }
+        return numTriangles;
+    }
+
+    public boolean hasTexcoords() {
+        return mHasTexcoords;
+    }
+
+    public float getBoundsMinX() {
+        return mBoundsMinX;
+    }
+
+    public float getBoundsMaxX() {
+        return mBoundsMaxX;
+    }
+
+    public float getBoundsMinY() {
+        return mBoundsMinY;
+    }
+
+    public float getBoundsMaxY() {
+        return mBoundsMaxY;
+    }
+
+    public float getBoundsMinZ() {
+        return mBoundsMinZ;
+    }
+
+    public float getBoundsMaxZ() {
+        return mBoundsMaxZ;
+    }
+
+    public void loadTexture(String name) throws IOException {
+        InputStream is = readFile(name + ".raw");
+        Texture texture = new Texture(is);
+        mTextures.put(name, texture);
+    }
+
+    private static void verifyByte(DataInputStream dis, int b) 
+    throws IOException {
+        int x = dis.read() & 0xff;
+        if (x != b) {
+            throw new RuntimeException("Bad byte: " +
+                    x +
+                    " (expected " + b + ")");
+        }
+    }
+
+    public void load(String filename) throws IOException {
+        reset();
+
+        DataInputStream dis = new DataInputStream(readFile(filename));
+        verifyByte(dis, 'g' + 128);
+        verifyByte(dis, 'l');
+        verifyByte(dis, 'e');
+        verifyByte(dis, 's');
+
+        int numTuples = dis.readInt();
+
+        this.mBoundsMinX = dis.readFloat();
+        this.mBoundsMaxX = dis.readFloat();
+        this.mBoundsMinY = dis.readFloat();
+        this.mBoundsMaxY = dis.readFloat();
+        this.mBoundsMinZ = dis.readFloat();
+        this.mBoundsMaxZ = dis.readFloat();
+
+        this.mHasTexcoords = dis.readInt() == 1;
+
+        int intsPerTuple = mHasTexcoords ? 8 : 6;
+        int numInts = numTuples*intsPerTuple;
+
+        int len = 4*numTuples*(mHasTexcoords ? 8 : 6);
+
+        byte[] tmp = new byte[len];
+        int tidx = 0;
+        while (tidx < len) {
+            tidx += dis.read(tmp, tidx, len - tidx);
+        }
+        if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
+            for (int i = 0; i < len; i += 4) {
+                byte tmp0 = tmp[i];
+                byte tmp1 = tmp[i + 1];
+                byte tmp2 = tmp[i + 2];
+                byte tmp3 = tmp[i + 3];
+                tmp[i] = tmp3;
+                tmp[i + 1] = tmp2;
+                tmp[i + 2] = tmp1;
+                tmp[i + 3] = tmp0;
+            }
+        }
+
+        ByteBuffer allbb = ByteBuffer.allocateDirect(len);
+        allbb.order(ByteOrder.nativeOrder());
+        allbb.put(tmp);
+
+        allbb.position(0);
+        allbb.limit(4*3*numTuples);
+        ByteBuffer vbb = allbb.slice();
+        this.mVertexBuffer = vbb.asIntBuffer();
+        mVertexBuffer.position(0);
+
+        if (mHasTexcoords) {
+            allbb.position(allbb.limit());
+            allbb.limit(allbb.position() + 4*2*numTuples);
+            ByteBuffer tbb = allbb.slice();
+            this.mTexcoordBuffer = tbb.asIntBuffer();
+            mTexcoordBuffer.position(0);
+        }
+
+        allbb.position(allbb.limit());
+        allbb.limit(allbb.position() + 4*3*numTuples);
+        ByteBuffer nbb = allbb.slice();
+        this.mNormalBuffer = nbb.asIntBuffer();
+        mNormalBuffer.position(0);
+
+        int numMaterials = dis.readInt();
+        for (int i = 0; i < numMaterials; i++) {
+            Material mat = new Material(this);
+            mat.load(dis);
+            mMaterials.put(mat.getName(), mat);
+        }
+
+        int numGroups = dis.readInt();
+        for (int i = 0; i < numGroups; i++) {
+            Group g = new Group(this);
+            g.load(dis);
+            mGroups.put(g.getName(), g);
+        }
+    }
+
+    public void draw(GL10 gl) {
+        Iterator<Group> iter = mGroups.values().iterator();
+        while (iter.hasNext()) {
+            iter.next().draw(gl);
+        }
+    }
+}
+
diff --git a/opengl/java/android/opengl/Texture.java b/opengl/java/android/opengl/Texture.java
new file mode 100644
index 0000000..dcd894d
--- /dev/null
+++ b/opengl/java/android/opengl/Texture.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.res.AssetManager;
+
+/**
+ * {@hide}
+ */
+public class Texture {
+
+    private int width, height, bpp;
+    private ByteBuffer data;
+    private int name = -1;
+
+    // Texture maps have the following format.  All integers
+    // are 16 bits, high byte first.  Pixels are in 5/6/5
+    // RGB format, low byte first.
+    //
+    // width
+    // height
+    // pixel (0, 0)
+    // pixel (1, 0)
+    // ...
+    // pixel (width - 1, height - 1)
+
+    private int readInt16(InputStream is) throws IOException {
+        return is.read() | (is.read() << 8);
+    }
+
+    public Texture(InputStream is) throws IOException {
+        this.width  = readInt16(is);
+        this.height  = readInt16(is);
+        this.bpp = 2;
+
+        int npixels = width*height;
+        int nbytes = npixels*bpp;
+        byte[] arr = new byte[nbytes];
+
+        int idx = 0;
+        while (idx < nbytes) {
+            int nread = is.read(arr, idx, nbytes - idx);
+            idx += nread;
+        }
+
+        if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
+            // Swap pairs of bytes on big-endian platforms
+            for (int i = 0; i < npixels; i++) {
+                int j = i*2;
+                int k = j + 1;
+
+                byte tmp = arr[j];
+                arr[j] = arr[k];
+                arr[k] = tmp;
+            }
+        }
+
+        this.data = ByteBuffer.allocateDirect(arr.length);
+        this.data.order(ByteOrder.nativeOrder());
+        data.put(arr);
+        data.position(0);
+    }
+
+    private int loadTexture(GL10 gl,
+            int textureUnit,
+            int minFilter, int magFilter,
+            int wrapS, int wrapT,
+            int mode,
+            int width, int height,
+            int dataType,
+            Buffer data) {
+        int[] texture = new int[1];
+        gl.glGenTextures(1, texture, 0);
+
+        gl.glEnable(gl.GL_TEXTURE_2D);
+        gl.glClientActiveTexture(textureUnit);
+        gl.glBindTexture(gl.GL_TEXTURE_2D, texture[0]);
+        gl.glTexParameterf(gl.GL_TEXTURE_2D,
+                gl.GL_TEXTURE_MIN_FILTER,
+                minFilter);
+        gl.glTexParameterf(gl.GL_TEXTURE_2D,
+                gl.GL_TEXTURE_MAG_FILTER,
+                magFilter);
+        gl.glTexParameterf(gl.GL_TEXTURE_2D,
+                gl.GL_TEXTURE_WRAP_S,
+                wrapS);
+        gl.glTexParameterf(gl.GL_TEXTURE_2D,
+                gl.GL_TEXTURE_WRAP_T,
+                wrapT);
+        gl.glTexEnvf(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, mode);
+
+        gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB,
+                width, height,
+                0, gl.GL_RGB, dataType,
+                data);
+
+        return texture[0];
+    }
+
+    public void setTextureParameters(GL10 gl) {
+        if (name < 0) {
+            name = loadTexture(gl,
+                    gl.GL_TEXTURE0,
+                    gl.GL_NEAREST, gl.GL_NEAREST,
+                    gl.GL_REPEAT, gl.GL_REPEAT,
+                    gl.GL_MODULATE,
+                    width, height,
+                    gl.GL_UNSIGNED_SHORT_5_6_5,
+                    data);
+        }
+
+        gl.glBindTexture(gl.GL_TEXTURE_2D, name);
+    }
+}
diff --git a/opengl/java/android/opengl/Visibility.java b/opengl/java/android/opengl/Visibility.java
new file mode 100644
index 0000000..40e446f
--- /dev/null
+++ b/opengl/java/android/opengl/Visibility.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.opengl;
+
+/**
+ * A collection of utility methods for computing the visibility of triangle
+ * meshes.
+ *
+ */
+public class Visibility {
+    /**
+     * Test whether a given triangle mesh is visible on the screen. The mesh
+     * is specified as an indexed triangle list.
+     *
+     * @param ws the world space to screen space transform matrix, as an OpenGL
+     * column matrix.
+     * @param wsOffset an index into the ws array where the data starts.
+     * @param positions the vertex positions (x, y, z).
+     * @param positionsOffset the index in the positions array where the data
+     *        starts.
+     * @param indices the indices of the triangle list. The indices are
+     * expressed as chars because they are unsigned 16-bit values.
+     * @param indicesOffset the index in the indices array where the index data
+     *        starts.
+     * @param indexCount the number of indices in use. Typically a multiple of
+     * three. If not a multiple of three, the remaining one or two indices will
+     * be ignored.
+     * @return 2 if all of the mesh is visible, 1 if some part of the mesh is
+     *         visible, 0 if no part is visible.
+     *
+     * @throws IllegalArgumentException if ws is null, wsOffset < 0,
+     * positions is null, positionsOffset < 0, indices is null,
+     * indicesOffset < 0, indicesOffset > indices.length - indexCount
+     */
+    public static native int visibilityTest(float[] ws, int wsOffset,
+            float[] positions, int positionsOffset, char[] indices,
+            int indicesOffset, int indexCount);
+
+    /**
+     * Given an OpenGL ES ModelView-Projection matrix (which implicitly
+     * describes a frustum) and a list of spheres, determine which spheres
+     * intersect the frustum.
+     * <p>
+     * A ModelView-Projection matrix can be computed by multiplying the
+     * a Projection matrix by the a ModelView matrix (in that order.). There
+     * are several possible ways to obtain the current ModelView and
+     * Projection matrices. The most generally applicable way is to keep
+     * track of the current matrices in application code. If that is not
+     * convenient, there are two optional OpenGL ES extensions which may
+     * be used to read the current matrices from OpenGL ES:
+     * <ul>
+     * <li>GL10Ext.glQueryMatrixxOES
+     * <li>GL11.GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES and
+     * GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES
+     * </ul>
+     * The problem with reading back the matrices is that your application
+     * will only work with devices that support the extension(s) that
+     * it uses.
+     * <p>
+     * A frustum is a six-sided truncated pyramid that defines the portion of
+     * world space that is visible in the view.
+     * <p>
+     * Spheres are described as four floating point values: x, y, z, and r, in
+     * world-space coordinates. R is the radius of the sphere.
+     * <p>
+     * @param mvp a float array containing the mode-view-projection matrix
+     * @param mvpOffset The offset of the mvp data within the mvp array.
+     * @param spheres a float array containing the sphere data.
+     * @param spheresOffset an offset into the sphere array where the sphere
+     *        data starts
+     * @param spheresCount the number of spheres to cull.
+     * @param results an integer array containing the indices of the spheres
+     * that are either contained entirely within or intersect the frustum.
+     * @param resultsOffset an offset into the results array where the results
+     *        start.
+     * @param resultsCapacity the number of array elements available for storing
+     *        results.
+     * @return the number of spheres that intersected the frustum. Can be
+     * larger than resultsCapacity, in which case only the first resultsCapacity
+     * results are written into the results array.
+     *
+     * @throws IllegalArgumentException if mvp is null, mvpOffset < 0,
+     * mvpOffset > mvp.length - 16, spheres is null, spheresOffset < 0,
+     * spheresOffset > spheres.length - sphereCount,
+     * results is null, resultsOffset < 0, resultsOffset > results.length -
+     * resultsCapacity.
+     */
+    public static native int frustumCullSpheres(float[] mvp, int mvpOffset,
+            float[] spheres, int spheresOffset, int spheresCount,
+            int[] results, int resultsOffset, int resultsCapacity);
+
+    /**
+     * Compute a bounding sphere for a set of points. It is approximately the
+     * minimal bounding sphere of an axis-aligned box that bounds the points.
+     *
+     * @param positions positions in x, y, z triples
+     * @param positionsOffset offset into positions array
+     * @param positionsCount number of position triples to process
+     * @param sphere array containing the output as (x, y, z, r)
+     * @param sphereOffset offset where the sphere data will be written
+     *
+     * @throws IllegalArgumentException if positions is null,
+     * positionsOffset < 0, positionsOffset > positions.length - positionsCount,
+     * sphere is null, sphereOffset < 0, sphereOffset > sphere.length - 4.
+     */
+    public static native void computeBoundingSphere(float[] positions,
+            int positionsOffset, int positionsCount, float[] sphere,
+            int sphereOffset);
+}
diff --git a/opengl/java/android/opengl/package.html b/opengl/java/android/opengl/package.html
new file mode 100644
index 0000000..7175b33
--- /dev/null
+++ b/opengl/java/android/opengl/package.html
@@ -0,0 +1,5 @@
+<HTML>
+<BODY>
+Provides OpenGL utilities.
+</BODY>
+</HTML>
diff --git a/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java b/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java
new file mode 100644
index 0000000..b03392e
--- /dev/null
+++ b/opengl/java/com/google/android/gles_jni/EGLConfigImpl.java
@@ -0,0 +1,32 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package com.google.android.gles_jni;
+
+import javax.microedition.khronos.egl.*;
+
+public class EGLConfigImpl extends EGLConfig {
+    private int mEGLConfig;
+
+    EGLConfigImpl(int config) {
+        mEGLConfig = config;
+    }
+    
+    int get() {
+        return mEGLConfig;
+    }
+}
diff --git a/opengl/java/com/google/android/gles_jni/EGLContextImpl.java b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
new file mode 100644
index 0000000..f10c02f
--- /dev/null
+++ b/opengl/java/com/google/android/gles_jni/EGLContextImpl.java
@@ -0,0 +1,36 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package com.google.android.gles_jni;
+
+import javax.microedition.khronos.egl.*;
+import javax.microedition.khronos.opengles.GL;
+
+public class EGLContextImpl extends EGLContext {
+    private GLImpl mGLContext;
+    int mEGLContext;
+    
+    public EGLContextImpl(int ctx) {
+        mEGLContext = ctx;
+        mGLContext = new GLImpl();
+    }
+ 
+    @Override
+    public GL getGL() {
+        return mGLContext;
+    }
+}
diff --git a/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
new file mode 100644
index 0000000..6321632
--- /dev/null
+++ b/opengl/java/com/google/android/gles_jni/EGLDisplayImpl.java
@@ -0,0 +1,28 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package com.google.android.gles_jni;
+
+import javax.microedition.khronos.egl.*;
+
+public class EGLDisplayImpl extends EGLDisplay {
+    int mEGLDisplay;
+
+    public EGLDisplayImpl(int dpy) {
+        mEGLDisplay = dpy;
+    }
+}
diff --git a/opengl/java/com/google/android/gles_jni/EGLImpl.java b/opengl/java/com/google/android/gles_jni/EGLImpl.java
new file mode 100644
index 0000000..a667e8d
--- /dev/null
+++ b/opengl/java/com/google/android/gles_jni/EGLImpl.java
@@ -0,0 +1,118 @@
+/*
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package com.google.android.gles_jni;
+
+import javax.microedition.khronos.egl.*;
+
+import android.view.Surface;
+import android.view.SurfaceView;
+import android.view.SurfaceHolder;
+import android.view.View;
+
+public class EGLImpl implements EGL10 {
+    private EGLContextImpl mContext = new EGLContextImpl(-1);
+    private EGLDisplayImpl mDisplay = new EGLDisplayImpl(-1);
+    private EGLSurfaceImpl mSurface = new EGLSurfaceImpl(-1);
+
+    public native boolean     eglInitialize(EGLDisplay display, int[] major_minor);
+    public native boolean     eglQueryContext(EGLDisplay display, EGLContext context, int attribute, int[] value);    
+    public native boolean     eglQuerySurface(EGLDisplay display, EGLSurface surface, int attribute, int[] value);
+    public native boolean     eglChooseConfig(EGLDisplay display, int[] attrib_list, EGLConfig[] configs, int config_size, int[] num_config);
+    public native boolean     eglGetConfigAttrib(EGLDisplay display, EGLConfig config, int attribute, int[] value);
+    public native boolean     eglGetConfigs(EGLDisplay display, EGLConfig[] configs, int config_size, int[] num_config);    
+    public native int         eglGetError();
+    public native boolean     eglDestroyContext(EGLDisplay display, EGLContext context);
+    public native boolean     eglDestroySurface(EGLDisplay display, EGLSurface surface);
+    public native boolean     eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context);
+    public native String      eglQueryString(EGLDisplay display, int name);
+    public native boolean     eglSwapBuffers(EGLDisplay display, EGLSurface surface);
+    public native boolean     eglTerminate(EGLDisplay display);
+    public native boolean     eglCopyBuffers(EGLDisplay display, EGLSurface surface, Object native_pixmap);
+    public native boolean     eglWaitGL();
+    public native boolean     eglWaitNative(int engine, Object bindTarget);
+
+    public EGLContext eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list) {
+        return new EGLContextImpl( _eglCreateContext(display, config, share_context, attrib_list) );
+    }
+
+    public EGLSurface eglCreatePbufferSurface(EGLDisplay display, EGLConfig config, int[] attrib_list) {
+        return new EGLSurfaceImpl( _eglCreatePbufferSurface(display, config, attrib_list) );
+    }
+    
+    public EGLSurface eglCreatePixmapSurface(EGLDisplay display, EGLConfig config, Object native_pixmap, int[] attrib_list) {
+        EGLSurfaceImpl sur = new EGLSurfaceImpl();
+        _eglCreatePixmapSurface(sur, display, config, native_pixmap, attrib_list);
+        return sur;
+    }
+
+    public EGLSurface eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list) {
+        Surface sur;
+        if (native_window instanceof SurfaceView) {
+            SurfaceView surfaceView = (SurfaceView)native_window;
+            sur = surfaceView.getHolder().getSurface();
+        } else if (native_window instanceof SurfaceHolder) {
+            SurfaceHolder holder = (SurfaceHolder)native_window;
+            sur = holder.getSurface();
+        } else {
+            throw new java.lang.UnsupportedOperationException(
+                "eglCreateWindowSurface() can only be called with an instance of " +
+                "SurfaceView or SurfaceHolder at the moment, this will be fixed later.");
+        }
+        return new EGLSurfaceImpl( _eglCreateWindowSurface(display, config, sur, attrib_list) );
+    }
+    
+    public synchronized EGLDisplay eglGetDisplay(Object native_display) {
+        int value = _eglGetDisplay(native_display);
+        if (mDisplay.mEGLDisplay != value)
+            mDisplay = new EGLDisplayImpl(value);
+        return mDisplay;
+    }
+
+    public synchronized EGLContext eglGetCurrentContext() {
+        int value = _eglGetCurrentContext();
+        if (mContext.mEGLContext != value)
+            mContext = new EGLContextImpl(value);
+        return mContext;
+    }
+    
+    public synchronized EGLDisplay eglGetCurrentDisplay() {
+        int value = _eglGetCurrentDisplay();
+        if (mDisplay.mEGLDisplay != value)
+            mDisplay = new EGLDisplayImpl(value);
+        return mDisplay;
+    }
+
+    public synchronized EGLSurface eglGetCurrentSurface(int readdraw) {
+        int value = _eglGetCurrentSurface(readdraw);
+        if (mSurface.mEGLSurface != value)
+            mSurface = new EGLSurfaceImpl(value);
+        return mSurface;
+    }
+
+    private native int _eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list);
+    private native int _eglCreatePbufferSurface(EGLDisplay display, EGLConfig config, int[] attrib_list);
+    private native void _eglCreatePixmapSurface(EGLSurface sur, EGLDisplay display, EGLConfig config, Object native_pixmap, int[] attrib_list);
+    private native int _eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list);    
+    private native int _eglGetDisplay(Object native_display);
+    private native int _eglGetCurrentContext();
+    private native int _eglGetCurrentDisplay();
+    private native int _eglGetCurrentSurface(int readdraw);
+
+    native private static void _nativeClassInit();
+    static { _nativeClassInit(); }
+}
diff --git a/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
new file mode 100644
index 0000000..66cc200
--- /dev/null
+++ b/opengl/java/com/google/android/gles_jni/EGLSurfaceImpl.java
@@ -0,0 +1,33 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package com.google.android.gles_jni;
+
+import javax.microedition.khronos.egl.*;
+
+public class EGLSurfaceImpl extends EGLSurface {
+    int mEGLSurface;
+    private int mNativePixelRef;
+    public EGLSurfaceImpl() {
+        mEGLSurface = 0;
+        mNativePixelRef = 0;
+    }
+    public EGLSurfaceImpl(int surface) {
+        mEGLSurface = surface;
+        mNativePixelRef = 0;
+    }
+}
diff --git a/opengl/java/com/google/android/gles_jni/GLImpl.java b/opengl/java/com/google/android/gles_jni/GLImpl.java
new file mode 100644
index 0000000..47f07d0
--- /dev/null
+++ b/opengl/java/com/google/android/gles_jni/GLImpl.java
@@ -0,0 +1,2115 @@
+/* //device/java/android/com/google/android/gles_jni/GLImpl.java
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+package com.google.android.gles_jni;
+
+import java.nio.Buffer;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL10Ext;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+public class GLImpl implements GL10, GL10Ext, GL11, GL11Ext, GL11ExtensionPack {
+
+    // Private accessors for native code
+
+    native private static void _nativeClassInit();
+    static {
+	_nativeClassInit();
+    }
+
+    Buffer _colorPointer = null;
+    Buffer _normalPointer = null;
+    Buffer _texCoordPointer = null;
+    Buffer _vertexPointer = null;
+
+    public GLImpl() {
+    }
+
+     public void glGetPointerv(int pname, java.nio.Buffer[] params) {
+         throw new UnsupportedOperationException("glGetPointerv");
+     }
+
+    // C function void glActiveTexture ( GLenum texture )
+
+    public native void glActiveTexture(
+        int texture
+    );
+
+    // C function void glAlphaFunc ( GLenum func, GLclampf ref )
+
+    public native void glAlphaFunc(
+        int func,
+        float ref
+    );
+
+    // C function void glAlphaFuncx ( GLenum func, GLclampx ref )
+
+    public native void glAlphaFuncx(
+        int func,
+        int ref
+    );
+
+    // C function void glBindTexture ( GLenum target, GLuint texture )
+
+    public native void glBindTexture(
+        int target,
+        int texture
+    );
+
+    // C function void glBlendFunc ( GLenum sfactor, GLenum dfactor )
+
+    public native void glBlendFunc(
+        int sfactor,
+        int dfactor
+    );
+
+    // C function void glClear ( GLbitfield mask )
+
+    public native void glClear(
+        int mask
+    );
+
+    // C function void glClearColor ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
+
+    public native void glClearColor(
+        float red,
+        float green,
+        float blue,
+        float alpha
+    );
+
+    // C function void glClearColorx ( GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha )
+
+    public native void glClearColorx(
+        int red,
+        int green,
+        int blue,
+        int alpha
+    );
+
+    // C function void glClearDepthf ( GLclampf depth )
+
+    public native void glClearDepthf(
+        float depth
+    );
+
+    // C function void glClearDepthx ( GLclampx depth )
+
+    public native void glClearDepthx(
+        int depth
+    );
+
+    // C function void glClearStencil ( GLint s )
+
+    public native void glClearStencil(
+        int s
+    );
+
+    // C function void glClientActiveTexture ( GLenum texture )
+
+    public native void glClientActiveTexture(
+        int texture
+    );
+
+    // C function void glColor4f ( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
+
+    public native void glColor4f(
+        float red,
+        float green,
+        float blue,
+        float alpha
+    );
+
+    // C function void glColor4x ( GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha )
+
+    public native void glColor4x(
+        int red,
+        int green,
+        int blue,
+        int alpha
+    );
+
+    // C function void glColorMask ( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha )
+
+    public native void glColorMask(
+        boolean red,
+        boolean green,
+        boolean blue,
+        boolean alpha
+    );
+
+    // C function void glColorPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+
+    private native void glColorPointerBounds(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer,
+        int remaining
+    );
+
+    public void glColorPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ) {
+        if ((size == 4) &&
+            ((type == GL_FLOAT) ||
+             (type == GL_UNSIGNED_BYTE) ||
+             (type == GL_FIXED)) &&
+            (stride >= 0)) {
+            _colorPointer = pointer;
+        }
+        glColorPointerBounds(
+            size,
+            type,
+            stride,
+            pointer,
+            pointer.remaining()
+        );
+    }
+
+    // C function void glCompressedTexImage2D ( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data )
+
+    public native void glCompressedTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int width,
+        int height,
+        int border,
+        int imageSize,
+        java.nio.Buffer data
+    );
+
+    // C function void glCompressedTexSubImage2D ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data )
+
+    public native void glCompressedTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int width,
+        int height,
+        int format,
+        int imageSize,
+        java.nio.Buffer data
+    );
+
+    // C function void glCopyTexImage2D ( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
+
+    public native void glCopyTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int x,
+        int y,
+        int width,
+        int height,
+        int border
+    );
+
+    // C function void glCopyTexSubImage2D ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height )
+
+    public native void glCopyTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int x,
+        int y,
+        int width,
+        int height
+    );
+
+    // C function void glCullFace ( GLenum mode )
+
+    public native void glCullFace(
+        int mode
+    );
+
+    // C function void glDeleteTextures ( GLsizei n, const GLuint *textures )
+
+    public native void glDeleteTextures(
+        int n,
+        int[] textures,
+        int offset
+    );
+
+    // C function void glDeleteTextures ( GLsizei n, const GLuint *textures )
+
+    public native void glDeleteTextures(
+        int n,
+        java.nio.IntBuffer textures
+    );
+
+    // C function void glDepthFunc ( GLenum func )
+
+    public native void glDepthFunc(
+        int func
+    );
+
+    // C function void glDepthMask ( GLboolean flag )
+
+    public native void glDepthMask(
+        boolean flag
+    );
+
+    // C function void glDepthRangef ( GLclampf zNear, GLclampf zFar )
+
+    public native void glDepthRangef(
+        float zNear,
+        float zFar
+    );
+
+    // C function void glDepthRangex ( GLclampx zNear, GLclampx zFar )
+
+    public native void glDepthRangex(
+        int zNear,
+        int zFar
+    );
+
+    // C function void glDisable ( GLenum cap )
+
+    public native void glDisable(
+        int cap
+    );
+
+    // C function void glDisableClientState ( GLenum array )
+
+    public native void glDisableClientState(
+        int array
+    );
+
+    // C function void glDrawArrays ( GLenum mode, GLint first, GLsizei count )
+
+    public native void glDrawArrays(
+        int mode,
+        int first,
+        int count
+    );
+
+    // C function void glDrawElements ( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
+
+    public native void glDrawElements(
+        int mode,
+        int count,
+        int type,
+        java.nio.Buffer indices
+    );
+
+    // C function void glEnable ( GLenum cap )
+
+    public native void glEnable(
+        int cap
+    );
+
+    // C function void glEnableClientState ( GLenum array )
+
+    public native void glEnableClientState(
+        int array
+    );
+
+    // C function void glFinish ( void )
+
+    public native void glFinish(
+    );
+
+    // C function void glFlush ( void )
+
+    public native void glFlush(
+    );
+
+    // C function void glFogf ( GLenum pname, GLfloat param )
+
+    public native void glFogf(
+        int pname,
+        float param
+    );
+
+    // C function void glFogfv ( GLenum pname, const GLfloat *params )
+
+    public native void glFogfv(
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glFogfv ( GLenum pname, const GLfloat *params )
+
+    public native void glFogfv(
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glFogx ( GLenum pname, GLfixed param )
+
+    public native void glFogx(
+        int pname,
+        int param
+    );
+
+    // C function void glFogxv ( GLenum pname, const GLfixed *params )
+
+    public native void glFogxv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glFogxv ( GLenum pname, const GLfixed *params )
+
+    public native void glFogxv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glFrontFace ( GLenum mode )
+
+    public native void glFrontFace(
+        int mode
+    );
+
+    // C function void glFrustumf ( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar )
+
+    public native void glFrustumf(
+        float left,
+        float right,
+        float bottom,
+        float top,
+        float zNear,
+        float zFar
+    );
+
+    // C function void glFrustumx ( GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar )
+
+    public native void glFrustumx(
+        int left,
+        int right,
+        int bottom,
+        int top,
+        int zNear,
+        int zFar
+    );
+
+    // C function void glGenTextures ( GLsizei n, GLuint *textures )
+
+    public native void glGenTextures(
+        int n,
+        int[] textures,
+        int offset
+    );
+
+    // C function void glGenTextures ( GLsizei n, GLuint *textures )
+
+    public native void glGenTextures(
+        int n,
+        java.nio.IntBuffer textures
+    );
+
+    // C function GLenum glGetError ( void )
+
+    public native int glGetError(
+    );
+
+    // C function void glGetIntegerv ( GLenum pname, GLint *params )
+
+    public native void glGetIntegerv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetIntegerv ( GLenum pname, GLint *params )
+
+    public native void glGetIntegerv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function const GLubyte * glGetString ( GLenum name )
+
+    public native String _glGetString(
+        int name
+    );
+
+    public String glGetString(
+        int name
+    ) {
+        String returnValue;
+        returnValue = _glGetString(
+            name
+        );
+        return returnValue;
+    }
+
+    // C function void glHint ( GLenum target, GLenum mode )
+
+    public native void glHint(
+        int target,
+        int mode
+    );
+
+    // C function void glLightModelf ( GLenum pname, GLfloat param )
+
+    public native void glLightModelf(
+        int pname,
+        float param
+    );
+
+    // C function void glLightModelfv ( GLenum pname, const GLfloat *params )
+
+    public native void glLightModelfv(
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glLightModelfv ( GLenum pname, const GLfloat *params )
+
+    public native void glLightModelfv(
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glLightModelx ( GLenum pname, GLfixed param )
+
+    public native void glLightModelx(
+        int pname,
+        int param
+    );
+
+    // C function void glLightModelxv ( GLenum pname, const GLfixed *params )
+
+    public native void glLightModelxv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glLightModelxv ( GLenum pname, const GLfixed *params )
+
+    public native void glLightModelxv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glLightf ( GLenum light, GLenum pname, GLfloat param )
+
+    public native void glLightf(
+        int light,
+        int pname,
+        float param
+    );
+
+    // C function void glLightfv ( GLenum light, GLenum pname, const GLfloat *params )
+
+    public native void glLightfv(
+        int light,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glLightfv ( GLenum light, GLenum pname, const GLfloat *params )
+
+    public native void glLightfv(
+        int light,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glLightx ( GLenum light, GLenum pname, GLfixed param )
+
+    public native void glLightx(
+        int light,
+        int pname,
+        int param
+    );
+
+    // C function void glLightxv ( GLenum light, GLenum pname, const GLfixed *params )
+
+    public native void glLightxv(
+        int light,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glLightxv ( GLenum light, GLenum pname, const GLfixed *params )
+
+    public native void glLightxv(
+        int light,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glLineWidth ( GLfloat width )
+
+    public native void glLineWidth(
+        float width
+    );
+
+    // C function void glLineWidthx ( GLfixed width )
+
+    public native void glLineWidthx(
+        int width
+    );
+
+    // C function void glLoadIdentity ( void )
+
+    public native void glLoadIdentity(
+    );
+
+    // C function void glLoadMatrixf ( const GLfloat *m )
+
+    public native void glLoadMatrixf(
+        float[] m,
+        int offset
+    );
+
+    // C function void glLoadMatrixf ( const GLfloat *m )
+
+    public native void glLoadMatrixf(
+        java.nio.FloatBuffer m
+    );
+
+    // C function void glLoadMatrixx ( const GLfixed *m )
+
+    public native void glLoadMatrixx(
+        int[] m,
+        int offset
+    );
+
+    // C function void glLoadMatrixx ( const GLfixed *m )
+
+    public native void glLoadMatrixx(
+        java.nio.IntBuffer m
+    );
+
+    // C function void glLogicOp ( GLenum opcode )
+
+    public native void glLogicOp(
+        int opcode
+    );
+
+    // C function void glMaterialf ( GLenum face, GLenum pname, GLfloat param )
+
+    public native void glMaterialf(
+        int face,
+        int pname,
+        float param
+    );
+
+    // C function void glMaterialfv ( GLenum face, GLenum pname, const GLfloat *params )
+
+    public native void glMaterialfv(
+        int face,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glMaterialfv ( GLenum face, GLenum pname, const GLfloat *params )
+
+    public native void glMaterialfv(
+        int face,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glMaterialx ( GLenum face, GLenum pname, GLfixed param )
+
+    public native void glMaterialx(
+        int face,
+        int pname,
+        int param
+    );
+
+    // C function void glMaterialxv ( GLenum face, GLenum pname, const GLfixed *params )
+
+    public native void glMaterialxv(
+        int face,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glMaterialxv ( GLenum face, GLenum pname, const GLfixed *params )
+
+    public native void glMaterialxv(
+        int face,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glMatrixMode ( GLenum mode )
+
+    public native void glMatrixMode(
+        int mode
+    );
+
+    // C function void glMultMatrixf ( const GLfloat *m )
+
+    public native void glMultMatrixf(
+        float[] m,
+        int offset
+    );
+
+    // C function void glMultMatrixf ( const GLfloat *m )
+
+    public native void glMultMatrixf(
+        java.nio.FloatBuffer m
+    );
+
+    // C function void glMultMatrixx ( const GLfixed *m )
+
+    public native void glMultMatrixx(
+        int[] m,
+        int offset
+    );
+
+    // C function void glMultMatrixx ( const GLfixed *m )
+
+    public native void glMultMatrixx(
+        java.nio.IntBuffer m
+    );
+
+    // C function void glMultiTexCoord4f ( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q )
+
+    public native void glMultiTexCoord4f(
+        int target,
+        float s,
+        float t,
+        float r,
+        float q
+    );
+
+    // C function void glMultiTexCoord4x ( GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q )
+
+    public native void glMultiTexCoord4x(
+        int target,
+        int s,
+        int t,
+        int r,
+        int q
+    );
+
+    // C function void glNormal3f ( GLfloat nx, GLfloat ny, GLfloat nz )
+
+    public native void glNormal3f(
+        float nx,
+        float ny,
+        float nz
+    );
+
+    // C function void glNormal3x ( GLfixed nx, GLfixed ny, GLfixed nz )
+
+    public native void glNormal3x(
+        int nx,
+        int ny,
+        int nz
+    );
+
+    // C function void glNormalPointer ( GLenum type, GLsizei stride, const GLvoid *pointer )
+
+    private native void glNormalPointerBounds(
+        int type,
+        int stride,
+        java.nio.Buffer pointer,
+        int remaining
+    );
+
+    public void glNormalPointer(
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ) {
+        if (((type == GL_FLOAT) ||
+             (type == GL_BYTE) ||
+             (type == GL_SHORT) ||
+             (type == GL_FIXED)) &&
+            (stride >= 0)) {
+            _normalPointer = pointer;
+        }
+        glNormalPointerBounds(
+            type,
+            stride,
+            pointer,
+            pointer.remaining()
+        );
+    }
+
+    // C function void glOrthof ( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar )
+
+    public native void glOrthof(
+        float left,
+        float right,
+        float bottom,
+        float top,
+        float zNear,
+        float zFar
+    );
+
+    // C function void glOrthox ( GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar )
+
+    public native void glOrthox(
+        int left,
+        int right,
+        int bottom,
+        int top,
+        int zNear,
+        int zFar
+    );
+
+    // C function void glPixelStorei ( GLenum pname, GLint param )
+
+    public native void glPixelStorei(
+        int pname,
+        int param
+    );
+
+    // C function void glPointSize ( GLfloat size )
+
+    public native void glPointSize(
+        float size
+    );
+
+    // C function void glPointSizex ( GLfixed size )
+
+    public native void glPointSizex(
+        int size
+    );
+
+    // C function void glPolygonOffset ( GLfloat factor, GLfloat units )
+
+    public native void glPolygonOffset(
+        float factor,
+        float units
+    );
+
+    // C function void glPolygonOffsetx ( GLfixed factor, GLfixed units )
+
+    public native void glPolygonOffsetx(
+        int factor,
+        int units
+    );
+
+    // C function void glPopMatrix ( void )
+
+    public native void glPopMatrix(
+    );
+
+    // C function void glPushMatrix ( void )
+
+    public native void glPushMatrix(
+    );
+
+    // C function void glReadPixels ( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels )
+
+    public native void glReadPixels(
+        int x,
+        int y,
+        int width,
+        int height,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    );
+
+    // C function void glRotatef ( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
+
+    public native void glRotatef(
+        float angle,
+        float x,
+        float y,
+        float z
+    );
+
+    // C function void glRotatex ( GLfixed angle, GLfixed x, GLfixed y, GLfixed z )
+
+    public native void glRotatex(
+        int angle,
+        int x,
+        int y,
+        int z
+    );
+
+    // C function void glSampleCoverage ( GLclampf value, GLboolean invert )
+
+    public native void glSampleCoverage(
+        float value,
+        boolean invert
+    );
+
+    // C function void glSampleCoveragex ( GLclampx value, GLboolean invert )
+
+    public native void glSampleCoveragex(
+        int value,
+        boolean invert
+    );
+
+    // C function void glScalef ( GLfloat x, GLfloat y, GLfloat z )
+
+    public native void glScalef(
+        float x,
+        float y,
+        float z
+    );
+
+    // C function void glScalex ( GLfixed x, GLfixed y, GLfixed z )
+
+    public native void glScalex(
+        int x,
+        int y,
+        int z
+    );
+
+    // C function void glScissor ( GLint x, GLint y, GLsizei width, GLsizei height )
+
+    public native void glScissor(
+        int x,
+        int y,
+        int width,
+        int height
+    );
+
+    // C function void glShadeModel ( GLenum mode )
+
+    public native void glShadeModel(
+        int mode
+    );
+
+    // C function void glStencilFunc ( GLenum func, GLint ref, GLuint mask )
+
+    public native void glStencilFunc(
+        int func,
+        int ref,
+        int mask
+    );
+
+    // C function void glStencilMask ( GLuint mask )
+
+    public native void glStencilMask(
+        int mask
+    );
+
+    // C function void glStencilOp ( GLenum fail, GLenum zfail, GLenum zpass )
+
+    public native void glStencilOp(
+        int fail,
+        int zfail,
+        int zpass
+    );
+
+    // C function void glTexCoordPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+
+    private native void glTexCoordPointerBounds(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer,
+        int remaining
+    );
+
+    public void glTexCoordPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ) {
+        if (((size == 2) ||
+             (size == 3) ||
+             (size == 4)) &&
+            ((type == GL_FLOAT) ||
+             (type == GL_BYTE) ||
+             (type == GL_SHORT) ||
+             (type == GL_FIXED)) &&
+            (stride >= 0)) {
+            _texCoordPointer = pointer;
+        }
+        glTexCoordPointerBounds(
+            size,
+            type,
+            stride,
+            pointer,
+            pointer.remaining()
+        );
+    }
+
+    // C function void glTexEnvf ( GLenum target, GLenum pname, GLfloat param )
+
+    public native void glTexEnvf(
+        int target,
+        int pname,
+        float param
+    );
+
+    // C function void glTexEnvfv ( GLenum target, GLenum pname, const GLfloat *params )
+
+    public native void glTexEnvfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glTexEnvfv ( GLenum target, GLenum pname, const GLfloat *params )
+
+    public native void glTexEnvfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glTexEnvx ( GLenum target, GLenum pname, GLfixed param )
+
+    public native void glTexEnvx(
+        int target,
+        int pname,
+        int param
+    );
+
+    // C function void glTexEnvxv ( GLenum target, GLenum pname, const GLfixed *params )
+
+    public native void glTexEnvxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glTexEnvxv ( GLenum target, GLenum pname, const GLfixed *params )
+
+    public native void glTexEnvxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glTexImage2D ( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+
+    public native void glTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int width,
+        int height,
+        int border,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    );
+
+    // C function void glTexParameterf ( GLenum target, GLenum pname, GLfloat param )
+
+    public native void glTexParameterf(
+        int target,
+        int pname,
+        float param
+    );
+
+    // C function void glTexParameterx ( GLenum target, GLenum pname, GLfixed param )
+
+    public native void glTexParameterx(
+        int target,
+        int pname,
+        int param
+    );
+
+    // C function void glTexSubImage2D ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+
+    public native void glTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int width,
+        int height,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    );
+
+    // C function void glTranslatef ( GLfloat x, GLfloat y, GLfloat z )
+
+    public native void glTranslatef(
+        float x,
+        float y,
+        float z
+    );
+
+    // C function void glTranslatex ( GLfixed x, GLfixed y, GLfixed z )
+
+    public native void glTranslatex(
+        int x,
+        int y,
+        int z
+    );
+
+    // C function void glVertexPointer ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+
+    private native void glVertexPointerBounds(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer,
+        int remaining
+    );
+
+    public void glVertexPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    ) {
+        if (((size == 2) ||
+             (size == 3) ||
+             (size == 4)) &&
+            ((type == GL_FLOAT) ||
+             (type == GL_BYTE) ||
+             (type == GL_SHORT) ||
+             (type == GL_FIXED)) &&
+            (stride >= 0)) {
+            _vertexPointer = pointer;
+        }
+        glVertexPointerBounds(
+            size,
+            type,
+            stride,
+            pointer,
+            pointer.remaining()
+        );
+    }
+
+    // C function void glViewport ( GLint x, GLint y, GLsizei width, GLsizei height )
+
+    public native void glViewport(
+        int x,
+        int y,
+        int width,
+        int height
+    );
+
+    // C function GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent )
+
+    public native int glQueryMatrixxOES(
+        int[] mantissa,
+        int mantissaOffset,
+        int[] exponent,
+        int exponentOffset
+    );
+
+    // C function GLbitfield glQueryMatrixxOES ( GLfixed *mantissa, GLint *exponent )
+
+    public native int glQueryMatrixxOES(
+        java.nio.IntBuffer mantissa,
+        java.nio.IntBuffer exponent
+    );
+
+    // C function void glBindBuffer ( GLenum target, GLuint buffer )
+
+    public native void glBindBuffer(
+        int target,
+        int buffer
+    );
+
+    // C function void glBufferData ( GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage )
+
+    public native void glBufferData(
+        int target,
+        int size,
+        java.nio.Buffer data,
+        int usage
+    );
+
+    // C function void glBufferSubData ( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data )
+
+    public native void glBufferSubData(
+        int target,
+        int offset,
+        int size,
+        java.nio.Buffer data
+    );
+
+    // C function void glClipPlanef ( GLenum plane, const GLfloat *equation )
+
+    public native void glClipPlanef(
+        int plane,
+        float[] equation,
+        int offset
+    );
+
+    // C function void glClipPlanef ( GLenum plane, const GLfloat *equation )
+
+    public native void glClipPlanef(
+        int plane,
+        java.nio.FloatBuffer equation
+    );
+
+    // C function void glClipPlanex ( GLenum plane, const GLfixed *equation )
+
+    public native void glClipPlanex(
+        int plane,
+        int[] equation,
+        int offset
+    );
+
+    // C function void glClipPlanex ( GLenum plane, const GLfixed *equation )
+
+    public native void glClipPlanex(
+        int plane,
+        java.nio.IntBuffer equation
+    );
+
+    // C function void glColor4ub ( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
+
+    public native void glColor4ub(
+        byte red,
+        byte green,
+        byte blue,
+        byte alpha
+    );
+
+    // C function void glColorPointer ( GLint size, GLenum type, GLsizei stride, GLint offset )
+
+    public native void glColorPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+    // C function void glDeleteBuffers ( GLsizei n, const GLuint *buffers )
+
+    public native void glDeleteBuffers(
+        int n,
+        int[] buffers,
+        int offset
+    );
+
+    // C function void glDeleteBuffers ( GLsizei n, const GLuint *buffers )
+
+    public native void glDeleteBuffers(
+        int n,
+        java.nio.IntBuffer buffers
+    );
+
+    // C function void glDrawElements ( GLenum mode, GLsizei count, GLenum type, GLint offset )
+
+    public native void glDrawElements(
+        int mode,
+        int count,
+        int type,
+        int offset
+    );
+
+    // C function void glGenBuffers ( GLsizei n, GLuint *buffers )
+
+    public native void glGenBuffers(
+        int n,
+        int[] buffers,
+        int offset
+    );
+
+    // C function void glGenBuffers ( GLsizei n, GLuint *buffers )
+
+    public native void glGenBuffers(
+        int n,
+        java.nio.IntBuffer buffers
+    );
+
+    // C function void glGetBooleanv ( GLenum pname, GLboolean *params )
+
+    public native void glGetBooleanv(
+        int pname,
+        boolean[] params,
+        int offset
+    );
+
+    // C function void glGetBooleanv ( GLenum pname, GLboolean *params )
+
+    public native void glGetBooleanv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params )
+
+    public native void glGetBufferParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetBufferParameteriv ( GLenum target, GLenum pname, GLint *params )
+
+    public native void glGetBufferParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetClipPlanef ( GLenum pname, GLfloat *eqn )
+
+    public native void glGetClipPlanef(
+        int pname,
+        float[] eqn,
+        int offset
+    );
+
+    // C function void glGetClipPlanef ( GLenum pname, GLfloat *eqn )
+
+    public native void glGetClipPlanef(
+        int pname,
+        java.nio.FloatBuffer eqn
+    );
+
+    // C function void glGetClipPlanex ( GLenum pname, GLfixed *eqn )
+
+    public native void glGetClipPlanex(
+        int pname,
+        int[] eqn,
+        int offset
+    );
+
+    // C function void glGetClipPlanex ( GLenum pname, GLfixed *eqn )
+
+    public native void glGetClipPlanex(
+        int pname,
+        java.nio.IntBuffer eqn
+    );
+
+    // C function void glGetFixedv ( GLenum pname, GLfixed *params )
+
+    public native void glGetFixedv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetFixedv ( GLenum pname, GLfixed *params )
+
+    public native void glGetFixedv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetFloatv ( GLenum pname, GLfloat *params )
+
+    public native void glGetFloatv(
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glGetFloatv ( GLenum pname, GLfloat *params )
+
+    public native void glGetFloatv(
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glGetLightfv ( GLenum light, GLenum pname, GLfloat *params )
+
+    public native void glGetLightfv(
+        int light,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glGetLightfv ( GLenum light, GLenum pname, GLfloat *params )
+
+    public native void glGetLightfv(
+        int light,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glGetLightxv ( GLenum light, GLenum pname, GLfixed *params )
+
+    public native void glGetLightxv(
+        int light,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetLightxv ( GLenum light, GLenum pname, GLfixed *params )
+
+    public native void glGetLightxv(
+        int light,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetMaterialfv ( GLenum face, GLenum pname, GLfloat *params )
+
+    public native void glGetMaterialfv(
+        int face,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glGetMaterialfv ( GLenum face, GLenum pname, GLfloat *params )
+
+    public native void glGetMaterialfv(
+        int face,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glGetMaterialxv ( GLenum face, GLenum pname, GLfixed *params )
+
+    public native void glGetMaterialxv(
+        int face,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetMaterialxv ( GLenum face, GLenum pname, GLfixed *params )
+
+    public native void glGetMaterialxv(
+        int face,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetTexEnviv ( GLenum env, GLenum pname, GLint *params )
+
+    public native void glGetTexEnviv(
+        int env,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetTexEnviv ( GLenum env, GLenum pname, GLint *params )
+
+    public native void glGetTexEnviv(
+        int env,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetTexEnvxv ( GLenum env, GLenum pname, GLfixed *params )
+
+    public native void glGetTexEnvxv(
+        int env,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetTexEnvxv ( GLenum env, GLenum pname, GLfixed *params )
+
+    public native void glGetTexEnvxv(
+        int env,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params )
+
+    public native void glGetTexParameterfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params )
+
+    public native void glGetTexParameterfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params )
+
+    public native void glGetTexParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetTexParameteriv ( GLenum target, GLenum pname, GLint *params )
+
+    public native void glGetTexParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetTexParameterxv ( GLenum target, GLenum pname, GLfixed *params )
+
+    public native void glGetTexParameterxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetTexParameterxv ( GLenum target, GLenum pname, GLfixed *params )
+
+    public native void glGetTexParameterxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function GLboolean glIsBuffer ( GLuint buffer )
+
+    public native boolean glIsBuffer(
+        int buffer
+    );
+
+    // C function GLboolean glIsEnabled ( GLenum cap )
+
+    public native boolean glIsEnabled(
+        int cap
+    );
+
+    // C function GLboolean glIsTexture ( GLuint texture )
+
+    public native boolean glIsTexture(
+        int texture
+    );
+
+    // C function void glNormalPointer ( GLenum type, GLsizei stride, GLint offset )
+
+    public native void glNormalPointer(
+        int type,
+        int stride,
+        int offset
+    );
+
+    // C function void glPointParameterf ( GLenum pname, GLfloat param )
+
+    public native void glPointParameterf(
+        int pname,
+        float param
+    );
+
+    // C function void glPointParameterfv ( GLenum pname, const GLfloat *params )
+
+    public native void glPointParameterfv(
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glPointParameterfv ( GLenum pname, const GLfloat *params )
+
+    public native void glPointParameterfv(
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glPointParameterx ( GLenum pname, GLfixed param )
+
+    public native void glPointParameterx(
+        int pname,
+        int param
+    );
+
+    // C function void glPointParameterxv ( GLenum pname, const GLfixed *params )
+
+    public native void glPointParameterxv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glPointParameterxv ( GLenum pname, const GLfixed *params )
+
+    public native void glPointParameterxv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glPointSizePointerOES ( GLenum type, GLsizei stride, const GLvoid *pointer )
+
+    public native void glPointSizePointerOES(
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    // C function void glTexCoordPointer ( GLint size, GLenum type, GLsizei stride, GLint offset )
+
+    public native void glTexCoordPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+    // C function void glTexEnvi ( GLenum target, GLenum pname, GLint param )
+
+    public native void glTexEnvi(
+        int target,
+        int pname,
+        int param
+    );
+
+    // C function void glTexEnviv ( GLenum target, GLenum pname, const GLint *params )
+
+    public native void glTexEnviv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glTexEnviv ( GLenum target, GLenum pname, const GLint *params )
+
+    public native void glTexEnviv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glTexParameterfv ( GLenum target, GLenum pname, const GLfloat *params )
+
+    public native void glTexParameterfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glTexParameterfv ( GLenum target, GLenum pname, const GLfloat *params )
+
+    public native void glTexParameterfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glTexParameteri ( GLenum target, GLenum pname, GLint param )
+
+    public native void glTexParameteri(
+        int target,
+        int pname,
+        int param
+    );
+
+    // C function void glTexParameteriv ( GLenum target, GLenum pname, const GLint *params )
+
+    public native void glTexParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glTexParameteriv ( GLenum target, GLenum pname, const GLint *params )
+
+    public native void glTexParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glTexParameterxv ( GLenum target, GLenum pname, const GLfixed *params )
+
+    public native void glTexParameterxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glTexParameterxv ( GLenum target, GLenum pname, const GLfixed *params )
+
+    public native void glTexParameterxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glVertexPointer ( GLint size, GLenum type, GLsizei stride, GLint offset )
+
+    public native void glVertexPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+    // C function void glCurrentPaletteMatrixOES ( GLuint matrixpaletteindex )
+
+    public native void glCurrentPaletteMatrixOES(
+        int matrixpaletteindex
+    );
+
+    // C function void glDrawTexfOES ( GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height )
+
+    public native void glDrawTexfOES(
+        float x,
+        float y,
+        float z,
+        float width,
+        float height
+    );
+
+    // C function void glDrawTexfvOES ( const GLfloat *coords )
+
+    public native void glDrawTexfvOES(
+        float[] coords,
+        int offset
+    );
+
+    // C function void glDrawTexfvOES ( const GLfloat *coords )
+
+    public native void glDrawTexfvOES(
+        java.nio.FloatBuffer coords
+    );
+
+    // C function void glDrawTexiOES ( GLint x, GLint y, GLint z, GLint width, GLint height )
+
+    public native void glDrawTexiOES(
+        int x,
+        int y,
+        int z,
+        int width,
+        int height
+    );
+
+    // C function void glDrawTexivOES ( const GLint *coords )
+
+    public native void glDrawTexivOES(
+        int[] coords,
+        int offset
+    );
+
+    // C function void glDrawTexivOES ( const GLint *coords )
+
+    public native void glDrawTexivOES(
+        java.nio.IntBuffer coords
+    );
+
+    // C function void glDrawTexsOES ( GLshort x, GLshort y, GLshort z, GLshort width, GLshort height )
+
+    public native void glDrawTexsOES(
+        short x,
+        short y,
+        short z,
+        short width,
+        short height
+    );
+
+    // C function void glDrawTexsvOES ( const GLshort *coords )
+
+    public native void glDrawTexsvOES(
+        short[] coords,
+        int offset
+    );
+
+    // C function void glDrawTexsvOES ( const GLshort *coords )
+
+    public native void glDrawTexsvOES(
+        java.nio.ShortBuffer coords
+    );
+
+    // C function void glDrawTexxOES ( GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height )
+
+    public native void glDrawTexxOES(
+        int x,
+        int y,
+        int z,
+        int width,
+        int height
+    );
+
+    // C function void glDrawTexxvOES ( const GLfixed *coords )
+
+    public native void glDrawTexxvOES(
+        int[] coords,
+        int offset
+    );
+
+    // C function void glDrawTexxvOES ( const GLfixed *coords )
+
+    public native void glDrawTexxvOES(
+        java.nio.IntBuffer coords
+    );
+
+    // C function void glLoadPaletteFromModelViewMatrixOES ( void )
+
+    public native void glLoadPaletteFromModelViewMatrixOES(
+    );
+
+    // C function void glMatrixIndexPointerOES ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+
+    public native void glMatrixIndexPointerOES(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    // C function void glMatrixIndexPointerOES ( GLint size, GLenum type, GLsizei stride, GLint offset )
+
+    public native void glMatrixIndexPointerOES(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+    // C function void glWeightPointerOES ( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+
+    public native void glWeightPointerOES(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    // C function void glWeightPointerOES ( GLint size, GLenum type, GLsizei stride, GLint offset )
+
+    public native void glWeightPointerOES(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+    // C function void glBindFramebufferOES ( GLint target, GLint framebuffer )
+
+    public native void glBindFramebufferOES(
+        int target,
+        int framebuffer
+    );
+
+    // C function void glBindRenderbufferOES ( GLint target, GLint renderbuffer )
+
+    public native void glBindRenderbufferOES(
+        int target,
+        int renderbuffer
+    );
+
+    // C function void glBlendEquation ( GLint mode )
+
+    public native void glBlendEquation(
+        int mode
+    );
+
+    // C function void glBlendEquationSeparate ( GLint modeRGB, GLint modeAlpha )
+
+    public native void glBlendEquationSeparate(
+        int modeRGB,
+        int modeAlpha
+    );
+
+    // C function void glBlendFuncSeparate ( GLint srcRGB, GLint dstRGB, GLint srcAlpha, GLint dstAlpha )
+
+    public native void glBlendFuncSeparate(
+        int srcRGB,
+        int dstRGB,
+        int srcAlpha,
+        int dstAlpha
+    );
+
+    // C function GLint glCheckFramebufferStatusOES ( GLint target )
+
+    public native int glCheckFramebufferStatusOES(
+        int target
+    );
+
+    // C function void glDeleteFramebuffersOES ( GLint n, GLint *framebuffers )
+
+    public native void glDeleteFramebuffersOES(
+        int n,
+        int[] framebuffers,
+        int offset
+    );
+
+    // C function void glDeleteFramebuffersOES ( GLint n, GLint *framebuffers )
+
+    public native void glDeleteFramebuffersOES(
+        int n,
+        java.nio.IntBuffer framebuffers
+    );
+
+    // C function void glDeleteRenderbuffersOES ( GLint n, GLint *renderbuffers )
+
+    public native void glDeleteRenderbuffersOES(
+        int n,
+        int[] renderbuffers,
+        int offset
+    );
+
+    // C function void glDeleteRenderbuffersOES ( GLint n, GLint *renderbuffers )
+
+    public native void glDeleteRenderbuffersOES(
+        int n,
+        java.nio.IntBuffer renderbuffers
+    );
+
+    // C function void glFramebufferRenderbufferOES ( GLint target, GLint attachment, GLint renderbuffertarget, GLint renderbuffer )
+
+    public native void glFramebufferRenderbufferOES(
+        int target,
+        int attachment,
+        int renderbuffertarget,
+        int renderbuffer
+    );
+
+    // C function void glFramebufferTexture2DOES ( GLint target, GLint attachment, GLint textarget, GLint texture, GLint level )
+
+    public native void glFramebufferTexture2DOES(
+        int target,
+        int attachment,
+        int textarget,
+        int texture,
+        int level
+    );
+
+    // C function void glGenerateMipmapOES ( GLint target )
+
+    public native void glGenerateMipmapOES(
+        int target
+    );
+
+    // C function void glGenFramebuffersOES ( GLint n, GLint *framebuffers )
+
+    public native void glGenFramebuffersOES(
+        int n,
+        int[] framebuffers,
+        int offset
+    );
+
+    // C function void glGenFramebuffersOES ( GLint n, GLint *framebuffers )
+
+    public native void glGenFramebuffersOES(
+        int n,
+        java.nio.IntBuffer framebuffers
+    );
+
+    // C function void glGenRenderbuffersOES ( GLint n, GLint *renderbuffers )
+
+    public native void glGenRenderbuffersOES(
+        int n,
+        int[] renderbuffers,
+        int offset
+    );
+
+    // C function void glGenRenderbuffersOES ( GLint n, GLint *renderbuffers )
+
+    public native void glGenRenderbuffersOES(
+        int n,
+        java.nio.IntBuffer renderbuffers
+    );
+
+    // C function void glGetFramebufferAttachmentParameterivOES ( GLint target, GLint attachment, GLint pname, GLint *params )
+
+    public native void glGetFramebufferAttachmentParameterivOES(
+        int target,
+        int attachment,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetFramebufferAttachmentParameterivOES ( GLint target, GLint attachment, GLint pname, GLint *params )
+
+    public native void glGetFramebufferAttachmentParameterivOES(
+        int target,
+        int attachment,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetRenderbufferParameterivOES ( GLint target, GLint pname, GLint *params )
+
+    public native void glGetRenderbufferParameterivOES(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetRenderbufferParameterivOES ( GLint target, GLint pname, GLint *params )
+
+    public native void glGetRenderbufferParameterivOES(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetTexGenfv ( GLint coord, GLint pname, GLfloat *params )
+
+    public native void glGetTexGenfv(
+        int coord,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glGetTexGenfv ( GLint coord, GLint pname, GLfloat *params )
+
+    public native void glGetTexGenfv(
+        int coord,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glGetTexGeniv ( GLint coord, GLint pname, GLint *params )
+
+    public native void glGetTexGeniv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetTexGeniv ( GLint coord, GLint pname, GLint *params )
+
+    public native void glGetTexGeniv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glGetTexGenxv ( GLint coord, GLint pname, GLint *params )
+
+    public native void glGetTexGenxv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glGetTexGenxv ( GLint coord, GLint pname, GLint *params )
+
+    public native void glGetTexGenxv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function GLboolean glIsFramebufferOES ( GLint framebuffer )
+
+    public native boolean glIsFramebufferOES(
+        int framebuffer
+    );
+
+    // C function GLboolean glIsRenderbufferOES ( GLint renderbuffer )
+
+    public native boolean glIsRenderbufferOES(
+        int renderbuffer
+    );
+
+    // C function void glRenderbufferStorageOES ( GLint target, GLint internalformat, GLint width, GLint height )
+
+    public native void glRenderbufferStorageOES(
+        int target,
+        int internalformat,
+        int width,
+        int height
+    );
+
+    // C function void glTexGenf ( GLint coord, GLint pname, GLfloat param )
+
+    public native void glTexGenf(
+        int coord,
+        int pname,
+        float param
+    );
+
+    // C function void glTexGenfv ( GLint coord, GLint pname, GLfloat *params )
+
+    public native void glTexGenfv(
+        int coord,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    // C function void glTexGenfv ( GLint coord, GLint pname, GLfloat *params )
+
+    public native void glTexGenfv(
+        int coord,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    // C function void glTexGeni ( GLint coord, GLint pname, GLint param )
+
+    public native void glTexGeni(
+        int coord,
+        int pname,
+        int param
+    );
+
+    // C function void glTexGeniv ( GLint coord, GLint pname, GLint *params )
+
+    public native void glTexGeniv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glTexGeniv ( GLint coord, GLint pname, GLint *params )
+
+    public native void glTexGeniv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    // C function void glTexGenx ( GLint coord, GLint pname, GLint param )
+
+    public native void glTexGenx(
+        int coord,
+        int pname,
+        int param
+    );
+
+    // C function void glTexGenxv ( GLint coord, GLint pname, GLint *params )
+
+    public native void glTexGenxv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    // C function void glTexGenxv ( GLint coord, GLint pname, GLint *params )
+
+    public native void glTexGenxv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+}
diff --git a/opengl/java/javax/microedition/khronos/egl/EGL.java b/opengl/java/javax/microedition/khronos/egl/EGL.java
new file mode 100644
index 0000000..b743968
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/egl/EGL.java
@@ -0,0 +1,22 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package javax.microedition.khronos.egl;
+
+public interface EGL {
+}
+
diff --git a/opengl/java/javax/microedition/khronos/egl/EGL10.java b/opengl/java/javax/microedition/khronos/egl/EGL10.java
new file mode 100644
index 0000000..2ae793a
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/egl/EGL10.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.microedition.khronos.egl;
+
+import java.lang.String;
+
+public interface EGL10 extends EGL {
+    int EGL_SUCCESS                     = 0x3000;
+    int EGL_NOT_INITIALIZED             = 0x3001;
+    int EGL_BAD_ACCESS                  = 0x3002;
+    int EGL_BAD_ALLOC                   = 0x3003;
+    int EGL_BAD_ATTRIBUTE               = 0x3004;
+    int EGL_BAD_CONFIG                  = 0x3005;
+    int EGL_BAD_CONTEXT                 = 0x3006;
+    int EGL_BAD_CURRENT_SURFACE         = 0x3007;
+    int EGL_BAD_DISPLAY                 = 0x3008;
+    int EGL_BAD_MATCH                   = 0x3009;
+    int EGL_BAD_NATIVE_PIXMAP           = 0x300A;
+    int EGL_BAD_NATIVE_WINDOW           = 0x300B;
+    int EGL_BAD_PARAMETER               = 0x300C;
+    int EGL_BAD_SURFACE                 = 0x300D;
+    int EGL_BUFFER_SIZE                 = 0x3020;
+    int EGL_ALPHA_SIZE                  = 0x3021;
+    int EGL_BLUE_SIZE                   = 0x3022;
+    int EGL_GREEN_SIZE                  = 0x3023;
+    int EGL_RED_SIZE                    = 0x3024;
+    int EGL_DEPTH_SIZE                  = 0x3025;
+    int EGL_STENCIL_SIZE                = 0x3026;
+    int EGL_CONFIG_CAVEAT               = 0x3027;
+    int EGL_CONFIG_ID                   = 0x3028;
+    int EGL_LEVEL                       = 0x3029;
+    int EGL_MAX_PBUFFER_HEIGHT          = 0x302A;
+    int EGL_MAX_PBUFFER_PIXELS          = 0x302B;
+    int EGL_MAX_PBUFFER_WIDTH           = 0x302C;
+    int EGL_NATIVE_RENDERABLE           = 0x302D;
+    int EGL_NATIVE_VISUAL_ID            = 0x302E;
+    int EGL_NATIVE_VISUAL_TYPE          = 0x302F;
+    int EGL_SAMPLES                     = 0x3031;
+    int EGL_SAMPLE_BUFFERS              = 0x3032;
+    int EGL_SURFACE_TYPE                = 0x3033;
+    int EGL_TRANSPARENT_TYPE            = 0x3034;
+    int EGL_TRANSPARENT_BLUE_VALUE      = 0x3035;
+    int EGL_TRANSPARENT_GREEN_VALUE     = 0x3036;
+    int EGL_TRANSPARENT_RED_VALUE       = 0x3037;
+    int EGL_NONE                        = 0x3038;
+    int EGL_LUMINANCE_SIZE              = 0x303D;
+    int EGL_ALPHA_MASK_SIZE             = 0x303E;
+    int EGL_COLOR_BUFFER_TYPE           = 0x303F;
+    int EGL_RENDERABLE_TYPE             = 0x3040;
+    int EGL_SLOW_CONFIG                 = 0x3050;
+    int EGL_NON_CONFORMANT_CONFIG       = 0x3051;
+    int EGL_TRANSPARENT_RGB             = 0x3052;
+    int EGL_RGB_BUFFER                  = 0x308E;
+    int EGL_LUMINANCE_BUFFER            = 0x308F;
+    int EGL_VENDOR                      = 0x3053;
+    int EGL_VERSION                     = 0x3054;
+    int EGL_EXTENSIONS                  = 0x3055;
+    int EGL_HEIGHT                      = 0x3056;
+    int EGL_WIDTH                       = 0x3057;
+    int EGL_LARGEST_PBUFFER             = 0x3058;
+    int EGL_RENDER_BUFFER               = 0x3086;
+    int EGL_COLORSPACE                  = 0x3087;
+    int EGL_ALPHA_FORMAT                = 0x3088;
+    int EGL_HORIZONTAL_RESOLUTION       = 0x3090;
+    int EGL_VERTICAL_RESOLUTION         = 0x3091;
+    int EGL_PIXEL_ASPECT_RATIO          = 0x3092;
+    int EGL_SINGLE_BUFFER               = 0x3085;
+    int EGL_CORE_NATIVE_ENGINE          = 0x305B;
+    int EGL_DRAW                        = 0x3059;
+    int EGL_READ                        = 0x305A;
+
+    int EGL_DONT_CARE                   = -1;
+
+    int EGL_PBUFFER_BIT                 = 0x01;
+    int EGL_PIXMAP_BIT                  = 0x02;
+    int EGL_WINDOW_BIT                  = 0x04;
+
+    Object     EGL_DEFAULT_DISPLAY = null;
+    EGLDisplay EGL_NO_DISPLAY = new com.google.android.gles_jni.EGLDisplayImpl(0);
+    EGLContext EGL_NO_CONTEXT = new com.google.android.gles_jni.EGLContextImpl(0);
+    EGLSurface EGL_NO_SURFACE = new com.google.android.gles_jni.EGLSurfaceImpl(0);
+    
+    boolean     eglChooseConfig(EGLDisplay display, int[] attrib_list, EGLConfig[] configs, int config_size, int[] num_config);
+    boolean     eglCopyBuffers(EGLDisplay display, EGLSurface surface, Object native_pixmap);
+    EGLContext  eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list);
+    EGLSurface  eglCreatePbufferSurface(EGLDisplay display, EGLConfig config, int[] attrib_list);
+    EGLSurface  eglCreatePixmapSurface(EGLDisplay display, EGLConfig config, Object native_pixmap, int[] attrib_list);
+    EGLSurface  eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list);
+    boolean     eglDestroyContext(EGLDisplay display, EGLContext context);
+    boolean     eglDestroySurface(EGLDisplay display, EGLSurface surface);
+    boolean     eglGetConfigAttrib(EGLDisplay display, EGLConfig config, int attribute, int[] value);
+    boolean     eglGetConfigs(EGLDisplay display, EGLConfig[] configs, int config_size, int[] num_config);
+    EGLContext  eglGetCurrentContext();
+    EGLDisplay  eglGetCurrentDisplay();
+    EGLSurface  eglGetCurrentSurface(int readdraw);
+    EGLDisplay  eglGetDisplay(Object native_display);
+    int         eglGetError();
+    boolean     eglInitialize(EGLDisplay display, int[] major_minor);
+    boolean     eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context);
+    boolean     eglQueryContext(EGLDisplay display, EGLContext context, int attribute, int[] value);
+    String      eglQueryString(EGLDisplay display, int name);
+    boolean     eglQuerySurface(EGLDisplay display, EGLSurface surface, int attribute, int[] value);
+    boolean     eglSwapBuffers(EGLDisplay display, EGLSurface surface);
+    boolean     eglTerminate(EGLDisplay display);
+    boolean     eglWaitGL();
+    boolean     eglWaitNative(int engine, Object bindTarget);
+}
diff --git a/opengl/java/javax/microedition/khronos/egl/EGL11.java b/opengl/java/javax/microedition/khronos/egl/EGL11.java
new file mode 100644
index 0000000..41d62e6
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/egl/EGL11.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package javax.microedition.khronos.egl;
+
+public interface EGL11 extends EGL10 {
+    int EGL_CONTEXT_LOST                = 0x300E;
+}
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLConfig.java b/opengl/java/javax/microedition/khronos/egl/EGLConfig.java
new file mode 100644
index 0000000..a1e496c
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/egl/EGLConfig.java
@@ -0,0 +1,22 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package javax.microedition.khronos.egl;
+
+public abstract class EGLConfig
+{
+}
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLContext.java b/opengl/java/javax/microedition/khronos/egl/EGLContext.java
new file mode 100644
index 0000000..fc94492
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/egl/EGLContext.java
@@ -0,0 +1,31 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package javax.microedition.khronos.egl;
+
+import javax.microedition.khronos.opengles.GL;
+
+public abstract class EGLContext
+{
+    private static final EGL EGL_INSTANCE = new com.google.android.gles_jni.EGLImpl();
+    
+    public static EGL getEGL() {
+        return EGL_INSTANCE;
+    }
+
+    public abstract GL getGL();
+}
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java b/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java
new file mode 100644
index 0000000..cd8a755
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/egl/EGLDisplay.java
@@ -0,0 +1,22 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package javax.microedition.khronos.egl;
+
+public abstract class EGLDisplay
+{
+}
diff --git a/opengl/java/javax/microedition/khronos/egl/EGLSurface.java b/opengl/java/javax/microedition/khronos/egl/EGLSurface.java
new file mode 100644
index 0000000..5349bc1
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/egl/EGLSurface.java
@@ -0,0 +1,22 @@
+/* 
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package javax.microedition.khronos.egl;
+
+public abstract class EGLSurface
+{
+}
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL.java b/opengl/java/javax/microedition/khronos/opengles/GL.java
new file mode 100644
index 0000000..3b78f3d
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/opengles/GL.java
@@ -0,0 +1,22 @@
+/* //device/java/android/javax/microedition/khronos/opengles/GL.java
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+package javax.microedition.khronos.opengles;
+
+public interface GL {
+}
+
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL10.java b/opengl/java/javax/microedition/khronos/opengles/GL10.java
new file mode 100644
index 0000000..4fcfb52
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/opengles/GL10.java
@@ -0,0 +1,972 @@
+/* //device/java/android/javax/microedition/khronos/opengles/GL10.java
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+package javax.microedition.khronos.opengles;
+
+public interface GL10 extends GL {
+    int GL_ADD                                   = 0x0104;
+    int GL_ALIASED_LINE_WIDTH_RANGE              = 0x846E;
+    int GL_ALIASED_POINT_SIZE_RANGE              = 0x846D;
+    int GL_ALPHA                                 = 0x1906;
+    int GL_ALPHA_BITS                            = 0x0D55;
+    int GL_ALPHA_TEST                            = 0x0BC0;
+    int GL_ALWAYS                                = 0x0207;
+    int GL_AMBIENT                               = 0x1200;
+    int GL_AMBIENT_AND_DIFFUSE                   = 0x1602;
+    int GL_AND                                   = 0x1501;
+    int GL_AND_INVERTED                          = 0x1504;
+    int GL_AND_REVERSE                           = 0x1502;
+    int GL_BACK                                  = 0x0405;
+    int GL_BLEND                                 = 0x0BE2;
+    int GL_BLUE_BITS                             = 0x0D54;
+    int GL_BYTE                                  = 0x1400;
+    int GL_CCW                                   = 0x0901;
+    int GL_CLAMP_TO_EDGE                         = 0x812F;
+    int GL_CLEAR                                 = 0x1500;
+    int GL_COLOR_ARRAY                           = 0x8076;
+    int GL_COLOR_BUFFER_BIT                      = 0x4000;
+    int GL_COLOR_LOGIC_OP                        = 0x0BF2;
+    int GL_COLOR_MATERIAL                        = 0x0B57;
+    int GL_COMPRESSED_TEXTURE_FORMATS            = 0x86A3;
+    int GL_CONSTANT_ATTENUATION                  = 0x1207;
+    int GL_COPY                                  = 0x1503;
+    int GL_COPY_INVERTED                         = 0x150C;
+    int GL_CULL_FACE                             = 0x0B44;
+    int GL_CW                                    = 0x0900;
+    int GL_DECAL                                 = 0x2101;
+    int GL_DECR                                  = 0x1E03;
+    int GL_DEPTH_BITS                            = 0x0D56;
+    int GL_DEPTH_BUFFER_BIT                      = 0x0100;
+    int GL_DEPTH_TEST                            = 0x0B71;
+    int GL_DIFFUSE                               = 0x1201;
+    int GL_DITHER                                = 0x0BD0;
+    int GL_DONT_CARE                             = 0x1100;
+    int GL_DST_ALPHA                             = 0x0304;
+    int GL_DST_COLOR                             = 0x0306;
+    int GL_EMISSION                              = 0x1600;
+    int GL_EQUAL                                 = 0x0202;
+    int GL_EQUIV                                 = 0x1509;
+    int GL_EXP                                   = 0x0800;
+    int GL_EXP2                                  = 0x0801;
+    int GL_EXTENSIONS                            = 0x1F03;
+    int GL_FALSE                                 = 0;
+    int GL_FASTEST                               = 0x1101;
+    int GL_FIXED                                 = 0x140C;
+    int GL_FLAT                                  = 0x1D00;
+    int GL_FLOAT                                 = 0x1406;
+    int GL_FOG                                   = 0x0B60;
+    int GL_FOG_COLOR                             = 0x0B66;
+    int GL_FOG_DENSITY                           = 0x0B62;
+    int GL_FOG_END                               = 0x0B64;
+    int GL_FOG_HINT                              = 0x0C54;
+    int GL_FOG_MODE                              = 0x0B65;
+    int GL_FOG_START                             = 0x0B63;
+    int GL_FRONT                                 = 0x0404;
+    int GL_FRONT_AND_BACK                        = 0x0408;
+    int GL_GEQUAL                                = 0x0206;
+    int GL_GREATER                               = 0x0204;
+    int GL_GREEN_BITS                            = 0x0D53;
+    int GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES  = 0x8B9B;
+    int GL_IMPLEMENTATION_COLOR_READ_TYPE_OES    = 0x8B9A;
+    int GL_INCR                                  = 0x1E02;
+    int GL_INVALID_ENUM                          = 0x0500;
+    int GL_INVALID_OPERATION                     = 0x0502;
+    int GL_INVALID_VALUE                         = 0x0501;
+    int GL_INVERT                                = 0x150A;
+    int GL_KEEP                                  = 0x1E00;
+    int GL_LEQUAL                                = 0x0203;
+    int GL_LESS                                  = 0x0201;
+    int GL_LIGHT_MODEL_AMBIENT                   = 0x0B53;
+    int GL_LIGHT_MODEL_TWO_SIDE                  = 0x0B52;
+    int GL_LIGHT0                                = 0x4000;
+    int GL_LIGHT1                                = 0x4001;
+    int GL_LIGHT2                                = 0x4002;
+    int GL_LIGHT3                                = 0x4003;
+    int GL_LIGHT4                                = 0x4004;
+    int GL_LIGHT5                                = 0x4005;
+    int GL_LIGHT6                                = 0x4006;
+    int GL_LIGHT7                                = 0x4007;
+    int GL_LIGHTING                              = 0x0B50;
+    int GL_LINE_LOOP                             = 0x0002;
+    int GL_LINE_SMOOTH                           = 0x0B20;
+    int GL_LINE_SMOOTH_HINT                      = 0x0C52;
+    int GL_LINE_STRIP                            = 0x0003;
+    int GL_LINEAR                                = 0x2601;
+    int GL_LINEAR_ATTENUATION                    = 0x1208;
+    int GL_LINEAR_MIPMAP_LINEAR                  = 0x2703;
+    int GL_LINEAR_MIPMAP_NEAREST                 = 0x2701;
+    int GL_LINES                                 = 0x0001;
+    int GL_LUMINANCE                             = 0x1909;
+    int GL_LUMINANCE_ALPHA                       = 0x190A;
+    int GL_MAX_ELEMENTS_INDICES                  = 0x80E9;
+    int GL_MAX_ELEMENTS_VERTICES                 = 0x80E8;
+    int GL_MAX_LIGHTS                            = 0x0D31;
+    int GL_MAX_MODELVIEW_STACK_DEPTH             = 0x0D36;
+    int GL_MAX_PROJECTION_STACK_DEPTH            = 0x0D38;
+    int GL_MAX_TEXTURE_SIZE                      = 0x0D33;
+    int GL_MAX_TEXTURE_STACK_DEPTH               = 0x0D39;
+    int GL_MAX_TEXTURE_UNITS                     = 0x84E2;
+    int GL_MAX_VIEWPORT_DIMS                     = 0x0D3A;
+    int GL_MODELVIEW                             = 0x1700;
+    int GL_MODULATE                              = 0x2100;
+    int GL_MULTISAMPLE                           = 0x809D;
+    int GL_NAND                                  = 0x150E;
+    int GL_NEAREST                               = 0x2600;
+    int GL_NEAREST_MIPMAP_LINEAR                 = 0x2702;
+    int GL_NEAREST_MIPMAP_NEAREST                = 0x2700;
+    int GL_NEVER                                 = 0x0200;
+    int GL_NICEST                                = 0x1102;
+    int GL_NO_ERROR                              = 0;
+    int GL_NOOP                                  = 0x1505;
+    int GL_NOR                                   = 0x1508;
+    int GL_NORMAL_ARRAY                          = 0x8075;
+    int GL_NORMALIZE                             = 0x0BA1;
+    int GL_NOTEQUAL                              = 0x0205;
+    int GL_NUM_COMPRESSED_TEXTURE_FORMATS        = 0x86A2;
+    int GL_ONE                                   = 1;
+    int GL_ONE_MINUS_DST_ALPHA                   = 0x0305;
+    int GL_ONE_MINUS_DST_COLOR                   = 0x0307;
+    int GL_ONE_MINUS_SRC_ALPHA                   = 0x0303;
+    int GL_ONE_MINUS_SRC_COLOR                   = 0x0301;
+    int GL_OR                                    = 0x1507;
+    int GL_OR_INVERTED                           = 0x150D;
+    int GL_OR_REVERSE                            = 0x150B;
+    int GL_OUT_OF_MEMORY                         = 0x0505;
+    int GL_PACK_ALIGNMENT                        = 0x0D05;
+    int GL_PALETTE4_R5_G6_B5_OES                 = 0x8B92;
+    int GL_PALETTE4_RGB5_A1_OES                  = 0x8B94;
+    int GL_PALETTE4_RGB8_OES                     = 0x8B90;
+    int GL_PALETTE4_RGBA4_OES                    = 0x8B93;
+    int GL_PALETTE4_RGBA8_OES                    = 0x8B91;
+    int GL_PALETTE8_R5_G6_B5_OES                 = 0x8B97;
+    int GL_PALETTE8_RGB5_A1_OES                  = 0x8B99;
+    int GL_PALETTE8_RGB8_OES                     = 0x8B95;
+    int GL_PALETTE8_RGBA4_OES                    = 0x8B98;
+    int GL_PALETTE8_RGBA8_OES                    = 0x8B96;
+    int GL_PERSPECTIVE_CORRECTION_HINT           = 0x0C50;
+    int GL_POINT_SMOOTH                          = 0x0B10;
+    int GL_POINT_SMOOTH_HINT                     = 0x0C51;
+    int GL_POINTS                                = 0x0000;
+    int GL_POINT_FADE_THRESHOLD_SIZE             = 0x8128;
+    int GL_POINT_SIZE                            = 0x0B11;
+    int GL_POLYGON_OFFSET_FILL                   = 0x8037;
+    int GL_POLYGON_SMOOTH_HINT                   = 0x0C53;
+    int GL_POSITION                              = 0x1203;
+    int GL_PROJECTION                            = 0x1701;
+    int GL_QUADRATIC_ATTENUATION                 = 0x1209;
+    int GL_RED_BITS                              = 0x0D52;
+    int GL_RENDERER                              = 0x1F01;
+    int GL_REPEAT                                = 0x2901;
+    int GL_REPLACE                               = 0x1E01;
+    int GL_RESCALE_NORMAL                        = 0x803A;
+    int GL_RGB                                   = 0x1907;
+    int GL_RGBA                                  = 0x1908;
+    int GL_SAMPLE_ALPHA_TO_COVERAGE              = 0x809E;
+    int GL_SAMPLE_ALPHA_TO_ONE                   = 0x809F;
+    int GL_SAMPLE_COVERAGE                       = 0x80A0;
+    int GL_SCISSOR_TEST                          = 0x0C11;
+    int GL_SET                                   = 0x150F;
+    int GL_SHININESS                             = 0x1601;
+    int GL_SHORT                                 = 0x1402;
+    int GL_SMOOTH                                = 0x1D01;
+    int GL_SMOOTH_LINE_WIDTH_RANGE               = 0x0B22;
+    int GL_SMOOTH_POINT_SIZE_RANGE               = 0x0B12;
+    int GL_SPECULAR                              = 0x1202;
+    int GL_SPOT_CUTOFF                           = 0x1206;
+    int GL_SPOT_DIRECTION                        = 0x1204;
+    int GL_SPOT_EXPONENT                         = 0x1205;
+    int GL_SRC_ALPHA                             = 0x0302;
+    int GL_SRC_ALPHA_SATURATE                    = 0x0308;
+    int GL_SRC_COLOR                             = 0x0300;
+    int GL_STACK_OVERFLOW                        = 0x0503;
+    int GL_STACK_UNDERFLOW                       = 0x0504;
+    int GL_STENCIL_BITS                          = 0x0D57;
+    int GL_STENCIL_BUFFER_BIT                    = 0x0400;
+    int GL_STENCIL_TEST                          = 0x0B90;
+    int GL_SUBPIXEL_BITS                         = 0x0D50;
+    int GL_TEXTURE                               = 0x1702;
+    int GL_TEXTURE_2D                            = 0x0DE1;
+    int GL_TEXTURE_COORD_ARRAY                   = 0x8078;
+    int GL_TEXTURE_ENV                           = 0x2300;
+    int GL_TEXTURE_ENV_COLOR                     = 0x2201;
+    int GL_TEXTURE_ENV_MODE                      = 0x2200;
+    int GL_TEXTURE_MAG_FILTER                    = 0x2800;
+    int GL_TEXTURE_MIN_FILTER                    = 0x2801;
+    int GL_TEXTURE_WRAP_S                        = 0x2802;
+    int GL_TEXTURE_WRAP_T                        = 0x2803;
+    int GL_TEXTURE0                              = 0x84C0;
+    int GL_TEXTURE1                              = 0x84C1;
+    int GL_TEXTURE2                              = 0x84C2;
+    int GL_TEXTURE3                              = 0x84C3;
+    int GL_TEXTURE4                              = 0x84C4;
+    int GL_TEXTURE5                              = 0x84C5;
+    int GL_TEXTURE6                              = 0x84C6;
+    int GL_TEXTURE7                              = 0x84C7;
+    int GL_TEXTURE8                              = 0x84C8;
+    int GL_TEXTURE9                              = 0x84C9;
+    int GL_TEXTURE10                             = 0x84CA;
+    int GL_TEXTURE11                             = 0x84CB;
+    int GL_TEXTURE12                             = 0x84CC;
+    int GL_TEXTURE13                             = 0x84CD;
+    int GL_TEXTURE14                             = 0x84CE;
+    int GL_TEXTURE15                             = 0x84CF;
+    int GL_TEXTURE16                             = 0x84D0;
+    int GL_TEXTURE17                             = 0x84D1;
+    int GL_TEXTURE18                             = 0x84D2;
+    int GL_TEXTURE19                             = 0x84D3;
+    int GL_TEXTURE20                             = 0x84D4;
+    int GL_TEXTURE21                             = 0x84D5;
+    int GL_TEXTURE22                             = 0x84D6;
+    int GL_TEXTURE23                             = 0x84D7;
+    int GL_TEXTURE24                             = 0x84D8;
+    int GL_TEXTURE25                             = 0x84D9;
+    int GL_TEXTURE26                             = 0x84DA;
+    int GL_TEXTURE27                             = 0x84DB;
+    int GL_TEXTURE28                             = 0x84DC;
+    int GL_TEXTURE29                             = 0x84DD;
+    int GL_TEXTURE30                             = 0x84DE;
+    int GL_TEXTURE31                             = 0x84DF;
+    int GL_TRIANGLE_FAN                          = 0x0006;
+    int GL_TRIANGLE_STRIP                        = 0x0005;
+    int GL_TRIANGLES                             = 0x0004;
+    int GL_TRUE                                  = 1;
+    int GL_UNPACK_ALIGNMENT                      = 0x0CF5;
+    int GL_UNSIGNED_BYTE                         = 0x1401;
+    int GL_UNSIGNED_SHORT                        = 0x1403;
+    int GL_UNSIGNED_SHORT_4_4_4_4                = 0x8033;
+    int GL_UNSIGNED_SHORT_5_5_5_1                = 0x8034;
+    int GL_UNSIGNED_SHORT_5_6_5                  = 0x8363;
+    int GL_VENDOR                                = 0x1F00;
+    int GL_VERSION                               = 0x1F02;
+    int GL_VERTEX_ARRAY                          = 0x8074;
+    int GL_XOR                                   = 0x1506;
+    int GL_ZERO                                  = 0;
+
+    void glActiveTexture(
+        int texture
+    );
+
+    void glAlphaFunc(
+        int func,
+        float ref
+    );
+
+    void glAlphaFuncx(
+        int func,
+        int ref
+    );
+
+    void glBindTexture(
+        int target,
+        int texture
+    );
+
+    void glBlendFunc(
+        int sfactor,
+        int dfactor
+    );
+
+    void glClear(
+        int mask
+    );
+
+    void glClearColor(
+        float red,
+        float green,
+        float blue,
+        float alpha
+    );
+
+    void glClearColorx(
+        int red,
+        int green,
+        int blue,
+        int alpha
+    );
+
+    void glClearDepthf(
+        float depth
+    );
+
+    void glClearDepthx(
+        int depth
+    );
+
+    void glClearStencil(
+        int s
+    );
+
+    void glClientActiveTexture(
+        int texture
+    );
+
+    void glColor4f(
+        float red,
+        float green,
+        float blue,
+        float alpha
+    );
+
+    void glColor4x(
+        int red,
+        int green,
+        int blue,
+        int alpha
+    );
+
+    void glColorMask(
+        boolean red,
+        boolean green,
+        boolean blue,
+        boolean alpha
+    );
+
+    void glColorPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    void glCompressedTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int width,
+        int height,
+        int border,
+        int imageSize,
+        java.nio.Buffer data
+    );
+
+    void glCompressedTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int width,
+        int height,
+        int format,
+        int imageSize,
+        java.nio.Buffer data
+    );
+
+    void glCopyTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int x,
+        int y,
+        int width,
+        int height,
+        int border
+    );
+
+    void glCopyTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int x,
+        int y,
+        int width,
+        int height
+    );
+
+    void glCullFace(
+        int mode
+    );
+
+    void glDeleteTextures(
+        int n,
+        int[] textures,
+        int offset
+    );
+
+    void glDeleteTextures(
+        int n,
+        java.nio.IntBuffer textures
+    );
+
+    void glDepthFunc(
+        int func
+    );
+
+    void glDepthMask(
+        boolean flag
+    );
+
+    void glDepthRangef(
+        float zNear,
+        float zFar
+    );
+
+    void glDepthRangex(
+        int zNear,
+        int zFar
+    );
+
+    void glDisable(
+        int cap
+    );
+
+    void glDisableClientState(
+        int array
+    );
+
+    void glDrawArrays(
+        int mode,
+        int first,
+        int count
+    );
+
+    void glDrawElements(
+        int mode,
+        int count,
+        int type,
+        java.nio.Buffer indices
+    );
+
+    void glEnable(
+        int cap
+    );
+
+    void glEnableClientState(
+        int array
+    );
+
+    void glFinish(
+    );
+
+    void glFlush(
+    );
+
+    void glFogf(
+        int pname,
+        float param
+    );
+
+    void glFogfv(
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glFogfv(
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glFogx(
+        int pname,
+        int param
+    );
+
+    void glFogxv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glFogxv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glFrontFace(
+        int mode
+    );
+
+    void glFrustumf(
+        float left,
+        float right,
+        float bottom,
+        float top,
+        float zNear,
+        float zFar
+    );
+
+    void glFrustumx(
+        int left,
+        int right,
+        int bottom,
+        int top,
+        int zNear,
+        int zFar
+    );
+
+    void glGenTextures(
+        int n,
+        int[] textures,
+        int offset
+    );
+
+    void glGenTextures(
+        int n,
+        java.nio.IntBuffer textures
+    );
+
+    int glGetError(
+    );
+
+    void glGetIntegerv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetIntegerv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    public String glGetString(
+        int name
+    );
+
+    void glHint(
+        int target,
+        int mode
+    );
+
+    void glLightModelf(
+        int pname,
+        float param
+    );
+
+    void glLightModelfv(
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glLightModelfv(
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glLightModelx(
+        int pname,
+        int param
+    );
+
+    void glLightModelxv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glLightModelxv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glLightf(
+        int light,
+        int pname,
+        float param
+    );
+
+    void glLightfv(
+        int light,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glLightfv(
+        int light,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glLightx(
+        int light,
+        int pname,
+        int param
+    );
+
+    void glLightxv(
+        int light,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glLightxv(
+        int light,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glLineWidth(
+        float width
+    );
+
+    void glLineWidthx(
+        int width
+    );
+
+    void glLoadIdentity(
+    );
+
+    void glLoadMatrixf(
+        float[] m,
+        int offset
+    );
+
+    void glLoadMatrixf(
+        java.nio.FloatBuffer m
+    );
+
+    void glLoadMatrixx(
+        int[] m,
+        int offset
+    );
+
+    void glLoadMatrixx(
+        java.nio.IntBuffer m
+    );
+
+    void glLogicOp(
+        int opcode
+    );
+
+    void glMaterialf(
+        int face,
+        int pname,
+        float param
+    );
+
+    void glMaterialfv(
+        int face,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glMaterialfv(
+        int face,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glMaterialx(
+        int face,
+        int pname,
+        int param
+    );
+
+    void glMaterialxv(
+        int face,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glMaterialxv(
+        int face,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glMatrixMode(
+        int mode
+    );
+
+    void glMultMatrixf(
+        float[] m,
+        int offset
+    );
+
+    void glMultMatrixf(
+        java.nio.FloatBuffer m
+    );
+
+    void glMultMatrixx(
+        int[] m,
+        int offset
+    );
+
+    void glMultMatrixx(
+        java.nio.IntBuffer m
+    );
+
+    void glMultiTexCoord4f(
+        int target,
+        float s,
+        float t,
+        float r,
+        float q
+    );
+
+    void glMultiTexCoord4x(
+        int target,
+        int s,
+        int t,
+        int r,
+        int q
+    );
+
+    void glNormal3f(
+        float nx,
+        float ny,
+        float nz
+    );
+
+    void glNormal3x(
+        int nx,
+        int ny,
+        int nz
+    );
+
+    void glNormalPointer(
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    void glOrthof(
+        float left,
+        float right,
+        float bottom,
+        float top,
+        float zNear,
+        float zFar
+    );
+
+    void glOrthox(
+        int left,
+        int right,
+        int bottom,
+        int top,
+        int zNear,
+        int zFar
+    );
+
+    void glPixelStorei(
+        int pname,
+        int param
+    );
+
+    void glPointSize(
+        float size
+    );
+
+    void glPointSizex(
+        int size
+    );
+
+    void glPolygonOffset(
+        float factor,
+        float units
+    );
+
+    void glPolygonOffsetx(
+        int factor,
+        int units
+    );
+
+    void glPopMatrix(
+    );
+
+    void glPushMatrix(
+    );
+
+    void glReadPixels(
+        int x,
+        int y,
+        int width,
+        int height,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    );
+
+    void glRotatef(
+        float angle,
+        float x,
+        float y,
+        float z
+    );
+
+    void glRotatex(
+        int angle,
+        int x,
+        int y,
+        int z
+    );
+
+    void glSampleCoverage(
+        float value,
+        boolean invert
+    );
+
+    void glSampleCoveragex(
+        int value,
+        boolean invert
+    );
+
+    void glScalef(
+        float x,
+        float y,
+        float z
+    );
+
+    void glScalex(
+        int x,
+        int y,
+        int z
+    );
+
+    void glScissor(
+        int x,
+        int y,
+        int width,
+        int height
+    );
+
+    void glShadeModel(
+        int mode
+    );
+
+    void glStencilFunc(
+        int func,
+        int ref,
+        int mask
+    );
+
+    void glStencilMask(
+        int mask
+    );
+
+    void glStencilOp(
+        int fail,
+        int zfail,
+        int zpass
+    );
+
+    void glTexCoordPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    void glTexEnvf(
+        int target,
+        int pname,
+        float param
+    );
+
+    void glTexEnvfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glTexEnvfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glTexEnvx(
+        int target,
+        int pname,
+        int param
+    );
+
+    void glTexEnvxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glTexEnvxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int width,
+        int height,
+        int border,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    );
+
+    void glTexParameterf(
+        int target,
+        int pname,
+        float param
+    );
+
+    void glTexParameterx(
+        int target,
+        int pname,
+        int param
+    );
+
+    void glTexSubImage2D(
+        int target,
+        int level,
+        int xoffset,
+        int yoffset,
+        int width,
+        int height,
+        int format,
+        int type,
+        java.nio.Buffer pixels
+    );
+
+    void glTranslatef(
+        float x,
+        float y,
+        float z
+    );
+
+    void glTranslatex(
+        int x,
+        int y,
+        int z
+    );
+
+    void glVertexPointer(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    void glViewport(
+        int x,
+        int y,
+        int width,
+        int height
+    );
+
+}
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java b/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java
new file mode 100644
index 0000000..562b20a
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/opengles/GL10Ext.java
@@ -0,0 +1,36 @@
+/* //device/java/android/javax/microedition/khronos/opengles/GL10Ext.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+package javax.microedition.khronos.opengles;
+
+public interface GL10Ext extends GL {
+
+    int glQueryMatrixxOES(
+        int[] mantissa,
+        int mantissaOffset,
+        int[] exponent,
+        int exponentOffset
+    );
+
+    int glQueryMatrixxOES(
+        java.nio.IntBuffer mantissa,
+        java.nio.IntBuffer exponent
+    );
+
+}
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11.java b/opengl/java/javax/microedition/khronos/opengles/GL11.java
new file mode 100644
index 0000000..3ba110c
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11.java
@@ -0,0 +1,550 @@
+/* //device/java/android/javax/microedition/khronos/opengles/GL11.java
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+package javax.microedition.khronos.opengles;
+
+public interface GL11 extends GL10 {
+    int GL_ACTIVE_TEXTURE                          = 0x84E0;
+    int GL_ADD_SIGNED                              = 0x8574;
+    int GL_ALPHA_SCALE                             = 0x0D1C;
+    int GL_ALPHA_TEST_FUNC                         = 0x0BC1;
+    int GL_ALPHA_TEST_REF                          = 0x0BC2;
+    int GL_ARRAY_BUFFER                            = 0x8892;
+    int GL_ARRAY_BUFFER_BINDING                    = 0x8894;
+    int GL_BLEND_DST                               = 0x0BE0;
+    int GL_BLEND_SRC                               = 0x0BE1;
+    int GL_BUFFER_ACCESS                           = 0x88BB;
+    int GL_BUFFER_SIZE                             = 0x8764;
+    int GL_BUFFER_USAGE                            = 0x8765;
+    int GL_CLIENT_ACTIVE_TEXTURE                   = 0x84E1;
+    int GL_CLIP_PLANE0                             = 0x3000;
+    int GL_CLIP_PLANE1                             = 0x3001;
+    int GL_CLIP_PLANE2                             = 0x3002;
+    int GL_CLIP_PLANE3                             = 0x3003;
+    int GL_CLIP_PLANE4                             = 0x3004;
+    int GL_CLIP_PLANE5                             = 0x3005;
+    int GL_COLOR_ARRAY_BUFFER_BINDING              = 0x8898;
+    int GL_COLOR_ARRAY_POINTER                     = 0x8090;
+    int GL_COLOR_ARRAY_SIZE                        = 0x8081;
+    int GL_COLOR_ARRAY_STRIDE                      = 0x8083;
+    int GL_COLOR_ARRAY_TYPE                        = 0x8082;
+    int GL_COLOR_CLEAR_VALUE                       = 0x0C22;
+    int GL_COLOR_WRITEMASK                         = 0x0C23;
+    int GL_COMBINE                                 = 0x8570;
+    int GL_COMBINE_ALPHA                           = 0x8572;
+    int GL_COMBINE_RGB                             = 0x8571;
+    int GL_CONSTANT                                = 0x8576;
+    int GL_COORD_REPLACE_OES                       = 0x8862;
+    int GL_CULL_FACE_MODE                          = 0x0B45;
+    int GL_CURRENT_COLOR                           = 0x0B00;
+    int GL_CURRENT_NORMAL                          = 0x0B02;
+    int GL_CURRENT_TEXTURE_COORDS                  = 0x0B03;
+    int GL_DEPTH_CLEAR_VALUE                       = 0x0B73;
+    int GL_DEPTH_FUNC                              = 0x0B74;
+    int GL_DEPTH_RANGE                             = 0x0B70;
+    int GL_DEPTH_WRITEMASK                         = 0x0B72;
+    int GL_DOT3_RGB                                = 0x86AE;
+    int GL_DOT3_RGBA                               = 0x86AF;
+    int GL_DYNAMIC_DRAW                            = 0x88E8;
+    int GL_ELEMENT_ARRAY_BUFFER                    = 0x8893;
+    int GL_ELEMENT_ARRAY_BUFFER_BINDING            = 0x8895;
+    int GL_FRONT_FACE                              = 0x0B46;
+    int GL_GENERATE_MIPMAP                         = 0x8191;
+    int GL_GENERATE_MIPMAP_HINT                    = 0x8192;
+    int GL_INTERPOLATE                             = 0x8575;
+    int GL_LINE_WIDTH                              = 0x0B21;
+    int GL_LOGIC_OP_MODE                           = 0x0BF0;
+    int GL_MATRIX_MODE                             = 0x0BA0;
+    int GL_MAX_CLIP_PLANES                         = 0x0D32;
+    int GL_MODELVIEW_MATRIX                        = 0x0BA6;
+    int GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES  = 0x898D;
+    int GL_MODELVIEW_STACK_DEPTH                   = 0x0BA3;
+    int GL_NORMAL_ARRAY_BUFFER_BINDING             = 0x8897;
+    int GL_NORMAL_ARRAY_POINTER                    = 0x808F;
+    int GL_NORMAL_ARRAY_STRIDE                     = 0x807F;
+    int GL_NORMAL_ARRAY_TYPE                       = 0x807E;
+    int GL_OPERAND0_ALPHA                          = 0x8598;
+    int GL_OPERAND0_RGB                            = 0x8590;
+    int GL_OPERAND1_ALPHA                          = 0x8599;
+    int GL_OPERAND1_RGB                            = 0x8591;
+    int GL_OPERAND2_ALPHA                          = 0x859A;
+    int GL_OPERAND2_RGB                            = 0x8592;
+    int GL_POINT_DISTANCE_ATTENUATION              = 0x8129;
+    int GL_POINT_FADE_THRESHOLD_SIZE               = 0x8128;
+    int GL_POINT_SIZE                              = 0x0B11;
+    int GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES     = 0x8B9F;
+    int GL_POINT_SIZE_ARRAY_OES                    = 0x8B9C;
+    int GL_POINT_SIZE_ARRAY_POINTER_OES            = 0x898C;
+    int GL_POINT_SIZE_ARRAY_STRIDE_OES             = 0x898B;
+    int GL_POINT_SIZE_ARRAY_TYPE_OES               = 0x898A;
+    int GL_POINT_SIZE_MAX                          = 0x8127;
+    int GL_POINT_SIZE_MIN                          = 0x8126;
+    int GL_POINT_SPRITE_OES                        = 0x8861;
+    int GL_POLYGON_OFFSET_FACTOR                   = 0x8038;
+    int GL_POLYGON_OFFSET_UNITS                    = 0x2A00;
+    int GL_PREVIOUS                                = 0x8578;
+    int GL_PRIMARY_COLOR                           = 0x8577;
+    int GL_PROJECTION_MATRIX                       = 0x0BA7;
+    int GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES = 0x898E;
+    int GL_PROJECTION_STACK_DEPTH                  = 0x0BA4;
+    int GL_RGB_SCALE                               = 0x8573;
+    int GL_SAMPLE_BUFFERS                          = 0x80A8;
+    int GL_SAMPLE_COVERAGE_INVERT                  = 0x80AB;
+    int GL_SAMPLE_COVERAGE_VALUE                   = 0x80AA;
+    int GL_SAMPLES                                 = 0x80A9;
+    int GL_SCISSOR_BOX                             = 0x0C10;
+    int GL_SHADE_MODEL                             = 0x0B54;
+    int GL_SRC0_ALPHA                              = 0x8588;
+    int GL_SRC0_RGB                                = 0x8580;
+    int GL_SRC1_ALPHA                              = 0x8589;
+    int GL_SRC1_RGB                                = 0x8581;
+    int GL_SRC2_ALPHA                              = 0x858A;
+    int GL_SRC2_RGB                                = 0x8582;
+    int GL_STATIC_DRAW                             = 0x88E4;
+    int GL_STENCIL_CLEAR_VALUE                     = 0x0B91;
+    int GL_STENCIL_FAIL                            = 0x0B94;
+    int GL_STENCIL_FUNC                            = 0x0B92;
+    int GL_STENCIL_PASS_DEPTH_FAIL                 = 0x0B95;
+    int GL_STENCIL_PASS_DEPTH_PASS                 = 0x0B96;
+    int GL_STENCIL_REF                             = 0x0B97;
+    int GL_STENCIL_VALUE_MASK                      = 0x0B93;
+    int GL_STENCIL_WRITEMASK                       = 0x0B98;
+    int GL_SUBTRACT                                = 0x84E7;
+    int GL_TEXTURE_BINDING_2D                      = 0x8069;
+    int GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING      = 0x889A;
+    int GL_TEXTURE_COORD_ARRAY_POINTER             = 0x8092;
+    int GL_TEXTURE_COORD_ARRAY_SIZE                = 0x8088;
+    int GL_TEXTURE_COORD_ARRAY_STRIDE              = 0x808A;
+    int GL_TEXTURE_COORD_ARRAY_TYPE                = 0x8089;
+    int GL_TEXTURE_MATRIX                          = 0x0BA8;
+    int GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES    = 0x898F;
+    int GL_TEXTURE_STACK_DEPTH                     = 0x0BA5;
+    int GL_VERTEX_ARRAY_BUFFER_BINDING             = 0x8896;
+    int GL_VERTEX_ARRAY_POINTER                    = 0x808E;
+    int GL_VERTEX_ARRAY_SIZE                       = 0x807A;
+    int GL_VERTEX_ARRAY_STRIDE                     = 0x807C;
+    int GL_VERTEX_ARRAY_TYPE                       = 0x807B;
+    int GL_VIEWPORT                                = 0x0BA2;
+    int GL_WRITE_ONLY                              = 0x88B9;
+
+    void glGetPointerv(int pname, java.nio.Buffer[] params);
+    void glBindBuffer(
+        int target,
+        int buffer
+    );
+
+    void glBufferData(
+        int target,
+        int size,
+        java.nio.Buffer data,
+        int usage
+    );
+
+    void glBufferSubData(
+        int target,
+        int offset,
+        int size,
+        java.nio.Buffer data
+    );
+
+    void glClipPlanef(
+        int plane,
+        float[] equation,
+        int offset
+    );
+
+    void glClipPlanef(
+        int plane,
+        java.nio.FloatBuffer equation
+    );
+
+    void glClipPlanex(
+        int plane,
+        int[] equation,
+        int offset
+    );
+
+    void glClipPlanex(
+        int plane,
+        java.nio.IntBuffer equation
+    );
+
+    void glColor4ub(
+        byte red,
+        byte green,
+        byte blue,
+        byte alpha
+    );
+
+    void glColorPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+    void glDeleteBuffers(
+        int n,
+        int[] buffers,
+        int offset
+    );
+
+    void glDeleteBuffers(
+        int n,
+        java.nio.IntBuffer buffers
+    );
+
+    void glDrawElements(
+        int mode,
+        int count,
+        int type,
+        int offset
+    );
+
+    void glGenBuffers(
+        int n,
+        int[] buffers,
+        int offset
+    );
+
+    void glGenBuffers(
+        int n,
+        java.nio.IntBuffer buffers
+    );
+
+    void glGetBooleanv(
+        int pname,
+        boolean[] params,
+        int offset
+    );
+
+    void glGetBooleanv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetBufferParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetBufferParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetClipPlanef(
+        int pname,
+        float[] eqn,
+        int offset
+    );
+
+    void glGetClipPlanef(
+        int pname,
+        java.nio.FloatBuffer eqn
+    );
+
+    void glGetClipPlanex(
+        int pname,
+        int[] eqn,
+        int offset
+    );
+
+    void glGetClipPlanex(
+        int pname,
+        java.nio.IntBuffer eqn
+    );
+
+    void glGetFixedv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetFixedv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetFloatv(
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glGetFloatv(
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glGetLightfv(
+        int light,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glGetLightfv(
+        int light,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glGetLightxv(
+        int light,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetLightxv(
+        int light,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetMaterialfv(
+        int face,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glGetMaterialfv(
+        int face,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glGetMaterialxv(
+        int face,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetMaterialxv(
+        int face,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetTexEnviv(
+        int env,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetTexEnviv(
+        int env,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetTexEnvxv(
+        int env,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetTexEnvxv(
+        int env,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetTexParameterfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glGetTexParameterfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glGetTexParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetTexParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetTexParameterxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetTexParameterxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    boolean glIsBuffer(
+        int buffer
+    );
+
+    boolean glIsEnabled(
+        int cap
+    );
+
+    boolean glIsTexture(
+        int texture
+    );
+
+    void glNormalPointer(
+        int type,
+        int stride,
+        int offset
+    );
+
+    void glPointParameterf(
+        int pname,
+        float param
+    );
+
+    void glPointParameterfv(
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glPointParameterfv(
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glPointParameterx(
+        int pname,
+        int param
+    );
+
+    void glPointParameterxv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glPointParameterxv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glPointSizePointerOES(
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    void glTexCoordPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+    void glTexEnvi(
+        int target,
+        int pname,
+        int param
+    );
+
+    void glTexEnviv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glTexEnviv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glTexParameterfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glTexParameterfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glTexParameteri(
+        int target,
+        int pname,
+        int param
+    );
+
+    void glTexParameteriv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glTexParameteriv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glTexParameterxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glTexParameterxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glVertexPointer(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+}
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java b/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java
new file mode 100644
index 0000000..459a1ab
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11Ext.java
@@ -0,0 +1,153 @@
+/* //device/java/android/javax/microedition/khronos/opengles/GL11Ext.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+package javax.microedition.khronos.opengles;
+
+public interface GL11Ext extends GL {
+    int GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES = 0x8B9E;
+    int GL_MATRIX_INDEX_ARRAY_OES                = 0x8844;
+    int GL_MATRIX_INDEX_ARRAY_POINTER_OES        = 0x8849;
+    int GL_MATRIX_INDEX_ARRAY_SIZE_OES           = 0x8846;
+    int GL_MATRIX_INDEX_ARRAY_STRIDE_OES         = 0x8848;
+    int GL_MATRIX_INDEX_ARRAY_TYPE_OES           = 0x8847;
+    int GL_MATRIX_PALETTE_OES                    = 0x8840;
+    int GL_MAX_PALETTE_MATRICES_OES              = 0x8842;
+    int GL_MAX_VERTEX_UNITS_OES                  = 0x86A4;
+    int GL_TEXTURE_CROP_RECT_OES                 = 0x8B9D;
+    int GL_WEIGHT_ARRAY_BUFFER_BINDING_OES       = 0x889E;
+    int GL_WEIGHT_ARRAY_OES                      = 0x86AD;
+    int GL_WEIGHT_ARRAY_POINTER_OES              = 0x86AC;
+    int GL_WEIGHT_ARRAY_SIZE_OES                 = 0x86AB;
+    int GL_WEIGHT_ARRAY_STRIDE_OES               = 0x86AA;
+    int GL_WEIGHT_ARRAY_TYPE_OES                 = 0x86A9;
+
+    void glTexParameterfv(int target, int pname, float[] param, int offset);
+
+    void glCurrentPaletteMatrixOES(
+        int matrixpaletteindex
+    );
+
+    void glDrawTexfOES(
+        float x,
+        float y,
+        float z,
+        float width,
+        float height
+    );
+
+    void glDrawTexfvOES(
+        float[] coords,
+        int offset
+    );
+
+    void glDrawTexfvOES(
+        java.nio.FloatBuffer coords
+    );
+
+    void glDrawTexiOES(
+        int x,
+        int y,
+        int z,
+        int width,
+        int height
+    );
+
+    void glDrawTexivOES(
+        int[] coords,
+        int offset
+    );
+
+    void glDrawTexivOES(
+        java.nio.IntBuffer coords
+    );
+
+    void glDrawTexsOES(
+        short x,
+        short y,
+        short z,
+        short width,
+        short height
+    );
+
+    void glDrawTexsvOES(
+        short[] coords,
+        int offset
+    );
+
+    void glDrawTexsvOES(
+        java.nio.ShortBuffer coords
+    );
+
+    void glDrawTexxOES(
+        int x,
+        int y,
+        int z,
+        int width,
+        int height
+    );
+
+    void glDrawTexxvOES(
+        int[] coords,
+        int offset
+    );
+
+    void glDrawTexxvOES(
+        java.nio.IntBuffer coords
+    );
+
+    void glEnable(
+        int cap
+    );
+
+    void glEnableClientState(
+        int array
+    );
+
+    void glLoadPaletteFromModelViewMatrixOES(
+    );
+
+    void glMatrixIndexPointerOES(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    void glMatrixIndexPointerOES(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+    void glWeightPointerOES(
+        int size,
+        int type,
+        int stride,
+        java.nio.Buffer pointer
+    );
+
+    void glWeightPointerOES(
+        int size,
+        int type,
+        int stride,
+        int offset
+    );
+
+}
diff --git a/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java b/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java
new file mode 100644
index 0000000..933c91e
--- /dev/null
+++ b/opengl/java/javax/microedition/khronos/opengles/GL11ExtensionPack.java
@@ -0,0 +1,434 @@
+/* //device/java/android/javax/microedition/khronos/opengles/GL11ExtensionPack.java
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+// This source file is automatically generated
+
+package javax.microedition.khronos.opengles;
+
+public interface GL11ExtensionPack extends GL {
+    int GL_BLEND_DST_ALPHA                                  = 0x80CA;
+    int GL_BLEND_DST_RGB                                    = 0x80C8;
+    int GL_BLEND_EQUATION                                   = 0x8009;
+    int GL_BLEND_EQUATION_ALPHA                             = 0x883D;
+    int GL_BLEND_EQUATION_RGB                               = 0x8009;
+    int GL_BLEND_SRC_ALPHA                                  = 0x80CB;
+    int GL_BLEND_SRC_RGB                                    = 0x80C9;
+    int GL_COLOR_ATTACHMENT0_OES                            = 0x8CE0;
+    int GL_COLOR_ATTACHMENT1_OES                            = 0x8CE1;
+    int GL_COLOR_ATTACHMENT2_OES                            = 0x8CE2;
+    int GL_COLOR_ATTACHMENT3_OES                            = 0x8CE3;
+    int GL_COLOR_ATTACHMENT4_OES                            = 0x8CE4;
+    int GL_COLOR_ATTACHMENT5_OES                            = 0x8CE5;
+    int GL_COLOR_ATTACHMENT6_OES                            = 0x8CE6;
+    int GL_COLOR_ATTACHMENT7_OES                            = 0x8CE7;
+    int GL_COLOR_ATTACHMENT8_OES                            = 0x8CE8;
+    int GL_COLOR_ATTACHMENT9_OES                            = 0x8CE9;
+    int GL_COLOR_ATTACHMENT10_OES                           = 0x8CEA;
+    int GL_COLOR_ATTACHMENT11_OES                           = 0x8CEB;
+    int GL_COLOR_ATTACHMENT12_OES                           = 0x8CEC;
+    int GL_COLOR_ATTACHMENT13_OES                           = 0x8CED;
+    int GL_COLOR_ATTACHMENT14_OES                           = 0x8CEE;
+    int GL_COLOR_ATTACHMENT15_OES                           = 0x8CEF;
+    int GL_DECR_WRAP                                        = 0x8508;
+    int GL_DEPTH_ATTACHMENT_OES                             = 0x8D00;
+    int GL_DEPTH_COMPONENT                                  = 0x1902;
+    int GL_DEPTH_COMPONENT16                                = 0x81A5;
+    int GL_DEPTH_COMPONENT24                                = 0x81A6;
+    int GL_DEPTH_COMPONENT32                                = 0x81A7;
+    int GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES           = 0x8CD1;
+    int GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES           = 0x8CD0;
+    int GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES = 0x8CD3;
+    int GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES         = 0x8CD2;
+    int GL_FRAMEBUFFER_BINDING_OES                          = 0x8CA6;
+    int GL_FRAMEBUFFER_COMPLETE_OES                         = 0x8CD5;
+    int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES            = 0x8CD6;
+    int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES            = 0x8CD9;
+    int GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_OES           = 0x8CDB;
+    int GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES               = 0x8CDA;
+    int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES    = 0x8CD7;
+    int GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_OES           = 0x8CDC;
+    int GL_FRAMEBUFFER_OES                                  = 0x8D40;
+    int GL_FRAMEBUFFER_UNSUPPORTED_OES                      = 0x8CDD;
+    int GL_FUNC_ADD                                         = 0x8006;
+    int GL_FUNC_REVERSE_SUBTRACT                            = 0x800B;
+    int GL_FUNC_SUBTRACT                                    = 0x800A;
+    int GL_INCR_WRAP                                        = 0x8507;
+    int GL_INVALID_FRAMEBUFFER_OPERATION_OES                = 0x0506;
+    int GL_MAX_COLOR_ATTACHMENTS_OES                        = 0x8CDF;
+    int GL_MAX_CUBE_MAP_TEXTURE_SIZE                        = 0x851C;
+    int GL_MAX_RENDERBUFFER_SIZE_OES                        = 0x84E8;
+    int GL_MIRRORED_REPEAT                                  = 0x8370;
+    int GL_NORMAL_MAP                                       = 0x8511;
+    int GL_REFLECTION_MAP                                   = 0x8512;
+    int GL_RENDERBUFFER_ALPHA_SIZE_OES                      = 0x8D53;
+    int GL_RENDERBUFFER_BINDING_OES                         = 0x8CA7;
+    int GL_RENDERBUFFER_BLUE_SIZE_OES                       = 0x8D52;
+    int GL_RENDERBUFFER_DEPTH_SIZE_OES                      = 0x8D54;
+    int GL_RENDERBUFFER_GREEN_SIZE_OES                      = 0x8D51;
+    int GL_RENDERBUFFER_HEIGHT_OES                          = 0x8D43;
+    int GL_RENDERBUFFER_INTERNAL_FORMAT_OES                 = 0x8D44;
+    int GL_RENDERBUFFER_OES                                 = 0x8D41;
+    int GL_RENDERBUFFER_RED_SIZE_OES                        = 0x8D50;
+    int GL_RENDERBUFFER_STENCIL_SIZE_OES                    = 0x8D55;
+    int GL_RENDERBUFFER_WIDTH_OES                           = 0x8D42;
+    int GL_RGB5_A1                                          = 0x8057;
+    int GL_RGB565_OES                                       = 0x8D62;
+    int GL_RGB8                                             = 0x8051;
+    int GL_RGBA4                                            = 0x8056;
+    int GL_RGBA8                                            = 0x8058;
+    int GL_STENCIL_ATTACHMENT_OES                           = 0x8D20;
+    int GL_STENCIL_INDEX                                    = 0x1901;
+    int GL_STENCIL_INDEX1_OES                               = 0x8D46;
+    int GL_STENCIL_INDEX4_OES                               = 0x8D47;
+    int GL_STENCIL_INDEX8_OES                               = 0x8D48;
+    int GL_STR                                              = -1;
+    int GL_TEXTURE_BINDING_CUBE_MAP                         = 0x8514;
+    int GL_TEXTURE_CUBE_MAP                                 = 0x8513;
+    int GL_TEXTURE_CUBE_MAP_NEGATIVE_X                      = 0x8516;
+    int GL_TEXTURE_CUBE_MAP_NEGATIVE_Y                      = 0x8518;
+    int GL_TEXTURE_CUBE_MAP_NEGATIVE_Z                      = 0x851A;
+    int GL_TEXTURE_CUBE_MAP_POSITIVE_X                      = 0x8515;
+    int GL_TEXTURE_CUBE_MAP_POSITIVE_Y                      = 0x8517;
+    int GL_TEXTURE_CUBE_MAP_POSITIVE_Z                      = 0x8519;
+    int GL_TEXTURE_GEN_MODE                                 = 0x2500;
+    int GL_TEXTURE_GEN_STR                                  = 0x8D60;
+
+    void glBindFramebufferOES(
+        int target,
+        int framebuffer
+    );
+
+    void glBindRenderbufferOES(
+        int target,
+        int renderbuffer
+    );
+
+    void glBindTexture(
+        int target,
+        int texture
+    );
+
+    void glBlendEquation(
+        int mode
+    );
+
+    void glBlendEquationSeparate(
+        int modeRGB,
+        int modeAlpha
+    );
+
+    void glBlendFuncSeparate(
+        int srcRGB,
+        int dstRGB,
+        int srcAlpha,
+        int dstAlpha
+    );
+
+    int glCheckFramebufferStatusOES(
+        int target
+    );
+
+    void glCompressedTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int width,
+        int height,
+        int border,
+        int imageSize,
+        java.nio.Buffer data
+    );
+
+    void glCopyTexImage2D(
+        int target,
+        int level,
+        int internalformat,
+        int x,
+        int y,
+        int width,
+        int height,
+        int border
+    );
+
+    void glDeleteFramebuffersOES(
+        int n,
+        int[] framebuffers,
+        int offset
+    );
+
+    void glDeleteFramebuffersOES(
+        int n,
+        java.nio.IntBuffer framebuffers
+    );
+
+    void glDeleteRenderbuffersOES(
+        int n,
+        int[] renderbuffers,
+        int offset
+    );
+
+    void glDeleteRenderbuffersOES(
+        int n,
+        java.nio.IntBuffer renderbuffers
+    );
+
+    void glEnable(
+        int cap
+    );
+
+    void glFramebufferRenderbufferOES(
+        int target,
+        int attachment,
+        int renderbuffertarget,
+        int renderbuffer
+    );
+
+    void glFramebufferTexture2DOES(
+        int target,
+        int attachment,
+        int textarget,
+        int texture,
+        int level
+    );
+
+    void glGenerateMipmapOES(
+        int target
+    );
+
+    void glGenFramebuffersOES(
+        int n,
+        int[] framebuffers,
+        int offset
+    );
+
+    void glGenFramebuffersOES(
+        int n,
+        java.nio.IntBuffer framebuffers
+    );
+
+    void glGenRenderbuffersOES(
+        int n,
+        int[] renderbuffers,
+        int offset
+    );
+
+    void glGenRenderbuffersOES(
+        int n,
+        java.nio.IntBuffer renderbuffers
+    );
+
+    void glGetFramebufferAttachmentParameterivOES(
+        int target,
+        int attachment,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetFramebufferAttachmentParameterivOES(
+        int target,
+        int attachment,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetIntegerv(
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetIntegerv(
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetRenderbufferParameterivOES(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetRenderbufferParameterivOES(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetTexGenfv(
+        int coord,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glGetTexGenfv(
+        int coord,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glGetTexGeniv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetTexGeniv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glGetTexGenxv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glGetTexGenxv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    boolean glIsFramebufferOES(
+        int framebuffer
+    );
+
+    boolean glIsRenderbufferOES(
+        int renderbuffer
+    );
+
+    void glRenderbufferStorageOES(
+        int target,
+        int internalformat,
+        int width,
+        int height
+    );
+
+    void glStencilOp(
+        int fail,
+        int zfail,
+        int zpass
+    );
+
+    void glTexEnvf(
+        int target,
+        int pname,
+        float param
+    );
+
+    void glTexEnvfv(
+        int target,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glTexEnvfv(
+        int target,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glTexEnvx(
+        int target,
+        int pname,
+        int param
+    );
+
+    void glTexEnvxv(
+        int target,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glTexEnvxv(
+        int target,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glTexGenf(
+        int coord,
+        int pname,
+        float param
+    );
+
+    void glTexGenfv(
+        int coord,
+        int pname,
+        float[] params,
+        int offset
+    );
+
+    void glTexGenfv(
+        int coord,
+        int pname,
+        java.nio.FloatBuffer params
+    );
+
+    void glTexGeni(
+        int coord,
+        int pname,
+        int param
+    );
+
+    void glTexGeniv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glTexGeniv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glTexGenx(
+        int coord,
+        int pname,
+        int param
+    );
+
+    void glTexGenxv(
+        int coord,
+        int pname,
+        int[] params,
+        int offset
+    );
+
+    void glTexGenxv(
+        int coord,
+        int pname,
+        java.nio.IntBuffer params
+    );
+
+    void glTexParameterf(
+        int target,
+        int pname,
+        float param
+    );
+
+}