diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 50d71d3..b06c1ad 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -1441,6 +1441,27 @@
                 <category android:name="android.intent.category.SAMPLE_CODE" />
             </intent-filter>
         </activity>
+                
+        <activity android:name=".graphics.CubeMapActivity"
+                android:label="Graphics/OpenGL ES/Cube Map"
+                android:theme="@android:style/Theme.NoTitleBar"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        
+                        
+        <activity android:name=".graphics.FrameBufferObjectActivity"
+                android:label="Graphics/OpenGL ES/Frame Buffer Object"
+                android:theme="@android:style/Theme.NoTitleBar"
+                android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
         
         <activity android:name=".graphics.GLSurfaceViewActivity"
                 android:label="Graphics/OpenGL ES/GLSurfaceView"
diff --git a/samples/ApiDemos/res/raw/skycubemap0.jpg b/samples/ApiDemos/res/raw/skycubemap0.jpg
new file mode 100644
index 0000000..db87df9
--- /dev/null
+++ b/samples/ApiDemos/res/raw/skycubemap0.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/raw/skycubemap1.jpg b/samples/ApiDemos/res/raw/skycubemap1.jpg
new file mode 100644
index 0000000..20a06bc
--- /dev/null
+++ b/samples/ApiDemos/res/raw/skycubemap1.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/raw/skycubemap2.jpg b/samples/ApiDemos/res/raw/skycubemap2.jpg
new file mode 100644
index 0000000..2bd886a
--- /dev/null
+++ b/samples/ApiDemos/res/raw/skycubemap2.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/raw/skycubemap3.jpg b/samples/ApiDemos/res/raw/skycubemap3.jpg
new file mode 100644
index 0000000..3700219
--- /dev/null
+++ b/samples/ApiDemos/res/raw/skycubemap3.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/raw/skycubemap4.jpg b/samples/ApiDemos/res/raw/skycubemap4.jpg
new file mode 100644
index 0000000..a8bc543
--- /dev/null
+++ b/samples/ApiDemos/res/raw/skycubemap4.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/raw/skycubemap5.jpg b/samples/ApiDemos/res/raw/skycubemap5.jpg
new file mode 100644
index 0000000..a69ed1b
--- /dev/null
+++ b/samples/ApiDemos/res/raw/skycubemap5.jpg
Binary files differ
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/CubeMapActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/CubeMapActivity.java
new file mode 100644
index 0000000..03b336e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/CubeMapActivity.java
@@ -0,0 +1,414 @@
+/*
+ * 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 com.example.android.apis.graphics;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.FloatBuffer;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11;
+import javax.microedition.khronos.opengles.GL11Ext;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+import android.app.Activity;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.opengl.GLUtils;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.example.android.apis.R;
+
+/**
+ * Demonstrate how to use the OES_texture_cube_map extension, available on some
+ * high-end OpenGL ES 1.x GPUs.
+ */
+public class CubeMapActivity extends Activity {
+    private GLSurfaceView mGLSurfaceView;
+    private class Renderer implements GLSurfaceView.Renderer {
+        private boolean mContextSupportsCubeMap;
+        private Grid mGrid;
+        private int mCubeMapTextureID;
+        private boolean mUseTexGen = false;
+        private float mAngle;
+
+        public void onDrawFrame(GL10 gl) {
+            checkGLError(gl);
+            if (mContextSupportsCubeMap) {
+                gl.glClearColor(0,0,1,0);
+            } else {
+                // Current context doesn't support cube maps.
+                // Indicate this by drawing a red background.
+                gl.glClearColor(1,0,0,0);
+            }
+            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+            gl.glEnable(GL10.GL_DEPTH_TEST);
+            gl.glMatrixMode(GL10.GL_MODELVIEW);
+            gl.glLoadIdentity();
+
+            GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+            gl.glRotatef(mAngle,        0, 1, 0);
+            gl.glRotatef(mAngle*0.25f,  1, 0, 0);
+
+            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+
+            checkGLError(gl);
+
+            if (mContextSupportsCubeMap) {
+                gl.glActiveTexture(GL10.GL_TEXTURE0);
+                checkGLError(gl);
+                gl.glEnable(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP);
+                checkGLError(gl);
+                gl.glBindTexture(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP, mCubeMapTextureID);
+                checkGLError(gl);
+                GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl;
+                gl11ep.glTexGeni(GL11ExtensionPack.GL_TEXTURE_GEN_STR,
+                        GL11ExtensionPack.GL_TEXTURE_GEN_MODE,
+                        GL11ExtensionPack.GL_REFLECTION_MAP);
+                checkGLError(gl);
+                gl.glEnable(GL11ExtensionPack.GL_TEXTURE_GEN_STR);
+                checkGLError(gl);
+                gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_DECAL);
+            }
+
+            checkGLError(gl);
+            mGrid.draw(gl);
+
+            if (mContextSupportsCubeMap) {
+                gl.glDisable(GL11ExtensionPack.GL_TEXTURE_GEN_STR);
+            }
+            checkGLError(gl);
+
+            mAngle += 1.2f;
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            checkGLError(gl);
+            gl.glViewport(0, 0, width, height);
+            float ratio = (float) width / height;
+            gl.glMatrixMode(GL10.GL_PROJECTION);
+            gl.glLoadIdentity();
+            gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+            checkGLError(gl);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            checkGLError(gl);
+            // This test needs to be done each time a context is created,
+            // because different contexts may support different extensions.
+            mContextSupportsCubeMap = checkIfContextSupportsCubeMap(gl);
+
+            mGrid = generateTorusGrid(gl, 60, 60, 3.0f, 0.75f);
+
+            if (mContextSupportsCubeMap) {
+                int[] cubeMapResourceIds = new int[]{
+                        R.raw.skycubemap0, R.raw.skycubemap1, R.raw.skycubemap2,
+                        R.raw.skycubemap3, R.raw.skycubemap4, R.raw.skycubemap5};
+                mCubeMapTextureID = generateCubeMap(gl, cubeMapResourceIds);
+            }
+            checkGLError(gl);
+        }
+
+        private int generateCubeMap(GL10 gl, int[] resourceIds) {
+            checkGLError(gl);
+            int[] ids = new int[1];
+            gl.glGenTextures(1, ids, 0);
+            int cubeMapTextureId = ids[0];
+            gl.glBindTexture(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP, cubeMapTextureId);
+            gl.glTexParameterf(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP,
+                    GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
+            gl.glTexParameterf(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP,
+                    GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
+
+            for (int face = 0; face < 6; face++) {
+                InputStream is = getResources().openRawResource(resourceIds[face]);
+                Bitmap bitmap;
+                try {
+                    bitmap = BitmapFactory.decodeStream(is);
+                } finally {
+                    try {
+                        is.close();
+                    } catch(IOException e) {
+                        Log.e("CubeMap", "Could not decode texture for face " + Integer.toString(face));
+                    }
+                }
+                GLUtils.texImage2D(GL11ExtensionPack.GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0,
+                        bitmap, 0);
+                bitmap.recycle();
+            }
+            checkGLError(gl);
+            return cubeMapTextureId;
+        }
+
+        private Grid generateTorusGrid(GL gl, int uSteps, int vSteps, float majorRadius, float minorRadius) {
+            Grid grid = new Grid(uSteps + 1, vSteps + 1);
+            for (int j = 0; j <= vSteps; j++) {
+                double angleV = Math.PI * 2 * j / vSteps;
+                float cosV = (float) Math.cos(angleV);
+                float sinV = (float) Math.sin(angleV);
+                for (int i = 0; i <= uSteps; i++) {
+                    double angleU = Math.PI * 2 * i / uSteps;
+                    float cosU = (float) Math.cos(angleU);
+                    float sinU = (float) Math.sin(angleU);
+                    float d = majorRadius+minorRadius*cosU;
+                    float x = d*cosV;
+                    float y = d*(-sinV);
+                    float z = minorRadius * sinU;
+
+                    float nx = cosV * cosU;
+                    float ny = -sinV * cosU;
+                    float nz = sinU;
+
+                    float length = (float) Math.sqrt(nx*nx + ny*ny + nz*nz);
+                    nx /= length;
+                    ny /= length;
+                    nz /= length;
+
+                    grid.set(i, j, x, y, z, nx, ny, nz);
+                }
+            }
+            grid.createBufferObjects(gl);
+            return grid;
+        }
+
+        private boolean checkIfContextSupportsCubeMap(GL10 gl) {
+            return checkIfContextSupportsExtension(gl, "GL_OES_texture_cube_map");
+        }
+
+        /**
+         * This is not the fastest way to check for an extension, but fine if
+         * we are only checking for a few extensions each time a context is created.
+         * @param gl
+         * @param extension
+         * @return true if the extension is present in the current context.
+         */
+        private boolean checkIfContextSupportsExtension(GL10 gl, String extension) {
+            String extensions = " " + gl.glGetString(GL10.GL_EXTENSIONS) + " ";
+            // The extensions string is padded with spaces between extensions, but not
+            // necessarily at the beginning or end. For simplicity, add spaces at the
+            // beginning and end of the extensions string to make it easy to find an
+            // extension.
+            return extensions.indexOf(" " + extension + " ") >= 0;
+        }
+    }
+
+    /** A grid is a topologically rectangular array of vertices.
+     *
+     * This grid class is customized for the vertex data required for this
+     * example.
+     *
+     * The vertex and index data are held in VBO objects because on most
+     * GPUs VBO objects are the fastest way of rendering static vertex
+     * and index data.
+     *
+     */
+
+    private static class Grid {
+        // Size of vertex data elements in bytes:
+        final static int FLOAT_SIZE = 4;
+        final static int CHAR_SIZE = 2;
+
+        // Vertex structure:
+        // float x, y, z;
+        // float nx, ny, nx;
+
+        final static int VERTEX_SIZE = 6 * FLOAT_SIZE;
+        final static int VERTEX_NORMAL_BUFFER_INDEX_OFFSET = 3;
+
+        private int mVertexBufferObjectId;
+        private int mElementBufferObjectId;
+
+        // These buffers are used to hold the vertex and index data while
+        // constructing the grid. Once createBufferObjects() is called
+        // the buffers are nulled out to save memory.
+
+        private ByteBuffer mVertexByteBuffer;
+        private FloatBuffer mVertexBuffer;
+        private CharBuffer mIndexBuffer;
+
+        private int mW;
+        private int mH;
+        private int mIndexCount;
+
+        public Grid(int w, int h) {
+            if (w < 0 || w >= 65536) {
+                throw new IllegalArgumentException("w");
+            }
+            if (h < 0 || h >= 65536) {
+                throw new IllegalArgumentException("h");
+            }
+            if (w * h >= 65536) {
+                throw new IllegalArgumentException("w * h >= 65536");
+            }
+
+            mW = w;
+            mH = h;
+            int size = w * h;
+
+            mVertexByteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * size)
+            .order(ByteOrder.nativeOrder());
+            mVertexBuffer = mVertexByteBuffer.asFloatBuffer();
+
+            int quadW = mW - 1;
+            int quadH = mH - 1;
+            int quadCount = quadW * quadH;
+            int indexCount = quadCount * 6;
+            mIndexCount = indexCount;
+            mIndexBuffer = ByteBuffer.allocateDirect(CHAR_SIZE * indexCount)
+            .order(ByteOrder.nativeOrder()).asCharBuffer();
+
+            /*
+             * Initialize triangle list mesh.
+             *
+             *     [0]-----[  1] ...
+             *      |    /   |
+             *      |   /    |
+             *      |  /     |
+             *     [w]-----[w+1] ...
+             *      |       |
+             *
+             */
+
+            {
+                int i = 0;
+                for (int y = 0; y < quadH; y++) {
+                    for (int x = 0; x < quadW; x++) {
+                        char a = (char) (y * mW + x);
+                        char b = (char) (y * mW + x + 1);
+                        char c = (char) ((y + 1) * mW + x);
+                        char d = (char) ((y + 1) * mW + x + 1);
+
+                        mIndexBuffer.put(i++, a);
+                        mIndexBuffer.put(i++, c);
+                        mIndexBuffer.put(i++, b);
+
+                        mIndexBuffer.put(i++, b);
+                        mIndexBuffer.put(i++, c);
+                        mIndexBuffer.put(i++, d);
+                    }
+                }
+            }
+        }
+
+        public void set(int i, int j, float x, float y, float z, float nx, float ny, float nz) {
+            if (i < 0 || i >= mW) {
+                throw new IllegalArgumentException("i");
+            }
+            if (j < 0 || j >= mH) {
+                throw new IllegalArgumentException("j");
+            }
+
+            int index = mW * j + i;
+
+            mVertexBuffer.position(index * VERTEX_SIZE / FLOAT_SIZE);
+            mVertexBuffer.put(x);
+            mVertexBuffer.put(y);
+            mVertexBuffer.put(z);
+            mVertexBuffer.put(nx);
+            mVertexBuffer.put(ny);
+            mVertexBuffer.put(nz);
+        }
+
+        public void createBufferObjects(GL gl) {
+            checkGLError(gl);
+            // Generate a the vertex and element buffer IDs
+            int[] vboIds = new int[2];
+            GL11 gl11 = (GL11) gl;
+            gl11.glGenBuffers(2, vboIds, 0);
+            mVertexBufferObjectId = vboIds[0];
+            mElementBufferObjectId = vboIds[1];
+
+            // Upload the vertex data
+            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId);
+            mVertexByteBuffer.position(0);
+            gl11.glBufferData(GL11.GL_ARRAY_BUFFER, mVertexByteBuffer.capacity(), mVertexByteBuffer, GL11.GL_STATIC_DRAW);
+
+            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId);
+            mIndexBuffer.position(0);
+            gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer.capacity() * CHAR_SIZE, mIndexBuffer, GL11.GL_STATIC_DRAW);
+
+            // We don't need the in-memory data any more
+            mVertexBuffer = null;
+            mVertexByteBuffer = null;
+            mIndexBuffer = null;
+            checkGLError(gl);
+        }
+
+        public void draw(GL10 gl) {
+            checkGLError(gl);
+            GL11 gl11 = (GL11) gl;
+
+            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+
+            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId);
+            gl11.glVertexPointer(3, GL10.GL_FLOAT, VERTEX_SIZE, 0);
+
+            gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
+            gl11.glNormalPointer(GL10.GL_FLOAT, VERTEX_SIZE, VERTEX_NORMAL_BUFFER_INDEX_OFFSET * FLOAT_SIZE);
+
+            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId);
+            gl11.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, 0);
+            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
+            gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
+            gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
+            gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
+            checkGLError(gl);
+        }
+    }
+
+    static void checkGLError(GL gl) {
+        int error = ((GL10) gl).glGetError();
+        if (error != GL10.GL_NO_ERROR) {
+            throw new RuntimeException("GLError 0x" + Integer.toHexString(error));
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create our surface view and set it as the content of our
+        // Activity
+        mGLSurfaceView = new GLSurfaceView(this);
+        mGLSurfaceView.setRenderer(new Renderer());
+        setContentView(mGLSurfaceView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mGLSurfaceView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mGLSurfaceView.onPause();
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/FrameBufferObjectActivity.java b/samples/ApiDemos/src/com/example/android/apis/graphics/FrameBufferObjectActivity.java
new file mode 100644
index 0000000..0c7bf64
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/graphics/FrameBufferObjectActivity.java
@@ -0,0 +1,273 @@
+/*
+ * 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 com.example.android.apis.graphics;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+import javax.microedition.khronos.opengles.GL11ExtensionPack;
+
+import android.app.Activity;
+import android.opengl.GLSurfaceView;
+import android.opengl.GLU;
+import android.os.Bundle;
+import android.os.SystemClock;
+
+/**
+ * Demonstrate the Frame Buffer Object OpenGL ES extension.
+ * <p>
+ * This sample renders a scene into an offscreen frame buffer, and then
+ * uses the resulting image as a texture to render an onscreen scene.
+ */
+public class FrameBufferObjectActivity extends Activity {
+    private GLSurfaceView mGLSurfaceView;
+
+    private class Renderer implements GLSurfaceView.Renderer {
+        private boolean mContextSupportsFrameBufferObject;
+        private int mTargetTexture;
+        private int mFramebuffer;
+        private int mFramebufferWidth = 256;
+        private int mFramebufferHeight = 256;
+        private int mSurfaceWidth;
+        private int mSurfaceHeight;
+
+        private Triangle mTriangle;
+        private Cube mCube;
+        private float mAngle;
+        private boolean mDebugOffscreenRenderer = false;
+
+        public void onDrawFrame(GL10 gl) {
+            checkGLError(gl);
+            if (mContextSupportsFrameBufferObject) {
+                GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl;
+                if (mDebugOffscreenRenderer) {
+                    drawOffscreenImage(gl, mSurfaceWidth, mSurfaceHeight);
+                } else {
+                    gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, mFramebuffer);
+                    drawOffscreenImage(gl, mFramebufferWidth, mFramebufferHeight);
+                    gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
+                    drawOnscreen(gl, mSurfaceWidth, mSurfaceHeight);
+                }
+            } else {
+                // Current context doesn't support frame buffer objects.
+                // Indicate this by drawing a red background.
+                gl.glClearColor(1,0,0,0);
+                gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+            }
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            checkGLError(gl);
+            mSurfaceWidth = width;
+            mSurfaceHeight = height;
+            gl.glViewport(0, 0, width, height);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            mContextSupportsFrameBufferObject = checkIfContextSupportsFrameBufferObject(gl);
+            if (mContextSupportsFrameBufferObject) {
+                mTargetTexture = createTargetTexture(gl, mFramebufferWidth, mFramebufferHeight);
+                mFramebuffer = createFrameBuffer(gl, mFramebufferWidth, mFramebufferHeight, mTargetTexture);
+
+                mCube = new Cube();
+                mTriangle = new Triangle();
+            }
+        }
+
+        private void drawOnscreen(GL10 gl, int width, int height) {
+            gl.glViewport(0, 0, width, height);
+            float ratio = (float) width / height;
+            gl.glMatrixMode(GL10.GL_PROJECTION);
+            gl.glLoadIdentity();
+            gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
+
+            gl.glClearColor(0,0,1,0);
+            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+            gl.glBindTexture(GL10.GL_TEXTURE_2D, mTargetTexture);
+
+            gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
+                    GL10.GL_REPLACE);
+
+            gl.glMatrixMode(GL10.GL_MODELVIEW);
+            gl.glLoadIdentity();
+
+            GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+
+            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+
+            gl.glActiveTexture(GL10.GL_TEXTURE0);
+
+            long time = SystemClock.uptimeMillis() % 4000L;
+            float angle = 0.090f * ((int) time);
+
+            gl.glRotatef(angle, 0, 0, 1.0f);
+
+            mTriangle.draw(gl);
+
+            // Restore default state so the other renderer is not affected.
+
+            gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
+            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
+            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+        }
+
+        private void drawOffscreenImage(GL10 gl, int width, int height) {
+            gl.glViewport(0, 0, width, height);
+            float ratio = (float) width / height;
+            gl.glMatrixMode(GL10.GL_PROJECTION);
+            gl.glLoadIdentity();
+            gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
+
+            gl.glEnable(GL10.GL_CULL_FACE);
+            gl.glEnable(GL10.GL_DEPTH_TEST);
+
+            gl.glClearColor(0,0.5f,1,0);
+            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+            gl.glMatrixMode(GL10.GL_MODELVIEW);
+            gl.glLoadIdentity();
+            gl.glTranslatef(0, 0, -3.0f);
+            gl.glRotatef(mAngle,        0, 1, 0);
+            gl.glRotatef(mAngle*0.25f,  1, 0, 0);
+
+            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+            gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
+
+            mCube.draw(gl);
+
+            gl.glRotatef(mAngle*2.0f, 0, 1, 1);
+            gl.glTranslatef(0.5f, 0.5f, 0.5f);
+
+            mCube.draw(gl);
+
+            mAngle += 1.2f;
+
+            // Restore default state so the other renderer is not affected.
+
+            gl.glDisable(GL10.GL_CULL_FACE);
+            gl.glDisable(GL10.GL_DEPTH_TEST);
+            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
+            gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
+        }
+
+        private int createTargetTexture(GL10 gl, int width, int height) {
+            int texture;
+            int[] textures = new int[1];
+            gl.glGenTextures(1, textures, 0);
+            texture = textures[0];
+            gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
+            gl.glTexImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, width, height, 0,
+                    GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null);
+            gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
+                    GL10.GL_NEAREST);
+            gl.glTexParameterf(GL10.GL_TEXTURE_2D,
+                    GL10.GL_TEXTURE_MAG_FILTER,
+                    GL10.GL_LINEAR);
+            gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
+                    GL10.GL_REPEAT);
+            gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
+                    GL10.GL_REPEAT);
+;            return texture;
+        }
+
+        private int createFrameBuffer(GL10 gl, int width, int height, int targetTextureId) {
+            GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl;
+            int framebuffer;
+            int[] framebuffers = new int[1];
+            gl11ep.glGenFramebuffersOES(1, framebuffers, 0);
+            framebuffer = framebuffers[0];
+            gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, framebuffer);
+
+            int depthbuffer;
+            int[] renderbuffers = new int[1];
+            gl11ep.glGenRenderbuffersOES(1, renderbuffers, 0);
+            depthbuffer = renderbuffers[0];
+
+            gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, depthbuffer);
+            gl11ep.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES,
+                    GL11ExtensionPack.GL_DEPTH_COMPONENT16, width, height);
+            gl11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
+                    GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES,
+                    GL11ExtensionPack.GL_RENDERBUFFER_OES, depthbuffer);
+
+            gl11ep.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES,
+                    GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D,
+                    targetTextureId, 0);
+            int status = gl11ep.glCheckFramebufferStatusOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES);
+            if (status != GL11ExtensionPack.GL_FRAMEBUFFER_COMPLETE_OES) {
+                throw new RuntimeException("Framebuffer is not complete: " +
+                        Integer.toHexString(status));
+            }
+            gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0);
+            return framebuffer;
+        }
+
+        private boolean checkIfContextSupportsFrameBufferObject(GL10 gl) {
+            return checkIfContextSupportsExtension(gl, "GL_OES_framebuffer_object");
+        }
+
+        /**
+         * This is not the fastest way to check for an extension, but fine if
+         * we are only checking for a few extensions each time a context is created.
+         * @param gl
+         * @param extension
+         * @return true if the extension is present in the current context.
+         */
+        private boolean checkIfContextSupportsExtension(GL10 gl, String extension) {
+            String extensions = " " + gl.glGetString(GL10.GL_EXTENSIONS) + " ";
+            // The extensions string is padded with spaces between extensions, but not
+            // necessarily at the beginning or end. For simplicity, add spaces at the
+            // beginning and end of the extensions string to make it easy to find an
+            // extension.
+            return extensions.indexOf(" " + extension + " ") >= 0;
+        }
+    }
+
+    static void checkGLError(GL gl) {
+        int error = ((GL10) gl).glGetError();
+        if (error != GL10.GL_NO_ERROR) {
+            throw new RuntimeException("GLError 0x" + Integer.toHexString(error));
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Create our surface view and set it as the content of our
+        // Activity
+        mGLSurfaceView = new GLSurfaceView(this);
+        mGLSurfaceView.setRenderer(new Renderer());
+        setContentView(mGLSurfaceView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mGLSurfaceView.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mGLSurfaceView.onPause();
+    }
+}
