Android Port

Announce new projects or updates of Irrlicht Engine related tools, games, and applications.
Also check the Wiki
grafikrobot
Posts: 44
Joined: Wed Dec 26, 2007 11:42 pm

Post by grafikrobot »

JNI might not kill performance depending on how you do it. If you avoid writing the main loop in Java you should be OK. But as far as bindings go.. I'd also favor being minimal and leaving it up to the game developers to make their own and just providing sufficient hooks to get Irrlicht rendering and interacting with the system (i.e. events and system access). This is what the iPhone port does and seems to works reasonably well.

And yes, I'm interested in an Android port.. As Android is in my list of platforms that would be nice to port my iPhone games to :-)
slytron
Posts: 10
Joined: Wed Oct 15, 2008 1:19 am
Contact:

irrlichtandroid compile errors

Post by slytron »

I checked out irrlichtandroid and tried to compile in cygwin and got the following errors: .. how do I include the irrlicht header when it compiles ?

$ make APP=irrlichtandroid
Android NDK: Building for application 'irrlichtandroid'
Compile++ arm : irrlicht <= apps/irrlichtandroid/project/jni/app-android.cpp
apps/irrlichtandroid/project/jni/app-android.cpp:27:22: warning: irrlicht.h: No
such file or directory
apps/irrlichtandroid/project/jni/app-android.cpp:29: error: 'irr' is not a names
pace-name
apps/irrlichtandroid/project/jni/app-android.cpp:29: error: expected namespace-n
ame before ';' token
apps/irrlichtandroid/project/jni/app-android.cpp:31: error: 'core' is not a name
space-name

etc

BTW thanks very much for publishing the port to android.. way cool
ellis2323
Posts: 37
Joined: Fri Feb 05, 2010 5:33 pm

Cygwin: Android.mk

Post by ellis2323 »

I'm coding on Mac OS X. But, it is probably an include problem. Open the Android.mk and modify the -Iapps/irrlicht/project/include/.

Try to put the absolute path.
slytron
Posts: 10
Joined: Wed Oct 15, 2008 1:19 am
Contact:

android compile

Post by slytron »

thanks ellis. that sounds like it would have fixed it. My fix was to just copy the include files into the src directory. It now compiles with eclipse/ndk/cygwin on windows xp.
New question. How do you plan to make the meshes and textures in your android app accessible from irrlicht c++. My current plan is to place them in the assets folder then copy them to the sdcard on startup using java so irrlicht can access them. Is there a better way?
ellis2323
Posts: 37
Joined: Fri Feb 05, 2010 5:33 pm

I do the same

Post by ellis2323 »

After looking on NDK mailing list, it appears that there is no other solution. So i put all my data in assets. And with the assetManager, i copy all data on /sdcard/irrlicht.
slytron
Posts: 10
Joined: Wed Oct 15, 2008 1:19 am
Contact:

thanks

Post by slytron »

I will be doing more or less the same thing.
I want to thank you again for publishing the source.
Best of Luck
ellis2323
Posts: 37
Joined: Fri Feb 05, 2010 5:33 pm

Need help to use gdb

Post by ellis2323 »

I try to use gdb without success on NDK. if you succeded, please help me...

http://groups.google.com/group/android- ... f5cc08714e
ellis2323
Posts: 37
Joined: Fri Feb 05, 2010 5:33 pm

Code unstable

Post by ellis2323 »

I'm trying to make some tests:
- scene 1: a sydney walking
- scene 2: load a quake like level
- scene 3: load a terrain with skydome or skybox

All is working... but often i have strange behaviours:
- by example, i modify one line of code or add a log and it works again. I'm not sure if gcc is doing poop but it is very painfull.
- better the code is working on emulator (2.1) but not on G1

But without gdb it is painfull to understand what is the problem.
ellis2323
Posts: 37
Joined: Fri Feb 05, 2010 5:33 pm

Compilation on AOSP

Post by ellis2323 »

Hi,

I didn't find how to debug with NDK. Not sure it is possible. So i'm using AOSP (Android Open Source Project).
grumpymonkey
Posts: 222
Joined: Mon Jan 19, 2009 10:03 pm
Location: Miami, Florida
Contact:

Post by grumpymonkey »

OMFG YOUR MY GOD!
Image
ellis2323
Posts: 37
Joined: Fri Feb 05, 2010 5:33 pm

Good news

Post by ellis2323 »

I have found a way to have my symbols in gdb. With this, i found errors and i will publish an update which allow font drawing.

On other side, i have posted a test of OpenGL ES 2.0:

http://www.scigems.org/downloads/HelloGL2.apk

If you have a Nexus One or an Acer Liquid, please test it and report FPS (in logcat).
slytron
Posts: 10
Joined: Wed Oct 15, 2008 1:19 am
Contact:

Some code to copy files from assets to sdcard

Post by slytron »

I am using the android port.
I use code similar to the following to copy the files using java in the Activity onCreate so that they are available to the c++ irrlicht code

Code: Select all

  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AssetManager assetManager = getAssets();  
        String[] files = null;  
        try 
        {  
             files = assetManager.list("");  
        }catch (IOException e) 
        {  
             Log.e(LOG_TAG, e.getMessage());  
        }  
        String strSdcardPath = "/sdcard/";
        String strDestFile;
        int iFileCnt = files.length;
        for( int i = 0; i < iFileCnt; i++)
        {
        	String strFileNameSrc = files[i];
        	if( strFileNameSrc.contentEquals("images"  ) ||
        			strFileNameSrc.contentEquals("sounds" ) ||
        			strFileNameSrc.contentEquals("skins" ) ||
        			strFileNameSrc.contentEquals("webkit" ) )
        	{
        		// dont copy.. not really a asset file
        		continue;
        	}
        	strDestFile = strSdcardPath + strFileNameSrc;
        	VxCopyAsssetToSdcard(strFileNameSrc, strDestFile, true);			
        }

//////////////////////////////////
	int VxCopyAsssetToSdcard( String strFileSrc, String strFileDest, boolean bDontCopyIfExistsAndSameSize )
	{
		int iSrcFileSize = 0;
		int iDestFileSize = 0;
		InputStream oInputStream = null;
		OutputStream oOutputStream = null;
		// get src file size and stream
		try 
		{
			oInputStream = m_oRes.getAssets().open(strFileSrc);
        	if( null != oInputStream)
        	{
        		iSrcFileSize = oInputStream.available();
        	}
        	else
        	{
                Log.e(LOG_TAG, "ERROR: VxCopyResourceToSdcard could not open file " + strFileSrc );  
        		return -1;
        	}
		} 
		catch (IOException e) 
		{
            Log.e(LOG_TAG, "ERROR: VxCopyResourceToSdcard could not open file " + strFileSrc );  
			// TODO Auto-generated catch block
			e.printStackTrace();
    		return -1;
		}
		if( bDontCopyIfExistsAndSameSize )
		{
			// get dest file size and stream
			try 
			{
				InputStream oTmpStream = null;
				File readFile = new File( strFileDest); 
				oTmpStream = new FileInputStream(readFile);  ;
	        	if( null != oTmpStream)
	        	{
	        		iDestFileSize = oTmpStream.available();
	        		oTmpStream.close();
	        	}
	        	else
	        	{
	                Log.e(LOG_TAG, "ERROR: VxCopyAsssetToSdcard could not get size of file " + strFileDest );  
	        		return -1;
	        	}
			} 
			catch (IOException e) 
			{
	            Log.e(LOG_TAG, "VxCopyAsssetToSdcard dest file doesnt exist.. will copy " + strFileDest );  
			}
		}
		if( bDontCopyIfExistsAndSameSize && ( iSrcFileSize == iDestFileSize))
		{
            Log.i(LOG_TAG, "VxCopyAsssetToSdcard file exists " + strFileDest );
            return 0;
		}
        // Read the entire asset into a local byte buffer.
        byte[] buffer = new byte[iSrcFileSize];
        try 
        {
			oInputStream.read(buffer);
	        oInputStream.close();
		} 
        catch (IOException e) 
        {
            Log.e(LOG_TAG, "ERROR: VxCopyAsssetToSdcard could not read file " + strFileSrc );  
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// write buffer to destination file
		try 
		{
			File oWriteFile = new File( strFileDest);
			try
			{  
				oWriteFile.createNewFile();  
			} 
			catch (IOException e) 
			{  
			   Log.e(LOG_TAG, "error creating file " + strFileDest, e);
   				e.printStackTrace();
			   return -1;
			}
			oOutputStream = new FileOutputStream(oWriteFile);  
			//Don’t forget to close stream
			if (oOutputStream != null) 
			{  
			    try 
			    {  
					oOutputStream.write(buffer); 
			    	oOutputStream.flush();  
			    	oOutputStream.close();  
			    	Log.i(LOG_TAG, "Success copying file " + strFileDest + " size " + iSrcFileSize );
			    } 
			    catch (IOException e) 
			    {  
	                Log.e(LOG_TAG, "ERROR: VxCopyResourceToSdcard could not write file " + strFileDest );  
	    			e.printStackTrace();
	        		return -1;
			    }  
			}
		}
		catch (IOException e) 
		{
			Log.e(LOG_TAG, "ERROR: VxCopyAsssetToSdcard could not read file " + strFileSrc );  
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
		return 0;
	}

ellis2323
Posts: 37
Joined: Fri Feb 05, 2010 5:33 pm

Thx Slytron

Post by ellis2323 »

I use similar code and i will provide a demo activity with a such data installer.

Probably i will mix your code and my code.

Question:
- what is your phone ?
- did you debug with NDK or AOSP?

I think that a tutorial to setup AOSP or NDK will be great.
slytron
Posts: 10
Joined: Wed Oct 15, 2008 1:19 am
Contact:

my phone and setup

Post by slytron »

Development OS: windows XP
My phone: motorola droid
My setup: I doubt I could remember all the steps but in general

make a folder C:\PhoneDev
make folders C:\PhoneDev\workspace and C:\PhoneDev\sdks
SDK setup
Install the latest sdk to C:\PhoneDev\sdks\android-sdk by following the
instructions here http://developer.android.com/intl/de/sd ... quickstart
I used the eclipse-java-galileo-SR2-win32.zip version of eclipse from
http://www.eclipse.org/downloads/downlo ... -win32.zip
NDK setup
install cygwin from http://www.cygwin.com/
I installed all packages of cygwin
download and extract the ndk from http://developer.android.com/intl/de/sd ... index.html
copy the contents of the extracted folder to C:\PhoneDev\sdks\android-ndk

run cygwin and cd to /cygdrives/c/PhoneDev/sdks/android-ndk/build/
execute command "export ANDROID_NDK_ROOT=/cygdrives/c/PhoneDev/sdks/android-ndk"
run the ndk setup with the command ./host-setup.sh

NOTE: I actually installed everything to my F: drive and had some issues with setting things up so in cygwin I made a directory /apps with the commad mkdir /apps then in the /etc/fstab file I added the line F:/PhoneDev/sdks/android-ndk /apps ntfs binary 0 0
this was so that the ndk apps directory was easilly accessable

once this is done make sure you can build hello-jni to make sure everything is installed and working

After working from the command line which is tedious I found a way to edit cpp files in eclipse and have it automatically build when the file is save and show the build results in eclipse..
If you like working from the eclipse gui instead of the command line follow the instructions at http://www.rbgrn.net/content/348-get-yo ... ted-ndk-on

Debugging
I never found a good way to debug so I just use lots of logging and asserts
the logging does show up in eclipse Catlog so that I dont have to open a log file or anything
example of how to log a message in cpp
log_msg( 0, "Failed getting earth texture");
example of assert
vx_assert( NULL != poEarthTex);

here is my code I use
vx_debug.h



Code: Select all

#pragma once
//============================================================================
// Copyright (C) 2010-2011 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brett.r.jones@gmail.com
// http://www.roguetreasure.com
//============================================================================



typedef void (*LOG_FUNCTION )( unsigned long, char * );

/// log message types
#define MSG_TYPE_STATUS				0x00
#define MSG_TYPE_ERR				0x01
#define MSG_TYPE_FATAL_ERR			0x02
#define MSG_TYPE_DEBUG				0x04
#define MSG_TYPE_LOG				0x08
#define MSG_TYPE_ASSERTION			0x10

// log message source flags.. should be or'd with log message types
// Applications should define their own source flags in available bits 17–32
#define MSG_SRC_UNKNOWN				0x00000000
#define MSG_SRC_TC					0x00000100
#define MSG_SRC_IRR					0x00000200
#define MSG_SRC_GAME				0x00000400

// handy macro to determine if log message is a fatal error
#define IS_FATAL_ERR( msgtype ) ( MSG_TYPE_FATAL_ERR & msgtype )

#define TC_STATUS		(MSG_SRC_TC | MSG_TYPE_STATUS)
#define TC_ERR			(MSG_SRC_TC | MSG_TYPE_ERR)
#define TC_FATAL_ERR	(MSG_SRC_TC | MSG_TYPE_FATAL_ERR)
#define TC_DBG			(MSG_SRC_TC | MSG_TYPE_DEBUG)
#define TC_LOG			(MSG_SRC_TC | MSG_TYPE_LOG)
#define TC_ASSERTION	(MSG_SRC_TC | MSG_TYPE_LOG)

#define IRR_STATUS		(MSG_SRC_IRR | MSG_TYPE_STATUS)
#define IRR_ERR			(MSG_SRC_IRR | MSG_TYPE_ERR)
#define IRR_FATAL_ERR	(MSG_SRC_IRR | MSG_TYPE_FATAL_ERR)
#define IRR_DBG			(MSG_SRC_IRR | MSG_TYPE_DEBUG)
#define IRR_LOG			(MSG_SRC_IRR | MSG_TYPE_LOG)

#define GAME_STATUS		(MSG_SRC_GAME | MSG_TYPE_STATUS)
#define GAME_ERR		(MSG_SRC_GAME | MSG_TYPE_ERR)
#define GAME_FATAL_ERR	(MSG_SRC_GAME | MSG_TYPE_FATAL_ERR)
#define GAME_DBG		(MSG_SRC_GAME | MSG_TYPE_DEBUG)
#define GAME_LOG		(MSG_SRC_GAME | MSG_TYPE_LOG)


/// set function that logs a message
void set_log_handler( LOG_FUNCTION pfuncLogHandler );

/// log a message
void log_msg( unsigned long u32MsgType, const char* msg, ...);

#define MAX_ERR_MSG_SIZE 2048

#ifdef _DEBUG
	/// This function is called by vx_assert() when the assertion fails.
	void  vx_error_output(char* exp, char * file, int line);
	// debug mode throws message if expression is false
	#define vx_assert(exp) { if (!(exp)) vx_error_output((char*)#exp,(char*)__FILE__,__LINE__); }
	#define vx_verify(exp) { if (!(exp)) vx_error_output((char*)#exp,(char*)__FILE__,__LINE__); }

#else
	// release mode evaluates vx_assert ect to null
	#define vx_assert(exp)
	#define vx_verify(exp) (exp)
#endif // RELEASE_MODE

vx_debug.cpp

Code: Select all

//============================================================================
// Copyright (C) 2010-2011 Brett R. Jones
// All Rights Reserved
//
// You may redistribute and/or modify for non commercial and commercial uses
// provided this copyright notice remains in place and is not modified
//
// This code is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// brett.r.jones@gmail.com
// http://www.roguetreasure.com
//============================================================================#include "VxUtilLib.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef WIN_PLATFORM
	#include "windows.h"
#endif// WIN_PLATFORM
#ifdef ANDROID_PLATFORM
	#include <android/log.h>
#endif// ANDROID_PLATFORM



void default_log_handler( unsigned long u32MsgType, char * pLogMsg );
void vx_error( const char* msg, ...);

LOG_FUNCTION g_pfuncLogHandler = default_log_handler;

//------------------------------------------------------------------------------
/// This function sets the handler of log messages
void set_log_handler( LOG_FUNCTION pfuncLogHandler )
{
	g_pfuncLogHandler = pfuncLogHandler;
}

//------------------------------------------------------------------------------
/// This function is called by vx_assert() when the assertion fails.
void  vx_error_output(char* exp, char * file, int line)
{
    vx_error("** RT ASSERTION **\r\nexpression: %s\r\nfile: %s\r\nline: %d\r\n", exp, file, line);
}

//------------------------------------------------------------------------------
/// This function is called by vx_assert2() when the assertion fails.
void vx_error_output2(char* exp, char* msg, char* file, int line)
{
    vx_error("** RT ASSERTION ***\r\nprogrammer says: %s\r\nexpression: %s\r\nfile: %s\r\nline: %d\r\n", msg, exp, file, line);
}

//------------------------------------------------------------------------------
/// This function is called when a serious situation is encountered which
/// requires abortion of the program.
void vx_error( const char* msg, ...)
{
	char as8Buf[ MAX_ERR_MSG_SIZE * 2 ];
    va_list argList;
    va_start(argList, msg);
	vsprintf( as8Buf, msg, argList );
    va_end(argList);

	// append the module name
	//strcat( as8Buf, "Module Name: " );
	//char as8ModuleName[ MAX_PATH ];
	//VxGetExecuteModuleName( as8ModuleName, sizeof( as8ModuleName ) );
	//strcat( as8Buf, as8ModuleName );
	//strcat( as8Buf, "\r\n\r\n" );

	//printf( as8Buf ); // show the error
	//std::string strAssertFile = g_strUserAppDataDir +  "vx_assert.txt";	
	//VxWriteWholeFile( strAssertFile.c_str(), as8Buf, (U32)strlen( as8Buf ) );
 //   fflush(stdout);
	log_msg( MSG_TYPE_ASSERTION,  as8Buf ); // send to log
	//if( wxTheApp )
	//{
	//	// if widgets is running attept to show the error
	//	wxMessageBox( as8Buf, "Program Error", wxICON_ERROR | wxICON_STOP );
	//}
    abort();
};
//------------------------------------------------------------------------------
/// default log handler
void default_log_handler( unsigned long u32MsgType, char * pLogMsg )
{
#ifdef ANDROID_PLATFORM
	__android_log_print(ANDROID_LOG_INFO, "AndroidNative", pLogMsg);
#else
	printf( pLogMsg );
#endif// ANDROID_PLATFORM
}
//------------------------------------------------------------------------------
/// log a message
void log_msg( unsigned long u32MsgType, const char* msg, ... )
{
	char as8Buf[ MAX_ERR_MSG_SIZE ];
    va_list argList;
    va_start(argList, msg);
	vsprintf( as8Buf, msg, argList );
    va_end(argList);
#ifdef WIN_PLATFORM
	#ifdef _DEBUG
		OutputDebugStringA(as8Buf);
	#endif //_DEBUG
#endif // WIN_PLATFORM

	// send to log handler
	g_pfuncLogHandler( u32MsgType, as8Buf );
}

I have not completed my code for callback into c++ code for mouse and gyroscope events but here is the example I am using for the basics
http://android.wooyd.org/JNIExample/
ellis2323
Posts: 37
Joined: Fri Feb 05, 2010 5:33 pm

Please send me patch

Post by ellis2323 »

If you find bugs and know how to fix them, please send me a mail with patch or diff.

laurent dot mallet _at_ gmail dot com.
Post Reply