History: OgreAndroidogresamplebrowser_cpp
Source of version: 2 (current)
Copy to clipboard
{CODE(wrap="1", colors="c++")}#include <jni.h>
#include <stdlib.h>
#include <iostream>
#include <stdexcept>
#include <string>
#include "ogrewrapper.h"
#include <OIS.h>
#include <android/log.h>
#include "OgreADPArchive.h"
#define LOG_TAG "libogresamplebrowser"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
class AndroidMultiTouch : public OIS::MultiTouch
{
public:
AndroidMultiTouch():OIS::MultiTouch("DWM", false, 0, 0){}
/** @copydoc Object::setBuffered */
virtual void setBuffered(bool buffered){}
/** @copydoc Object::capture */
virtual void capture(){}
/** @copydoc Object::queryInterface */
virtual OIS::Interface* queryInterface(OIS::Interface::IType type) {return 0;}
/** @copydoc Object::_initialize */
virtual void _initialize(){}
OIS::MultiTouchState &getMultiTouchState(int i){
while(i >= mStates.size()){
OIS::MultiTouchState state;
state.width = getRenderWindow()->getWidth();
state.height = getRenderWindow()->getHeight();
mStates.push_back(state);
}
return mStates[i];
}
};
class AndroidKeyboard : public OIS::Keyboard
{
public:
AndroidKeyboard():OIS::Keyboard("DWM", false, 1, 0){}
/** @copydoc Object::setBuffered */
virtual void setBuffered(bool buffered){}
/** @copydoc Object::capture */
virtual void capture(){}
/** @copydoc Object::queryInterface */
virtual OIS::Interface* queryInterface(OIS::Interface::IType type) {return 0;}
/** @copydoc Object::_initialize */
virtual void _initialize(){}
virtual bool isKeyDown( OIS::KeyCode key ) const{
return false;
}
virtual const std::string& getAsString( OIS::KeyCode kc ){
static std::string defstr = "";
return defstr;
}
virtual void copyKeyStates( char keys[256] ) const{
}
};
#include "SampleBrowser.h"
static AndroidMultiTouch *g_multiTouch = 0;
static AndroidKeyboard *g_keyboard = 0;
static OgreBites::SampleBrowser *g_browser = 0;
static bool g_rootInit = false;
static int g_xOffset = 0, g_yOffset = 0;
static void injectTouchEvent(int pointerId, int action, float x, float y){
if(g_browser){
OIS::MultiTouchState &state = g_multiTouch->getMultiTouchState(pointerId);
switch(action){
case 0:
state.touchType = OIS::MT_Pressed;
break;
case 1:
state.touchType = OIS::MT_Released;
break;
case 2:
state.touchType = OIS::MT_Moved;
break;
case 3:
state.touchType = OIS::MT_Cancelled;
break;
default:
state.touchType = OIS::MT_None;
}
if(state.touchType != OIS::MT_None){
int last = state.X.abs;
state.X.abs = g_xOffset + (int)x;
state.X.rel = state.X.abs - last;
last = state.Y.abs;
state.Y.abs = g_yOffset + (int)y;
state.Y.rel = state.Y.abs - last;
//last = state.Z.abs;
state.Z.abs = 0;
state.Z.rel = 0;
OIS::MultiTouchEvent evt(g_multiTouch, state);
switch(state.touchType){
case OIS::MT_Pressed:
g_browser->touchPressed(evt);
break;
case OIS::MT_Released:
g_browser->touchReleased(evt);
break;
case OIS::MT_Moved:
g_browser->touchMoved(evt);
break;
case OIS::MT_Cancelled:
g_browser->touchCancelled(evt);
break;
}
}
}
}
static void injectKeyEvent(int action, int keyCode){
if(g_browser){
OIS::KeyCode kc = OIS::KC_UNASSIGNED;
unsigned int txt = 0;
switch(keyCode){
case 7:
kc = OIS::KC_0;
txt = '0';
break;
case 8:
kc = OIS::KC_1;
txt = '1';
break;
case 9:
kc = OIS::KC_2;
txt = '2';
break;
case 10:
kc = OIS::KC_3;
txt = '3';
break;
case 11:
kc = OIS::KC_4;
txt = '4';
break;
case 12:
kc = OIS::KC_5;
txt = '5';
break;
case 13:
kc = OIS::KC_6;
txt = '6';
break;
case 14:
kc = OIS::KC_7;
txt = '7';
break;
case 15:
kc = OIS::KC_8;
txt = '8';
break;
case 16:
kc = OIS::KC_9;
txt = '9';
break;
case 69:
kc = OIS::KC_MINUS;
txt = '-';
break;
case 70:
kc = OIS::KC_EQUALS;
txt = '=';
break;
case 61:
kc = OIS::KC_TAB;
txt = '\t';
break;
case 67:
kc = OIS::KC_BACK;
txt = '\b';
break;
case 29:
kc = OIS::KC_A;
txt = 'A';
break;
case 30:
kc = OIS::KC_B;
txt = 'B';
break;
case 31:
kc = OIS::KC_C;
txt = 'C';
break;
case 32:
kc = OIS::KC_D;
txt = 'D';
break;
case 33:
kc = OIS::KC_E;
txt = 'E';
break;
case 34:
kc = OIS::KC_F;
txt = 'F';
break;
case 35:
kc = OIS::KC_G;
txt = 'G';
break;
case 36:
kc = OIS::KC_H;
txt = 'H';
break;
case 37:
kc = OIS::KC_I;
txt = 'I';
break;
case 38:
kc = OIS::KC_J;
txt = 'J';
break;
case 39:
kc = OIS::KC_K;
txt = 'K';
break;
case 40:
kc = OIS::KC_L;
txt = 'L';
break;
case 41:
kc = OIS::KC_M;
txt = 'M';
break;
case 42:
kc = OIS::KC_N;
txt = 'N';
break;
case 43:
kc = OIS::KC_O;
txt = 'O';
break;
case 44:
kc = OIS::KC_P;
txt = 'P';
break;
case 45:
kc = OIS::KC_Q;
txt = 'Q';
break;
case 46:
kc = OIS::KC_R;
txt = 'R';
break;
case 47:
kc = OIS::KC_S;
txt = 'S';
break;
case 48:
kc = OIS::KC_T;
txt = 'T';
break;
case 49:
kc = OIS::KC_U;
txt = 'U';
break;
case 50:
kc = OIS::KC_V;
txt = 'V';
break;
case 51:
kc = OIS::KC_W;
txt = 'W';
break;
case 52:
kc = OIS::KC_X;
txt = 'X';
break;
case 53:
kc = OIS::KC_Y;
txt = 'Y';
break;
case 54:
kc = OIS::KC_Z;
txt = 'Z';
break;
case 71:
kc = OIS::KC_LBRACKET;
txt = '[';
break;
case 72:
kc = OIS::KC_RBRACKET;
txt = ']';
break;
case 66:
kc = OIS::KC_RETURN;
txt = '\n';
break;
case 74:
kc = OIS::KC_SEMICOLON;
txt = ';';
break;
case 75:
kc = OIS::KC_APOSTROPHE;
txt = '\'';
break;
case 73:
kc = OIS::KC_BACKSLASH;
txt = '\\';
break;
case 55:
kc = OIS::KC_COMMA;
txt = ',';
break;
case 56:
kc = OIS::KC_PERIOD;
txt = '.';
break;
case 76:
kc = OIS::KC_SLASH;
txt = '/';
break;
case 19:
kc = OIS::KC_UP;
break;
case 20:
kc = OIS::KC_DOWN;
break;
case 21:
kc = OIS::KC_LEFT;
break;
case 22:
kc = OIS::KC_RIGHT;
break;
}
OIS::KeyEvent evt(g_keyboard, kc, txt);
if(action == 0)
{
g_browser->keyPressed(evt);
}
else
{
g_browser->keyReleased(evt);
}
}
}
static bool hasFile(JNIEnv *env, const char *name){
// Get the asset manager
jclass cls = env->FindClass("org/ogre/ADPManager");
jmethodID hasFile_method = env->GetMethodID(cls, "hasFile", "(Ljava/lang/String;)Z");
jmethodID getInstance_method = env->GetStaticMethodID(cls, "getInstance", "()Lorg/ogre/ADPManager;");
jobject obj = env->CallStaticObjectMethod(cls, getInstance_method);
jstring str = env->NewStringUTF(name);
jboolean result = env->CallBooleanMethod(obj, hasFile_method, str);
return (result == JNI_TRUE);
}
static void loadFile(JNIEnv* env, const char *name, void **ptr, size_t *size){
// Get the asset manager
jclass cls = env->FindClass("org/ogre/ADPManager");
jmethodID getFileSize_method = env->GetMethodID(cls, "getFileSize", "(Ljava/lang/String;)I");
jmethodID beginStream_method = env->GetMethodID(cls, "beginStream", "(Ljava/lang/String;)V");
jmethodID endStream_method = env->GetMethodID(cls, "endStream", "()V");
jmethodID readStream_method = env->GetMethodID(cls, "readStream", "()Lorg/ogre/ADPManager$RawData;");
jmethodID getInstance_method = env->GetStaticMethodID(cls, "getInstance", "()Lorg/ogre/ADPManager;");
jobject obj = env->CallStaticObjectMethod(cls, getInstance_method);
jstring filename = env->NewStringUTF(name);
// Get the total file size
jint filesize = env->CallIntMethod(obj, getFileSize_method, filename);
if(filesize > 0){
// Allocate the buffer
*size = filesize;
*ptr = OGRE_MALLOC(filesize, Ogre::MEMCATEGORY_GENERAL);
unsigned char *ptr2 = (unsigned char*)*ptr;
// Start the streaming
static jclass RawData_class = env->FindClass("org/ogre/ADPManager$RawData");
static jfieldID lengthId = env->GetFieldID(RawData_class, "length", "I");
static jfieldID dataId = env->GetFieldID(RawData_class, "data", "[B");
env->CallVoidMethod(obj, beginStream_method, filename);
int offset = 0; // Store where into the buffer we're writing to
while(offset < filesize){
jobject rawData = env->CallObjectMethod(obj, readStream_method);
if(rawData != 0){
jbyteArray buffer = (jbyteArray) env->GetObjectField(rawData, dataId);
int length = env->GetIntField(rawData, lengthId);
env->GetByteArrayRegion(buffer, 0, length, (jbyte*)(ptr2 + offset)); // Copy the bytes
offset += length;
}
}
env->CallVoidMethod(obj, endStream_method);
}
}
class JavaADPSource : public Ogre::ADPSource{
private:
JNIEnv* mEnv;
public:
JavaADPSource(JNIEnv* env):mEnv(env){}
Ogre::DataStreamPtr getPackage(const Ogre::String &name){
if(!hasFile(mEnv, name.c_str())){
return Ogre::DataStreamPtr();
}
void *data = 0;
size_t size = 0;
loadFile(mEnv, name.c_str(), &data, &size);
Ogre::DataStreamPtr stream;
if(data)
stream = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(data, size, true));
return stream;
}
};
static JavaADPSource *g_adpSource = 0;
static Ogre::ADPArchiveFactory *g_archiveFactory = 0;
jboolean init(JNIEnv* env, jobject thiz)
{
bool ret = initOgreRoot();
if(!ret)
return JNI_FALSE;
g_rootInit = true;
g_adpSource = OGRE_NEW JavaADPSource(env);
g_archiveFactory = OGRE_NEW Ogre::ADPArchiveFactory(g_adpSource);
Ogre::ArchiveManager::getSingleton().addArchiveFactory(g_archiveFactory);
LOGI("Adding resource locations");
Ogre::ResourceGroupManager::getSingleton().createResourceGroup("Popular");
Ogre::ResourceGroupManager::getSingleton().createResourceGroup("Essential");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("rtss.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("cubemap.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("cubemapJS.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("fonts.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("fresneldemo.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("materials.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("meshes.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("skybox.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("textures.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("particle.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("sinbad.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("dragon.mp3", "ADP", "Popular");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("SdkTrays.mp3", "ADP", "Essential");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("thumbnails.mp3", "ADP", "Essential");
}
jboolean render(JNIEnv* env, jobject thiz, jint drawWidth, jint drawHeight, jboolean forceRedraw)
{
// Check that a render window even exists
if(getRenderWindow() == 0){
initRenderWindow(0, drawWidth, drawHeight, 0);
}
// Initialize the sample browser
if(g_multiTouch == 0){
g_multiTouch = new AndroidMultiTouch();
}
if(g_keyboard == 0){
g_keyboard = new AndroidKeyboard();
}
if(g_browser == 0){
LOGI("Initializing the sample browser");
g_browser = OGRE_NEW OgreBites::SampleBrowser();
g_browser->initAppForAndroid(getRenderWindow(), g_multiTouch, g_keyboard);
g_browser->initApp();
LOGI("Browser initialized");
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
renderOneFrame();
return JNI_TRUE;
}
void cleanup(JNIEnv* env)
{
if(g_browser){
g_browser->closeApp();
OGRE_DELETE g_browser;
g_browser = 0;
}
if(g_multiTouch){
delete g_multiTouch;
g_multiTouch = 0;
}
if(g_keyboard){
delete g_keyboard;
g_keyboard = 0;
}
if(getRenderWindow()){
destroyRenderWindow();
}
LOGI("deleting ogre root");
if(g_rootInit){
destroyOgreRoot();
g_rootInit = false;
}
LOGI("deleting ADP stuff");
if(g_archiveFactory){
OGRE_DELETE g_archiveFactory;
g_archiveFactory = 0;
}
if(g_adpSource){
OGRE_DELETE g_adpSource;
g_adpSource = 0;
}
}
jboolean inputEvent(JNIEnv* env, jobject thiz, jint action, jfloat mx, jfloat my)
{
injectTouchEvent(0, action, mx, my);
return JNI_TRUE;
}
jboolean keyEvent(JNIEnv* env, jobject thiz, jint action, jint unicodeChar, jint keyCode, jobject keyEvent)
{
injectKeyEvent(action, keyCode);
return JNI_TRUE;
}
void setOffsets(JNIEnv* env, jobject thiz, jint x, jint y)
{
g_xOffset = x;
g_yOffset = y;
}
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv *env;
LOGI("JNI_OnLoad called");
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
{
LOGE("Failed to get the environment using GetEnv()");
return -1;
}
JNINativeMethod methods[] =
{
{
"init",
"()Z",
(void *) init
},
{
"render",
"(IIZ)Z",
(void *) render
},
{
"inputEvent",
"(IFFLandroid/view/MotionEvent;)Z",
(void *) inputEvent
},
{
"keyEvent",
"(IIILandroid/view/KeyEvent;)Z",
(void *) keyEvent
},
{
"cleanup",
"()V",
(void *) cleanup
},
{
"setOffsets",
"(II)V",
(void *) setOffsets
},
};
jclass k;
k = (env)->FindClass ("org/ogre/samples/OgreSampleBrowserActivity");
(env)->RegisterNatives(k, methods, 6);
return JNI_VERSION_1_4;
}{CODE}