- 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
master
nadro 2013-10-17 23:11:56 +00:00
parent 5987dfc654
commit 0395fc3648
9 changed files with 371 additions and 533 deletions

View File

@ -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("");
}

View File

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

View File

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

View File

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

View File

@ -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<s32>* 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<pointerCount ; i++ )
Event.EventType = EET_MULTI_TOUCH_EVENT;
Event.MultiTouchInput.clear();
for (s32 i = 0; i < PointerCount; ++i)
{
irrEvent.MultiTouchInput.Touched[i] = 1;
irrEvent.MultiTouchInput.PrevX[i] = irrEvent.MultiTouchInput.X[i];
irrEvent.MultiTouchInput.PrevY[i] = irrEvent.MultiTouchInput.Y[i];
irrEvent.MultiTouchInput.X[i] = AMotionEvent_getX(androidEvent, i);
irrEvent.MultiTouchInput.Y[i] = AMotionEvent_getY(androidEvent, i);
if (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( ;i<NUMBER_OF_MULTI_TOUCHES ; i++ )
{
irrEvent.MultiTouchInput.Touched[i] = 0;
irrEvent.MultiTouchInput.PrevX[i] = 0;
irrEvent.MultiTouchInput.PrevY[i] = 0;
irrEvent.MultiTouchInput.X[i] = 0;
irrEvent.MultiTouchInput.Y[i] = 0;
}
Device->postEventFromUser(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

View File

@ -9,167 +9,75 @@
#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_
#include <android/sensor.h>
#include <android_native_app_glue.h>
#include "CIrrDeviceStub.h"
#include "IrrlichtDevice.h"
#include "IImagePresenter.h"
#include "ICursorControl.h"
#include "CEGLManager.h"
#include <android/sensor.h>
#include <android_native_app_glue.h>
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<s32>* 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<s32>* 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<f32> &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<s32> &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<s32>& getPosition()
{
updateCursorPos();
return CursorPos;
}
//! Returns the current position of the mouse cursor.
virtual core::position2d<f32> getRelativePosition()
{
updateCursorPos();
return core::position2d<f32>(CursorPos.X / (f32)Device->DeviceWidth,
CursorPos.Y / (f32)Device->DeviceHeight);
}
virtual void setReferenceRect(core::rect<s32>* 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<s32> 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

View File

@ -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()

View File

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

View File

@ -47,7 +47,6 @@ COGLES1Driver::COGLES1Driver(const SIrrlichtCreationParameters& params,
core::dimension2d<u32> 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)
{