summaryrefslogtreecommitdiffstats
path: root/ndk/sources
diff options
context:
space:
mode:
authorHak Matsuda <hakuro@google.com>2013-09-26 20:58:00 -0700
committerAndrew Hsieh <andrewhsieh@google.com>2013-10-28 11:41:58 +0800
commit5d1c91fb75468fb6daad8aa66de64c5d177f3158 (patch)
tree28e6875a55605a20ceb317c7e94d7fb3a51602a4 /ndk/sources
parent122d194b36e41ca6291efe6c27e02fc73d2a1683 (diff)
downloadandroid_development-5d1c91fb75468fb6daad8aa66de64c5d177f3158.tar.gz
android_development-5d1c91fb75468fb6daad8aa66de64c5d177f3158.tar.bz2
android_development-5d1c91fb75468fb6daad8aa66de64c5d177f3158.zip
cleaned code, added pinch gesture detector, better opengl context handling, fixed issues
Change-Id: I26a28374ae74391204586b4584d03cf0c58772c2
Diffstat (limited to 'ndk/sources')
-rw-r--r--ndk/sources/android/helper/Android.mk16
-rw-r--r--ndk/sources/android/helper/GLContext.cpp302
-rw-r--r--ndk/sources/android/helper/GLContext.h104
-rw-r--r--ndk/sources/android/helper/JNIHelper.cpp270
-rw-r--r--ndk/sources/android/helper/JNIHelper.h80
-rw-r--r--ndk/sources/android/helper/NDKHelper.h34
-rw-r--r--ndk/sources/android/helper/gestureDetector.cpp345
-rw-r--r--ndk/sources/android/helper/gestureDetector.h143
-rw-r--r--ndk/sources/android/helper/gl3stub.c343
-rw-r--r--ndk/sources/android/helper/gl3stub.h500
-rw-r--r--ndk/sources/android/helper/interpolator.cpp169
-rw-r--r--ndk/sources/android/helper/interpolator.h78
-rw-r--r--ndk/sources/android/helper/perfMonitor.cpp65
-rw-r--r--ndk/sources/android/helper/perfMonitor.h56
-rw-r--r--ndk/sources/android/helper/shader.cpp151
-rw-r--r--ndk/sources/android/helper/shader.h63
-rw-r--r--ndk/sources/android/helper/tapCamera.cpp313
-rw-r--r--ndk/sources/android/helper/tapCamera.h108
-rw-r--r--ndk/sources/android/helper/vecmath.cpp265
-rw-r--r--ndk/sources/android/helper/vecmath.h1051
20 files changed, 4456 insertions, 0 deletions
diff --git a/ndk/sources/android/helper/Android.mk b/ndk/sources/android/helper/Android.mk
new file mode 100644
index 000000000..a5c3be4e6
--- /dev/null
+++ b/ndk/sources/android/helper/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= helper
+LOCAL_SRC_FILES:= JNIHelper.cpp interpolator.cpp tapCamera.cpp gestureDetector.cpp perfMonitor.cpp vecmath.cpp GLContext.cpp shader.cpp gl3stub.c
+
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_EXPORT_LDLIBS := -llog -landroid -lEGL -lGLESv2
+
+LOCAL_STATIC_LIBRARIES := cpufeatures android_native_app_glue
+
+include $(BUILD_STATIC_LIBRARY)
+
+#$(call import-module,android/native_app_glue)
+#$(call import-module,android/cpufeatures) \ No newline at end of file
diff --git a/ndk/sources/android/helper/GLContext.cpp b/ndk/sources/android/helper/GLContext.cpp
new file mode 100644
index 000000000..4595456e8
--- /dev/null
+++ b/ndk/sources/android/helper/GLContext.cpp
@@ -0,0 +1,302 @@
+/*
+ * Copyright 2013 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.
+ */
+
+//--------------------------------------------------------------------------------
+// GLContext.cpp
+//--------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------
+// includes
+//--------------------------------------------------------------------------------
+#include <unistd.h>
+#include "GLContext.h"
+#include "gl3stub.h"
+
+//--------------------------------------------------------------------------------
+// eGLContext
+//--------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------
+// Ctor
+//--------------------------------------------------------------------------------
+GLContext::GLContext() : _display(EGL_NO_DISPLAY),
+ _surface(EGL_NO_SURFACE),
+ _context(EGL_NO_CONTEXT),
+ _iWidth( 0 ),
+ _iHeight( 0 ),
+ _bES3Support( false ),
+ _bEGLContextInitialized( false ),
+ _bGLESInitialized( false )
+{
+}
+
+void GLContext::initGLES()
+{
+ if( _bGLESInitialized )
+ return;
+ //
+ //Initialize OpenGL ES 3 if available
+ //
+ const char* versionStr = (const char*)glGetString(GL_VERSION);
+ if (strstr(versionStr, "OpenGL ES 3.")
+ && gl3stubInit())
+ {
+ _bES3Support = true;
+ _fGLVersion = 3.0f;
+ }
+ else
+ {
+ _fGLVersion = 2.0f;
+ }
+
+ _bGLESInitialized = true;
+}
+
+//--------------------------------------------------------------------------------
+// Dtor
+//--------------------------------------------------------------------------------
+GLContext::~GLContext()
+{
+ terminate();
+}
+
+bool GLContext::init( ANativeWindow* window )
+{
+ if( _bEGLContextInitialized )
+ return true;
+
+ //
+ //Initialize EGL
+ //
+ _window = window;
+ initEGLSurface();
+ initEGLContext();
+ initGLES();
+
+ _bEGLContextInitialized = true;
+
+ return true;
+}
+
+bool GLContext::initEGLSurface()
+{
+ _display = eglGetDisplay( EGL_DEFAULT_DISPLAY );
+ eglInitialize( _display, 0, 0 );
+
+ /*
+ * Here specify the attributes of the desired configuration.
+ * Below, we select an EGLConfig with at least 8 bits per color
+ * component compatible with on-screen windows
+ */
+ const EGLint attribs[] = {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //Request opengl ES2.0
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_DEPTH_SIZE, 24,
+ EGL_NONE
+ };
+ _iColorSize = 8;
+ _iDepthSize = 24;
+
+ EGLint numConfigs;
+ eglChooseConfig( _display, attribs, &_config, 1, &numConfigs );
+
+ if( !numConfigs )
+ {
+ //Fall back to 16bit depth buffer
+ const EGLint attribs[] = {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //Request opengl ES2.0
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_DEPTH_SIZE, 16,
+ EGL_NONE
+ };
+ eglChooseConfig( _display, attribs, &_config, 1, &numConfigs );
+ _iDepthSize = 16;
+ }
+
+ if ( !numConfigs )
+ {
+ LOGW("Unable to retrieve EGL config");
+ return false;
+ }
+
+ _surface = eglCreateWindowSurface( _display, _config, _window, NULL );
+ eglQuerySurface(_display, _surface, EGL_WIDTH, &_iWidth);
+ eglQuerySurface(_display, _surface, EGL_HEIGHT, &_iHeight);
+
+ /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
+ * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
+ * As soon as we picked a EGLConfig, we can safely reconfigure the
+ * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
+ EGLint format;
+ eglGetConfigAttrib(_display, _config, EGL_NATIVE_VISUAL_ID, &format);
+ ANativeWindow_setBuffersGeometry( _window, 0, 0, format);
+
+ return true;
+}
+
+bool GLContext::initEGLContext()
+{
+ const EGLint contextAttribs[] = {
+ EGL_CONTEXT_CLIENT_VERSION, 2, //Request opengl ES2.0
+ EGL_NONE
+ };
+ _context = eglCreateContext( _display, _config, NULL, contextAttribs );
+
+ if( eglMakeCurrent(_display, _surface, _surface, _context) == EGL_FALSE )
+ {
+ LOGW("Unable to eglMakeCurrent");
+ return false;
+ }
+
+ _bContextValid = true;
+ return true;
+}
+
+EGLint GLContext::swap()
+{
+ bool b = eglSwapBuffers( _display, _surface);
+ if( !b )
+ {
+ EGLint err = eglGetError();
+ if( err == EGL_BAD_SURFACE )
+ {
+ //Recreate surface
+ initEGLSurface();
+ }
+ else if( err == EGL_CONTEXT_LOST || err == EGL_BAD_CONTEXT )
+ {
+ //Context has been lost!!
+ _bContextValid = false;
+ terminate();
+ initEGLContext();
+ }
+ return err;
+ }
+ return EGL_SUCCESS;
+}
+
+void GLContext::terminate()
+{
+ if( _display != EGL_NO_DISPLAY )
+ {
+ eglMakeCurrent( _display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
+ if ( _context != EGL_NO_CONTEXT )
+ {
+ eglDestroyContext( _display, _context );
+ }
+
+ if( _surface != EGL_NO_SURFACE )
+ {
+ eglDestroySurface( _display, _surface );
+ }
+ eglTerminate( _display );
+ }
+
+ _display = EGL_NO_DISPLAY;
+ _context = EGL_NO_CONTEXT;
+ _surface = EGL_NO_SURFACE;
+ _bContextValid = false;
+
+}
+
+EGLint GLContext::resume(ANativeWindow* window)
+{
+ if( _bEGLContextInitialized == false )
+ {
+ init( window );
+ return EGL_SUCCESS;
+ }
+
+ int32_t iOriginalWidth = _iWidth;
+ int32_t iOriginalHeight = _iHeight;
+
+ //Create surface
+ _window = window;
+ _surface = eglCreateWindowSurface( _display, _config, _window, NULL );
+ eglQuerySurface(_display, _surface, EGL_WIDTH, &_iWidth);
+ eglQuerySurface(_display, _surface, EGL_HEIGHT, &_iHeight);
+
+ if( _iWidth != iOriginalWidth || _iHeight != iOriginalHeight )
+ {
+ //Screen resized
+ LOGI("Screen resized");
+ }
+
+ if( eglMakeCurrent(_display, _surface, _surface, _context) == EGL_TRUE )
+ return EGL_SUCCESS;
+
+ EGLint err = eglGetError();
+ LOGW("Unable to eglMakeCurrent %d", err);
+
+ if( err == EGL_CONTEXT_LOST )
+ {
+ //Recreate context
+ LOGI("Re-creating egl context");
+ initEGLContext();
+ }
+ else
+ {
+ //Recreate surface
+ terminate();
+ initEGLSurface();
+ initEGLContext();
+ }
+
+ return err;
+
+}
+
+void GLContext::suspend()
+{
+ if( _surface != EGL_NO_SURFACE )
+ {
+ eglDestroySurface( _display, _surface );
+ _surface = EGL_NO_SURFACE;
+ }
+}
+
+bool GLContext::invalidate()
+{
+ terminate();
+
+ _bEGLContextInitialized = false;
+ return true;
+}
+
+
+bool GLContext::checkExtension( const char* extension )
+{
+ if( extension == NULL )
+ return false;
+
+ std::string extensions = std::string( (char*)glGetString(GL_EXTENSIONS) );
+ std::string str = std::string( extension );
+ str.append( " " );
+
+ size_t pos = 0;
+ if( extensions.find( extension, pos ) != std::string::npos )
+ {
+ return true;
+ }
+
+ return false;
+}
diff --git a/ndk/sources/android/helper/GLContext.h b/ndk/sources/android/helper/GLContext.h
new file mode 100644
index 000000000..29692f283
--- /dev/null
+++ b/ndk/sources/android/helper/GLContext.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2013 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.
+ */
+
+//--------------------------------------------------------------------------------
+// glContext.h
+//--------------------------------------------------------------------------------
+
+#ifndef GLCONTEXT_H_
+#define GLCONTEXT_H_
+
+#include <android/sensor.h>
+#include <android/log.h>
+#include <android_native_app_glue.h>
+#include <android/native_window_jni.h>
+#include "JNIHelper.h"
+
+//--------------------------------------------------------------------------------
+// Constants
+//--------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------
+// Class
+//--------------------------------------------------------------------------------
+
+/******************************************************************
+ * OpenGL context handler
+ * The class handles OpenGL and EGL context based on Android activity life cycle
+ * The caller needs to call corresponding methods for each activity life cycle events as it's done in sample codes.
+ *
+ * Also the class initializes OpenGL ES3 when the compatible driver is installed in the device.
+ * getGLVersion() returns 3.0~ when the device supports OpenGLES3.0
+ */
+class GLContext
+{
+private:
+ //ELG configurations
+ ANativeWindow* _window;
+ EGLDisplay _display;
+ EGLSurface _surface;
+ EGLContext _context;
+ EGLConfig _config;
+
+ //Screen parameters
+ int32_t _iWidth;
+ int32_t _iHeight;
+ int32_t _iColorSize;
+ int32_t _iDepthSize;
+
+ //Flags
+ bool _bGLESInitialized;
+ bool _bEGLContextInitialized;
+ bool _bES3Support;
+ float _fGLVersion;
+
+ void initGLES();
+ bool _bContextValid;
+ void terminate();
+ bool initEGLSurface();
+ bool initEGLContext();
+public:
+ static GLContext* getInstance()
+ {
+ //Singleton
+ static GLContext instance;
+
+ return &instance;
+ }
+
+ GLContext( GLContext const& );
+ void operator=( GLContext const& );
+
+ GLContext();
+ virtual ~GLContext();
+
+ bool init( ANativeWindow* window );
+ EGLint swap();
+ bool invalidate();
+
+ void suspend();
+ EGLint resume(ANativeWindow* window);
+
+ int32_t getScreenWidth() { return _iWidth; }
+ int32_t getScreenHeight() { return _iHeight; }
+
+ int32_t getBufferColorSize() { return _iColorSize; }
+ int32_t getBufferDepthSize() { return _iDepthSize; }
+ float getGLVersion() { return _fGLVersion; }
+ bool checkExtension( const char* extension );
+};
+
+#endif /* GLCONTEXT_H_ */
diff --git a/ndk/sources/android/helper/JNIHelper.cpp b/ndk/sources/android/helper/JNIHelper.cpp
new file mode 100644
index 000000000..a17f5aa59
--- /dev/null
+++ b/ndk/sources/android/helper/JNIHelper.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#include "JNIHelper.h"
+
+#define CLASS_NAME "android/app/NativeActivity"
+#define APPLICATION_CLASS_NAME "com/sample/helper/NDKHelper"
+
+//---------------------------------------------------------------------------
+//JNI Helper functions
+//---------------------------------------------------------------------------
+//Static variable
+ANativeActivity* JNIHelper::_activity;
+jobject JNIHelper::_objJNIHelper;
+jclass JNIHelper::_clsJNIHelper;
+std::string JNIHelper::_appName;
+
+jclass retrieveClass(JNIEnv *jni, ANativeActivity* activity,
+ const char* className) {
+ jclass activityClass = jni->FindClass(CLASS_NAME);
+ jmethodID getClassLoader = jni->GetMethodID(activityClass, "getClassLoader",
+ "()Ljava/lang/ClassLoader;");
+ jobject cls = jni->CallObjectMethod(activity->clazz, getClassLoader);
+ jclass classLoader = jni->FindClass("java/lang/ClassLoader");
+ jmethodID findClass = jni->GetMethodID(classLoader, "loadClass",
+ "(Ljava/lang/String;)Ljava/lang/Class;");
+
+ jstring strClassName = jni->NewStringUTF(className);
+ jclass classRetrieved = (jclass) jni->CallObjectMethod(cls, findClass,
+ strClassName);
+ jni->DeleteLocalRef(strClassName);
+ return classRetrieved;
+}
+
+//---------------------------------------------------------------------------
+//Init
+//---------------------------------------------------------------------------
+void JNIHelper::init( ANativeActivity* activity )
+{
+ _activity = activity;
+
+ JNIEnv *env;
+ _activity->vm->AttachCurrentThread(&env, NULL);
+
+ //Retrieve app name
+ jclass android_content_Context = env->GetObjectClass(_activity->clazz);
+ jmethodID midGetPackageName = env->GetMethodID(android_content_Context, "getPackageName", "()Ljava/lang/String;");
+
+ jstring packageName= (jstring)env->CallObjectMethod(_activity->clazz, midGetPackageName);
+ const char* appname = env->GetStringUTFChars(packageName, NULL);
+ _appName = std::string(appname);
+
+ _activity->vm->DetachCurrentThread();
+
+};
+
+//---------------------------------------------------------------------------
+//readFile
+//---------------------------------------------------------------------------
+bool JNIHelper::readFile(const char* fileName, std::vector<uint8_t>& buffer)
+{
+ if (_activity == NULL) {
+ return false;
+ }
+
+ //First, try reading from externalFileDir;
+ JNIEnv *env;
+ jmethodID mid;
+
+ _activity->vm->AttachCurrentThread(&env, NULL);
+
+ jstring strPath = getExternalFilesDir(env);
+ const char* path = env->GetStringUTFChars(strPath, NULL);
+ std::string s(path);
+
+ if (fileName[0] != '/') {
+ s.append("/");
+ }
+ s.append(fileName);
+ std::ifstream f(s.c_str(), std::ios::binary);
+
+ env->ReleaseStringUTFChars(strPath, path);
+ _activity->vm->DetachCurrentThread();
+
+ if (f) {
+ LOGI("reading:%s", s.c_str());
+ f.seekg(0, std::ifstream::end);
+ int32_t fileSize = f.tellg();
+ f.seekg(0, std::ifstream::beg);
+ buffer.reserve(fileSize);
+ buffer.assign(std::istreambuf_iterator<char>(f),
+ std::istreambuf_iterator<char>());
+ return true;
+ } else {
+ //Fallback to assetManager
+ AAssetManager* assetManager = _activity->assetManager;
+ AAsset* assetFile = AAssetManager_open(assetManager, fileName,
+ AASSET_MODE_BUFFER);
+ if (!assetFile) {
+ return false;
+ }
+ uint8_t* data = (uint8_t*) AAsset_getBuffer(assetFile);
+ int32_t iSize = AAsset_getLength(assetFile);
+ if (data == NULL) {
+ AAsset_close(assetFile);
+
+ LOGI("Failed to load:%s", fileName);
+ return false;
+ }
+
+ buffer.assign(data, data + iSize);
+
+ AAsset_close(assetFile);
+ return true;
+ }
+}
+
+jstring JNIHelper::getExternalFilesDir(JNIEnv *env)
+{
+ if (_activity == NULL) {
+ return NULL;
+ }
+ // getExternalFilesDir() - java
+ jclass cls_Env = env->FindClass(CLASS_NAME);
+ jmethodID mid = env->GetMethodID(cls_Env, "getExternalFilesDir",
+ "(Ljava/lang/String;)Ljava/io/File;");
+ jobject obj_File = env->CallObjectMethod(_activity->clazz, mid, NULL);
+ jclass cls_File = env->FindClass("java/io/File");
+ jmethodID mid_getPath = env->GetMethodID(cls_File, "getPath",
+ "()Ljava/lang/String;");
+ jstring obj_Path = (jstring) env->CallObjectMethod(obj_File, mid_getPath);
+ return obj_Path;
+}
+
+uint32_t JNIHelper::loadTexture(const char* fileName)
+{
+ if (_activity == NULL) {
+ return 0;
+ }
+
+ JNIEnv *env;
+ jmethodID mid;
+
+ _activity->vm->AttachCurrentThread(&env, NULL);
+
+ if (_clsJNIHelper == 0) {
+ jclass cls = retrieveClass(env, _activity, APPLICATION_CLASS_NAME);
+ _clsJNIHelper = (jclass) env->NewGlobalRef(cls);
+
+ jmethodID constructor = env->GetMethodID(_clsJNIHelper, "<init>",
+ "()V");
+ _objJNIHelper = env->NewObject(_clsJNIHelper, constructor);
+ _objJNIHelper = env->NewGlobalRef(_objJNIHelper);
+ }
+
+ jstring name = env->NewStringUTF(fileName);
+#if 0
+ /* Ask the PNG manager for a bitmap */
+ mid = env->GetMethodID(_clsJNIHelper, "openBitmap",
+ "(Ljava/lang/String;Z)Landroid/graphics/Bitmap;");
+
+ jobject png = env->CallObjectMethod(_objJNIHelper, mid, name, true);
+ env->DeleteLocalRef(name);
+ env->NewGlobalRef(png);
+
+ /* Get image dimensions */
+ mid = env->GetMethodID(_clsJNIHelper, "getBitmapWidth", "(Landroid/graphics/Bitmap;)I");
+ int width = env->CallIntMethod(_objJNIHelper, mid, png);
+ mid = env->GetMethodID(_clsJNIHelper, "getBitmapHeight", "(Landroid/graphics/Bitmap;)I");
+ int height = env->CallIntMethod(_objJNIHelper, mid, png);
+
+ /* Get pixels */
+ jintArray array = env->NewIntArray(width * height);
+ env->NewGlobalRef(array);
+ mid = env->GetMethodID(_clsJNIHelper, "getBitmapPixels", "(Landroid/graphics/Bitmap;[I)V");
+ env->CallVoidMethod(_objJNIHelper, mid, png, array);
+
+ jint *pixels = env->GetIntArrayElements(array, 0);
+
+ LOGI( "Loaded bitmap %s, width %d height %d",fileName, width, height);
+
+ GLuint tex;
+ glGenTextures( 1, &tex );
+ glBindTexture( GL_TEXTURE_2D, tex );
+
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_NEAREST );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+
+ //Generate mipmap
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+ env->ReleaseIntArrayElements(array, pixels, 0);
+ env->DeleteGlobalRef(array);
+
+ /* Free image */
+ mid = env->GetMethodID(_clsJNIHelper, "closeBitmap", "(Landroid/graphics/Bitmap;)V");
+ env->CallVoidMethod(_objJNIHelper, mid, png);
+ env->DeleteGlobalRef(png);
+#else
+ GLuint tex;
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_LINEAR_MIPMAP_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ mid = env->GetMethodID(_clsJNIHelper, "loadTexture",
+ "(Ljava/lang/String;)V");
+ env->CallVoidMethod(_objJNIHelper, mid, name);
+
+ //Generate mipmap
+ glGenerateMipmap(GL_TEXTURE_2D);
+
+#endif
+
+ _activity->vm->DetachCurrentThread();
+
+ return tex;
+
+}
+
+std::string JNIHelper::convertString( const char* str, const char* encode )
+{
+ if (_activity == NULL)
+ {
+ return std::string("");
+ }
+
+ JNIEnv *env;
+
+ _activity->vm->AttachCurrentThread(&env, NULL);
+
+ int32_t iLength = strlen( (const char*)str );
+
+ jbyteArray array = env->NewByteArray( iLength );
+ env->SetByteArrayRegion( array, 0, iLength, (const signed char*)str );
+
+ jstring strEncode = env->NewStringUTF( encode );
+
+ jclass cls = env->FindClass("java/lang/String");
+ jmethodID ctor = env->GetMethodID(cls, "<init>",
+ "([BLjava/lang/String;)V");
+ jstring object = (jstring)env->NewObject( cls, ctor, array, strEncode );
+
+ const char *cparam = env->GetStringUTFChars( object, NULL );
+
+ std::string s = std::string(cparam);
+
+ env->ReleaseStringUTFChars( object, cparam );
+ _activity->vm->DetachCurrentThread();
+
+ return s;
+}
diff --git a/ndk/sources/android/helper/JNIHelper.h b/ndk/sources/android/helper/JNIHelper.h
new file mode 100644
index 000000000..253ce6aff
--- /dev/null
+++ b/ndk/sources/android/helper/JNIHelper.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#pragma once
+
+#include <jni.h>
+#include <errno.h>
+#include <vector>
+#include <map>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#include <EGL/egl.h>
+#include <GLES2/gl2.h>
+
+#include <android/sensor.h>
+#include <android/log.h>
+#include <android_native_app_glue.h>
+
+#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, JNIHelper::getAppName(), __VA_ARGS__))
+#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, JNIHelper::getAppName(), __VA_ARGS__))
+#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, JNIHelper::getAppName(), __VA_ARGS__))
+
+jclass retrieveClass(JNIEnv *jni, ANativeActivity* activity, const char* className);
+
+/******************************************************************
+ * Helpers to invoke Java methods
+ * To use this class, add NDKHelper.java as a corresponding helpers in Java side
+ */
+class JNIHelper
+{
+private:
+ static ANativeActivity* _activity;
+ static jobject _objJNIHelper;
+ static jclass _clsJNIHelper;
+
+ static jstring getExternalFilesDir( JNIEnv *env );
+
+ static std::string _appName;
+public:
+ JNIHelper()
+ {
+ };
+ ~JNIHelper() {
+ JNIEnv *env;
+ _activity->vm->AttachCurrentThread(&env, NULL);
+
+ env->DeleteGlobalRef(_objJNIHelper);
+ env->DeleteGlobalRef(_clsJNIHelper);
+
+ _activity->vm->DetachCurrentThread();
+
+ };
+ static void init( ANativeActivity* activity );
+ static bool readFile( const char* fileName, std::vector<uint8_t>& buffer );
+ static uint32_t loadTexture(const char* fileName );
+ static std::string convertString( const char* str, const char* encode );
+
+ static const char* getAppName() {
+ return _appName.c_str();
+ };
+
+
+
+
+};
diff --git a/ndk/sources/android/helper/NDKHelper.h b/ndk/sources/android/helper/NDKHelper.h
new file mode 100644
index 000000000..da7dc615e
--- /dev/null
+++ b/ndk/sources/android/helper/NDKHelper.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef _NDKSUPPORT_H
+#define _NDKSUPPORT_H
+
+/******************************************************************
+ * NDK support helpers
+ *
+ */
+#include "gl3stub.h" //GLES3 stubs
+#include "GLContext.h" //EGL & OpenGL manager
+#include "shader.h" //Shader compiler support
+#include "vecmath.h" //Vector math support, C++ implementation n current version
+#include "tapCamera.h" //Tap/Pinch camera control
+#include "JNIHelper.h" //JNI support
+#include "gestureDetector.h" //Tap/Doubletap/Pinch detector
+#include "perfMonitor.h" //FPS counter
+#include "interpolator.h" //Interpolator
+
+#endif
diff --git a/ndk/sources/android/helper/gestureDetector.cpp b/ndk/sources/android/helper/gestureDetector.cpp
new file mode 100644
index 000000000..59255b043
--- /dev/null
+++ b/ndk/sources/android/helper/gestureDetector.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2013 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.
+ */
+
+//--------------------------------------------------------------------------------
+// gestureDetector.cpp
+//--------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------
+// includes
+//--------------------------------------------------------------------------------
+#include "gestureDetector.h"
+
+//--------------------------------------------------------------------------------
+// GestureDetector
+//--------------------------------------------------------------------------------
+GestureDetector::GestureDetector()
+{
+ _fDpFactor = 1.f;
+}
+
+void GestureDetector::setConfiguration(AConfiguration* config)
+{
+ _fDpFactor = 160.f / AConfiguration_getDensity(config);
+}
+
+//--------------------------------------------------------------------------------
+// TapDetector
+//--------------------------------------------------------------------------------
+GESTURE_STATE TapDetector::detect(const AInputEvent* motion_event)
+{
+ if( AMotionEvent_getPointerCount(motion_event) > 1 )
+ {
+ //Only support single touch
+ return false;
+ }
+
+ int32_t iAction = AMotionEvent_getAction(motion_event);
+ unsigned int flags = iAction & AMOTION_EVENT_ACTION_MASK;
+ switch( flags )
+ {
+ case AMOTION_EVENT_ACTION_DOWN:
+ _iDownPointerID = AMotionEvent_getPointerId(motion_event, 0);
+ _fDownX = AMotionEvent_getX(motion_event, 0);
+ _fDownY = AMotionEvent_getY(motion_event, 0);
+ break;
+ case AMOTION_EVENT_ACTION_UP:
+ {
+ int64_t eventTime = AMotionEvent_getEventTime(motion_event);
+ int64_t downTime = AMotionEvent_getDownTime(motion_event);
+ if( eventTime - downTime <= TAP_TIMEOUT )
+ {
+ if( _iDownPointerID == AMotionEvent_getPointerId(motion_event, 0) )
+ {
+ float fX = AMotionEvent_getX(motion_event, 0) - _fDownX;
+ float fY = AMotionEvent_getY(motion_event, 0) - _fDownY;
+ if( fX * fX + fY * fY < TOUCH_SLOP * TOUCH_SLOP * _fDpFactor )
+ {
+ LOGI("TapDetector: Tap detected");
+ return GESTURE_STATE_ACTION;
+ }
+ }
+ }
+ break;
+ }
+ }
+ return GESTURE_STATE_NONE;
+}
+
+//--------------------------------------------------------------------------------
+// DoubletapDetector
+//--------------------------------------------------------------------------------
+GESTURE_STATE DoubletapDetector::detect(const AInputEvent* motion_event)
+{
+ if( AMotionEvent_getPointerCount(motion_event) > 1 )
+ {
+ //Only support single double tap
+ return false;
+ }
+
+ bool bDetectedTap = _tapDetector.detect(motion_event);
+
+ int32_t iAction = AMotionEvent_getAction(motion_event);
+ unsigned int flags = iAction & AMOTION_EVENT_ACTION_MASK;
+ switch( flags )
+ {
+ case AMOTION_EVENT_ACTION_DOWN:
+ {
+ int64_t eventTime = AMotionEvent_getEventTime(motion_event);
+ if( eventTime - _lastTapTime <= DOUBLE_TAP_TIMEOUT )
+ {
+ float fX = AMotionEvent_getX(motion_event, 0) - _fLastTapX;
+ float fY = AMotionEvent_getY(motion_event, 0) - _fLastTapY;
+ if( fX * fX + fY * fY < DOUBLE_TAP_SLOP * DOUBLE_TAP_SLOP * _fDpFactor )
+ {
+ LOGI("DoubletapDetector: Doubletap detected");
+ return GESTURE_STATE_ACTION;
+ }
+ }
+ break;
+ }
+ case AMOTION_EVENT_ACTION_UP:
+ if( bDetectedTap )
+ {
+ _lastTapTime = AMotionEvent_getEventTime(motion_event);
+ _fLastTapX = AMotionEvent_getX(motion_event, 0);
+ _fLastTapY = AMotionEvent_getY(motion_event, 0);
+ }
+ break;
+ }
+ return GESTURE_STATE_NONE;
+}
+
+void DoubletapDetector::setConfiguration(AConfiguration* config)
+{
+ _fDpFactor = 160.f / AConfiguration_getDensity(config);
+ _tapDetector.setConfiguration(config);
+}
+
+//--------------------------------------------------------------------------------
+// PinchDetector
+//--------------------------------------------------------------------------------
+
+int32_t PinchDetector::findIndex( const AInputEvent* event, int32_t iID )
+{
+ int32_t iCount = AMotionEvent_getPointerCount(event);
+ for( uint32_t i = 0; i < iCount; ++i )
+ {
+ if( iID == AMotionEvent_getPointerId(event, i) )
+ return i;
+ }
+ return -1;
+}
+
+
+GESTURE_STATE PinchDetector::detect(const AInputEvent* event)
+{
+ GESTURE_STATE ret = GESTURE_STATE_NONE;
+ int32_t iAction = AMotionEvent_getAction(event);
+ uint32_t flags = iAction & AMOTION_EVENT_ACTION_MASK;
+ _event = event;
+
+ int32_t iCount = AMotionEvent_getPointerCount(event);
+ switch( flags )
+ {
+ case AMOTION_EVENT_ACTION_DOWN:
+ _vecPointers.push_back( AMotionEvent_getPointerId( event, 0 ) );
+ break;
+ case AMOTION_EVENT_ACTION_POINTER_DOWN:
+ {
+ int32_t iIndex = (iAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ _vecPointers.push_back(AMotionEvent_getPointerId(event, iIndex));
+ if( iCount == 2 )
+ {
+ //Start new pinch
+ ret = GESTURE_STATE_START;
+ }
+ }
+ break;
+ case AMOTION_EVENT_ACTION_UP:
+ _vecPointers.pop_back();
+ break;
+ case AMOTION_EVENT_ACTION_POINTER_UP:
+ {
+ int32_t iIndex = (iAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ int32_t iReleasedPointerID = AMotionEvent_getPointerId(event, iIndex);
+
+ std::vector<int32_t>::iterator it = _vecPointers.begin();
+ std::vector<int32_t>::iterator itEnd = _vecPointers.end();
+ int32_t i = 0;
+ for(;it!=itEnd;++it, ++i)
+ {
+ if( *it == iReleasedPointerID )
+ {
+ _vecPointers.erase(it);
+ break;
+ }
+ }
+
+ if( i <= 1 )
+ {
+ //Reset pinch or drag
+ if( iCount != 2 )
+ {
+ //Start new pinch
+ ret = GESTURE_STATE_START | GESTURE_STATE_END;
+ }
+ }
+ }
+ break;
+ case AMOTION_EVENT_ACTION_MOVE:
+ switch(iCount)
+ {
+ case 1:
+ break;
+ default:
+ //Multi touch
+ ret = GESTURE_STATE_MOVE;
+ break;
+ }
+ break;
+ case AMOTION_EVENT_ACTION_CANCEL:
+ break;
+ }
+
+
+ return ret;
+}
+
+bool PinchDetector::getPointers( vec2& v1, vec2& v2 )
+{
+ if( _vecPointers.size() < 2 )
+ return false;
+
+ int32_t iIndex = findIndex( _event, _vecPointers[0] );
+ if( iIndex == -1 )
+ return false;
+
+ float fX = AMotionEvent_getX( _event, iIndex);
+ float fY = AMotionEvent_getY( _event, iIndex);
+
+ iIndex = findIndex( _event, _vecPointers[1] );
+ if( iIndex == -1 )
+ return false;
+
+ float fX2 = AMotionEvent_getX( _event, iIndex);
+ float fY2 = AMotionEvent_getY( _event, iIndex);
+
+ v1 = vec2( fX, fY );
+ v2 = vec2( fX2, fY2 );
+
+ return true;
+}
+
+//--------------------------------------------------------------------------------
+// DragDetector
+//--------------------------------------------------------------------------------
+
+int32_t DragDetector::findIndex( const AInputEvent* event, int32_t iID )
+{
+ int32_t iCount = AMotionEvent_getPointerCount(event);
+ for( uint32_t i = 0; i < iCount; ++i )
+ {
+ if( iID == AMotionEvent_getPointerId(event, i) )
+ return i;
+ }
+ return -1;
+}
+
+
+GESTURE_STATE DragDetector::detect(const AInputEvent* event)
+{
+ GESTURE_STATE ret = GESTURE_STATE_NONE;
+ int32_t iAction = AMotionEvent_getAction(event);
+ int32_t iIndex = (iAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+ uint32_t flags = iAction & AMOTION_EVENT_ACTION_MASK;
+ _event = event;
+
+ int32_t iCount = AMotionEvent_getPointerCount(event);
+ switch( flags )
+ {
+ case AMOTION_EVENT_ACTION_DOWN:
+ _vecPointers.push_back( AMotionEvent_getPointerId( event, 0 ) );
+ ret = GESTURE_STATE_START;
+ break;
+ case AMOTION_EVENT_ACTION_POINTER_DOWN:
+ _vecPointers.push_back(AMotionEvent_getPointerId(event, iIndex));
+ break;
+ case AMOTION_EVENT_ACTION_UP:
+ _vecPointers.pop_back();
+ ret = GESTURE_STATE_END;
+ break;
+ case AMOTION_EVENT_ACTION_POINTER_UP:
+ {
+ int32_t iReleasedPointerID = AMotionEvent_getPointerId(event, iIndex);
+
+ std::vector<int32_t>::iterator it = _vecPointers.begin();
+ std::vector<int32_t>::iterator itEnd = _vecPointers.end();
+ int32_t i = 0;
+ for(;it!=itEnd;++it, ++i)
+ {
+ if( *it == iReleasedPointerID )
+ {
+ _vecPointers.erase(it);
+ break;
+ }
+ }
+
+ if( i <= 1 )
+ {
+ //Reset pinch or drag
+ if( iCount == 2 )
+ {
+ ret = GESTURE_STATE_START;
+ }
+ }
+ break;
+ }
+ case AMOTION_EVENT_ACTION_MOVE:
+ switch(iCount)
+ {
+ case 1:
+ //Drag
+ ret = GESTURE_STATE_MOVE;
+ break;
+ default:
+ break;
+ }
+ break;
+ case AMOTION_EVENT_ACTION_CANCEL:
+ break;
+ }
+
+ return ret;
+}
+
+bool DragDetector::getPointer( vec2& v )
+{
+ if( _vecPointers.size() < 1 )
+ return false;
+
+ int32_t iIndex = findIndex( _event, _vecPointers[0] );
+ if( iIndex == -1 )
+ return false;
+
+ float fX = AMotionEvent_getX( _event, iIndex);
+ float fY = AMotionEvent_getY( _event, iIndex);
+
+ v = vec2( fX, fY );
+
+ return true;
+}
+
diff --git a/ndk/sources/android/helper/gestureDetector.h b/ndk/sources/android/helper/gestureDetector.h
new file mode 100644
index 000000000..f3c8942ce
--- /dev/null
+++ b/ndk/sources/android/helper/gestureDetector.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2013 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.
+ */
+
+//--------------------------------------------------------------------------------
+// gestureDetector.h
+//--------------------------------------------------------------------------------
+
+#ifndef GESTUREDETECTOR_H_
+#define GESTUREDETECTOR_H_
+
+#include <vector>
+
+#include <android/sensor.h>
+#include <android/log.h>
+#include <android_native_app_glue.h>
+#include <android/native_window_jni.h>
+#include "JNIHelper.h"
+#include "vecmath.h"
+
+//--------------------------------------------------------------------------------
+// Constants
+//--------------------------------------------------------------------------------
+const int32_t DOUBLE_TAP_TIMEOUT = 300 * 1000000;
+const int32_t TAP_TIMEOUT = 180 * 1000000;
+const int32_t DOUBLE_TAP_SLOP = 100;
+const int32_t TOUCH_SLOP = 8;
+
+#define GESTURE_STATE_NONE (0)
+#define GESTURE_STATE_START (1)
+#define GESTURE_STATE_MOVE (2)
+#define GESTURE_STATE_END (4)
+#define GESTURE_STATE_ACTION (GESTURE_STATE_START | GESTURE_STATE_END)
+typedef int32_t GESTURE_STATE;
+
+/******************************************************************
+ * Base class of Gesture Detectors
+ * GestureDetectors handles input events and detect gestures
+ * Note that different detectors may detect gestures with an event at
+ * same time. The caller needs to manage gesture priority accordingly
+ *
+ */
+class GestureDetector
+{
+protected:
+ float _fDpFactor;
+public:
+ GestureDetector();
+ virtual ~GestureDetector() {}
+ virtual void setConfiguration(AConfiguration* config);
+
+ virtual GESTURE_STATE detect(const AInputEvent* motion_event) = 0;
+};
+
+/******************************************************************
+ * Tap gesture detector
+ * Returns GESTURE_STATE_ACTION when a tap gesture is detected
+ *
+ */
+class TapDetector : public GestureDetector
+{
+private:
+ int32_t _iDownPointerID;
+ float _fDownX;
+ float _fDownY;
+public:
+ TapDetector() {}
+ virtual ~TapDetector() {}
+ virtual GESTURE_STATE detect(const AInputEvent* motion_event);
+};
+
+/******************************************************************
+ * Pinch gesture detector
+ * Returns GESTURE_STATE_ACTION when a double-tap gesture is detected
+ *
+ */
+class DoubletapDetector : public GestureDetector
+{
+private:
+ TapDetector _tapDetector;
+ int64_t _lastTapTime;
+ float _fLastTapX;
+ float _fLastTapY;
+
+public:
+ DoubletapDetector() {}
+ virtual ~DoubletapDetector() {}
+ virtual GESTURE_STATE detect(const AInputEvent* motion_event);
+ virtual void setConfiguration(AConfiguration* config);
+};
+
+/******************************************************************
+ * Double gesture detector
+ * Returns pinch gesture state when a pinch gesture is detected
+ * The class handles multiple touches more than 2
+ * When the finger 1,2,3 are tapped and then finger 1 is released,
+ * the detector start new pinch gesture with finger 2 & 3.
+ */
+class PinchDetector : public GestureDetector
+{
+private:
+ int32_t findIndex( const AInputEvent* event, int32_t iID );
+ const AInputEvent* _event;
+ std::vector<int32_t> _vecPointers;
+
+public:
+ PinchDetector() {}
+ virtual ~PinchDetector() {}
+ virtual GESTURE_STATE detect(const AInputEvent* event);
+ bool getPointers( vec2& v1, vec2& v2 );
+};
+
+/******************************************************************
+ * Drag gesture detector
+ * Returns drag gesture state when a drag-tap gesture is detected
+ *
+ */
+class DragDetector : public GestureDetector
+{
+private:
+ int32_t findIndex( const AInputEvent* event, int32_t iID );
+ const AInputEvent* _event;
+ std::vector<int32_t> _vecPointers;
+public:
+ DragDetector() {}
+ virtual ~DragDetector() {}
+ virtual GESTURE_STATE detect(const AInputEvent* event);
+ bool getPointer( vec2& v );
+};
+
+#endif /* GESTUREDETECTOR_H_ */
diff --git a/ndk/sources/android/helper/gl3stub.c b/ndk/sources/android/helper/gl3stub.c
new file mode 100644
index 000000000..0f0a40c01
--- /dev/null
+++ b/ndk/sources/android/helper/gl3stub.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#include <EGL/egl.h>
+#include "gl3stub.h"
+
+GLboolean gl3stubInit() {
+ #define FIND_PROC(s) s = (void*)eglGetProcAddress(#s);
+ FIND_PROC(glReadBuffer);
+ FIND_PROC(glDrawRangeElements);
+ FIND_PROC(glTexImage3D);
+ FIND_PROC(glTexSubImage3D);
+ FIND_PROC(glCopyTexSubImage3D);
+ FIND_PROC(glCompressedTexImage3D);
+ FIND_PROC(glCompressedTexSubImage3D);
+ FIND_PROC(glGenQueries);
+ FIND_PROC(glDeleteQueries);
+ FIND_PROC(glIsQuery);
+ FIND_PROC(glBeginQuery);
+ FIND_PROC(glEndQuery);
+ FIND_PROC(glGetQueryiv);
+ FIND_PROC(glGetQueryObjectuiv);
+ FIND_PROC(glUnmapBuffer);
+ FIND_PROC(glGetBufferPointerv);
+ FIND_PROC(glDrawBuffers);
+ FIND_PROC(glUniformMatrix2x3fv);
+ FIND_PROC(glUniformMatrix3x2fv);
+ FIND_PROC(glUniformMatrix2x4fv);
+ FIND_PROC(glUniformMatrix4x2fv);
+ FIND_PROC(glUniformMatrix3x4fv);
+ FIND_PROC(glUniformMatrix4x3fv);
+ FIND_PROC(glBlitFramebuffer);
+ FIND_PROC(glRenderbufferStorageMultisample);
+ FIND_PROC(glFramebufferTextureLayer);
+ FIND_PROC(glMapBufferRange);
+ FIND_PROC(glFlushMappedBufferRange);
+ FIND_PROC(glBindVertexArray);
+ FIND_PROC(glDeleteVertexArrays);
+ FIND_PROC(glGenVertexArrays);
+ FIND_PROC(glIsVertexArray);
+ FIND_PROC(glGetIntegeri_v);
+ FIND_PROC(glBeginTransformFeedback);
+ FIND_PROC(glEndTransformFeedback);
+ FIND_PROC(glBindBufferRange);
+ FIND_PROC(glBindBufferBase);
+ FIND_PROC(glTransformFeedbackVaryings);
+ FIND_PROC(glGetTransformFeedbackVarying);
+ FIND_PROC(glVertexAttribIPointer);
+ FIND_PROC(glGetVertexAttribIiv);
+ FIND_PROC(glGetVertexAttribIuiv);
+ FIND_PROC(glVertexAttribI4i);
+ FIND_PROC(glVertexAttribI4ui);
+ FIND_PROC(glVertexAttribI4iv);
+ FIND_PROC(glVertexAttribI4uiv);
+ FIND_PROC(glGetUniformuiv);
+ FIND_PROC(glGetFragDataLocation);
+ FIND_PROC(glUniform1ui);
+ FIND_PROC(glUniform2ui);
+ FIND_PROC(glUniform3ui);
+ FIND_PROC(glUniform4ui);
+ FIND_PROC(glUniform1uiv);
+ FIND_PROC(glUniform2uiv);
+ FIND_PROC(glUniform3uiv);
+ FIND_PROC(glUniform4uiv);
+ FIND_PROC(glClearBufferiv);
+ FIND_PROC(glClearBufferuiv);
+ FIND_PROC(glClearBufferfv);
+ FIND_PROC(glClearBufferfi);
+ FIND_PROC(glGetStringi);
+ FIND_PROC(glCopyBufferSubData);
+ FIND_PROC(glGetUniformIndices);
+ FIND_PROC(glGetActiveUniformsiv);
+ FIND_PROC(glGetUniformBlockIndex);
+ FIND_PROC(glGetActiveUniformBlockiv);
+ FIND_PROC(glGetActiveUniformBlockName);
+ FIND_PROC(glUniformBlockBinding);
+ FIND_PROC(glDrawArraysInstanced);
+ FIND_PROC(glDrawElementsInstanced);
+ FIND_PROC(glFenceSync);
+ FIND_PROC(glIsSync);
+ FIND_PROC(glDeleteSync);
+ FIND_PROC(glClientWaitSync);
+ FIND_PROC(glWaitSync);
+ FIND_PROC(glGetInteger64v);
+ FIND_PROC(glGetSynciv);
+ FIND_PROC(glGetInteger64i_v);
+ FIND_PROC(glGetBufferParameteri64v);
+ FIND_PROC(glGenSamplers);
+ FIND_PROC(glDeleteSamplers);
+ FIND_PROC(glIsSampler);
+ FIND_PROC(glBindSampler);
+ FIND_PROC(glSamplerParameteri);
+ FIND_PROC(glSamplerParameteriv);
+ FIND_PROC(glSamplerParameterf);
+ FIND_PROC(glSamplerParameterfv);
+ FIND_PROC(glGetSamplerParameteriv);
+ FIND_PROC(glGetSamplerParameterfv);
+ FIND_PROC(glVertexAttribDivisor);
+ FIND_PROC(glBindTransformFeedback);
+ FIND_PROC(glDeleteTransformFeedbacks);
+ FIND_PROC(glGenTransformFeedbacks);
+ FIND_PROC(glIsTransformFeedback);
+ FIND_PROC(glPauseTransformFeedback);
+ FIND_PROC(glResumeTransformFeedback);
+ FIND_PROC(glGetProgramBinary);
+ FIND_PROC(glProgramBinary);
+ FIND_PROC(glProgramParameteri);
+ FIND_PROC(glInvalidateFramebuffer);
+ FIND_PROC(glInvalidateSubFramebuffer);
+ FIND_PROC(glTexStorage2D);
+ FIND_PROC(glTexStorage3D);
+ FIND_PROC(glGetInternalformativ);
+ #undef FIND_PROC
+
+ if (!glReadBuffer ||
+ !glDrawRangeElements ||
+ !glTexImage3D ||
+ !glTexSubImage3D ||
+ !glCopyTexSubImage3D ||
+ !glCompressedTexImage3D ||
+ !glCompressedTexSubImage3D ||
+ !glGenQueries ||
+ !glDeleteQueries ||
+ !glIsQuery ||
+ !glBeginQuery ||
+ !glEndQuery ||
+ !glGetQueryiv ||
+ !glGetQueryObjectuiv ||
+ !glUnmapBuffer ||
+ !glGetBufferPointerv ||
+ !glDrawBuffers ||
+ !glUniformMatrix2x3fv ||
+ !glUniformMatrix3x2fv ||
+ !glUniformMatrix2x4fv ||
+ !glUniformMatrix4x2fv ||
+ !glUniformMatrix3x4fv ||
+ !glUniformMatrix4x3fv ||
+ !glBlitFramebuffer ||
+ !glRenderbufferStorageMultisample ||
+ !glFramebufferTextureLayer ||
+ !glMapBufferRange ||
+ !glFlushMappedBufferRange ||
+ !glBindVertexArray ||
+ !glDeleteVertexArrays ||
+ !glGenVertexArrays ||
+ !glIsVertexArray ||
+ !glGetIntegeri_v ||
+ !glBeginTransformFeedback ||
+ !glEndTransformFeedback ||
+ !glBindBufferRange ||
+ !glBindBufferBase ||
+ !glTransformFeedbackVaryings ||
+ !glGetTransformFeedbackVarying ||
+ !glVertexAttribIPointer ||
+ !glGetVertexAttribIiv ||
+ !glGetVertexAttribIuiv ||
+ !glVertexAttribI4i ||
+ !glVertexAttribI4ui ||
+ !glVertexAttribI4iv ||
+ !glVertexAttribI4uiv ||
+ !glGetUniformuiv ||
+ !glGetFragDataLocation ||
+ !glUniform1ui ||
+ !glUniform2ui ||
+ !glUniform3ui ||
+ !glUniform4ui ||
+ !glUniform1uiv ||
+ !glUniform2uiv ||
+ !glUniform3uiv ||
+ !glUniform4uiv ||
+ !glClearBufferiv ||
+ !glClearBufferuiv ||
+ !glClearBufferfv ||
+ !glClearBufferfi ||
+ !glGetStringi ||
+ !glCopyBufferSubData ||
+ !glGetUniformIndices ||
+ !glGetActiveUniformsiv ||
+ !glGetUniformBlockIndex ||
+ !glGetActiveUniformBlockiv ||
+ !glGetActiveUniformBlockName ||
+ !glUniformBlockBinding ||
+ !glDrawArraysInstanced ||
+ !glDrawElementsInstanced ||
+ !glFenceSync ||
+ !glIsSync ||
+ !glDeleteSync ||
+ !glClientWaitSync ||
+ !glWaitSync ||
+ !glGetInteger64v ||
+ !glGetSynciv ||
+ !glGetInteger64i_v ||
+ !glGetBufferParameteri64v ||
+ !glGenSamplers ||
+ !glDeleteSamplers ||
+ !glIsSampler ||
+ !glBindSampler ||
+ !glSamplerParameteri ||
+ !glSamplerParameteriv ||
+ !glSamplerParameterf ||
+ !glSamplerParameterfv ||
+ !glGetSamplerParameteriv ||
+ !glGetSamplerParameterfv ||
+ !glVertexAttribDivisor ||
+ !glBindTransformFeedback ||
+ !glDeleteTransformFeedbacks ||
+ !glGenTransformFeedbacks ||
+ !glIsTransformFeedback ||
+ !glPauseTransformFeedback ||
+ !glResumeTransformFeedback ||
+ !glGetProgramBinary ||
+ !glProgramBinary ||
+ !glProgramParameteri ||
+ !glInvalidateFramebuffer ||
+ !glInvalidateSubFramebuffer ||
+ !glTexStorage2D ||
+ !glTexStorage3D ||
+ !glGetInternalformativ)
+ {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+/* Function pointer definitions */
+GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode);
+GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
+GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
+GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id);
+GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
+GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target);
+GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
+GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target);
+GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
+GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
+GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array);
+GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
+GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
+GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array);
+GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
+GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
+GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
+GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
+GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
+GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
+GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
+GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
+GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
+GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
+GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
+GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync);
+GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync);
+GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
+GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
+GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
+GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
+GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
+GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler);
+GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
+GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
+GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
+GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
+GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
+GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
+GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
+GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
+GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
+GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
+GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void);
+GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
+GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
diff --git a/ndk/sources/android/helper/gl3stub.h b/ndk/sources/android/helper/gl3stub.h
new file mode 100644
index 000000000..a6ca63612
--- /dev/null
+++ b/ndk/sources/android/helper/gl3stub.h
@@ -0,0 +1,500 @@
+#ifndef __gl3_h_
+#define __gl3_h_
+
+/*
+ * stub gl3.h for dynamic loading, based on:
+ * gl3.h last updated on $Date: 2013-02-12 14:37:24 -0800 (Tue, 12 Feb 2013) $
+ *
+ * Changes:
+ * - Added #include <GLES2/gl2.h>
+ * - Removed duplicate OpenGL ES 2.0 declarations
+ * - Converted OpenGL ES 3.0 function prototypes to function pointer
+ * declarations
+ * - Added gl3stubInit() declaration
+ */
+
+#include <GLES2/gl2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007-2013 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/*
+ * This files is for apps that want to use ES3 if present,
+ * but continue to work on pre-API-18 devices. They can't just link to -lGLESv3 since
+ * that library doesn't exist on pre-API-18 devices.
+ * The function dynamically check if OpenGLES3.0 APIs are present and fill in if there are.
+ * Also the header defines some extra variables for OpenGLES3.0.
+ *
+ */
+
+/* Call this function before calling any OpenGL ES 3.0 functions. It will
+ * return GL_TRUE if the OpenGL ES 3.0 was successfully initialized, GL_FALSE
+ * otherwise. */
+GLboolean gl3stubInit();
+
+/*-------------------------------------------------------------------------
+ * Data type definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 3.0 */
+
+typedef unsigned short GLhalf;
+typedef khronos_int64_t GLint64;
+typedef khronos_uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+
+/*-------------------------------------------------------------------------
+ * Token definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES core versions */
+#define GL_ES_VERSION_3_0 1
+
+/* OpenGL ES 3.0 */
+
+#define GL_READ_BUFFER 0x0C02
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#define GL_UNPACK_SKIP_ROWS 0x0CF3
+#define GL_UNPACK_SKIP_PIXELS 0x0CF4
+#define GL_PACK_ROW_LENGTH 0x0D02
+#define GL_PACK_SKIP_ROWS 0x0D03
+#define GL_PACK_SKIP_PIXELS 0x0D04
+#define GL_COLOR 0x1800
+#define GL_DEPTH 0x1801
+#define GL_STENCIL 0x1802
+#define GL_RED 0x1903
+#define GL_RGB8 0x8051
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_COMPARE_REF_TO_TEXTURE 0x884E
+#define GL_MAJOR_VERSION 0x821B
+#define GL_MINOR_VERSION 0x821C
+#define GL_NUM_EXTENSIONS 0x821D
+#define GL_RGBA32F 0x8814
+#define GL_RGB32F 0x8815
+#define GL_RGBA16F 0x881A
+#define GL_RGB16F 0x881B
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
+#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
+#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
+#define GL_MAX_VARYING_COMPONENTS 0x8B4B
+#define GL_TEXTURE_2D_ARRAY 0x8C1A
+#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
+#define GL_R11F_G11F_B10F 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
+#define GL_RGB9_E5 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
+#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
+#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
+#define GL_RASTERIZER_DISCARD 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS 0x8C8C
+#define GL_SEPARATE_ATTRIBS 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
+#define GL_RGBA32UI 0x8D70
+#define GL_RGB32UI 0x8D71
+#define GL_RGBA16UI 0x8D76
+#define GL_RGB16UI 0x8D77
+#define GL_RGBA8UI 0x8D7C
+#define GL_RGB8UI 0x8D7D
+#define GL_RGBA32I 0x8D82
+#define GL_RGB32I 0x8D83
+#define GL_RGBA16I 0x8D88
+#define GL_RGB16I 0x8D89
+#define GL_RGBA8I 0x8D8E
+#define GL_RGB8I 0x8D8F
+#define GL_RED_INTEGER 0x8D94
+#define GL_RGB_INTEGER 0x8D98
+#define GL_RGBA_INTEGER 0x8D99
+#define GL_SAMPLER_2D_ARRAY 0x8DC1
+#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
+#define GL_UNSIGNED_INT_VEC2 0x8DC6
+#define GL_UNSIGNED_INT_VEC3 0x8DC7
+#define GL_UNSIGNED_INT_VEC4 0x8DC8
+#define GL_INT_SAMPLER_2D 0x8DCA
+#define GL_INT_SAMPLER_3D 0x8DCB
+#define GL_INT_SAMPLER_CUBE 0x8DCC
+#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
+#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
+#define GL_DEPTH_COMPONENT32F 0x8CAC
+#define GL_DEPTH32F_STENCIL8 0x8CAD
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD
+#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210
+#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211
+#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212
+#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213
+#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214
+#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215
+#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216
+#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
+#define GL_FRAMEBUFFER_DEFAULT 0x8218
+#define GL_FRAMEBUFFER_UNDEFINED 0x8219
+#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GL_DEPTH_STENCIL 0x84F9
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#define GL_DEPTH24_STENCIL8 0x88F0
+#define GL_UNSIGNED_NORMALIZED 0x8C17
+#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4
+#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF
+#define GL_COLOR_ATTACHMENT1 0x8CE1
+#define GL_COLOR_ATTACHMENT2 0x8CE2
+#define GL_COLOR_ATTACHMENT3 0x8CE3
+#define GL_COLOR_ATTACHMENT4 0x8CE4
+#define GL_COLOR_ATTACHMENT5 0x8CE5
+#define GL_COLOR_ATTACHMENT6 0x8CE6
+#define GL_COLOR_ATTACHMENT7 0x8CE7
+#define GL_COLOR_ATTACHMENT8 0x8CE8
+#define GL_COLOR_ATTACHMENT9 0x8CE9
+#define GL_COLOR_ATTACHMENT10 0x8CEA
+#define GL_COLOR_ATTACHMENT11 0x8CEB
+#define GL_COLOR_ATTACHMENT12 0x8CEC
+#define GL_COLOR_ATTACHMENT13 0x8CED
+#define GL_COLOR_ATTACHMENT14 0x8CEE
+#define GL_COLOR_ATTACHMENT15 0x8CEF
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#define GL_MAX_SAMPLES 0x8D57
+#define GL_HALF_FLOAT 0x140B
+#define GL_MAP_READ_BIT 0x0001
+#define GL_MAP_WRITE_BIT 0x0002
+#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004
+#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008
+#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010
+#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020
+#define GL_RG 0x8227
+#define GL_RG_INTEGER 0x8228
+#define GL_R8 0x8229
+#define GL_RG8 0x822B
+#define GL_R16F 0x822D
+#define GL_R32F 0x822E
+#define GL_RG16F 0x822F
+#define GL_RG32F 0x8230
+#define GL_R8I 0x8231
+#define GL_R8UI 0x8232
+#define GL_R16I 0x8233
+#define GL_R16UI 0x8234
+#define GL_R32I 0x8235
+#define GL_R32UI 0x8236
+#define GL_RG8I 0x8237
+#define GL_RG8UI 0x8238
+#define GL_RG16I 0x8239
+#define GL_RG16UI 0x823A
+#define GL_RG32I 0x823B
+#define GL_RG32UI 0x823C
+#define GL_VERTEX_ARRAY_BINDING 0x85B5
+#define GL_R8_SNORM 0x8F94
+#define GL_RG8_SNORM 0x8F95
+#define GL_RGB8_SNORM 0x8F96
+#define GL_RGBA8_SNORM 0x8F97
+#define GL_SIGNED_NORMALIZED 0x8F9C
+#define GL_PRIMITIVE_RESTART_FIXED_INDEX 0x8D69
+#define GL_COPY_READ_BUFFER 0x8F36
+#define GL_COPY_WRITE_BUFFER 0x8F37
+#define GL_COPY_READ_BUFFER_BINDING GL_COPY_READ_BUFFER
+#define GL_COPY_WRITE_BUFFER_BINDING GL_COPY_WRITE_BUFFER
+#define GL_UNIFORM_BUFFER 0x8A11
+#define GL_UNIFORM_BUFFER_BINDING 0x8A28
+#define GL_UNIFORM_BUFFER_START 0x8A29
+#define GL_UNIFORM_BUFFER_SIZE 0x8A2A
+#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B
+#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D
+#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E
+#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F
+#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30
+#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31
+#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33
+#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34
+#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35
+#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36
+#define GL_UNIFORM_TYPE 0x8A37
+#define GL_UNIFORM_SIZE 0x8A38
+#define GL_UNIFORM_NAME_LENGTH 0x8A39
+#define GL_UNIFORM_BLOCK_INDEX 0x8A3A
+#define GL_UNIFORM_OFFSET 0x8A3B
+#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C
+#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D
+#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E
+#define GL_UNIFORM_BLOCK_BINDING 0x8A3F
+#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40
+#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42
+#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46
+#define GL_INVALID_INDEX 0xFFFFFFFFu
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
+#define GL_ANY_SAMPLES_PASSED 0x8C2F
+#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE 0x8D6A
+#define GL_SAMPLER_BINDING 0x8919
+#define GL_RGB10_A2UI 0x906F
+#define GL_TEXTURE_SWIZZLE_R 0x8E42
+#define GL_TEXTURE_SWIZZLE_G 0x8E43
+#define GL_TEXTURE_SWIZZLE_B 0x8E44
+#define GL_TEXTURE_SWIZZLE_A 0x8E45
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_INT_2_10_10_10_REV 0x8D9F
+#define GL_TRANSFORM_FEEDBACK 0x8E22
+#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
+#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
+#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25
+#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257
+#define GL_PROGRAM_BINARY_LENGTH 0x8741
+#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE
+#define GL_PROGRAM_BINARY_FORMATS 0x87FF
+#define GL_COMPRESSED_R11_EAC 0x9270
+#define GL_COMPRESSED_SIGNED_R11_EAC 0x9271
+#define GL_COMPRESSED_RG11_EAC 0x9272
+#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
+#define GL_COMPRESSED_RGB8_ETC2 0x9274
+#define GL_COMPRESSED_SRGB8_ETC2 0x9275
+#define GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9276
+#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
+#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
+#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
+#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
+#define GL_MAX_ELEMENT_INDEX 0x8D6B
+#define GL_NUM_SAMPLE_COUNTS 0x9380
+#define GL_TEXTURE_IMMUTABLE_LEVELS 0x82DF
+
+/*-------------------------------------------------------------------------
+ * Entrypoint definitions
+ *-----------------------------------------------------------------------*/
+
+/* OpenGL ES 3.0 */
+
+extern GL_APICALL void (* GL_APIENTRY glReadBuffer) (GLenum mode);
+extern GL_APICALL void (* GL_APIENTRY glDrawRangeElements) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices);
+extern GL_APICALL void (* GL_APIENTRY glTexImage3D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+extern GL_APICALL void (* GL_APIENTRY glTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
+extern GL_APICALL void (* GL_APIENTRY glCopyTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glCompressedTexImage3D) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+extern GL_APICALL void (* GL_APIENTRY glCompressedTexSubImage3D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
+extern GL_APICALL void (* GL_APIENTRY glGenQueries) (GLsizei n, GLuint* ids);
+extern GL_APICALL void (* GL_APIENTRY glDeleteQueries) (GLsizei n, const GLuint* ids);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsQuery) (GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glBeginQuery) (GLenum target, GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glEndQuery) (GLenum target);
+extern GL_APICALL void (* GL_APIENTRY glGetQueryiv) (GLenum target, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetQueryObjectuiv) (GLuint id, GLenum pname, GLuint* params);
+extern GL_APICALL GLboolean (* GL_APIENTRY glUnmapBuffer) (GLenum target);
+extern GL_APICALL void (* GL_APIENTRY glGetBufferPointerv) (GLenum target, GLenum pname, GLvoid** params);
+extern GL_APICALL void (* GL_APIENTRY glDrawBuffers) (GLsizei n, const GLenum* bufs);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix2x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix3x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix2x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix4x2fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix3x4fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glUniformMatrix4x3fv) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glBlitFramebuffer) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+extern GL_APICALL void (* GL_APIENTRY glRenderbufferStorageMultisample) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glFramebufferTextureLayer) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+extern GL_APICALL GLvoid* (* GL_APIENTRY glMapBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access);
+extern GL_APICALL void (* GL_APIENTRY glFlushMappedBufferRange) (GLenum target, GLintptr offset, GLsizeiptr length);
+extern GL_APICALL void (* GL_APIENTRY glBindVertexArray) (GLuint array);
+extern GL_APICALL void (* GL_APIENTRY glDeleteVertexArrays) (GLsizei n, const GLuint* arrays);
+extern GL_APICALL void (* GL_APIENTRY glGenVertexArrays) (GLsizei n, GLuint* arrays);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsVertexArray) (GLuint array);
+extern GL_APICALL void (* GL_APIENTRY glGetIntegeri_v) (GLenum target, GLuint index, GLint* data);
+extern GL_APICALL void (* GL_APIENTRY glBeginTransformFeedback) (GLenum primitiveMode);
+extern GL_APICALL void (* GL_APIENTRY glEndTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glBindBufferRange) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+extern GL_APICALL void (* GL_APIENTRY glBindBufferBase) (GLenum target, GLuint index, GLuint buffer);
+extern GL_APICALL void (* GL_APIENTRY glTransformFeedbackVaryings) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode);
+extern GL_APICALL void (* GL_APIENTRY glGetTransformFeedbackVarying) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribIPointer) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);
+extern GL_APICALL void (* GL_APIENTRY glGetVertexAttribIiv) (GLuint index, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetVertexAttribIuiv) (GLuint index, GLenum pname, GLuint* params);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4i) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4ui) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4iv) (GLuint index, const GLint* v);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribI4uiv) (GLuint index, const GLuint* v);
+extern GL_APICALL void (* GL_APIENTRY glGetUniformuiv) (GLuint program, GLint location, GLuint* params);
+extern GL_APICALL GLint (* GL_APIENTRY glGetFragDataLocation) (GLuint program, const GLchar *name);
+extern GL_APICALL void (* GL_APIENTRY glUniform1ui) (GLint location, GLuint v0);
+extern GL_APICALL void (* GL_APIENTRY glUniform2ui) (GLint location, GLuint v0, GLuint v1);
+extern GL_APICALL void (* GL_APIENTRY glUniform3ui) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+extern GL_APICALL void (* GL_APIENTRY glUniform4ui) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+extern GL_APICALL void (* GL_APIENTRY glUniform1uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform2uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform3uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glUniform4uiv) (GLint location, GLsizei count, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferiv) (GLenum buffer, GLint drawbuffer, const GLint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferuiv) (GLenum buffer, GLint drawbuffer, const GLuint* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferfv) (GLenum buffer, GLint drawbuffer, const GLfloat* value);
+extern GL_APICALL void (* GL_APIENTRY glClearBufferfi) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+extern GL_APICALL const GLubyte* (* GL_APIENTRY glGetStringi) (GLenum name, GLuint index);
+extern GL_APICALL void (* GL_APIENTRY glCopyBufferSubData) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
+extern GL_APICALL void (* GL_APIENTRY glGetUniformIndices) (GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformsiv) (GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params);
+extern GL_APICALL GLuint (* GL_APIENTRY glGetUniformBlockIndex) (GLuint program, const GLchar* uniformBlockName);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockiv) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetActiveUniformBlockName) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName);
+extern GL_APICALL void (* GL_APIENTRY glUniformBlockBinding) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
+extern GL_APICALL void (* GL_APIENTRY glDrawArraysInstanced) (GLenum mode, GLint first, GLsizei count, GLsizei instanceCount);
+extern GL_APICALL void (* GL_APIENTRY glDrawElementsInstanced) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount);
+extern GL_APICALL GLsync (* GL_APIENTRY glFenceSync) (GLenum condition, GLbitfield flags);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsSync) (GLsync sync);
+extern GL_APICALL void (* GL_APIENTRY glDeleteSync) (GLsync sync);
+extern GL_APICALL GLenum (* GL_APIENTRY glClientWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+extern GL_APICALL void (* GL_APIENTRY glWaitSync) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+extern GL_APICALL void (* GL_APIENTRY glGetInteger64v) (GLenum pname, GLint64* params);
+extern GL_APICALL void (* GL_APIENTRY glGetSynciv) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values);
+extern GL_APICALL void (* GL_APIENTRY glGetInteger64i_v) (GLenum target, GLuint index, GLint64* data);
+extern GL_APICALL void (* GL_APIENTRY glGetBufferParameteri64v) (GLenum target, GLenum pname, GLint64* params);
+extern GL_APICALL void (* GL_APIENTRY glGenSamplers) (GLsizei count, GLuint* samplers);
+extern GL_APICALL void (* GL_APIENTRY glDeleteSamplers) (GLsizei count, const GLuint* samplers);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsSampler) (GLuint sampler);
+extern GL_APICALL void (* GL_APIENTRY glBindSampler) (GLuint unit, GLuint sampler);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameteri) (GLuint sampler, GLenum pname, GLint param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameteriv) (GLuint sampler, GLenum pname, const GLint* param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameterf) (GLuint sampler, GLenum pname, GLfloat param);
+extern GL_APICALL void (* GL_APIENTRY glSamplerParameterfv) (GLuint sampler, GLenum pname, const GLfloat* param);
+extern GL_APICALL void (* GL_APIENTRY glGetSamplerParameteriv) (GLuint sampler, GLenum pname, GLint* params);
+extern GL_APICALL void (* GL_APIENTRY glGetSamplerParameterfv) (GLuint sampler, GLenum pname, GLfloat* params);
+extern GL_APICALL void (* GL_APIENTRY glVertexAttribDivisor) (GLuint index, GLuint divisor);
+extern GL_APICALL void (* GL_APIENTRY glBindTransformFeedback) (GLenum target, GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glDeleteTransformFeedbacks) (GLsizei n, const GLuint* ids);
+extern GL_APICALL void (* GL_APIENTRY glGenTransformFeedbacks) (GLsizei n, GLuint* ids);
+extern GL_APICALL GLboolean (* GL_APIENTRY glIsTransformFeedback) (GLuint id);
+extern GL_APICALL void (* GL_APIENTRY glPauseTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glResumeTransformFeedback) (void);
+extern GL_APICALL void (* GL_APIENTRY glGetProgramBinary) (GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary);
+extern GL_APICALL void (* GL_APIENTRY glProgramBinary) (GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length);
+extern GL_APICALL void (* GL_APIENTRY glProgramParameteri) (GLuint program, GLenum pname, GLint value);
+extern GL_APICALL void (* GL_APIENTRY glInvalidateFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments);
+extern GL_APICALL void (* GL_APIENTRY glInvalidateSubFramebuffer) (GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glTexStorage2D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
+extern GL_APICALL void (* GL_APIENTRY glTexStorage3D) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
+extern GL_APICALL void (* GL_APIENTRY glGetInternalformativ) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/ndk/sources/android/helper/interpolator.cpp b/ndk/sources/android/helper/interpolator.cpp
new file mode 100644
index 000000000..137b64f42
--- /dev/null
+++ b/ndk/sources/android/helper/interpolator.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#include "interpolator.h"
+#include <math.h>
+#include "interpolator.h"
+
+
+//-------------------------------------------------
+//Ctor
+//-------------------------------------------------
+interpolator::interpolator()
+{
+ m_listParams.clear();
+}
+
+//-------------------------------------------------
+//Dtor
+//-------------------------------------------------
+interpolator::~interpolator()
+{
+ m_listParams.clear();
+}
+
+void interpolator::clear()
+{
+ m_listParams.clear();
+}
+
+interpolator& interpolator::set(float start,float dest, INTERPOLATOR_TYPE type, double duration)
+{
+ //init the parameters for the interpolation process
+ _dStartTime = perfMonitor::getCurrentTime();
+ _dDestTime = _dStartTime + duration;
+ _type = type;
+
+ _fStartValue = start;
+ _fDestValue = dest;
+ return *this;
+}
+
+interpolator& interpolator::add(const float dest,
+ INTERPOLATOR_TYPE type, double duration)
+{
+ interpolatorParam param;
+ param.fDestValue = dest;
+ param.type = type;
+ param.dDuration = duration;
+ m_listParams.push_back( param );
+ return *this;
+}
+
+bool interpolator::update( const double currentTime, float& p )
+{
+ bool bContinue;
+ if( currentTime >= _dDestTime )
+ {
+ p = _fDestValue;
+ if( m_listParams.size () )
+ {
+ interpolatorParam& item = m_listParams.front();
+ set(_fDestValue, item.fDestValue, item.type, item.dDuration );
+ m_listParams.pop_front();
+
+ bContinue = true;
+ }
+ else
+ {
+ bContinue = false;
+ }
+ }
+ else
+ {
+ float t = (float)(currentTime - _dStartTime);
+ float d = (float)(_dDestTime - _dStartTime);
+ float b = _fStartValue;
+ float c = _fDestValue - _fStartValue;
+ p = getFormula(_type, t, b, d, c);
+
+ bContinue = true;
+ }
+ return bContinue;
+}
+
+float interpolator::getFormula(INTERPOLATOR_TYPE type, float t, float b, float d, float c)
+{
+ float t1;
+ switch( type )
+ {
+ case INTERPOLATOR_TYPE_LINEAR:
+ // simple linear interpolation - no easing
+ return (c * t / d + b);
+
+ case INTERPOLATOR_TYPE_EASEINQUAD:
+ // quadratic (t^2) easing in - accelerating from zero velocity
+ t1 = t / d;
+ return (c * t1 * t1 + b);
+
+ case INTERPOLATOR_TYPE_EASEOUTQUAD:
+ // quadratic (t^2) easing out - decelerating to zero velocity
+ t1 = t / d;
+ return (-c * t1 * (t1-2) + b);
+
+ case INTERPOLATOR_TYPE_EASEINOUTQUAD:
+ // quadratic easing in/out - acceleration until halfway, then deceleration
+ t1 = t / d / 2;
+ if (t1 < 1)
+ return ( c/2 * t1 * t1 + b);
+ else
+ {
+ t1 = t1 -1;
+ return (-c/2 * (t1 * (t1-2) - 1) + b);
+ }
+ case INTERPOLATOR_TYPE_EASEINCUBIC:
+ // cubic easing in - accelerating from zero velocity
+ t1 = t / d;
+ return (c * t1 * t1 * t1 + b);
+
+ case INTERPOLATOR_TYPE_EASEOUTCUBIC:
+ // cubic easing in - accelerating from zero velocity
+ t1 = t / d - 1;
+ return (c * (t1 * t1 * t1 + 1) + b);
+
+ case INTERPOLATOR_TYPE_EASEINOUTCUBIC:
+ // cubic easing in - accelerating from zero velocity
+ t1 = t / d / 2;
+
+ if ( t1 < 1)
+ return (c/2 * t1 * t1 * t1 + b);
+ else
+ {
+ t1 -= 2;
+ return (c/2 * (t1 * t1 * t1 + 2 ) + b);
+ }
+ case INTERPOLATOR_TYPE_EASEINQUART:
+ // quartic easing in - accelerating from zero velocity
+ t1 = t / d;
+ return (c * t1 * t1 * t1 * t1 + b);
+
+ case INTERPOLATOR_TYPE_EASEINEXPO:
+ // exponential (2^t) easing in - accelerating from zero velocity
+ if (t==0)
+ return b;
+ else
+ return (c*powf(2,(10*(t/d-1)))+b);
+
+ case INTERPOLATOR_TYPE_EASEOUTEXPO:
+ // exponential (2^t) easing out - decelerating to zero velocity
+ if (t==d)
+ return (b+c);
+ else
+ return (c * (-powf(2,-10*t/d)+1)+b);
+ default:
+ return 0;
+ }
+}
diff --git a/ndk/sources/android/helper/interpolator.h b/ndk/sources/android/helper/interpolator.h
new file mode 100644
index 000000000..66e887ba6
--- /dev/null
+++ b/ndk/sources/android/helper/interpolator.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef INTERPOLATOR_H_
+#define INTERPOLATOR_H_
+
+#include <jni.h>
+#include <errno.h>
+#include <time.h>
+#include "JNIHelper.h"
+#include "perfMonitor.h"
+#include <list>
+
+enum INTERPOLATOR_TYPE
+{
+ INTERPOLATOR_TYPE_LINEAR,
+ INTERPOLATOR_TYPE_EASEINQUAD,
+ INTERPOLATOR_TYPE_EASEOUTQUAD,
+ INTERPOLATOR_TYPE_EASEINOUTQUAD,
+ INTERPOLATOR_TYPE_EASEINCUBIC,
+ INTERPOLATOR_TYPE_EASEOUTCUBIC,
+ INTERPOLATOR_TYPE_EASEINOUTCUBIC,
+ INTERPOLATOR_TYPE_EASEINQUART,
+ INTERPOLATOR_TYPE_EASEINEXPO,
+ INTERPOLATOR_TYPE_EASEOUTEXPO,
+};
+
+struct interpolatorParam {
+ float fDestValue;
+ INTERPOLATOR_TYPE type;
+ double dDuration;
+};
+
+/******************************************************************
+ * Interpolates values with several interpolation methods
+ */
+class interpolator {
+private:
+ double _dStartTime;
+ double _dDestTime;
+ INTERPOLATOR_TYPE _type;
+
+ float _fStartValue;
+ float _fDestValue;
+ std::list< interpolatorParam > m_listParams;
+
+ float getFormula(INTERPOLATOR_TYPE type, float t, float b, float d, float c);
+public:
+ interpolator();
+ ~interpolator();
+
+ interpolator& set(const float start,
+ const float dest,
+ INTERPOLATOR_TYPE type, double duration);
+
+ interpolator& add(const float dest,
+ INTERPOLATOR_TYPE type, double duration);
+
+ bool update( const double currentTime, float& p );
+
+ void clear();
+};
+
+
+#endif /* INTERPOLATOR_H_ */
diff --git a/ndk/sources/android/helper/perfMonitor.cpp b/ndk/sources/android/helper/perfMonitor.cpp
new file mode 100644
index 000000000..bc4f337d1
--- /dev/null
+++ b/ndk/sources/android/helper/perfMonitor.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#include "perfMonitor.h"
+
+perfMonitor::perfMonitor():
+ _dLastTick(0.f),
+ _tvLastSec(0),
+ _tickindex(0),
+ _ticksum(0)
+{
+ for(int32_t i = 0; i < NUM_SAMPLES; ++i )
+ _ticklist[i] = 0;
+}
+
+perfMonitor::~perfMonitor() {
+}
+
+double perfMonitor::updateTick(double currentTick)
+{
+ _ticksum -= _ticklist[_tickindex];
+ _ticksum += currentTick;
+ _ticklist[_tickindex] = currentTick;
+ _tickindex = (_tickindex+1)%NUM_SAMPLES;
+
+ return((double)_ticksum/NUM_SAMPLES);
+}
+
+bool perfMonitor::update(float &fFPS)
+{
+ struct timeval Time;
+ gettimeofday( &Time, NULL );
+
+ double time = Time.tv_sec + Time.tv_usec * 1.0/1000000.0;
+ double dTick = time - _dLastTick;
+ double d = updateTick( dTick );
+ _dLastTick = time;
+
+ if( Time.tv_sec - _tvLastSec >= 1 )
+ {
+ double time = Time.tv_sec + Time.tv_usec * 1.0/1000000.0;
+ _fCurrentFPS = 1.f / d;
+ _tvLastSec = Time.tv_sec;
+ fFPS = _fCurrentFPS;
+ return true;
+ }
+ else
+ {
+ fFPS = _fCurrentFPS;
+ return false;
+ }
+}
diff --git a/ndk/sources/android/helper/perfMonitor.h b/ndk/sources/android/helper/perfMonitor.h
new file mode 100644
index 000000000..c57f45bc2
--- /dev/null
+++ b/ndk/sources/android/helper/perfMonitor.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef PERFMONITOR_H_
+#define PERFMONITOR_H_
+
+#include <jni.h>
+#include <errno.h>
+#include <time.h>
+#include "JNIHelper.h"
+
+const int32_t NUM_SAMPLES = 100;
+
+/******************************************************************
+ * Helper class for a performance monitoring and get current tick time
+ */
+class perfMonitor {
+private:
+ float _fCurrentFPS;
+ time_t _tvLastSec;
+
+ double _dLastTick;
+ int32_t _tickindex;
+ double _ticksum;
+ double _ticklist[ NUM_SAMPLES ];
+
+ double updateTick(double currentTick);
+public:
+ perfMonitor();
+ virtual ~perfMonitor();
+
+ bool update(float &fFPS);
+
+ static double getCurrentTime()
+ {
+ struct timeval Time;
+ gettimeofday( &Time, NULL );
+ double dTime = Time.tv_sec + Time.tv_usec * 1.0/1000000.0;
+ return dTime;
+ }
+};
+
+#endif /* PERFMONITOR_H_ */
diff --git a/ndk/sources/android/helper/shader.cpp b/ndk/sources/android/helper/shader.cpp
new file mode 100644
index 000000000..f361a7ad7
--- /dev/null
+++ b/ndk/sources/android/helper/shader.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#include "shader.h"
+#include "JNIHelper.h"
+
+#define DEBUG (1)
+
+bool shader::compileShader(GLuint *shader, const GLenum type,
+ const char *strFileName, const std::map<std::string, std::string>& mapParameters)
+{
+ std::vector<uint8_t> data;
+ bool b = JNIHelper::readFile(strFileName, data);
+ if (!b)
+ {
+ LOGI("Can not open a file:%s", strFileName);
+ return false;
+ }
+
+ //Fill-in parameters
+ std::string str(data.begin(), data.end());
+ std::map<std::string, std::string>::const_iterator it = mapParameters.begin();
+ std::map<std::string, std::string>::const_iterator itEnd = mapParameters.end();
+ while( it != itEnd )
+ {
+ size_t pos = 0;
+ while( (pos = str.find( it->first, pos )) != std::string::npos )
+ {
+ str.replace( pos, it->first.length(), it->second );
+ pos += it->second.length();
+ }
+ it++;
+ }
+
+ std::vector<uint8_t> v( str.begin(), str.end() );
+ str.clear();
+ return shader::compileShader( shader, type, v );
+}
+
+bool shader::compileShader(GLuint *shader, const GLenum type,
+ const GLchar *source, const int32_t iSize)
+{
+ if( source == NULL || iSize <= 0 )
+ return false;
+
+ *shader = glCreateShader(type);
+ glShaderSource(*shader, 1, &source, &iSize); //Not specifying 3rd parameter (size) could be troublesome..
+
+ glCompileShader(*shader);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *) malloc(logLength);
+ glGetShaderInfoLog(*shader, logLength, &logLength, log);
+ LOGI("Shader compile log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ GLint status;
+ glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
+ if (status == 0) {
+ glDeleteShader(*shader);
+ return false;
+ }
+
+ return true;
+}
+
+bool shader::compileShader(GLuint *shader, const GLenum type,
+ std::vector<uint8_t>& data)
+{
+ if( !data.size() )
+ return false;
+
+ const GLchar *source = (GLchar *) &data[0];
+ int32_t iSize = data.size();
+ return shader::compileShader( shader, type, source, iSize );
+}
+
+bool shader::compileShader(GLuint *shader, const GLenum type,
+ const char *strFileName) {
+ std::vector<uint8_t> data;
+ bool b = JNIHelper::readFile(strFileName, data);
+ if (!b)
+ {
+ LOGI("Can not open a file:%s", strFileName);
+ return false;
+ }
+
+ return shader::compileShader( shader, type, data );
+}
+
+bool shader::linkProgram(const GLuint prog) {
+ GLint status;
+
+ glLinkProgram(prog);
+
+#if defined(DEBUG)
+ GLint logLength;
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *) malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ LOGI("Program link log:\n%s", log);
+ free(log);
+ }
+#endif
+
+ glGetProgramiv(prog, GL_LINK_STATUS, &status);
+ if (status == 0) {
+ LOGI("Program link failed\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool shader::validateProgram(const GLuint prog) {
+ GLint logLength, status;
+
+ glValidateProgram(prog);
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
+ if (logLength > 0) {
+ GLchar *log = (GLchar *) malloc(logLength);
+ glGetProgramInfoLog(prog, logLength, &logLength, log);
+ LOGI("Program validate log:\n%s", log);
+ free(log);
+ }
+
+ glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
+ if (status == 0)
+ return false;
+
+ return true;
+}
diff --git a/ndk/sources/android/helper/shader.h b/ndk/sources/android/helper/shader.h
new file mode 100644
index 000000000..3cdfeb4cd
--- /dev/null
+++ b/ndk/sources/android/helper/shader.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef SHADER_H_
+#define SHADER_H_
+
+#include <jni.h>
+#include <errno.h>
+
+#include <vector>
+#include <map>
+#include <string>
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+#include <android/sensor.h>
+#include <android/log.h>
+#include <android_native_app_glue.h>
+#include <android/native_window_jni.h>
+#include <cpu-features.h>
+
+#include "JNIHelper.h"
+
+/******************************************************************
+ * Shader compiler helper
+ *
+ * compileShader() with std::map helps patching on a shader on the fly.
+ * For a example,
+ * map : %KEY% -> %VALUE% replaces all %KEY% entries in the given shader code to %VALUE"
+ *
+ */
+class shader {
+public:
+ static bool compileShader(GLuint *shader, const GLenum type,
+ std::vector<uint8_t>& data);
+ static bool compileShader(GLuint *shader, const GLenum type,
+ const GLchar *source, const int32_t iSize);
+ static bool compileShader(GLuint *shader, const GLenum type,
+ const char *strFileName);
+ static bool compileShader(GLuint *shader, const GLenum type,
+ const char *strFileName, const std::map<std::string, std::string>& mapParameters);
+ static bool linkProgram(const GLuint prog);
+ static bool validateProgram(const GLuint prog);
+};
+
+
+
+
+#endif /* SHADER_H_ */
diff --git a/ndk/sources/android/helper/tapCamera.cpp b/ndk/sources/android/helper/tapCamera.cpp
new file mode 100644
index 000000000..0b0f94b02
--- /dev/null
+++ b/ndk/sources/android/helper/tapCamera.cpp
@@ -0,0 +1,313 @@
+/*
+ * Copyright 2013 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.
+ */
+
+//----------------------------------------------------------
+// tapCamera.cpp
+// Camera control with tap
+//
+//----------------------------------------------------------
+
+#include <fstream>
+#include "tapCamera.h"
+
+const float TRANSFORM_FACTOR = 15.f;
+const float TRANSFORM_FACTORZ = 10.f;
+
+const float MOMENTUM_FACTOR_DECREASE = 0.85f;
+const float MOMENTUM_FACTOR_DECREASE_SHIFT = 0.9f;
+const float MOMENTUM_FACTOR = 0.8f;
+const float MOMENTUM_FACTOR_THRESHOLD = 0.001f;
+
+//----------------------------------------------------------
+// Ctor
+//----------------------------------------------------------
+tapCamera::tapCamera():
+ _bDragging(false),
+ _bPinching( false ),
+ _bMomentum(false),
+ _fBallRadius( 0.75f ),
+ _fPinchStartDistanceSQ( 0.f ),
+ _fRotation( 0.f ),
+ _fRotationStart( 0.f ),
+ _fRotationNow( 0.f ),
+ _fMomentumSteps( 0.f ),
+ _fFlipZ( 0.f )
+{
+ //Init offset
+ initParameters();
+
+ _vFlip = vec2( 1.f, -1.f );
+ _fFlipZ = -1.f;
+ _vPinchTransformFactor = vec3( 1.f, 1.f, 1.f );
+
+ _vBallCenter = vec2( 0, 0 );
+ _vBallNow = vec2( 0, 0 );
+ _vBallDown = vec2( 0, 0 );
+
+ _vecPinchStart = vec2( 0, 0 );
+ _vecPinchStartCenter = vec2( 0, 0 );
+
+ _vFlip = vec2( 0, 0 );
+
+}
+
+void tapCamera::initParameters()
+{
+ //Init parameters
+ _vecOffset = vec3();
+ _vecOffsetNow = vec3();
+
+ _qBallRot = quaternion();
+ _qBallNow = quaternion();
+ _qBallNow.toMatrix(_mRotation);
+ _fRotation = 0.f;
+
+ _vDragDelta = vec2();
+ _vecOffsetDelta = vec3();
+
+ _bMomentum = false;
+}
+
+//----------------------------------------------------------
+// Dtor
+//----------------------------------------------------------
+tapCamera::~tapCamera()
+{
+
+}
+
+void tapCamera::update()
+{
+ if( _bMomentum )
+ {
+ float fMomenttumSteps = _fMomentumSteps;
+
+ //Momentum rotation
+ vec2 v = _vDragDelta;
+ beginDrag(vec2() ); //NOTE:This call reset _VDragDelta
+ drag(v * _vFlip);
+
+ //Momentum shift
+ _vecOffset += _vecOffsetDelta;
+
+ ballUpdate();
+ endDrag();
+
+ //Decrease deltas
+ _vDragDelta = v * MOMENTUM_FACTOR_DECREASE;
+ _vecOffsetDelta = _vecOffsetDelta * MOMENTUM_FACTOR_DECREASE_SHIFT;
+
+ //Count steps
+ _fMomentumSteps = fMomenttumSteps * MOMENTUM_FACTOR_DECREASE;
+ if( _fMomentumSteps < MOMENTUM_FACTOR_THRESHOLD )
+ {
+ _bMomentum = false;
+ }
+ }
+ else
+ {
+ _vDragDelta *= MOMENTUM_FACTOR;
+ _vecOffsetDelta = _vecOffsetDelta * MOMENTUM_FACTOR;
+ ballUpdate();
+ }
+
+ vec3 vec = _vecOffset + _vecOffsetNow;
+ vec3 vecTmp(TRANSFORM_FACTOR, -TRANSFORM_FACTOR, TRANSFORM_FACTORZ);
+
+ vec *= vecTmp * _vPinchTransformFactor;
+
+ _mTransform = mat4::translation(vec);
+}
+
+mat4& tapCamera::getRotationMatrix()
+{
+ return _mRotation;
+}
+
+mat4& tapCamera::getTransformMatrix()
+{
+ return _mTransform;
+}
+
+void tapCamera::reset(const bool bAnimate)
+{
+ initParameters();
+ update();
+
+}
+
+//----------------------------------------------------------
+//Drag control
+//----------------------------------------------------------
+void tapCamera::beginDrag(const vec2& v)
+{
+ if( _bDragging )
+ endDrag();
+
+ if( _bPinching )
+ endPinch();
+
+ vec2 vec = v * _vFlip;
+ _vBallNow = vec;
+ _vBallDown = _vBallNow;
+
+ _bDragging = true;
+ _bMomentum = false;
+ _vLastInput = vec;
+ _vDragDelta = vec2();
+}
+
+void tapCamera::endDrag()
+{
+ int i;
+ _qBallDown = _qBallNow;
+ _qBallRot = quaternion();
+
+ _bDragging = false;
+ _bMomentum = true;
+ _fMomentumSteps = 1.0f;
+}
+
+void tapCamera::drag(const vec2& v )
+{
+ if( !_bDragging )
+ return;
+
+ vec2 vec = v * _vFlip;
+ _vBallNow = vec;
+
+ _vDragDelta = _vDragDelta * MOMENTUM_FACTOR + (vec - _vLastInput);
+ _vLastInput = vec;
+}
+
+//----------------------------------------------------------
+//Pinch controll
+//----------------------------------------------------------
+void tapCamera::beginPinch(const vec2& v1, const vec2& v2)
+{
+ if( _bDragging )
+ endDrag();
+
+ if( _bPinching )
+ endPinch();
+
+ beginDrag( vec2() );
+
+ _vecPinchStartCenter = (v1 + v2) / 2.f;
+
+ vec2 vec = v1 - v2;
+ float fXDiff;
+ float fYDiff;
+ vec.value( fXDiff, fYDiff );
+
+ _fPinchStartDistanceSQ = fXDiff*fXDiff + fYDiff*fYDiff;
+ _fRotationStart = atan2f( fYDiff, fXDiff );
+ _fRotationNow = 0;
+
+ _bPinching = true;
+ _bMomentum = false;
+
+ //Init momentum factors
+ _vecOffsetDelta = vec3();
+}
+
+
+void tapCamera::endPinch()
+{
+ _bPinching = false;
+ _bMomentum = true;
+ _fMomentumSteps = 1.f;
+ _vecOffset += _vecOffsetNow;
+ _fRotation += _fRotationNow;
+ _vecOffsetNow = vec3();
+
+ _fRotationNow = 0;
+
+ endDrag();
+}
+
+void tapCamera::pinch(const vec2& v1, const vec2& v2)
+{
+ if( !_bPinching )
+ return;
+
+ //Update momentum factor
+ _vecOffsetLast = _vecOffsetNow;
+
+ float fXDiff, fYDiff;
+ vec2 vec = v1 - v2;
+ vec.value(fXDiff, fYDiff);
+
+ float fDistanceSQ = fXDiff * fXDiff + fYDiff * fYDiff;
+
+ float f = _fPinchStartDistanceSQ / fDistanceSQ;
+ if( f < 1.f)
+ f = -1.f / f + 1.0f;
+ else
+ f = f - 1.f;
+ if( isnan(f) ) f = 0.f;
+
+ vec = (v1 + v2) / 2.f - _vecPinchStartCenter;
+ _vecOffsetNow = vec3( vec,
+ _fFlipZ * f );
+
+ //Update momentum factor
+ _vecOffsetDelta = _vecOffsetDelta * MOMENTUM_FACTOR + (_vecOffsetNow - _vecOffsetLast);
+
+ //
+ //Update ration quaternion
+ float fRotation = atan2f( fYDiff, fXDiff );
+ _fRotationNow = fRotation - _fRotationStart;
+
+ //Trackball rotation
+ _qBallRot = quaternion( 0.f, 0.f, sinf(-_fRotationNow*0.5f), cosf(-_fRotationNow*0.5f) );
+}
+
+//----------------------------------------------------------
+//Trackball controll
+//----------------------------------------------------------
+void tapCamera::ballUpdate()
+{
+ if (_bDragging) {
+ vec3 vFrom = pointOnSphere(_vBallDown);
+ vec3 vTo = pointOnSphere(_vBallNow);
+
+ vec3 vec = vFrom.cross(vTo);
+ float w = vFrom.dot( vTo );
+
+ quaternion qDrag = quaternion(vec, w);
+ qDrag = qDrag * _qBallDown;
+ _qBallNow = _qBallRot * qDrag;
+ }
+ _qBallNow.toMatrix(_mRotation);
+}
+
+vec3 tapCamera::pointOnSphere(vec2& point)
+{
+ vec3 ballMouse;
+ float mag;
+ vec2 vec = (point - _vBallCenter) / _fBallRadius;
+ mag = vec.dot( vec );
+ if (mag > 1.f)
+ {
+ float scale = 1.f / sqrtf(mag);
+ vec *= scale;
+ ballMouse = vec3( vec, 0.f );
+ } else {
+ ballMouse = vec3( vec, sqrtf(1.f - mag) );
+ }
+ return (ballMouse);
+}
diff --git a/ndk/sources/android/helper/tapCamera.h b/ndk/sources/android/helper/tapCamera.h
new file mode 100644
index 000000000..0c013c54d
--- /dev/null
+++ b/ndk/sources/android/helper/tapCamera.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#pragma once
+#include <vector>
+#include <string>
+#include <GLES2/gl2.h>
+
+#include "JNIHelper.h"
+#include "vecmath.h"
+#include "interpolator.h"
+
+/******************************************************************
+ * Camera control helper class with a tap gesture
+ * This class is mainly used for 3D space camera control in samples.
+ *
+ */
+class tapCamera
+{
+private:
+ //Trackball
+ vec2 _vBallCenter;
+ float _fBallRadius;
+ quaternion _qBallNow;
+ quaternion _qBallDown;
+ vec2 _vBallNow;
+ vec2 _vBallDown;
+ quaternion _qBallRot;
+
+ bool _bDragging;
+ bool _bPinching;
+
+ //Pinch related info
+ vec2 _vecPinchStart;
+ vec2 _vecPinchStartCenter;
+ float _fPinchStartDistanceSQ;
+
+ //Camera shift
+ vec3 _vecOffset;
+ vec3 _vecOffsetNow;
+
+ //Camera Rotation
+ float _fRotation;
+ float _fRotationStart;
+ float _fRotationNow;
+
+ //Momentum support
+ bool _bMomentum;
+ vec2 _vDragDelta;
+ vec2 _vLastInput;
+ vec3 _vecOffsetLast;
+ vec3 _vecOffsetDelta;
+ float _fMomentumSteps;
+
+ vec2 _vFlip;
+ float _fFlipZ;
+
+ mat4 _mRotation;
+ mat4 _mTransform;
+
+ vec3 pointOnSphere(vec2& point);
+ void ballUpdate();
+ void initParameters();
+
+ vec3 _vPinchTransformFactor;
+
+public:
+ tapCamera();
+ virtual ~tapCamera();
+ void beginDrag(const vec2& vec);
+ void endDrag();
+ void drag(const vec2& vec);
+ void update();
+
+ mat4& getRotationMatrix();
+ mat4& getTransformMatrix();
+
+ void beginPinch(const vec2& v1, const vec2& v2);
+ void endPinch();
+ void pinch(const vec2& v1, const vec2& v2);
+
+ void setFlip(const float fX, const float fY, const float fZ)
+ {
+ _vFlip = vec2( fX, fY );
+ _fFlipZ = fZ;
+ }
+
+ void setPinchTransformFactor(const float fX, const float fY, const float fZ)
+ {
+ _vPinchTransformFactor = vec3( fX, fY, fZ);
+ }
+
+ void reset(const bool bAnimate);
+
+};
diff --git a/ndk/sources/android/helper/vecmath.cpp b/ndk/sources/android/helper/vecmath.cpp
new file mode 100644
index 000000000..1008523dc
--- /dev/null
+++ b/ndk/sources/android/helper/vecmath.cpp
@@ -0,0 +1,265 @@
+/*
+ * Copyright 2013 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.
+ */
+
+//--------------------------------------------------------------------------------
+// vecmath.cpp
+//--------------------------------------------------------------------------------
+
+#include "vecmath.h"
+
+//--------------------------------------------------------------------------------
+// vec3
+//--------------------------------------------------------------------------------
+vec3::vec3(const vec4& vec)
+{
+ x = vec.x; y = vec.y; z = vec.z;
+}
+
+//--------------------------------------------------------------------------------
+// vec4
+//--------------------------------------------------------------------------------
+vec4 vec4::operator*(const mat4& rhs) const
+{
+ vec4 out;
+ out.x = x * rhs.f[0] + y * rhs.f[1] + z * rhs.f[2] + w * rhs.f[3];
+ out.y = x * rhs.f[4] + y * rhs.f[5] + z * rhs.f[6] + w * rhs.f[7];
+ out.z = x * rhs.f[8] + y * rhs.f[9] + z * rhs.f[10] + w * rhs.f[11];
+ out.w = x * rhs.f[12] + y * rhs.f[13] + z * rhs.f[14] + w * rhs.f[15];
+ return out;
+}
+
+//--------------------------------------------------------------------------------
+// mat4
+//--------------------------------------------------------------------------------
+mat4::mat4()
+{
+ for(int32_t i = 0; i < 16; ++i)
+ f[i] = 0.f;
+}
+
+mat4::mat4(const float* mIn )
+{
+ for(int32_t i = 0; i < 16; ++i)
+ f[i] = mIn[i];
+}
+
+mat4 mat4::operator*(const mat4& rhs) const
+{
+ mat4 ret;
+ ret.f[0] = f[0]*rhs.f[0] + f[4]*rhs.f[1] + f[8]*rhs.f[2] + f[12]*rhs.f[3];
+ ret.f[1] = f[1]*rhs.f[0] + f[5]*rhs.f[1] + f[9]*rhs.f[2] + f[13]*rhs.f[3];
+ ret.f[2] = f[2]*rhs.f[0] + f[6]*rhs.f[1] + f[10]*rhs.f[2] + f[14]*rhs.f[3];
+ ret.f[3] = f[3]*rhs.f[0] + f[7]*rhs.f[1] + f[11]*rhs.f[2] + f[15]*rhs.f[3];
+
+ ret.f[4] = f[0]*rhs.f[4] + f[4]*rhs.f[5] + f[8]*rhs.f[6] + f[12]*rhs.f[7];
+ ret.f[5] = f[1]*rhs.f[4] + f[5]*rhs.f[5] + f[9]*rhs.f[6] + f[13]*rhs.f[7];
+ ret.f[6] = f[2]*rhs.f[4] + f[6]*rhs.f[5] + f[10]*rhs.f[6] + f[14]*rhs.f[7];
+ ret.f[7] = f[3]*rhs.f[4] + f[7]*rhs.f[5] + f[11]*rhs.f[6] + f[15]*rhs.f[7];
+
+ ret.f[8] = f[0]*rhs.f[8] + f[4]*rhs.f[9] + f[8]*rhs.f[10] + f[12]*rhs.f[11];
+ ret.f[9] = f[1]*rhs.f[8] + f[5]*rhs.f[9] + f[9]*rhs.f[10] + f[13]*rhs.f[11];
+ ret.f[10] = f[2]*rhs.f[8] + f[6]*rhs.f[9] + f[10]*rhs.f[10] + f[14]*rhs.f[11];
+ ret.f[11] = f[3]*rhs.f[8] + f[7]*rhs.f[9] + f[11]*rhs.f[10] + f[15]*rhs.f[11];
+
+ ret.f[12] = f[0]*rhs.f[12] + f[4]*rhs.f[13] + f[8]*rhs.f[14] + f[12]*rhs.f[15];
+ ret.f[13] = f[1]*rhs.f[12] + f[5]*rhs.f[13] + f[9]*rhs.f[14] + f[13]*rhs.f[15];
+ ret.f[14] = f[2]*rhs.f[12] + f[6]*rhs.f[13] + f[10]*rhs.f[14] + f[14]*rhs.f[15];
+ ret.f[15] = f[3]*rhs.f[12] + f[7]*rhs.f[13] + f[11]*rhs.f[14] + f[15]*rhs.f[15];
+
+ return ret;
+}
+
+vec4 mat4::operator*(const vec4& rhs) const
+{
+ vec4 ret;
+ ret.x = rhs.x*f[0] + rhs.y*f[4] + rhs.z*f[8] + rhs.w*f[12];
+ ret.y = rhs.x*f[1] + rhs.y*f[5] + rhs.z*f[9] + rhs.w*f[13];
+ ret.z = rhs.x*f[2] + rhs.y*f[6] + rhs.z*f[10] + rhs.w*f[14];
+ ret.w = rhs.x*f[3] + rhs.y*f[7] + rhs.z*f[11] + rhs.w*f[15];
+ return ret;
+}
+
+mat4 mat4::inverse()
+{
+ mat4 ret;
+ float det_1;
+ float pos = 0;
+ float neg = 0;
+ float temp;
+
+ temp = f[0] * f[5] * f[10];
+ if (temp >= 0) pos += temp; else neg += temp;
+ temp = f[4] * f[9] * f[2];
+ if (temp >= 0) pos += temp; else neg += temp;
+ temp = f[8] * f[1] * f[6];
+ if (temp >= 0) pos += temp; else neg += temp;
+ temp = -f[8] * f[5] * f[2];
+ if (temp >= 0) pos += temp; else neg += temp;
+ temp = -f[4] * f[1] * f[10];
+ if (temp >= 0) pos += temp; else neg += temp;
+ temp = -f[0] * f[9] * f[6];
+ if (temp >= 0) pos += temp; else neg += temp;
+ det_1 = pos + neg;
+
+ if (det_1 == 0.0)
+ {
+ //Error
+ }
+ else
+ {
+ det_1 = 1.0f / det_1;
+ ret.f[0] = ( f[ 5] * f[10] - f[ 9] * f[ 6] ) * det_1;
+ ret.f[1] = -( f[ 1] * f[10] - f[ 9] * f[ 2] ) * det_1;
+ ret.f[2] = ( f[ 1] * f[ 6] - f[ 5] * f[ 2] ) * det_1;
+ ret.f[4] = -( f[ 4] * f[10] - f[ 8] * f[ 6] ) * det_1;
+ ret.f[5] = ( f[ 0] * f[10] - f[ 8] * f[ 2] ) * det_1;
+ ret.f[6] = -( f[ 0] * f[ 6] - f[ 4] * f[ 2] ) * det_1;
+ ret.f[8] = ( f[ 4] * f[ 9] - f[ 8] * f[ 5] ) * det_1;
+ ret.f[9] = -( f[ 0] * f[ 9] - f[ 8] * f[ 1] ) * det_1;
+ ret.f[10] = ( f[ 0] * f[ 5] - f[ 4] * f[ 1] ) * det_1;
+
+ /* Calculate -C * inverse(A) */
+ ret.f[12] = - ( f[12] *ret.f[0] + f[13] * ret.f[4] + f[14] *ret.f[8] );
+ ret.f[13] = - ( f[12] * ret.f[1] + f[13] * ret.f[5] + f[14] * ret.f[9] );
+ ret.f[14] = - ( f[12] * ret.f[2] + f[13] * ret.f[6] + f[14] * ret.f[10] );
+
+ ret.f[ 3] = 0.0f;
+ ret.f[ 7] = 0.0f;
+ ret.f[11] = 0.0f;
+ ret.f[15] = 1.0f;
+ }
+
+ *this = ret;
+ return *this;
+}
+
+//--------------------------------------------------------------------------------
+// Misc
+//--------------------------------------------------------------------------------
+mat4 mat4::rotationX(
+ const float fAngle)
+{
+ mat4 ret;
+ float fCosine, fSine;
+
+ fCosine = cosf(fAngle);
+ fSine = sinf(fAngle);
+
+ ret.f[ 0]=1.0f; ret.f[ 4]=0.0f; ret.f[ 8]=0.0f; ret.f[12]=0.0f;
+ ret.f[ 1]=0.0f; ret.f[ 5]=fCosine; ret.f[ 9]=fSine; ret.f[13]=0.0f;
+ ret.f[ 2]=0.0f; ret.f[ 6]=-fSine; ret.f[10]=fCosine; ret.f[14]=0.0f;
+ ret.f[ 3]=0.0f; ret.f[ 7]=0.0f; ret.f[11]=0.0f; ret.f[15]=1.0f;
+ return ret;
+}
+
+mat4 mat4::rotationY(
+ const float fAngle)
+{
+ mat4 ret;
+ float fCosine, fSine;
+
+ fCosine = cosf(fAngle);
+ fSine = sinf(fAngle);
+
+ ret.f[ 0]=fCosine; ret.f[ 4]=0.0f; ret.f[ 8]=-fSine; ret.f[12]=0.0f;
+ ret.f[ 1]=0.0f; ret.f[ 5]=1.0f; ret.f[ 9]=0.0f; ret.f[13]=0.0f;
+ ret.f[ 2]=fSine; ret.f[ 6]=0.0f; ret.f[10]=fCosine; ret.f[14]=0.0f;
+ ret.f[ 3]=0.0f; ret.f[ 7]=0.0f; ret.f[11]=0.0f; ret.f[15]=1.0f;
+ return ret;
+
+}
+
+mat4 mat4::rotationZ(
+ const float fAngle)
+{
+ mat4 ret;
+ float fCosine, fSine;
+
+ fCosine = cosf(fAngle);
+ fSine = sinf(fAngle);
+
+ ret.f[ 0]=fCosine; ret.f[ 4]=fSine; ret.f[ 8]=0.0f; ret.f[12]=0.0f;
+ ret.f[ 1]=-fSine; ret.f[ 5]=fCosine; ret.f[ 9]=0.0f; ret.f[13]=0.0f;
+ ret.f[ 2]=0.0f; ret.f[ 6]=0.0f; ret.f[10]=1.0f; ret.f[14]=0.0f;
+ ret.f[ 3]=0.0f; ret.f[ 7]=0.0f; ret.f[11]=0.0f; ret.f[15]=1.0f;
+ return ret;
+}
+
+mat4 mat4::translation(
+ const float fX,
+ const float fY,
+ const float fZ)
+{
+ mat4 ret;
+ ret.f[ 0]=1.0f; ret.f[ 4]=0.0f; ret.f[ 8]=0.0f; ret.f[12]=fX;
+ ret.f[ 1]=0.0f; ret.f[ 5]=1.0f; ret.f[ 9]=0.0f; ret.f[13]=fY;
+ ret.f[ 2]=0.0f; ret.f[ 6]=0.0f; ret.f[10]=1.0f; ret.f[14]=fZ;
+ ret.f[ 3]=0.0f; ret.f[ 7]=0.0f; ret.f[11]=0.0f; ret.f[15]=1.0f;
+ return ret;
+}
+
+mat4 mat4::translation(
+ const vec3 vec)
+{
+ mat4 ret;
+ ret.f[ 0]=1.0f; ret.f[ 4]=0.0f; ret.f[ 8]=0.0f; ret.f[12]=vec.x;
+ ret.f[ 1]=0.0f; ret.f[ 5]=1.0f; ret.f[ 9]=0.0f; ret.f[13]=vec.y;
+ ret.f[ 2]=0.0f; ret.f[ 6]=0.0f; ret.f[10]=1.0f; ret.f[14]=vec.z;
+ ret.f[ 3]=0.0f; ret.f[ 7]=0.0f; ret.f[11]=0.0f; ret.f[15]=1.0f;
+ return ret;
+}
+
+mat4 mat4::perspective(
+ float width,
+ float height,
+ float nearPlane, float farPlane)
+{
+ float n2 = 2.0f * nearPlane;
+ float rcpnmf = 1.f/(nearPlane - farPlane);
+
+ mat4 result;
+ result.f[0] = n2 / width; result.f[4] = 0; result.f[8] = 0; result.f[12] = 0;
+ result.f[1] = 0; result.f[5] = n2 / height; result.f[9] = 0; result.f[13] = 0;
+ result.f[2] = 0; result.f[6] = 0; result.f[10] = (farPlane+nearPlane)*rcpnmf; result.f[14] = farPlane*rcpnmf*n2;
+ result.f[3] = 0; result.f[7] = 0; result.f[11] = -1.0; result.f[15]=0;
+
+ return result;
+}
+
+mat4 mat4::lookAt(const vec3& vEye, const vec3& vAt, const vec3& vUp)
+{
+ vec3 vForward, vUpNorm, vSide;
+ mat4 result;
+
+ vForward.x = vEye.x - vAt.x;
+ vForward.y = vEye.y - vAt.y;
+ vForward.z = vEye.z - vAt.z;
+
+ vForward.normalize();
+ vUpNorm = vUp;
+ vUpNorm.normalize();
+ vSide = vUpNorm.cross( vForward);
+ vUpNorm = vForward.cross(vSide);
+
+ result.f[0]=vSide.x; result.f[4]=vSide.y; result.f[8]=vSide.z; result.f[12]=0;
+ result.f[1]=vUpNorm.x; result.f[5]=vUpNorm.y; result.f[9]=vUpNorm.z; result.f[13]=0;
+ result.f[2]=vForward.x; result.f[6]=vForward.y; result.f[10]=vForward.z; result.f[14]=0;
+ result.f[3]=0; result.f[7]=0; result.f[11]=0; result.f[15]=1.0;
+
+ result.postTranslate(-vEye.x, -vEye.y, -vEye.z);
+ return result;
+}
+
diff --git a/ndk/sources/android/helper/vecmath.h b/ndk/sources/android/helper/vecmath.h
new file mode 100644
index 000000000..a959dff6e
--- /dev/null
+++ b/ndk/sources/android/helper/vecmath.h
@@ -0,0 +1,1051 @@
+/*
+ * Copyright 2013 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.
+ */
+
+#ifndef VECMATH_H_
+#define VECMATH_H_
+
+#include <math.h>
+#include "JNIHelper.h"
+
+/******************************************************************
+ * Helper class for vector math operations
+ * Currently all implementations are in pure C++.
+ * Each class is an opaque class so caller does not have a direct access
+ * to each element. This is for an ease of future optimization to use vector operations.
+ *
+ */
+
+class vec2;
+class vec3;
+class vec4;
+class mat4;
+
+/******************************************************************
+ * 2 elements vector class
+ *
+ */
+class vec2
+{
+private:
+ float x,y;
+
+public:
+ friend class vec3;
+ friend class vec4;
+ friend class mat4;
+ friend class quaternion;
+
+ vec2()
+ {
+ x = y = 0.f;
+ }
+
+ vec2(const float fX, const float fY)
+ {
+ x = fX; y = fY;
+ }
+
+ vec2(const vec2& vec)
+ {
+ x = vec.x;
+ y = vec.y;
+ }
+
+ vec2(const float* pVec)
+ {
+ x = (*pVec++); y = (*pVec++);
+ }
+
+ //Operators
+ vec2 operator*(const vec2& rhs) const
+ {
+ vec2 ret;
+ ret.x = x*rhs.x;
+ ret.y = y*rhs.y;
+ return ret;
+ }
+
+ vec2 operator/(const vec2& rhs) const
+ {
+ vec2 ret;
+ ret.x = x/rhs.x;
+ ret.y = y/rhs.y;
+ return ret;
+ }
+
+ vec2 operator+(const vec2& rhs) const
+ {
+ vec2 ret;
+ ret.x = x + rhs.x;
+ ret.y = y + rhs.y;
+ return ret;
+ }
+
+ vec2 operator-(const vec2& rhs) const
+ {
+ vec2 ret;
+ ret.x = x - rhs.x;
+ ret.y = y - rhs.y;
+ return ret;
+ }
+
+ vec2& operator+=(const vec2& rhs)
+ {
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+ }
+
+ vec2& operator-=(const vec2& rhs)
+ {
+ x -= rhs.x;
+ y -= rhs.y;
+ return *this;
+ }
+
+ vec2& operator*=(const vec2& rhs)
+ {
+ x *= rhs.x;
+ y *= rhs.y;
+ return *this;
+ }
+
+ vec2& operator/=(const vec2& rhs)
+ {
+ x /= rhs.x;
+ y /= rhs.y;
+ return *this;
+ }
+
+ //External operators
+ friend vec2 operator-(const vec2& rhs) { return vec2(rhs) *= -1; }
+
+ friend vec2 operator*(const float lhs, const vec2& rhs)
+ {
+ vec2 ret;
+ ret.x = lhs * rhs.x;
+ ret.y = lhs * rhs.y;
+ return ret;
+ }
+
+ friend vec2 operator/(const float lhs, const vec2& rhs)
+ {
+ vec2 ret;
+ ret.x = lhs / rhs.x;
+ ret.y = lhs / rhs.y;
+ return ret;
+ }
+
+ //Operators with float
+ vec2 operator*(const float& rhs) const
+ {
+ vec2 ret;
+ ret.x = x * rhs;
+ ret.y = y * rhs;
+ return ret;
+ }
+
+ vec2& operator*=(const float& rhs)
+ {
+ x = x * rhs;
+ y = y * rhs;
+ return *this;
+ }
+
+ vec2 operator/(const float& rhs) const
+ {
+ vec2 ret;
+ ret.x = x / rhs;
+ ret.y = y / rhs;
+ return ret;
+ }
+
+ vec2& operator/=(const float& rhs)
+ {
+ x = x / rhs;
+ y = y / rhs;
+ return *this;
+ }
+
+ //Compare
+ bool operator==(const vec2& rhs) const
+ {
+ if(x != rhs.x || y != rhs.y ) return false;
+ return true;
+ }
+
+ bool operator!=(const vec2& rhs) const
+ {
+ if(x == rhs.x)
+ return false;
+
+ return true;
+ }
+
+ float length() const
+ {
+ return sqrtf(x*x + y*y);
+ }
+
+ vec2 normalize()
+ {
+ float len = length();
+ x = x / len;
+ y = y / len;
+ return *this;
+ }
+
+ float dot(const vec2& rhs)
+ {
+ return x * rhs.x + y*rhs.y;
+ }
+
+ bool validate()
+ {
+ if( isnan( x ) || isnan( y ) )
+ return false;
+ return true;
+ }
+
+ void value(float& fX, float& fY)
+ {
+ fX = x;
+ fY = y;
+ }
+
+ void dump()
+ {
+ LOGI("vec2 %f %f", x, y);
+ }
+};
+
+/******************************************************************
+ * 3 elements vector class
+ *
+ */
+class vec3
+{
+private:
+ float x,y,z;
+
+public:
+ friend class vec4;
+ friend class mat4;
+ friend class quaternion;
+
+ vec3()
+ {
+ x = y = z = 0.f;
+ }
+
+ vec3(const float fX, const float fY, const float fZ)
+ {
+ x = fX; y = fY; z = fZ;
+ }
+
+ vec3(const vec3& vec)
+ {
+ x = vec.x;
+ y = vec.y;
+ z = vec.z;
+ }
+
+ vec3(const float* pVec)
+ {
+ x = (*pVec++); y = (*pVec++); z = *pVec;
+ }
+
+ vec3(const vec2& vec, float f )
+ {
+ x = vec.x;
+ y = vec.y;
+ z = f;
+ }
+
+ vec3(const vec4& vec );
+
+ //Operators
+ vec3 operator*(const vec3& rhs) const
+ {
+ vec3 ret;
+ ret.x = x*rhs.x;
+ ret.y = y*rhs.y;
+ ret.z = z*rhs.z;
+ return ret;
+ }
+
+ vec3 operator/(const vec3& rhs) const
+ {
+ vec3 ret;
+ ret.x = x/rhs.x;
+ ret.y = y/rhs.y;
+ ret.z = z/rhs.z;
+ return ret;
+ }
+
+ vec3 operator+(const vec3& rhs) const
+ {
+ vec3 ret;
+ ret.x = x + rhs.x;
+ ret.y = y + rhs.y;
+ ret.z = z + rhs.z;
+ return ret;
+ }
+
+ vec3 operator-(const vec3& rhs) const
+ {
+ vec3 ret;
+ ret.x = x - rhs.x;
+ ret.y = y - rhs.y;
+ ret.z = z - rhs.z;
+ return ret;
+ }
+
+ vec3& operator+=(const vec3& rhs)
+ {
+ x += rhs.x;
+ y += rhs.y;
+ z += rhs.z;
+ return *this;
+ }
+
+ vec3& operator-=(const vec3& rhs)
+ {
+ x -= rhs.x;
+ y -= rhs.y;
+ z -= rhs.z;
+ return *this;
+ }
+
+ vec3& operator*=(const vec3& rhs)
+ {
+ x *= rhs.x;
+ y *= rhs.y;
+ z *= rhs.z;
+ return *this;
+ }
+
+ vec3& operator/=(const vec3& rhs)
+ {
+ x /= rhs.x;
+ y /= rhs.y;
+ z /= rhs.z;
+ return *this;
+ }
+
+ //External operators
+ friend vec3 operator-(const vec3& rhs) { return vec3(rhs) *= -1; }
+
+ friend vec3 operator*(const float lhs, const vec3& rhs)
+ {
+ vec3 ret;
+ ret.x = lhs * rhs.x;
+ ret.y = lhs * rhs.y;
+ ret.z = lhs * rhs.z;
+ return ret;
+ }
+
+ friend vec3 operator/(const float lhs, const vec3& rhs)
+ {
+ vec3 ret;
+ ret.x = lhs / rhs.x;
+ ret.y = lhs / rhs.y;
+ ret.z = lhs / rhs.z;
+ return ret;
+ }
+
+ //Operators with float
+ vec3 operator*(const float& rhs) const
+ {
+ vec3 ret;
+ ret.x = x * rhs;
+ ret.y = y * rhs;
+ ret.z = z * rhs;
+ return ret;
+ }
+
+ vec3& operator*=(const float& rhs)
+ {
+ x = x * rhs;
+ y = y * rhs;
+ z = z * rhs;
+ return *this;
+ }
+
+ vec3 operator/(const float& rhs) const
+ {
+ vec3 ret;
+ ret.x = x / rhs;
+ ret.y = y / rhs;
+ ret.z = z / rhs;
+ return ret;
+ }
+
+ vec3& operator/=(const float& rhs)
+ {
+ x = x / rhs;
+ y = y / rhs;
+ z = z / rhs;
+ return *this;
+ }
+
+ //Compare
+ bool operator==(const vec3& rhs) const
+ {
+ if(x != rhs.x || y != rhs.y || z != rhs.z) return false;
+ return true;
+ }
+
+ bool operator!=(const vec3& rhs) const
+ {
+ if(x == rhs.x)
+ return false;
+
+ return true;
+ }
+
+ float length() const
+ {
+ return sqrtf(x*x + y*y + z*z);
+ }
+
+ vec3 normalize()
+ {
+ float len = length();
+ x = x / len;
+ y = y / len;
+ z = z / len;
+ return *this;
+ }
+
+ float dot(const vec3& rhs)
+ {
+ return x * rhs.x + y*rhs.y + z*rhs.z;
+ }
+
+ vec3 cross(const vec3& rhs)
+ {
+ vec3 ret;
+ ret.x = y*rhs.z - z*rhs.y;
+ ret.y = z*rhs.x - x*rhs.z;
+ ret.z = x*rhs.y - y*rhs.x;
+ return ret;
+ }
+
+ bool validate()
+ {
+ if( isnan( x ) || isnan( y ) || isnan( z ) )
+ return false;
+ return true;
+ }
+
+ void value(float& fX, float& fY, float& fZ)
+ {
+ fX = x;
+ fY = y;
+ fZ = z;
+ }
+
+ void dump()
+ {
+ LOGI("vec3 %f %f %f", x, y, z);
+ }
+};
+
+/******************************************************************
+ * 4 elements vector class
+ *
+ */
+class vec4
+{
+private:
+ float x,y,z,w;
+
+public:
+ friend class vec3;
+ friend class mat4;
+ friend class quaternion;
+
+ vec4()
+ {
+ x = y = z = w = 0.f;
+ }
+
+ vec4(const float fX, const float fY, const float fZ, const float fW )
+ {
+ x = fX; y = fY; z = fZ; w = fW;
+ }
+
+ vec4(const vec4& vec)
+ {
+ x = vec.x;
+ y = vec.y;
+ z = vec.z;
+ w = vec.w;
+ }
+
+ vec4(const vec3& vec, const float fW )
+ {
+ x = vec.x; y = vec.y; z = vec.z; w = fW;
+ }
+
+ vec4(const float* pVec)
+ {
+ x = (*pVec++); y = (*pVec++); z = *pVec; w = *pVec;
+ }
+
+ //Operators
+ vec4 operator*(const vec4& rhs) const
+ {
+ vec4 ret;
+ ret.x = x*rhs.x;
+ ret.y = y*rhs.y;
+ ret.z = z*rhs.z;
+ ret.w = z*rhs.w;
+ return ret;
+ }
+
+ vec4 operator/(const vec4& rhs) const
+ {
+ vec4 ret;
+ ret.x = x/rhs.x;
+ ret.y = y/rhs.y;
+ ret.z = z/rhs.z;
+ ret.w = z/rhs.w;
+ return ret;
+ }
+
+ vec4 operator+(const vec4& rhs) const
+ {
+ vec4 ret;
+ ret.x = x+rhs.x;
+ ret.y = y+rhs.y;
+ ret.z = z+rhs.z;
+ ret.w = z+rhs.w;
+ return ret;
+ }
+
+ vec4 operator-(const vec4& rhs) const
+ {
+ vec4 ret;
+ ret.x = x-rhs.x;
+ ret.y = y-rhs.y;
+ ret.z = z-rhs.z;
+ ret.w = z-rhs.w;
+ return ret;
+ }
+
+ vec4& operator+=(const vec4& rhs)
+ {
+ x += rhs.x;
+ y += rhs.y;
+ z += rhs.z;
+ w += rhs.w;
+ return *this;
+ }
+
+ vec4& operator-=(const vec4& rhs)
+ {
+ x -= rhs.x;
+ y -= rhs.y;
+ z -= rhs.z;
+ w -= rhs.w;
+ return *this;
+ }
+
+ vec4& operator*=(const vec4& rhs)
+ {
+ x *= rhs.x;
+ y *= rhs.y;
+ z *= rhs.z;
+ w *= rhs.w;
+ return *this;
+ }
+
+ vec4& operator/=(const vec4& rhs)
+ {
+ x /= rhs.x;
+ y /= rhs.y;
+ z /= rhs.z;
+ w /= rhs.w;
+ return *this;
+ }
+
+ //External operators
+ friend vec4 operator-(const vec4& rhs) { return vec4(rhs) *= -1; }
+
+ friend vec4 operator*(const float lhs, const vec4& rhs)
+ {
+ vec4 ret;
+ ret.x = lhs * rhs.x;
+ ret.y = lhs * rhs.y;
+ ret.z = lhs * rhs.z;
+ ret.w = lhs * rhs.w;
+ return ret;
+ }
+
+ friend vec4 operator/(const float lhs, const vec4& rhs)
+ {
+ vec4 ret;
+ ret.x = lhs / rhs.x;
+ ret.y = lhs / rhs.y;
+ ret.z = lhs / rhs.z;
+ ret.w = lhs / rhs.w;
+ return ret;
+ }
+
+ //Operators with float
+ vec4 operator*(const float& rhs) const
+ {
+ vec4 ret;
+ ret.x = x * rhs;
+ ret.y = y * rhs;
+ ret.z = z * rhs;
+ ret.w = w * rhs;
+ return ret;
+ }
+
+ vec4& operator*=(const float& rhs)
+ {
+ x = x * rhs;
+ y = y * rhs;
+ z = z * rhs;
+ w = w * rhs;
+ return *this;
+ }
+
+ vec4 operator/(const float& rhs) const
+ {
+ vec4 ret;
+ ret.x = x / rhs;
+ ret.y = y / rhs;
+ ret.z = z /rhs;
+ ret.w = w /rhs;
+ return ret;
+ }
+
+ vec4& operator/=(const float& rhs)
+ {
+ x = x / rhs;
+ y = y / rhs;
+ z = z / rhs;
+ w = w / rhs;
+ return *this;
+ }
+
+ //Compare
+ bool operator==(const vec4& rhs) const
+ {
+ if(x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w) return false;
+ return true;
+ }
+
+ bool operator!=(const vec4& rhs) const
+ {
+ if(x == rhs.x)
+ return false;
+
+ return true;
+ }
+
+ vec4 operator*(const mat4& rhs) const;
+
+ float length() const
+ {
+ return sqrtf(x*x + y*y + z*z + w*w);
+ }
+
+ vec4 normalize()
+ {
+ float len = length();
+ x = x / len;
+ y = y / len;
+ z = z / len;
+ w = w / len;
+ return *this;
+ }
+
+ float dot(const vec3& rhs)
+ {
+ return x * rhs.x + y*rhs.y + z*rhs.z;
+ }
+
+ vec3 cross(const vec3& rhs)
+ {
+ vec3 ret;
+ ret.x = y*rhs.z - z*rhs.y;
+ ret.y = z*rhs.x - x*rhs.z;
+ ret.z = x*rhs.y - y*rhs.x;
+ return ret;
+ }
+
+ bool validate()
+ {
+ if( isnan( x ) || isnan( y ) || isnan( z ) || isnan( w ))
+ return false;
+ return true;
+ }
+
+ void value(float& fX, float& fY, float& fZ, float& fW)
+ {
+ fX = x;
+ fY = y;
+ fZ = z;
+ fW = w;
+ }
+};
+
+/******************************************************************
+ * 4x4 matrix
+ *
+ */
+class mat4
+{
+private:
+ float f[16];
+
+public:
+ friend class vec3;
+ friend class vec4;
+ friend class quaternion;
+
+ mat4();
+ mat4(const float*);
+
+ mat4 operator*(const mat4& rhs) const;
+ vec4 operator*(const vec4& rhs) const;
+
+ mat4 operator+(const mat4& rhs) const
+ {
+ mat4 ret;
+ for(int32_t i=0; i < 16; ++i)
+ {
+ ret.f[i] = f[i] + rhs.f[i];
+ }
+ return ret;
+ }
+
+ mat4 operator-(const mat4& rhs) const
+ {
+ mat4 ret;
+ for(int32_t i=0; i < 16; ++i)
+ {
+ ret.f[i] = f[i] - rhs.f[i];
+ }
+ return ret;
+ }
+
+ mat4& operator+=(const mat4& rhs)
+ {
+ for(int32_t i=0; i < 16; ++i)
+ {
+ f[i] += rhs.f[i];
+ }
+ return *this;
+ }
+
+ mat4& operator-=(const mat4& rhs)
+ {
+ for(int32_t i=0; i < 16; ++i)
+ {
+ f[i] -= rhs.f[i];
+ }
+ return *this;
+ }
+
+ mat4& operator*=(const mat4& rhs)
+ {
+ mat4 ret;
+ ret.f[0] = f[0] * rhs.f[0] + f[4] * rhs.f[1] + f[8] * rhs.f[2] + f[12] * rhs.f[3];
+ ret.f[1] = f[1] * rhs.f[0] + f[5] * rhs.f[1] + f[9] * rhs.f[2] + f[13] * rhs.f[3];
+ ret.f[2] = f[2] * rhs.f[0] + f[6] * rhs.f[1] + f[10] * rhs.f[2] + f[14] * rhs.f[3];
+ ret.f[3] = f[3] * rhs.f[0] + f[7] * rhs.f[1] + f[11] * rhs.f[2] + f[15] * rhs.f[3];
+
+ ret.f[4] = f[0] * rhs.f[4] + f[4] * rhs.f[5] + f[8] * rhs.f[6] + f[12] * rhs.f[7];
+ ret.f[5] = f[1] * rhs.f[4] + f[5] * rhs.f[5] + f[9] * rhs.f[6] + f[13] * rhs.f[7];
+ ret.f[6] = f[2] * rhs.f[4] + f[6] * rhs.f[5] + f[10] * rhs.f[6] + f[14] * rhs.f[7];
+ ret.f[7] = f[3] * rhs.f[4] + f[7] * rhs.f[5] + f[11] * rhs.f[6] + f[15] * rhs.f[7];
+
+ ret.f[8] = f[0] * rhs.f[8] + f[4] * rhs.f[9] + f[8] * rhs.f[10] + f[12] * rhs.f[11];
+ ret.f[9] = f[1] * rhs.f[8] + f[5] * rhs.f[9] + f[9] * rhs.f[10] + f[13] * rhs.f[11];
+ ret.f[10] = f[2] * rhs.f[8] + f[6] * rhs.f[9] + f[10] * rhs.f[10] + f[14] * rhs.f[11];
+ ret.f[11] = f[3] * rhs.f[8] + f[7] * rhs.f[9] + f[11] * rhs.f[10] + f[15] * rhs.f[11];
+
+ ret.f[12] = f[0] * rhs.f[12] + f[4] * rhs.f[13] + f[8] * rhs.f[14] + f[12] * rhs.f[15];
+ ret.f[13] = f[1] * rhs.f[12] + f[5] * rhs.f[13] + f[9] * rhs.f[14] + f[13] * rhs.f[15];
+ ret.f[14] = f[2] * rhs.f[12] + f[6] * rhs.f[13] + f[10] * rhs.f[14] + f[14] * rhs.f[15];
+ ret.f[15] = f[3] * rhs.f[12] + f[7] * rhs.f[13] + f[11] * rhs.f[14] + f[15] * rhs.f[15];
+
+ *this = ret;
+ return *this;
+ }
+
+ mat4 operator*(const float rhs)
+ {
+ mat4 ret;
+ for(int32_t i=0; i < 16; ++i)
+ {
+ ret.f[i] = f[i] * rhs;
+ }
+ return ret;
+ }
+
+ mat4& operator*=(const float rhs)
+ {
+ for(int32_t i=0; i < 16; ++i)
+ {
+ f[i] *= rhs;
+ }
+ return *this;
+ }
+
+ mat4& operator=(const mat4& rhs)
+ {
+ for(int32_t i=0; i < 16; ++i)
+ {
+ f[i] = rhs.f[i];
+ }
+ return *this;
+ }
+
+ mat4 inverse();
+
+ mat4 transpose()
+ {
+ mat4 ret;
+ ret.f[0] = f[0]; ret.f[1] = f[4]; ret.f[2] = f[8]; ret.f[3] = f[12];
+ ret.f[4] = f[1]; ret.f[5] = f[5]; ret.f[6] = f[9]; ret.f[7] = f[13];
+ ret.f[8] = f[2]; ret.f[9] = f[6]; ret.f[10] = f[10]; ret.f[11] = f[14];
+ ret.f[12] = f[3]; ret.f[13] = f[7]; ret.f[14] = f[11]; ret.f[15] = f[15];
+ *this = ret;
+ return *this;
+ }
+
+ mat4& postTranslate(float tx, float ty, float tz)
+ {
+ f[12] += (tx*f[0])+(ty*f[4])+(tz*f[8]);
+ f[13] += (tx*f[1])+(ty*f[5])+(tz*f[9]);
+ f[14] += (tx*f[2])+(ty*f[6])+(tz*f[10]);
+ f[15] += (tx*f[3])+(ty*f[7])+(tz*f[11]);
+ return *this;
+ }
+
+ float* ptr() {
+ return f;
+ }
+
+ //--------------------------------------------------------------------------------
+ // Misc
+ //--------------------------------------------------------------------------------
+ static mat4 perspective(
+ float width,
+ float height,
+ float nearPlane, float farPlane);
+
+ static mat4 lookAt(const vec3& vEye, const vec3& vAt, const vec3& vUp);
+
+ static mat4 translation(
+ const float fX,
+ const float fY,
+ const float fZ);
+ static mat4 translation(
+ const vec3 vec);
+
+ static mat4 rotationX(
+ const float fAngle);
+
+ static mat4 rotationY(const float fAngle);
+
+ static mat4 rotationZ(const float fAngle);
+
+ static mat4 identity()
+ {
+ mat4 ret;
+ ret.f[0] = 1.f; ret.f[1] = 0; ret.f[2] = 0; ret.f[3] = 0;
+ ret.f[4] = 0; ret.f[5] = 1.f; ret.f[6] = 0; ret.f[7] = 0;
+ ret.f[8] = 0; ret.f[9] = 0; ret.f[10] = 1.f;ret.f[11] = 0;
+ ret.f[12] = 0; ret.f[13] = 0; ret.f[14] = 0; ret.f[15] = 1.f;
+ return ret;
+ }
+
+ void dump()
+ {
+ LOGI("%f %f %f %f", f[0], f[1], f[2], f[3]);
+ LOGI("%f %f %f %f", f[4], f[5], f[6], f[7]);
+ LOGI("%f %f %f %f", f[8], f[9], f[10], f[11]);
+ LOGI("%f %f %f %f", f[12], f[13], f[14], f[15]);
+ }
+};
+
+/******************************************************************
+ * quaternion class
+ *
+ */
+class quaternion
+{
+private:
+ float x,y,z,w;
+
+public:
+ friend class vec3;
+ friend class vec4;
+ friend class mat4;
+
+ quaternion()
+ {
+ x = 0.f;
+ y = 0.f;
+ z = 0.f;
+ w = 1.f;
+ }
+
+ quaternion(const float fX, const float fY, const float fZ, const float fW)
+ {
+ x = fX;
+ y = fY;
+ z = fZ;
+ w = fW;
+ }
+
+ quaternion(const vec3 vec, const float fW)
+ {
+ x = vec.x;
+ y = vec.y;
+ z = vec.z;
+ w = fW;
+ }
+
+ quaternion(const float* p)
+ {
+ x = *p++;
+ y = *p++;
+ z = *p++;
+ w = *p++;
+ }
+
+ quaternion operator*(const quaternion rhs)
+ {
+ quaternion ret;
+ ret.x = x * rhs.w + y * rhs.z - z * rhs.y + w * rhs.x;
+ ret.y = -x * rhs.z + y * rhs.w + z * rhs.x + w * rhs.y;
+ ret.z = x * rhs.y - y * rhs.x + z * rhs.w + w * rhs.z;
+ ret.w = -x * rhs.x - y * rhs.y - z * rhs.z + w * rhs.w;
+ return ret;
+ }
+
+ quaternion& operator*=(const quaternion rhs)
+ {
+ quaternion ret;
+ ret.x = x * rhs.w + y * rhs.z - z * rhs.y + w * rhs.x;
+ ret.y = -x * rhs.z + y * rhs.w + z * rhs.x + w * rhs.y;
+ ret.z = x * rhs.y - y * rhs.x + z * rhs.w + w * rhs.z;
+ ret.w = -x * rhs.x - y * rhs.y - z * rhs.z + w * rhs.w;
+ *this = ret;
+ return *this;
+ }
+
+ quaternion conjugate()
+ {
+ x = -x;
+ y = -y;
+ z = -z;
+ return *this;
+ }
+
+ //Non destuctive version
+ quaternion conjugated()
+ {
+ quaternion ret;
+ ret.x = -x;
+ ret.y = -y;
+ ret.z = -z;
+ ret.w = w;
+ return ret;
+ }
+
+ void toMatrix(mat4& mat)
+ {
+ float x2 = x * x * 2.0f;
+ float y2 = y * y * 2.0f;
+ float z2 = z * z * 2.0f;
+ float xy = x * y * 2.0f;
+ float yz = y * z * 2.0f;
+ float zx = z * x * 2.0f;
+ float xw = x * w * 2.0f;
+ float yw = y * w * 2.0f;
+ float zw = z * w * 2.0f;
+
+ mat.f[0] = 1.0f - y2 - z2;
+ mat.f[1] = xy + zw;
+ mat.f[2] = zx - yw;
+ mat.f[4] = xy - zw;
+ mat.f[5] = 1.0f - z2 - x2;
+ mat.f[6] = yz + xw;
+ mat.f[8] = zx + yw;
+ mat.f[9] = yz - xw;
+ mat.f[10] = 1.0f - x2 - y2;
+
+ mat.f[3] = mat.f[7] = mat.f[11] = mat.f[12] = mat.f[13] = mat.f[14] = 0.0f;
+ mat.f[15] = 1.0f;
+ }
+
+ void toMatrixPreserveTranslate(mat4& mat)
+ {
+ float x2 = x * x * 2.0f;
+ float y2 = y * y * 2.0f;
+ float z2 = z * z * 2.0f;
+ float xy = x * y * 2.0f;
+ float yz = y * z * 2.0f;
+ float zx = z * x * 2.0f;
+ float xw = x * w * 2.0f;
+ float yw = y * w * 2.0f;
+ float zw = z * w * 2.0f;
+
+ mat.f[0] = 1.0f - y2 - z2;
+ mat.f[1] = xy + zw;
+ mat.f[2] = zx - yw;
+ mat.f[4] = xy - zw;
+ mat.f[5] = 1.0f - z2 - x2;
+ mat.f[6] = yz + xw;
+ mat.f[8] = zx + yw;
+ mat.f[9] = yz - xw;
+ mat.f[10] = 1.0f - x2 - y2;
+
+ mat.f[3] = mat.f[7] = mat.f[11] = 0.0f;
+ mat.f[15] = 1.0f;
+ }
+
+ static quaternion rotationAxis(const vec3 axis, const float angle )
+ {
+ quaternion ret;
+ float s = sinf(angle / 2);
+ ret.x = s * axis.x;
+ ret.y = s * axis.y;
+ ret.z = s * axis.z;
+ ret.w = cosf( angle / 2 );
+ return ret;
+ }
+
+ void value(float& fX, float& fY, float& fZ, float& fW)
+ {
+ fX = x;
+ fY = y;
+ fZ = z;
+ fW = w;
+ }
+};
+
+#endif /* VECMATH_H_ */