From 0395fc3648ecc3dbe7d2c687b395b41461bf9b7a Mon Sep 17 00:00:00 2001 From: nadro Date: Thu, 17 Oct 2013 23:11:56 +0000 Subject: [PATCH] - Clean-up Android device source file. - Improved multi-touch support on Android. - Fixed problem with context lost on Android when application was resumed. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@4590 dfc29bdd-3216-0410-991c-e03cc46cb475 --- .../Android/CAndroidAssetFileArchive.cpp | 7 +- .../Android/CAndroidAssetFileArchive.h | 5 + .../Irrlicht/Android/CAndroidAssetReader.cpp | 4 +- source/Irrlicht/Android/CAndroidAssetReader.h | 6 +- source/Irrlicht/Android/CIrrDeviceAndroid.cpp | 494 +++++++----------- source/Irrlicht/Android/CIrrDeviceAndroid.h | 188 ++----- source/Irrlicht/CEGLManager.cpp | 173 +++--- source/Irrlicht/CEGLManager.h | 25 +- source/Irrlicht/COGLESDriver.cpp | 2 - 9 files changed, 371 insertions(+), 533 deletions(-) diff --git a/source/Irrlicht/Android/CAndroidAssetFileArchive.cpp b/source/Irrlicht/Android/CAndroidAssetFileArchive.cpp index 8ddeaa0f..3f01bd8b 100644 --- a/source/Irrlicht/Android/CAndroidAssetFileArchive.cpp +++ b/source/Irrlicht/Android/CAndroidAssetFileArchive.cpp @@ -22,18 +22,19 @@ namespace irr namespace io { -CAndroidAssetFileArchive *createAndroidAssetFileArchive(bool ignoreCase, bool ignorePaths) +CAndroidAssetFileArchive *CAndroidAssetFileArchive::createAndroidAssetFileArchive(bool ignoreCase, bool ignorePaths) { - if(!CIrrDeviceAndroid::getAndroidApp()) + if(!CAndroidAssetFileArchive::Activity) return NULL; return new CAndroidAssetFileArchive(ignoreCase, ignorePaths); } +ANativeActivity* CAndroidAssetFileArchive::Activity = 0; CAndroidAssetFileArchive::CAndroidAssetFileArchive(bool ignoreCase, bool ignorePaths) : CFileList("/asset", ignoreCase, ignorePaths) { - AssetManager = CIrrDeviceAndroid::getAndroidApp()->activity->assetManager; + AssetManager = Activity->assetManager; addDirectory(""); } diff --git a/source/Irrlicht/Android/CAndroidAssetFileArchive.h b/source/Irrlicht/Android/CAndroidAssetFileArchive.h index 8ba35240..a71288b2 100644 --- a/source/Irrlicht/Android/CAndroidAssetFileArchive.h +++ b/source/Irrlicht/Android/CAndroidAssetFileArchive.h @@ -52,7 +52,12 @@ namespace io //! API does not return names of directories, they need to //! be added manually. virtual void addDirectory(const io::path &filename); + + static ANativeActivity* Activity; + protected: + static CAndroidAssetFileArchive* createAndroidAssetFileArchive(bool ignoreCase, bool ignorePaths); + //! Android's asset manager - keep a copy here AAssetManager *AssetManager; diff --git a/source/Irrlicht/Android/CAndroidAssetReader.cpp b/source/Irrlicht/Android/CAndroidAssetReader.cpp index 3180925f..b08801d8 100644 --- a/source/Irrlicht/Android/CAndroidAssetReader.cpp +++ b/source/Irrlicht/Android/CAndroidAssetReader.cpp @@ -22,9 +22,11 @@ namespace irr namespace io { +ANativeActivity* CAndroidAssetReader::Activity = 0; + CAndroidAssetReader::CAndroidAssetReader(const io::path &filename) { - AssetManager = CIrrDeviceAndroid::getAndroidApp()->activity->assetManager; + AssetManager = Activity->assetManager; Asset = AAssetManager_open(AssetManager, core::stringc(filename).c_str(), AASSET_MODE_RANDOM); diff --git a/source/Irrlicht/Android/CAndroidAssetReader.h b/source/Irrlicht/Android/CAndroidAssetReader.h index 5dbd9bea..dd4029f7 100644 --- a/source/Irrlicht/Android/CAndroidAssetReader.h +++ b/source/Irrlicht/Android/CAndroidAssetReader.h @@ -15,6 +15,7 @@ struct AAssetManager; struct AAsset; +struct ANativeActivity; namespace irr { @@ -56,7 +57,10 @@ namespace io /** Return true if the file could be opened. */ bool isOpen() const { return Asset!=NULL; } - protected: + + static ANativeActivity* Activity; + + private: //! Android's asset manager - keep a copy here AAssetManager *AssetManager; diff --git a/source/Irrlicht/Android/CIrrDeviceAndroid.cpp b/source/Irrlicht/Android/CIrrDeviceAndroid.cpp index 1dd04dea..a7830c03 100644 --- a/source/Irrlicht/Android/CIrrDeviceAndroid.cpp +++ b/source/Irrlicht/Android/CIrrDeviceAndroid.cpp @@ -9,8 +9,11 @@ #include "os.h" #include "CFileSystem.h" +#include "CAndroidAssetReader.h" #include "CAndroidAssetFileArchive.h" #include "CEGLManager.h" +#include "ISceneManager.h" +#include "IGUIEnvironment.h" namespace irr { @@ -27,189 +30,110 @@ namespace irr namespace irr { -android_app* CIrrDeviceAndroid::Android = NULL; - -//! constructor CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param) - : CIrrDeviceStub(param), - Animating(false), - IsReady(false), - IsClosing(false), - DeviceWidth(param.WindowSize.Width), - DeviceHeight(param.WindowSize.Height), - MouseX(0), - MouseY(0) + : CIrrDeviceStub(param), Focused(false), Initialized(false), Paused(true) { - int ident; - int events; - struct android_poll_source* source; - - #ifdef _DEBUG +#ifdef _DEBUG setDebugName("CIrrDeviceAndroid"); - #endif +#endif // Get the interface to the native Android activity. - Android = (android_app *)(param.PrivateData); + Android = (android_app*)(param.PrivateData); + + io::CAndroidAssetReader::Activity = Android->activity; + io::CAndroidAssetFileArchive::Activity = Android->activity; // Set the private data so we can use it in any static callbacks. Android->userData = this; - // Set the default command handler. This is a callback function - // that the Android OS invokes to send the native activity - // messages. + // Set the default command handler. This is a callback function that the Android + // OS invokes to send the native activity messages. Android->onAppCmd = handleAndroidCommand; - // Create a sensor manager to recieve touch screen events from the - // java acivity. + // Create a sensor manager to recieve touch screen events from the java acivity. SensorManager = ASensorManager_getInstance(); - SensorEventQueue = ASensorManager_createEventQueue( - SensorManager, Android->looper, - LOOPER_ID_USER, NULL, NULL); + SensorEventQueue = ASensorManager_createEventQueue(SensorManager, Android->looper, LOOPER_ID_USER, 0, 0); Android->onInputEvent = handleInput; - - // Need to find a better way of doing this... but poll until the - // Android activity has been created and a window is open. The device - // cannot be created until the main window has been created by the - // Android OS. + + // Create EGL manager. + EGLManager = new video::CEGLManager(CreationParams, &ExposedVideoData); + os::Printer::log("Waiting for Android activity window to be created.", ELL_DEBUG); - - do + + do { - while( (ident = ALooper_pollAll( 0, NULL, &events,(void**)&source)) >= 0 ) - { - // Process this event. - if( source != NULL ) - { - source->process( Android, source ); - } - } + s32 Events = 0; + android_poll_source* Source = 0; + + while ((ALooper_pollAll(((Focused && !Paused) || !Initialized) ? 0 : -1, 0, &Events, (void**)&Source)) >= 0) + { + if(Source) + Source->process(Android, Source); + } } - while( IsReady == false ); + while(!Initialized); -#ifdef _DEBUG - assert( Android->window ); -#endif + io::CAndroidAssetFileArchive* Assets = new io::CAndroidAssetFileArchive(false, false); + Assets->addDirectory("media"); + FileSystem->addFileArchive(Assets); - // Create cursor control - CursorControl = new CCursorControl(this); - - io::CAndroidAssetFileArchive *assets = io::createAndroidAssetFileArchive(false, false); - assets->addDirectory("media"); - FileSystem->addFileArchive(assets); - - // Create the driver. - getEGLManager()->createContext(); createDriver(); if (VideoDriver) createGUIAndScene(); - - // TODO - // - // if engine->app->savedState is not NULL then use postEventFromUser() - // with a custom android event so the user can use their own event - // receiver in order to load the apps previous state. - // The message should have a pointer to be filled and a size variable - // of how much data has been saved. Android free's this data later so - // there's no need to free it manually. - - Animating = true; } -CIrrDeviceAndroid::~CIrrDeviceAndroid(void) +CIrrDeviceAndroid::~CIrrDeviceAndroid() { + if (GUIEnvironment) + { + GUIEnvironment->drop(); + GUIEnvironment = 0; + } + + if (SceneManager) + { + SceneManager->drop(); + SceneManager = 0; + } + + if (VideoDriver) + { + VideoDriver->drop(); + VideoDriver = 0; + } + delete EGLManager; } -void CIrrDeviceAndroid::createDriver( void ) +bool CIrrDeviceAndroid::run() { - - - // Create the driver. - switch(CreationParams.DriverType) - { - case video::EDT_OGLES1: - #ifdef _IRR_COMPILE_WITH_OGLES1_ - VideoDriver = video::createOGLES1Driver(CreationParams, ExposedVideoData, FileSystem, EGLManager); - #else - os::Printer::log("No OpenGL ES 1.0 support compiled in.", ELL_ERROR); - #endif - break; - - case video::EDT_OGLES2: - #ifdef _IRR_COMPILE_WITH_OGLES2_ - VideoDriver = video::createOGLES2Driver(CreationParams, ExposedVideoData, FileSystem); - #else - os::Printer::log("No OpenGL ES 2.0 support compiled in.", ELL_ERROR); - #endif - break; + if (!Initialized) + return false; - case video::EDT_NULL: - VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); - break; - - default: - os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); - break; - } -} - -bool CIrrDeviceAndroid::run( void ) -{ - bool close = false; - - // Read all pending events. - int ident; - int events; - struct android_poll_source* source; - - // Check if Android is trying to shut us down. - if( IsClosing == true ) - return( false ); - - // If not animating, we will block forever waiting for events. - // If animating, we loop until all events are read, then continue - // to draw the next frame of animation. - while( ( ident = ALooper_pollAll( ( Animating || IsClosing ) ? 0 : -1, - NULL, &events, - (void**)&source)) >= 0 ) - { - // Process this event. - if( source != NULL ) - { - source->process( Android, source ); - } -#if 0 - // If a sensor has data, process it now. - if (ident == LOOPER_ID_USER) { - if (engine.accelerometerSensor != NULL) { - ASensorEvent event; - while (ASensorEventQueue_getEvents(engine.sensorEventQueue, - &event, 1) > 0) { - DEBUG_INFO1("accelerometer: x=%f y=%f z=%f", - event.acceleration.x, event.acceleration.y, - event.acceleration.z); - } - } - } -#endif - // Check if we are exiting. - if( Android->destroyRequested != 0 ) - { - close = true; - } - } - os::Timer::tick(); - return( !close ); + + s32 Events = 0; + android_poll_source* Source = 0; + + while ((ALooper_pollAll(((Focused && !Paused) || !Initialized) ? 0 : -1, 0, &Events, (void**)&Source)) >= 0) + { + if(Source) + Source->process(Android, Source); + + if(!Initialized) + break; + } + + return Initialized; } -void CIrrDeviceAndroid::yield( void ) +void CIrrDeviceAndroid::yield() { } -void CIrrDeviceAndroid::sleep( u32 timeMs, bool pauseTimer ) +void CIrrDeviceAndroid::sleep(u32 timeMs, bool pauseTimer) { } @@ -219,41 +143,41 @@ void CIrrDeviceAndroid::setWindowCaption(const wchar_t* text) bool CIrrDeviceAndroid::present(video::IImage* surface, void* windowId, core::rect* srcClip) { - return( true ); + return true; } -bool CIrrDeviceAndroid::isWindowActive( void ) const +bool CIrrDeviceAndroid::isWindowActive() const { - return Animating; + return (Focused && !Paused); } -bool CIrrDeviceAndroid::isWindowFocused( void ) const +bool CIrrDeviceAndroid::isWindowFocused() const { - return Animating; + return Focused; } -bool CIrrDeviceAndroid::isWindowMinimized( void ) const +bool CIrrDeviceAndroid::isWindowMinimized() const { - return !Animating; + return !Focused; } -void CIrrDeviceAndroid::closeDevice( void ) +void CIrrDeviceAndroid::closeDevice() { } -void CIrrDeviceAndroid::setResizable( bool resize ) +void CIrrDeviceAndroid::setResizable(bool resize) { } -void CIrrDeviceAndroid::minimizeWindow( void ) +void CIrrDeviceAndroid::minimizeWindow() { } -void CIrrDeviceAndroid::maximizeWindow( void ) +void CIrrDeviceAndroid::maximizeWindow() { } -void CIrrDeviceAndroid::restoreWindow( void ) +void CIrrDeviceAndroid::restoreWindow() { } @@ -262,201 +186,161 @@ core::position2di CIrrDeviceAndroid::getWindowPosition() return core::position2di(0, 0); } -E_DEVICE_TYPE CIrrDeviceAndroid::getType( void ) const +E_DEVICE_TYPE CIrrDeviceAndroid::getType() const { - return( EIDT_ANDROID ); + return EIDT_ANDROID; } - -/////////////////////////////// -/////////////////////////////// - -void CIrrDeviceAndroid::handleAndroidCommand( struct android_app* app, s32 cmd ) + +void CIrrDeviceAndroid::handleAndroidCommand(android_app* app, int32_t cmd) { - CIrrDeviceAndroid *deviceAndroid = (CIrrDeviceAndroid *)app->userData; + CIrrDeviceAndroid* Device = (CIrrDeviceAndroid*)app->userData; + switch (cmd) { case APP_CMD_SAVE_STATE: os::Printer::log("Android command APP_CMD_SAVE_STATE", ELL_DEBUG); - - // TODO - // - // use postEventFromUser() with a custom android event so the user can - // use their own event receiver in order to save the apps state. - // The message should have a pointer to be filled and a size variable - // of ho emuch data has been saved. -#if 0 - // The system has asked us to save our current state. Do so. - engine->app->savedState = malloc(sizeof(struct saved_state)); - *((struct saved_state*)engine->app->savedState) = engine->state; - engine->app->savedStateSize = sizeof(struct saved_state); -#endif break; case APP_CMD_INIT_WINDOW: os::Printer::log("Android command APP_CMD_INIT_WINDOW", ELL_DEBUG); - deviceAndroid->getExposedVideoData().OGLESAndroid.window = Android->window; - deviceAndroid->getEGLManager()->createEGL(); - deviceAndroid->IsReady = true; - deviceAndroid->Animating = true; + Device->getExposedVideoData().OGLESAndroid.window = app->window; + Device->getEGLManager()->initializeEGL(); + Device->getEGLManager()->createSurface(); + Device->getEGLManager()->createContext(); + Device->Initialized = true; break; case APP_CMD_TERM_WINDOW: os::Printer::log("Android command APP_CMD_TERM_WINDOW", ELL_DEBUG); - deviceAndroid->getEGLManager()->destroyEGL(); - deviceAndroid->Animating = false; + Device->getEGLManager()->destroySurface(); break; case APP_CMD_GAINED_FOCUS: os::Printer::log("Android command APP_CMD_GAINED_FOCUS", ELL_DEBUG); -#if 0 - // When our app gains focus, we start monitoring the accelerometer. - if (engine->accelerometerSensor != NULL) { - ASensorEventQueue_enableSensor(engine->sensorEventQueue, - engine->accelerometerSensor); - // We'd like to get 60 events per second (in us). - ASensorEventQueue_setEventRate(engine->sensorEventQueue, - engine->accelerometerSensor, (1000L/60)*1000); - } -#endif - deviceAndroid->Animating = true; + Device->Focused = true; break; case APP_CMD_LOST_FOCUS: os::Printer::log("Android command APP_CMD_LOST_FOCUS", ELL_DEBUG); - // When our app loses focus, we stop monitoring the accelerometer. - // This is to avoid consuming battery while not being used. -#if 0 - if (engine->accelerometerSensor != NULL) { - ASensorEventQueue_disableSensor(engine->sensorEventQueue, - engine->accelerometerSensor); - } -#endif - // Also stop animating. - deviceAndroid->Animating = false; - + Device->Focused = false; break; case APP_CMD_DESTROY: - // The application is being destroyed. We must close the native - // acitivity code and clean up otherwise the acitivity will stay - // active. os::Printer::log("Android command APP_CMD_DESTROY", ELL_DEBUG); - deviceAndroid->IsClosing = true; + Device->Initialized = false; break; - case APP_CMD_PAUSE: os::Printer::log("Android command APP_CMD_PAUSE", ELL_DEBUG); - break; - + Device->Paused = true; + break; case APP_CMD_STOP: os::Printer::log("Android command APP_CMD_STOP", ELL_DEBUG); - break; - + break; case APP_CMD_RESUME: os::Printer::log("Android command APP_CMD_RESUME", ELL_DEBUG); + Device->Paused = false; break; - default: - os::Printer::log("Unhandled android command", - core::stringc(cmd).c_str(), ELL_WARNING ); - + break; } } -s32 CIrrDeviceAndroid::handleInput( struct android_app* app, AInputEvent* androidEvent ) +s32 CIrrDeviceAndroid::handleInput(android_app* app, AInputEvent* androidEvent) { - CIrrDeviceAndroid *deviceAndroid = (CIrrDeviceAndroid *)app->userData; - int32_t eventAction; - int pointerCount = 0; - SEvent irrEvent; - int i = 0; - - if( AInputEvent_getType( androidEvent ) == AINPUT_EVENT_TYPE_MOTION ) + CIrrDeviceAndroid* Device = (CIrrDeviceAndroid*)app->userData; + s32 Status = 0; + + if (AInputEvent_getType(androidEvent) == AINPUT_EVENT_TYPE_MOTION) { - // Get the number of pointers. - pointerCount = AMotionEvent_getPointerCount( androidEvent ); + SEvent Event; + s32 PointerCount = AMotionEvent_getPointerCount(androidEvent); + s32 EventAction = AMotionEvent_getAction(androidEvent); - // Get the actual input event type. - eventAction = AMotionEvent_getAction( androidEvent ); + bool MultiTouchEvent = true; - switch( eventAction ) + switch (EventAction) { - case AMOTION_EVENT_ACTION_DOWN: - if( pointerCount == 1 ) - { - irrEvent.EventType = EET_MOUSE_INPUT_EVENT; - irrEvent.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN; - } - break; - - case AMOTION_EVENT_ACTION_MOVE: - if( pointerCount == 1 ) - { - irrEvent.EventType = EET_MOUSE_INPUT_EVENT; - irrEvent.MouseInput.Event = EMIE_MOUSE_MOVED; - } - else - { - irrEvent.EventType = EET_MULTI_TOUCH_EVENT; - irrEvent.MultiTouchInput.Event = EMTIE_MOVED; - } - - deviceAndroid->postEventFromUser(irrEvent); - break; - - case AMOTION_EVENT_ACTION_UP: - if( pointerCount == 1 ) - { - irrEvent.EventType = EET_MOUSE_INPUT_EVENT; - irrEvent.MouseInput.Event = EMIE_LMOUSE_LEFT_UP; - } - break; - default: - os::Printer::log("Unhandled motion event", - core::stringc(eventAction).c_str(), - ELL_WARNING ); + case AMOTION_EVENT_ACTION_DOWN: + Event.MultiTouchInput.Event = EMTIE_PRESSED_DOWN; + break; + case AMOTION_EVENT_ACTION_MOVE: + Event.MultiTouchInput.Event = EMTIE_MOVED; + break; + case AMOTION_EVENT_ACTION_UP: + Event.MultiTouchInput.Event = EMTIE_LEFT_UP; + break; + default: + MultiTouchEvent = false; + break; } - - if( pointerCount == 1 ) + + if (MultiTouchEvent) { - // Fill in the details for a one touch event. - deviceAndroid->MouseX = irrEvent.MouseInput.X = AMotionEvent_getX(androidEvent, 0); - deviceAndroid->MouseY = irrEvent.MouseInput.Y = AMotionEvent_getY(androidEvent, 0); - irrEvent.MouseInput.ButtonStates = 0; - } - else if( pointerCount > 1 ) - { - // Fill in the details for a multi touch event. - for( i=0 ; i= NUMBER_OF_MULTI_TOUCHES) + break; + + Event.MultiTouchInput.PrevX[i] = 0; // TODO + Event.MultiTouchInput.PrevY[i] = 0; // TODO + Event.MultiTouchInput.X[i] = AMotionEvent_getX(androidEvent, i); + Event.MultiTouchInput.Y[i] = AMotionEvent_getX(androidEvent, i); + + Event.MultiTouchInput.Touched[i] = true; } - - // Reset the data for the rest of the pointers that aren't being used. - for( ;ipostEventFromUser(Event); + + Status = 1; } - else - { - // Shouldn't ever get here, but just in case... - os::Printer::log("We had a input event but no pointers were active!", ELL_DEBUG); - return( 0 ); - } - - deviceAndroid->postEventFromUser(irrEvent); - - return( 1 ); } - return( 0 ); + + return Status; +} + +void CIrrDeviceAndroid::createDriver() +{ + switch(CreationParams.DriverType) + { + case video::EDT_OGLES1: +#ifdef _IRR_COMPILE_WITH_OGLES1_ + VideoDriver = video::createOGLES1Driver(CreationParams, ExposedVideoData, FileSystem, EGLManager); +#else + os::Printer::log("No OpenGL ES 1.0 support compiled in.", ELL_ERROR); +#endif + break; + case video::EDT_OGLES2: +#ifdef _IRR_COMPILE_WITH_OGLES2_ + VideoDriver = video::createOGLES2Driver(CreationParams, ExposedVideoData, FileSystem); +#else + os::Printer::log("No OpenGL ES 2.0 support compiled in.", ELL_ERROR); +#endif + break; + case video::EDT_NULL: + VideoDriver = video::createNullDriver(FileSystem, CreationParams.WindowSize); + break; + case video::EDT_SOFTWARE: + case video::EDT_BURNINGSVIDEO: + case video::EDT_OPENGL: + case video::EDT_DIRECT3D8: + case video::EDT_DIRECT3D9: + os::Printer::log("This driver is not available in Linux. Try OpenGL ES 1.0 or ES 2.0.", ELL_ERROR); + break; + default: + os::Printer::log("Unable to create video driver of unknown type.", ELL_ERROR); + break; + } +} + +video::SExposedVideoData& CIrrDeviceAndroid::getExposedVideoData() +{ + return ExposedVideoData; +} + +video::CEGLManager* CIrrDeviceAndroid::getEGLManager() +{ + return EGLManager; } } // end namespace irr #endif - diff --git a/source/Irrlicht/Android/CIrrDeviceAndroid.h b/source/Irrlicht/Android/CIrrDeviceAndroid.h index 01fc0799..212a716a 100644 --- a/source/Irrlicht/Android/CIrrDeviceAndroid.h +++ b/source/Irrlicht/Android/CIrrDeviceAndroid.h @@ -9,167 +9,75 @@ #ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_ -#include -#include #include "CIrrDeviceStub.h" #include "IrrlichtDevice.h" #include "IImagePresenter.h" #include "ICursorControl.h" #include "CEGLManager.h" +#include +#include + namespace irr { - class CIrrDeviceAndroid : public CIrrDeviceStub, video::IImagePresenter { public: - - //! constructor CIrrDeviceAndroid(const SIrrlichtCreationParameters& param); - //! destructor virtual ~CIrrDeviceAndroid(); - virtual bool run( void ); - virtual void yield( void ); - virtual void sleep( u32 timeMs, bool pauseTimer=false ); + virtual bool run(); + + virtual void yield(); + + virtual void sleep(u32 timeMs, bool pauseTimer = false); + virtual void setWindowCaption(const wchar_t* text); - virtual bool present(video::IImage* surface, void* windowId, core::rect* srcClip) ; - virtual bool isWindowActive( void ) const; - virtual bool isWindowFocused( void ) const; - virtual bool isWindowMinimized( void ) const; - virtual void closeDevice( void ); - virtual void setResizable( bool resize=false ); - virtual void minimizeWindow( void ); - virtual void maximizeWindow( void ); - virtual void restoreWindow( void ); - - //! Get the position of this window on screen + + virtual bool present(video::IImage* surface, void* windowId, core::rect* srcClip); + + virtual bool isWindowActive() const; + + virtual bool isWindowFocused() const; + + virtual bool isWindowMinimized() const; + + virtual void closeDevice(); + + virtual void setResizable(bool resize = false); + + virtual void minimizeWindow(); + + virtual void maximizeWindow(); + + virtual void restoreWindow(); + virtual core::position2di getWindowPosition(); - virtual E_DEVICE_TYPE getType( void ) const; + virtual E_DEVICE_TYPE getType() const; - //! Implementation of the linux cursor control - class CCursorControl : public gui::ICursorControl - { - public: - - CCursorControl(CIrrDeviceAndroid* dev) - : Device(dev), IsVisible(true) - { - } - - //! Changes the visible state of the mouse cursor. - virtual void setVisible(bool visible) - { - IsVisible = visible; - //if ( visible ) - // SDL_ShowCursor( SDL_ENABLE ); - //else - // SDL_ShowCursor( SDL_DISABLE ); - } - - //! Returns if the cursor is currently visible. - virtual bool isVisible() const - { - return IsVisible; - } - - //! Sets the new position of the cursor. - virtual void setPosition(const core::position2d &pos) - { - setPosition(pos.X, pos.Y); - } - - //! Sets the new position of the cursor. - virtual void setPosition(f32 x, f32 y) - { - setPosition((s32)(x*Device->DeviceWidth), (s32)(y*Device->DeviceHeight)); - } - - //! Sets the new position of the cursor. - virtual void setPosition(const core::position2d &pos) - { - setPosition(pos.X, pos.Y); - } - - //! Sets the new position of the cursor. - virtual void setPosition(s32 x, s32 y) - { - //SDL_WarpMouse( x, y ); - } - - //! Returns the current position of the mouse cursor. - virtual const core::position2d& getPosition() - { - updateCursorPos(); - return CursorPos; - } - - //! Returns the current position of the mouse cursor. - virtual core::position2d getRelativePosition() - { - updateCursorPos(); - return core::position2d(CursorPos.X / (f32)Device->DeviceWidth, - CursorPos.Y / (f32)Device->DeviceHeight); - } - - virtual void setReferenceRect(core::rect* rect=0) - { - } - - private: - - void updateCursorPos() - { - CursorPos.X = Device->MouseX; - CursorPos.Y = Device->MouseY; - - if (CursorPos.X < 0) - CursorPos.X = 0; - if (CursorPos.X > (s32)Device->DeviceWidth) - CursorPos.X = Device->DeviceWidth; - if (CursorPos.Y < 0) - CursorPos.Y = 0; - if (CursorPos.Y > (s32)Device->DeviceHeight) - CursorPos.Y = Device->DeviceHeight; - } - - CIrrDeviceAndroid* Device; - core::position2d CursorPos; - bool IsVisible; - }; - - static android_app *getAndroidApp() { return Android; } - - video::SExposedVideoData& getExposedVideoData() - { - return ExposedVideoData; - } - - video::CEGLManager* getEGLManager() - { - if (!EGLManager) - EGLManager = new video::CEGLManager(CreationParams, ExposedVideoData); - - return EGLManager; - } private: - - static android_app *Android; - ASensorManager *SensorManager; - ASensorEventQueue *SensorEventQueue; - bool Animating; - bool IsReady; - bool IsClosing; - u32 DeviceWidth, DeviceHeight; - u32 MouseX, MouseY; - void createDriver( void ); - static void handleAndroidCommand( struct android_app* app, s32 cmd ); - static s32 handleInput( struct android_app* app, AInputEvent* event ); + static void handleAndroidCommand(android_app* app, int32_t cmd); - video::SExposedVideoData ExposedVideoData; - video::CEGLManager* EGLManager; + static s32 handleInput(android_app* app, AInputEvent* event); + + void createDriver(); + + video::SExposedVideoData& getExposedVideoData(); + + video::CEGLManager* getEGLManager(); + + android_app* Android; + ASensorManager* SensorManager; + ASensorEventQueue* SensorEventQueue; + + bool Focused; + bool Initialized; + bool Paused; + + video::SExposedVideoData ExposedVideoData; + video::CEGLManager* EGLManager; }; } // end namespace irr diff --git a/source/Irrlicht/CEGLManager.cpp b/source/Irrlicht/CEGLManager.cpp index 12abdeeb..047ce14f 100755 --- a/source/Irrlicht/CEGLManager.cpp +++ b/source/Irrlicht/CEGLManager.cpp @@ -12,76 +12,121 @@ namespace irr namespace video { -CEGLManager::CEGLManager(const SIrrlichtCreationParameters& params, SExposedVideoData& data) : - EglSurface(EGL_NO_SURFACE), EglContext(EGL_NO_CONTEXT), EglConfig(0), EglReady(false), Params(params), Data(data) +CEGLManager::CEGLManager(const SIrrlichtCreationParameters& params, SExposedVideoData* data) : EglWindow(0), EglDisplay(EGL_NO_DISPLAY), + EglSurface(EGL_NO_SURFACE), EglContext(EGL_NO_CONTEXT), EglConfig(0), Params(params), Data(data), MajorVersion(0), MinorVersion(0) { -#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) - EglWindow = (NativeWindowType)data.OpenGLWin32.HWnd; - HDc = GetDC((HWND)EglWindow); - EglDisplay = eglGetDisplay((NativeDisplayType)HDc); -#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) - EglWindow = (NativeWindowType)ExposedData.OpenGLLinux.X11Window; - EglDisplay = eglGetDisplay((NativeDisplayType)ExposedData.OpenGLLinux.X11Display); -#elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) - EglWindow = (ANativeWindow*)data.OGLESAndroid.window; - EglDisplay = eglGetDisplay((NativeDisplayType) EGL_DEFAULT_DISPLAY); +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + HDc = 0; #endif - - if (EglDisplay == EGL_NO_DISPLAY) - os::Printer::log("Could not get EGL display."); } CEGLManager::~CEGLManager() { destroyContext(); - destroyEGL(); - -#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) - if (HDc) - ReleaseDC((HWND)EglWindow, HDc); -#endif + destroySurface(); + terminateEGL(); } -bool CEGLManager::createEGL() +bool CEGLManager::initializeEGL() +{ + if (EglWindow != 0 && EglDisplay != EGL_NO_DISPLAY) + return true; + +#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) + EglWindow = (NativeWindowType)Data->OpenGLWin32.HWnd; + HDc = GetDC((HWND)EglWindow); + EglDisplay = eglGetDisplay((NativeDisplayType)HDc); +#elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) + EglWindow = (NativeWindowType)Data->OpenGLLinux.X11Window; + EglDisplay = eglGetDisplay((NativeDisplayType)Data->OpenGLLinux.X11Display); +#elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) + EglWindow = (ANativeWindow*)Data->OGLESAndroid.window; + EglDisplay = eglGetDisplay((NativeDisplayType) EGL_DEFAULT_DISPLAY); +#endif + + if (EglDisplay == EGL_NO_DISPLAY) + { + os::Printer::log("Could not get EGL display."); + +#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) + if (HDc) + { + ReleaseDC((HWND)EglWindow, HDc); + HDc = 0; + } +#endif + + return false; + } + + if (!eglInitialize(EglDisplay, &MajorVersion, &MinorVersion)) + { + os::Printer::log("Could not initialize EGL display."); + + EglDisplay = EGL_NO_DISPLAY; + +#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) + if (HDc) + { + ReleaseDC((HWND)EglWindow, HDc); + HDc = 0; + } +#endif + + return false; + } + else + os::Printer::log("EGL version", core::stringc(MajorVersion+(MinorVersion*0.1f)).c_str()); + + return true; +} + +void CEGLManager::terminateEGL() +{ + if (EglWindow == 0 && EglDisplay == EGL_NO_DISPLAY) + return; + + eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + eglTerminate(EglDisplay); + EglDisplay = EGL_NO_DISPLAY; + +#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) + if (HDc) + { + ReleaseDC((HWND)EglWindow, HDc); + HDc = 0; + } +#endif + + MajorVersion = 0; + MinorVersion = 0; +} + +bool CEGLManager::createSurface() { if (EglDisplay == EGL_NO_DISPLAY) return false; - if (EglReady) + if (EglSurface != EGL_NO_SURFACE) return true; - EGLint MajorVersion = 0, MinorVersion = 0; - - if (!eglInitialize(EglDisplay, &MajorVersion, &MinorVersion)) - os::Printer::log("Could not initialize EGL display."); - else - os::Printer::log("EGL version", core::stringc(MajorVersion+(MinorVersion*0.1f)).c_str()); - EGLint Attribs[] = { -#if defined( _IRR_COMPILE_WITH_ANDROID_DEVICE_ ) - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_BLUE_SIZE, 8, - EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, Params.WithAlphaChannel ? 1:0, + EGL_BUFFER_SIZE, Params.Bits, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_DEPTH_SIZE, Params.ZBufferBits, - EGL_NONE -#else - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, params.WithAlphaChannel ? 1:0, - EGL_BUFFER_SIZE, params.Bits, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_DEPTH_SIZE, params.ZBufferBits, - EGL_STENCIL_SIZE, params.Stencilbuffer, - EGL_SAMPLE_BUFFERS, params.AntiAlias ? 1:0, - EGL_SAMPLES, params.AntiAlias, + EGL_STENCIL_SIZE, Params.Stencilbuffer, + EGL_SAMPLE_BUFFERS, Params.AntiAlias ? 1:0, + EGL_SAMPLES, Params.AntiAlias, #ifdef EGL_VERSION_1_3 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif - EGL_NONE, 0 -#endif + EGL_NONE, 0 }; EglConfig = 0; @@ -186,10 +231,7 @@ bool CEGLManager::createEGL() EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, 0, 0); if (EGL_NO_SURFACE == EglSurface) - { os::Printer::log("Could not create EGL surface."); - eglTerminate(EglDisplay); - } #ifdef EGL_VERSION_1_2 if (MinorVersion > 1) @@ -202,36 +244,23 @@ bool CEGLManager::createEGL() if (EglContext != EGL_NO_CONTEXT) eglMakeCurrent(EglDisplay, EglSurface, EglSurface, EglContext); - EglReady = true; - return true; } -bool CEGLManager::destroyEGL() +void CEGLManager::destroySurface() { - if (!EglReady) - return false; + if (EglSurface == EGL_NO_SURFACE) + return; eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroySurface(EglDisplay, EglSurface); - eglTerminate(EglDisplay); - EglSurface = EGL_NO_SURFACE; - -#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) - if (HDc) - ReleaseDC((HWND)EglWindow, HDc); -#endif - - EglReady = false; - - return true; } bool CEGLManager::createContext() { - if (EglDisplay == EGL_NO_DISPLAY || !EglReady) + if (EglDisplay == EGL_NO_DISPLAY || EglSurface == EGL_NO_SURFACE) return false; if (EglContext != EGL_NO_CONTEXT) @@ -254,19 +283,19 @@ bool CEGLManager::createContext() if (testEGLError()) os::Printer::log("Could not make EGL context current."); + + return true; } -bool CEGLManager::destroyContext() +void CEGLManager::destroyContext() { if (EglContext == EGL_NO_CONTEXT) - return false; + return; eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(EglDisplay, EglContext); EglContext = EGL_NO_CONTEXT; - - return true; } void CEGLManager::swapBuffers() diff --git a/source/Irrlicht/CEGLManager.h b/source/Irrlicht/CEGLManager.h index 534fced6..6c562fa4 100755 --- a/source/Irrlicht/CEGLManager.h +++ b/source/Irrlicht/CEGLManager.h @@ -25,22 +25,28 @@ namespace video { public: //! Constructor. - CEGLManager(const SIrrlichtCreationParameters& params, SExposedVideoData& data); + CEGLManager(const SIrrlichtCreationParameters& params, SExposedVideoData* data); //! Destructor. ~CEGLManager(); - // Create window, display and surface. - bool createEGL(); + // Initialize EGL. + bool initializeEGL(); - // Destroy window, display and surface. - bool destroyEGL(); + // Terminate EGL. + void terminateEGL(); + + // Create EGL surface. + bool createSurface(); + + // Destroy EGL surface. + void destroySurface(); // Create EGL context. bool createContext(); // Destroy EGL context. - bool destroyContext(); + void destroyContext(); // Swap buffers. void swapBuffers(); @@ -55,14 +61,15 @@ namespace video EGLConfig EglConfig; - bool EglReady; - #ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ HDC HDc; #endif SIrrlichtCreationParameters Params; - SExposedVideoData Data; + SExposedVideoData* Data; + + EGLint MajorVersion; + EGLint MinorVersion; }; } } diff --git a/source/Irrlicht/COGLESDriver.cpp b/source/Irrlicht/COGLESDriver.cpp index 9c6224f9..3c976fd2 100644 --- a/source/Irrlicht/COGLESDriver.cpp +++ b/source/Irrlicht/COGLESDriver.cpp @@ -47,7 +47,6 @@ COGLES1Driver::COGLES1Driver(const SIrrlichtCreationParameters& params, core::dimension2d WindowSize(0, 0); #if defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_WINDOWS_API_) || defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) - EGLManager->createEGL(); EGLManager->createContext(); WindowSize = params.WindowSize; @@ -96,7 +95,6 @@ COGLES1Driver::~COGLES1Driver() #if defined(_IRR_COMPILE_WITH_X11_DEVICE_) || defined(_IRR_WINDOWS_API_) || defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) EGLManager->destroyContext(); - EGLManager->destroyEGL(); #elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) if (0 != ViewFramebuffer) {