diff options
| author | Hak Matsuda <hakuro@google.com> | 2013-09-26 20:58:00 -0700 |
|---|---|---|
| committer | Andrew Hsieh <andrewhsieh@google.com> | 2013-10-28 11:41:58 +0800 |
| commit | 5d1c91fb75468fb6daad8aa66de64c5d177f3158 (patch) | |
| tree | 28e6875a55605a20ceb317c7e94d7fb3a51602a4 /ndk/sources | |
| parent | 122d194b36e41ca6291efe6c27e02fc73d2a1683 (diff) | |
| download | android_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')
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_ */ |
