cleaned code, added pinch gesture detector, better opengl context handling, fixed issues

Change-Id: I26a28374ae74391204586b4584d03cf0c58772c2
This commit is contained in:
Hak Matsuda
2013-09-26 20:58:00 -07:00
committed by Andrew Hsieh
parent 122d194b36
commit 5d1c91fb75
55 changed files with 6544 additions and 763 deletions

View File

@@ -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;
}