Create samples showing how to call OpenGL from JNI libraries.
diff --git a/opengl/tests/gl_jni/Android.mk b/opengl/tests/gl_jni/Android.mk
new file mode 100644
index 0000000..4029fa1
--- /dev/null
+++ b/opengl/tests/gl_jni/Android.mk
@@ -0,0 +1,53 @@
+#########################################################################
+# OpenGL ES JNI sample
+# This makefile builds both an activity and a shared library.
+#########################################################################
+ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean
+
+TOP_LOCAL_PATH:= $(call my-dir)
+
+# Build activity
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := user
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_PACKAGE_NAME := GLJNI
+
+LOCAL_JNI_SHARED_LIBRARIES := libgljni
+
+include $(BUILD_PACKAGE)
+
+#########################################################################
+# Build JNI Shared Library
+#########################################################################
+
+LOCAL_PATH:= $(LOCAL_PATH)/jni
+
+include $(CLEAR_VARS)
+
+# Optional tag would mean it doesn't get installed by default
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_CFLAGS := -Werror
+
+LOCAL_SRC_FILES:= \
+  gl_code.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libEGL \
+	libGLESv1_CM
+
+LOCAL_MODULE := libgljni
+
+LOCAL_ARM_MODE := arm
+
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif # TARGET_SIMULATOR
diff --git a/opengl/tests/gl_jni/AndroidManifest.xml b/opengl/tests/gl_jni/AndroidManifest.xml
new file mode 100644
index 0000000..64bd6bf
--- /dev/null
+++ b/opengl/tests/gl_jni/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2009, 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.
+*/
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.gljni">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <application
+            android:label="@string/gljni_activity">
+        <activity android:name="GLJNIActivity"
+                android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            	android:launchMode="singleTask"
+            	android:screenOrientation="landscape"
+            	android:configChanges="orientation|keyboardHidden">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/opengl/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp
new file mode 100644
index 0000000..b85a433
--- /dev/null
+++ b/opengl/tests/gl_jni/jni/gl_code.cpp
@@ -0,0 +1,177 @@
+// OpenGL ES 1.0 code
+
+#include <nativehelper/jni.h>
+#define LOG_TAG "GLJNI gl_code.cpp"
+#include <utils/Log.h>

+#include <GLES/gl.h>
+
+#include <stdio.h>

+#include <stdlib.h>
+#include <math.h>
+

+GLuint texture;

+

+#define FIXED_ONE 0x10000

+
+static void printGLString(const char *name, GLenum s) {
+    const char *v = (const char *) glGetString(s);
+    LOGI("GL %s = %s\n", name, v);
+}
+
+static void gluLookAt(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 / sqrtf(fx*fx + fy*fy + fz*fz);
+    fx *= rlf;
+    fy *= rlf;
+    fz *= rlf;
+
+    // Normalize up
+    float rlup = 1.0f / sqrtf(upX*upX + upY*upY + upZ*upZ);
+    upX *= rlup;
+    upY *= rlup;
+    upZ *= rlup;
+
+    // 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;
+
+    // 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[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;
+
+    glMultMatrixf(m);
+    glTranslatef(-eyeX, -eyeY, -eyeZ);
+}
+
+void init_scene(int width, int height)

+{
+    printGLString("Version", GL_VERSION);
+    printGLString("Vendor", GL_VENDOR);
+    printGLString("Renderer", GL_RENDERER);
+    printGLString("Extensions", GL_EXTENSIONS);

+    glDisable(GL_DITHER);
+    glEnable(GL_CULL_FACE);
+
+
+    float ratio = width / height;
+    glViewport(0, 0, width, height);
+
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glFrustumf(-ratio, ratio, -1, 1, 1, 10);

+
+
+    glMatrixMode(GL_MODELVIEW);

+    glLoadIdentity();
+    gluLookAt(
+            0, 0, 3,  // eye
+            0, 0, 0,  // center
+            0, 1, 0); // up
+

+    glEnable(GL_TEXTURE_2D);

+    glEnableClientState(GL_VERTEX_ARRAY);

+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+}

+

+void create_texture()

+{

+    const unsigned int on = 0xff0000ff;
+    const unsigned int off = 0xffffffff;
+    const unsigned int pixels[] =
+    {
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+            on, off, on, off, on, off, on, off,
+            off, on, off, on, off, on, off, on,
+    };

+    glGenTextures(1, &texture);

+    glBindTexture(GL_TEXTURE_2D, texture);

+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

+}
+
+extern "C" {
+    JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj,  jint width, jint height);
+    JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj);
+};
+

+

+JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_init(JNIEnv * env, jobject obj,  jint width, jint height)

+{

+    init_scene(width, height);

+    create_texture();

+}

+
+JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_step(JNIEnv * env, jobject obj)

+{

+    const GLfloat vertices[] = {

+            -1,  -1,  0,

+             1,  -1,  0,

+             1,   1,  0,

+            -1,   1,  0

+    };

+

+    const GLfixed texCoords[] = {

+            0,            0,

+            FIXED_ONE,    0,

+            FIXED_ONE,    FIXED_ONE,

+            0,            FIXED_ONE

+    };

+

+    const GLushort quadIndices[] = { 0, 1, 2,  0, 2, 3 };
+
+    glVertexPointer(3, GL_FLOAT, 0, vertices);

+    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+
+
+    int nelem = sizeof(quadIndices)/sizeof(quadIndices[0]);
+    static float grey;
+    grey += 0.01f;
+    if (grey > 1.0f) {
+        grey = 0.0f;
+    }
+    glClearColor(grey, grey, grey, 1.0f);
+    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+    glDrawElements(GL_TRIANGLES, nelem, GL_UNSIGNED_SHORT, quadIndices);

+}

+
diff --git a/opengl/tests/gl_jni/res/values/strings.xml b/opengl/tests/gl_jni/res/values/strings.xml
new file mode 100644
index 0000000..880f5c9
--- /dev/null
+++ b/opengl/tests/gl_jni/res/values/strings.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** 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 file contains resource definitions for displayed strings, allowing
+     them to be changed based on the locale and options. -->
+
+<resources>
+    <!-- Simple strings. -->
+    <string name="gljni_activity">GLJNI</string>
+
+</resources>
+
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java
new file mode 100644
index 0000000..df1f957
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIActivity.java
@@ -0,0 +1,46 @@
+/*
+ * 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.android.gljni;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.WindowManager;
+
+import java.io.File;
+
+
+public class GLJNIActivity extends Activity {
+
+    GLJNIView mView;
+
+    @Override protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        mView = new GLJNIView(getApplication());
+	setContentView(mView);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+        mView.onPause();
+    }
+
+    @Override protected void onResume() {
+        super.onResume();
+        mView.onResume();
+    }
+}
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java
new file mode 100644
index 0000000..8662725
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNILib.java
@@ -0,0 +1,33 @@
+/*
+ * 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.android.gljni;
+
+// Wrapper for native library
+
+public class GLJNILib {
+
+     static {
+         System.loadLibrary("gljni");
+     }
+
+    /**
+     * @param width the current view width
+     * @param height the current view height
+     */
+     public static native void init(int width, int height);
+     public static native void step();
+}
diff --git a/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java
new file mode 100644
index 0000000..9ea1059
--- /dev/null
+++ b/opengl/tests/gl_jni/src/com/android/gljni/GLJNIView.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2009 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.android.gljni;
+/*
+ * 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.
+ */
+
+
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+/**
+ * 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.
+ */
+class GLJNIView extends GLSurfaceView {
+    GLJNIView(Context context) {
+        super(context);
+        init();
+    }
+
+    public GLJNIView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    private void init() {
+        setRenderer(new Renderer());
+    }
+
+    private class Renderer implements GLSurfaceView.Renderer {
+        private static final String TAG = "Renderer";
+        public void onDrawFrame(GL10 gl) {
+            GLJNILib.step();
+        }
+
+        public void onSurfaceChanged(GL10 gl, int width, int height) {
+            GLJNILib.init(width, height);
+        }
+
+        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+            // Do nothing.
+        }
+    }
+}
+