From 27ad1ef820ef0fd8bfe47b440330975a3931b9c2 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Thu, 22 Oct 2009 16:59:10 -0700 Subject: [PATCH] Add a new sample named "hello-gl2" that shows how to call OGL ES 2.0 functions from native code through JNI. --- ndk/apps/hello-gl2/Application.mk | 3 + ndk/apps/hello-gl2/project/Android.mk | 10 + .../hello-gl2/project/AndroidManifest.xml | 36 +++ ndk/apps/hello-gl2/project/default.properties | 11 + ndk/apps/hello-gl2/project/jni/Android.mk | 24 ++ ndk/apps/hello-gl2/project/jni/gl_code.cpp | 182 +++++++++++ .../hello-gl2/project/res/values/strings.xml | 29 ++ .../com/android/gl2jni/GL2JNIActivity.java | 46 +++ .../src/com/android/gl2jni/GL2JNILib.java | 33 ++ .../src/com/android/gl2jni/GL2JNIView.java | 296 ++++++++++++++++++ ndk/docs/CHANGES.TXT | 11 + ndk/docs/STABLE-APIS.TXT | 3 + 12 files changed, 684 insertions(+) create mode 100644 ndk/apps/hello-gl2/Application.mk create mode 100644 ndk/apps/hello-gl2/project/Android.mk create mode 100644 ndk/apps/hello-gl2/project/AndroidManifest.xml create mode 100644 ndk/apps/hello-gl2/project/default.properties create mode 100644 ndk/apps/hello-gl2/project/jni/Android.mk create mode 100644 ndk/apps/hello-gl2/project/jni/gl_code.cpp create mode 100644 ndk/apps/hello-gl2/project/res/values/strings.xml create mode 100644 ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIActivity.java create mode 100644 ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNILib.java create mode 100644 ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java diff --git a/ndk/apps/hello-gl2/Application.mk b/ndk/apps/hello-gl2/Application.mk new file mode 100644 index 000000000..6f884bfbb --- /dev/null +++ b/ndk/apps/hello-gl2/Application.mk @@ -0,0 +1,3 @@ +APP_PROJECT_PATH := $(call my-dir)/project +APP_MODULES := libgl2jni + diff --git a/ndk/apps/hello-gl2/project/Android.mk b/ndk/apps/hello-gl2/project/Android.mk new file mode 100644 index 000000000..2e3616504 --- /dev/null +++ b/ndk/apps/hello-gl2/project/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH:= $(LOCAL_PATH)/jni + +include $(CLEAR_VARS) + +LOCAL_MODULE := libgl2jni +LOCAL_CFLAGS := -Werror +LOCAL_SRC_FILES := gl_code.cpp +LOCAL_LDLIBS := -llog -lGLESv2 + +include $(BUILD_SHARED_LIBRARY) diff --git a/ndk/apps/hello-gl2/project/AndroidManifest.xml b/ndk/apps/hello-gl2/project/AndroidManifest.xml new file mode 100644 index 000000000..0ef6fb0db --- /dev/null +++ b/ndk/apps/hello-gl2/project/AndroidManifest.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + diff --git a/ndk/apps/hello-gl2/project/default.properties b/ndk/apps/hello-gl2/project/default.properties new file mode 100644 index 000000000..dbf05f24f --- /dev/null +++ b/ndk/apps/hello-gl2/project/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-5 diff --git a/ndk/apps/hello-gl2/project/jni/Android.mk b/ndk/apps/hello-gl2/project/jni/Android.mk new file mode 100644 index 000000000..a995c8679 --- /dev/null +++ b/ndk/apps/hello-gl2/project/jni/Android.mk @@ -0,0 +1,24 @@ +# 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. +# +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libgl2jni +LOCAL_CFLAGS := -Werror +LOCAL_SRC_FILES := gl_code.cpp +LOCAL_LDLIBS := -llog -lGLESv2 + +include $(BUILD_SHARED_LIBRARY) diff --git a/ndk/apps/hello-gl2/project/jni/gl_code.cpp b/ndk/apps/hello-gl2/project/jni/gl_code.cpp new file mode 100644 index 000000000..e1e30cefd --- /dev/null +++ b/ndk/apps/hello-gl2/project/jni/gl_code.cpp @@ -0,0 +1,182 @@ +/* + * 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. + */ + +// OpenGL ES 2.0 code + +#include +#include + +#include +#include + +#include +#include +#include + +#define LOG_TAG "libgl2jni" +#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) + +static void printGLString(const char *name, GLenum s) { + const char *v = (const char *) glGetString(s); + LOGI("GL %s = %s\n", name, v); +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + LOGI("after %s() glError (0x%x)\n", op, error); + } +} + +static const char gVertexShader[] = "attribute vec4 vPosition;\n" + "void main() {\n" + " gl_Position = vPosition;\n" + "}\n"; + +static const char gFragmentShader[] = "precision mediump float;\n" + "void main() {\n" + " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" + "}\n"; + +GLuint loadShader(GLenum shaderType, const char* pSource) { + GLuint shader = glCreateShader(shaderType); + if (shader) { + glShaderSource(shader, 1, &pSource, NULL); + glCompileShader(shader); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(shader, infoLen, NULL, buf); + LOGE("Could not compile shader %d:\n%s\n", + shaderType, buf); + free(buf); + } + glDeleteShader(shader); + shader = 0; + } + } + } + return shader; +} + +GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); + if (!vertexShader) { + return 0; + } + + GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); + if (!pixelShader) { + return 0; + } + + GLuint program = glCreateProgram(); + if (program) { + glAttachShader(program, vertexShader); + checkGlError("glAttachShader"); + glAttachShader(program, pixelShader); + checkGlError("glAttachShader"); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(program, bufLength, NULL, buf); + LOGE("Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(program); + program = 0; + } + } + return program; +} + +GLuint gProgram; +GLuint gvPositionHandle; + +bool setupGraphics(int w, int h) { + printGLString("Version", GL_VERSION); + printGLString("Vendor", GL_VENDOR); + printGLString("Renderer", GL_RENDERER); + printGLString("Extensions", GL_EXTENSIONS); + + LOGI("setupGraphics(%d, %d)", w, h); + gProgram = createProgram(gVertexShader, gFragmentShader); + if (!gProgram) { + LOGE("Could not create program."); + return false; + } + gvPositionHandle = glGetAttribLocation(gProgram, "vPosition"); + checkGlError("glGetAttribLocation"); + LOGI("glGetAttribLocation(\"vPosition\") = %d\n", + gvPositionHandle); + + glViewport(0, 0, w, h); + checkGlError("glViewport"); + return true; +} + +const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f }; + +void renderFrame() { + static float grey; + grey += 0.01f; + if (grey > 1.0f) { + grey = 0.0f; + } + glClearColor(grey, grey, grey, 1.0f); + checkGlError("glClearColor"); + glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + checkGlError("glClear"); + + glUseProgram(gProgram); + checkGlError("glUseProgram"); + + glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); + checkGlError("glVertexAttribPointer"); + glEnableVertexAttribArray(gvPositionHandle); + checkGlError("glEnableVertexAttribArray"); + glDrawArrays(GL_TRIANGLES, 0, 3); + checkGlError("glDrawArrays"); +} + +extern "C" { + JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height); + JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj); +}; + +JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_init(JNIEnv * env, jobject obj, jint width, jint height) +{ + setupGraphics(width, height); +} + +JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_step(JNIEnv * env, jobject obj) +{ + renderFrame(); +} diff --git a/ndk/apps/hello-gl2/project/res/values/strings.xml b/ndk/apps/hello-gl2/project/res/values/strings.xml new file mode 100644 index 000000000..e3f733188 --- /dev/null +++ b/ndk/apps/hello-gl2/project/res/values/strings.xml @@ -0,0 +1,29 @@ + + + + + + + + GL2JNI + + + diff --git a/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIActivity.java b/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIActivity.java new file mode 100644 index 000000000..c366a2cbc --- /dev/null +++ b/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIActivity.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.gl2jni; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.WindowManager; + +import java.io.File; + + +public class GL2JNIActivity extends Activity { + + GL2JNIView mView; + + @Override protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + mView = new GL2JNIView(getApplication()); + setContentView(mView); + } + + @Override protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNILib.java b/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNILib.java new file mode 100644 index 000000000..040a98480 --- /dev/null +++ b/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNILib.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.gl2jni; + +// Wrapper for native library + +public class GL2JNILib { + + static { + System.loadLibrary("gl2jni"); + } + + /** + * @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/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java b/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java new file mode 100644 index 000000000..72b1dfb9b --- /dev/null +++ b/ndk/apps/hello-gl2/project/src/com/android/gl2jni/GL2JNIView.java @@ -0,0 +1,296 @@ +/* + * 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.gl2jni; +/* + * 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.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +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 GL2JNIView extends GLSurfaceView { + private static String TAG = "GL2JNIView"; + + public GL2JNIView(Context context) { + super(context); + init(false, 0, 0); + } + + public GL2JNIView(Context context, boolean translucent, int depth, int stencil) { + super(context); + init(translucent, depth, stencil); + } + + private void init(boolean translucent, int depth, int stencil) { + setEGLContextFactory(new ContextFactory()); + setEGLConfigChooser( translucent ? + new ConfigChooser(8,8,8,8, depth, stencil) : + new ConfigChooser(5,6,5,0, depth, stencil)); + setRenderer(new Renderer()); + } + + private static class ContextFactory implements GLSurfaceView.EGLContextFactory { + private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { + Log.w(TAG, "creating OpenGL ES 2.0 context"); + checkEglError("Before eglCreateContext", egl); + int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; + EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); + checkEglError("After eglCreateContext", egl); + return context; + } + + public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { + egl.eglDestroyContext(display, context); + } + } + + private static void checkEglError(String prompt, EGL10 egl) { + int error; + while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) { + Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error)); + } + } + + private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { + private static int EGL_OPENGL_ES2_BIT = 4; + private static int[] s_configAttribs2 = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + }; + + public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { + mRedSize = r; + mGreenSize = g; + mBlueSize = b; + mAlphaSize = a; + mDepthSize = depth; + mStencilSize = stencil; + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + + int[] num_config = new int[1]; + egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); + + int numConfigs = num_config[0]; + + if (numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + EGLConfig[] configs = new EGLConfig[numConfigs]; + egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); + // printConfigs(egl, display, configs); + return chooseConfig(egl, display, configs); + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + EGLConfig closestConfig = null; + int closestDistance = 1000; + for(EGLConfig config : configs) { + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); + if (d >= mDepthSize && s>= mStencilSize) { + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + int distance = Math.abs(r - mRedSize) + + Math.abs(g - mGreenSize) + + Math.abs(b - mBlueSize) + + Math.abs(a - mAlphaSize); + if (distance < closestDistance) { + closestDistance = distance; + closestConfig = config; + } + } + } + return closestConfig; + } + + private int findConfigAttrib(EGL10 egl, EGLDisplay display, + EGLConfig config, int attribute, int defaultValue) { + + if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { + return mValue[0]; + } + return defaultValue; + } + + private void printConfigs(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + int numConfigs = configs.length; + Log.w(TAG, String.format("%d configurations", numConfigs)); + for (int i = 0; i < numConfigs; i++) { + Log.w(TAG, String.format("Configuration %d:\n", i)); + printConfig(egl, display, configs[i]); + } + } + + private void printConfig(EGL10 egl, EGLDisplay display, + EGLConfig config) { + int[] attributes = { + EGL10.EGL_BUFFER_SIZE, + EGL10.EGL_ALPHA_SIZE, + EGL10.EGL_BLUE_SIZE, + EGL10.EGL_GREEN_SIZE, + EGL10.EGL_RED_SIZE, + EGL10.EGL_DEPTH_SIZE, + EGL10.EGL_STENCIL_SIZE, + EGL10.EGL_CONFIG_CAVEAT, + EGL10.EGL_CONFIG_ID, + EGL10.EGL_LEVEL, + EGL10.EGL_MAX_PBUFFER_HEIGHT, + EGL10.EGL_MAX_PBUFFER_PIXELS, + EGL10.EGL_MAX_PBUFFER_WIDTH, + EGL10.EGL_NATIVE_RENDERABLE, + EGL10.EGL_NATIVE_VISUAL_ID, + EGL10.EGL_NATIVE_VISUAL_TYPE, + 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, + EGL10.EGL_SAMPLES, + EGL10.EGL_SAMPLE_BUFFERS, + EGL10.EGL_SURFACE_TYPE, + EGL10.EGL_TRANSPARENT_TYPE, + EGL10.EGL_TRANSPARENT_RED_VALUE, + EGL10.EGL_TRANSPARENT_GREEN_VALUE, + EGL10.EGL_TRANSPARENT_BLUE_VALUE, + 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, + 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, + 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, + 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, + EGL10.EGL_LUMINANCE_SIZE, + EGL10.EGL_ALPHA_MASK_SIZE, + EGL10.EGL_COLOR_BUFFER_TYPE, + EGL10.EGL_RENDERABLE_TYPE, + 0x3042 // EGL10.EGL_CONFORMANT + }; + String[] names = { + "EGL_BUFFER_SIZE", + "EGL_ALPHA_SIZE", + "EGL_BLUE_SIZE", + "EGL_GREEN_SIZE", + "EGL_RED_SIZE", + "EGL_DEPTH_SIZE", + "EGL_STENCIL_SIZE", + "EGL_CONFIG_CAVEAT", + "EGL_CONFIG_ID", + "EGL_LEVEL", + "EGL_MAX_PBUFFER_HEIGHT", + "EGL_MAX_PBUFFER_PIXELS", + "EGL_MAX_PBUFFER_WIDTH", + "EGL_NATIVE_RENDERABLE", + "EGL_NATIVE_VISUAL_ID", + "EGL_NATIVE_VISUAL_TYPE", + "EGL_PRESERVED_RESOURCES", + "EGL_SAMPLES", + "EGL_SAMPLE_BUFFERS", + "EGL_SURFACE_TYPE", + "EGL_TRANSPARENT_TYPE", + "EGL_TRANSPARENT_RED_VALUE", + "EGL_TRANSPARENT_GREEN_VALUE", + "EGL_TRANSPARENT_BLUE_VALUE", + "EGL_BIND_TO_TEXTURE_RGB", + "EGL_BIND_TO_TEXTURE_RGBA", + "EGL_MIN_SWAP_INTERVAL", + "EGL_MAX_SWAP_INTERVAL", + "EGL_LUMINANCE_SIZE", + "EGL_ALPHA_MASK_SIZE", + "EGL_COLOR_BUFFER_TYPE", + "EGL_RENDERABLE_TYPE", + "EGL_CONFORMANT" + }; + int[] value = new int[1]; + for (int i = 0; i < attributes.length; i++) { + int attribute = attributes[i]; + String name = names[i]; + if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { + Log.w(TAG, String.format(" %s: %d\n", name, value[0])); + } else { + // Log.w(TAG, String.format(" %s: failed\n", name)); + while (egl.eglGetError() != EGL10.EGL_SUCCESS); + } + } + } + + // Subclasses can adjust these values: + protected int mRedSize; + protected int mGreenSize; + protected int mBlueSize; + protected int mAlphaSize; + protected int mDepthSize; + protected int mStencilSize; + private int[] mValue = new int[1]; + } + + private static class Renderer implements GLSurfaceView.Renderer { + public void onDrawFrame(GL10 gl) { + GL2JNILib.step(); + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + GL2JNILib.init(width, height); + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + // Do nothing. + } + } +} + diff --git a/ndk/docs/CHANGES.TXT b/ndk/docs/CHANGES.TXT index 6c2deb217..c162886b3 100644 --- a/ndk/docs/CHANGES.TXT +++ b/ndk/docs/CHANGES.TXT @@ -12,6 +12,17 @@ IMPORTANT BUG FIXES: - Actually use the awk version detected by host-setup.sh during the build. + +IMPORTANT CHANGES: + +- Added platform eclair-5 to reflect the Eclair branch. This is merely a copy + of android-4 that also includes headers and libraries for OpenGL ES 2.0. + + See the sample named "hello-gl2" for a *very* basic demonstration. Note that + OpenGL ES 2.0 is currently *not* available from Java, and must be used through + native code exclusively. + + OTHER FIXES & CHANGES: - Added --prebuilt-ndk=FILE option to build/tools/make-release.sh script to diff --git a/ndk/docs/STABLE-APIS.TXT b/ndk/docs/STABLE-APIS.TXT index 67bc998e9..7d5d175be 100644 --- a/ndk/docs/STABLE-APIS.TXT +++ b/ndk/docs/STABLE-APIS.TXT @@ -180,3 +180,6 @@ are *not* available. EGL is used to perform surface creation and flipping VM application instead, for example with a GLSurfaceView, as described here: http://android-developers.blogspot.com/2009/04/introducing-glsurfaceview.html + +The "hello-gl2" sample application demonstrate this. It is used to draw a very +simple triangle with the help of a vertex and fragment shaders.