Android Port

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Android Port

Post by CuteAlien »

Just some quick feedback on this. The soft keyboard handling got into Irrlicht a few days ago. The command handler stuff is currently discussed on the mailinglist - the most likely solution right now is adding another event for it, but we're still talking about the structures to use for it. So I'm coding other stuff this week - but command events will hopefully get into the engine next week.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Neirdan
Posts: 39
Joined: Tue Aug 14, 2012 10:29 pm

Re: Android Port

Post by Neirdan »

Disregard this post, I don't have the latest release


I just tried Render to texture.
It doesn't work either on OGLES1 or OGLES2
mapTextureRender = this->getVideoDriver()->addRenderTargetTexture(irr::core::dimension2d<irr::u32>(256,256));
This line on ogles2 simply unloads another texture, and when applying texture created with a camera, it just randomly displays another texture loaded (sometimes the skybox, sometimes an .obj texture).
On ogles1, the behavior is different: it simply displays a black texture.
More infos:
-My code works on desktop openGL
-I did add a light scene node and removed the light flag on my meshes (since for ogles1 light shaders works - more or less)
-My camera position & target works (again, same code, so it works)
ent1ty
Competition winner
Posts: 1106
Joined: Sun Nov 08, 2009 11:09 am

Re: Android Port

Post by ent1ty »

I implemented accelerometer and gyroscope events for the android device

Code: Select all

 
Index: CIrrDeviceAndroid.cpp
===================================================================
--- CIrrDeviceAndroid.cpp   (revision 4892)
+++ CIrrDeviceAndroid.cpp   (working copy)
@@ -33,7 +33,7 @@
 {
 
 CIrrDeviceAndroid::CIrrDeviceAndroid(const SIrrlichtCreationParameters& param)
-   : CIrrDeviceStub(param), Focused(false), Initialized(false), Paused(true), JNIEnvAttachedToVM(0)
+   : CIrrDeviceStub(param), Accelerometer(0), Gyroscope(0), Focused(false), Initialized(false), Paused(true), JNIEnvAttachedToVM(0)
 {
 #ifdef _DEBUG
    setDebugName("CIrrDeviceAndroid");
@@ -104,14 +104,46 @@
 
    os::Timer::tick();
 
+   s32 ID;
    s32 Events = 0;
    android_poll_source* Source = 0;
 
-   while ((ALooper_pollAll(((Focused && !Paused) || !Initialized) ? 0 : -1, 0, &Events, (void**)&Source)) >= 0)
+   while ((ID = ALooper_pollAll(((Focused && !Paused) || !Initialized) ? 0 : -1, 0, &Events, (void**)&Source)) >= 0)
    {
        if(Source)
            Source->process(Android, Source);
 
+       // if a sensor has data, we'll process it now.
+        if (ID == LOOPER_ID_USER)
+       {
+           ASensorEvent sensorEvent;
+           while (ASensorEventQueue_getEvents(SensorEventQueue, &sensorEvent, 1) > 0)
+           {
+               switch (sensorEvent.type)
+               {
+                   case ASENSOR_TYPE_ACCELEROMETER:
+                       SEvent accEvent;
+                       accEvent.EventType = EET_ACCELEROMETER_EVENT;
+                       accEvent.AccelerometerEvent.X = sensorEvent.acceleration.x;
+                       accEvent.AccelerometerEvent.Y = sensorEvent.acceleration.y;
+                       accEvent.AccelerometerEvent.Z = sensorEvent.acceleration.z;
+                       
+                       postEventFromUser(accEvent);
+                       break;
+
+                   case ASENSOR_TYPE_GYROSCOPE:
+                       SEvent gyroEvent;
+                       gyroEvent.EventType = EET_GYROSCOPE_EVENT;
+                       gyroEvent.GyroscopeEvent.X = sensorEvent.vector.x;
+                       gyroEvent.GyroscopeEvent.Y = sensorEvent.vector.y;
+                       gyroEvent.GyroscopeEvent.Z = sensorEvent.vector.z;
+
+                       postEventFromUser(gyroEvent);
+                       break;
+               }
+           }
+       }
+
        if(!Initialized)
            break;
    }
@@ -192,6 +224,82 @@
    return core::position2di(0, 0);
 }
 
+bool CIrrDeviceAndroid::activateAccelerometer(float updateInterval)
+{
+   if (!isAccelerometerAvailable())
+       return false;
+
+   ASensorEventQueue_enableSensor(SensorEventQueue, Accelerometer);
+    ASensorEventQueue_setEventRate(SensorEventQueue, Accelerometer, updateInterval*1000*1000); // in microseconds
+   
+   os::Printer::log("Activated accelerometer", ELL_DEBUG);
+   return true;
+}
+
+bool CIrrDeviceAndroid::deactivateAccelerometer()
+{
+   if (Accelerometer)
+   {
+       ASensorEventQueue_disableSensor(SensorEventQueue, Accelerometer);
+       Accelerometer = 0;
+       os::Printer::log("Deactivated accelerometer", ELL_DEBUG);
+       return true;
+   }
+
+   return false;
+}
+
+bool CIrrDeviceAndroid::isAccelerometerActive()
+{
+   return (Accelerometer != 0);
+}
+
+bool CIrrDeviceAndroid::isAccelerometerAvailable()
+{
+   if (!Accelerometer)
+       Accelerometer = ASensorManager_getDefaultSensor(SensorManager, ASENSOR_TYPE_ACCELEROMETER);
+
+   return (Accelerometer != 0);
+}
+
+bool CIrrDeviceAndroid::activateGyroscope(float updateInterval)
+{
+   if (!isGyroscopeAvailable())
+       return false;
+
+   ASensorEventQueue_enableSensor(SensorEventQueue, Gyroscope);
+    ASensorEventQueue_setEventRate(SensorEventQueue, Gyroscope, updateInterval*1000*1000); // in microseconds
+   
+   os::Printer::log("Activated gyroscope", ELL_DEBUG);
+   return true;
+}
+        
+bool CIrrDeviceAndroid::deactivateGyroscope()
+{
+   if (Gyroscope)
+   {
+       ASensorEventQueue_disableSensor(SensorEventQueue, Gyroscope);
+       Gyroscope = 0;
+       os::Printer::log("Deactivated gyroscope", ELL_DEBUG);
+       return true;
+   }
+
+   return false;
+}
+        
+bool CIrrDeviceAndroid::isGyroscopeActive()
+{
+   return (Gyroscope != 0);
+}
+        
+bool CIrrDeviceAndroid::isGyroscopeAvailable()
+{
+   if (!Gyroscope)
+       Gyroscope = ASensorManager_getDefaultSensor(SensorManager, ASENSOR_TYPE_GYROSCOPE);
+
+   return (Gyroscope != 0);
+}
+
 E_DEVICE_TYPE CIrrDeviceAndroid::getType() const
 {
    return EIDT_ANDROID;
Index: CIrrDeviceAndroid.h
===================================================================
--- CIrrDeviceAndroid.h (revision 4892)
+++ CIrrDeviceAndroid.h (working copy)
@@ -54,6 +54,22 @@
 
        virtual core::position2di getWindowPosition();
 
+       virtual bool activateAccelerometer(float updateInterval);
+
+        virtual bool deactivateAccelerometer();
+
+        virtual bool isAccelerometerActive();
+
+        virtual bool isAccelerometerAvailable();
+       
+       virtual bool activateGyroscope(float updateInterval);
+        
+       virtual bool deactivateGyroscope();
+        
+       virtual bool isGyroscopeActive();
+        
+       virtual bool isGyroscopeAvailable();
+
        virtual E_DEVICE_TYPE getType() const;
 
    private:
@@ -71,6 +87,8 @@
        android_app* Android;
        ASensorManager* SensorManager;
        ASensorEventQueue* SensorEventQueue;
+       const ASensor* Accelerometer;
+       const ASensor* Gyroscope;
 
        bool Focused;
        bool Initialized;
 
 
Here in better-readable plain text
irrRenderer 1.0
Height2Normal v. 2.1 - convert height maps to normal maps

Step back! I have a void pointer, and I'm not afraid to use it!
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Android Port

Post by Nadro »

Thanks for this patch. Currently I'm more focused on video drivers things in both ogl-es and shader-pipeline than pure Android stuff, but when I'll find some time I'll merge it with trunk, but maybe CuteAlien will be faster than me :)
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Android Port

Post by The_Glitch »

And I thought you died..... silly me
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Android Port

Post by CuteAlien »

I suppose entity already noticed the problems - that you can't call the tool functions like activateAccelerometer from user-code. Hybrid had a proposal for this part of the interface recently on the mailinglist. But his proposal also moved the events away which was something I wasn't so happy about. But anyway - the part that checks for device availability and enables/disables them belongs into own interfaces - that's something where Hybrid and me agreed on I think. Not sure about events for now. I would put them in there like entity, but not sure Hybrid agrees to this or not at the moment.

Is the poll code really in the right place? On first view it looks like it checks for events once in the setup phase and then never again.

Thanks for the code, it will make it easier to work on this at least. I had planned to work on it, but due to lack of time it's likely a feature I have to drop in my game, which means I won't get to it this time.

Also I'm still struggling with command events. Hybrid gave some good feedback about the downside of a proposal I had for that (passing through all system events to users generally), but I'm still not seeing another good solution (so I coded other stuff instead last week).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
ent1ty
Competition winner
Posts: 1106
Joined: Sun Nov 08, 2009 11:09 am

Re: Android Port

Post by ent1ty »

CuteAlien wrote:I suppose entity already noticed the problems - that you can't call the tool functions like activateAccelerometer from user-code.
Uhmm actually, the interface for irrlicht device in the ogl-es branch has those methods declared...
https://github.com/3ntity/irrlicht-git/ ... ice.h#L264
CuteAlien wrote: Hybrid had a proposal for this part of the interface recently on the mailinglist. But his proposal also moved the events away which was something I wasn't so happy about. But anyway - the part that checks for device availability and enables/disables them belongs into own interfaces - that's something where Hybrid and me agreed on I think. Not sure about events for now. I would put them in there like entity, but not sure Hybrid agrees to this or not at the moment.
Not sure what you mean by this, the android device is there for android-specific code, is it not
CuteAlien wrote:Is the poll code really in the right place? On first view it looks like it checks for events once in the setup phase and then never again.
The events are checked for every time you call Device::run(). Yes, they have to be checked for in there. You can move the code into a private function, but you have to call it from Device::run() anyway.


Edit: Just to be perfectly clear, i didn't add anything into the interface, the methods and the event structs were already in place. I only implemeted those 8 methods for the android device and added some code which fires the events. You can use it from the IrrlichtDevice interface class.
irrRenderer 1.0
Height2Normal v. 2.1 - convert height maps to normal maps

Step back! I have a void pointer, and I'm not afraid to use it!
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Android Port

Post by CuteAlien »

Ow, I didn't see someone had added such an interface in that header. Probably happened for iOS. But can't say I'm happy with this interface :-( I finally get why Hybrid thought it was so important to rework input-devices before merging ogl-es branch with trunk. I had completely missed that someone added those functions.

About the other lines... sorry, I just got confused because I thought it's put in the constructor (that has identical looking ALooper_pollAll code and I didn't notice the line-numbers jump). So yes, that part is correct and like I would like to see it added.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Android Port

Post by Nadro »

CuteAlien wrote:Probably happened for iOS. But can't say I'm happy with this interface :-( I finally get why Hybrid thought it was so important to rework input-devices before merging ogl-es branch with trunk. I had completely missed that someone added those functions.
Yes, I added it for handle iOS stuff ~1 year ago. I talked about it with Hybrid and we agreed that it's good just as temp solution, however an event system still isn't redesigned.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
ent1ty
Competition winner
Posts: 1106
Joined: Sun Nov 08, 2009 11:09 am

Re: Android Port

Post by ent1ty »

Does anyone know how I can check whether the android device suppors NPOT render target textures?
I found out the Nexus 7(2012) does not support those, but an Xperia mini (2011) does, which was weird.
irrRenderer 1.0
Height2Normal v. 2.1 - convert height maps to normal maps

Step back! I have a void pointer, and I'm not afraid to use it!
BinMa
Posts: 19
Joined: Wed Feb 19, 2014 8:59 am

Re: Android Port

Post by BinMa »

ent1ty wrote:Does anyone know how I can check whether the android device suppors NPOT render target textures?
I found out the Nexus 7(2012) does not support those, but an Xperia mini (2011) does, which was weird.
I've met NPOT issue in my project too. try to check it like below.

Code: Select all

if (driver->getDriverType() == EDT_OGLES2) {
    isNPOTSupported = ((COGLES2Driver *) driver)->queryOpenGLFeature(COGLES2ExtensionHandler::IRR_OES_texture_npot);
} else {
    isNPOTSupported = ((COGLES1Driver *) driver)->queryOpenGLFeature(COGLES1ExtensionHandler::IRR_OES_texture_npot);
}
 
luthyr
Posts: 69
Joined: Wed Dec 30, 2009 5:47 pm

Re: Android Port

Post by luthyr »

These may be two separate issues, but I am wondering how to implement context preservation via setPreserveEGLContextOnPause so that when returning to the application, it doesn't force a reload. I am currently getting the application and phone to hang whenever I go to and return from the lock screen, so I'm not sure how else to resolve these issues.
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Android Port

Post by Nadro »

You should update ogl-es branch, because this issue was fixed some time ago. You don't need setPreserveEGLContextOnPause etc.

With OpenGL ES2.0 driver you don't need "IRR_OES_texture_npot" if mipmaps are disabled and wrap mode is set to clamp to edge, however some buggy drivers may have problems with that.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
luthyr
Posts: 69
Joined: Wed Dec 30, 2009 5:47 pm

Re: Android Port

Post by luthyr »

Hmm, I've been mostly keeping up to date with the branch (at least regarding driver files), but still get lock up even with hello world android example. I have some modifications elsewhere in Irrlicht (though not in system/video driver stuff), so I don't yet know if this is entirely on my end.

If I break in debugger after attempting to return out of lock screen, it shows it stuck at:
pthread_mutex_unlock(&android_app->mutex);

Code: Select all

 
static void android_app_free(struct android_app* android_app) {
    pthread_mutex_lock(&android_app->mutex);
    android_app_write_cmd(android_app, APP_CMD_DESTROY);
    while (!android_app->destroyed) {
        pthread_cond_wait(&android_app->cond, &android_app->mutex);
    }
    pthread_mutex_unlock(&android_app->mutex);
 
    close(android_app->msgread);
    close(android_app->msgwrite);
    pthread_cond_destroy(&android_app->cond);
    pthread_mutex_destroy(&android_app->mutex);
    free(android_app);
}
 
When I shut off my phone screen, the device requests to be destroyed and so I exit my program, but while the screen is off it creates the application again and eventually seems to get stuck in in ALooper_pollAll function in CIrrDeviceAndroid::run() if I am reading things right. I am not sure if this is the proper behavior.
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Android Port

Post by Nadro »

Please checkout ogl-es again, build Android example and check how it works. Phone model + Android version may be useful too.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
Post Reply