Port Ogre to Android?

A place for users of OGRE to discuss ideas and experiences of utilitising OGRE in their games / demos / applications.
Post Reply
User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

Hi CrystaX,

I had some problems with the old version which I resolved by downloading the darwin function and just replace the executables with the windows ones.
I guess thats about the same as you did, anyway...Thanks for this great work! I only had some issues with the build-toolchain.sh because on your website you state that you have uses a src.diff file to patch GCC after it has been downloaded, but I didn't have that one so build-toolchain.sh would always fail.

Anyway, Thanks! this has helped a great deal and I'm almost at the point where I have fully ported Ogre over to android because of your lib. (I was basically doing the same, but at a much harder way before we noticed you released a modified NDK).

BTW, have you ever looked into getting the libs from the android device itself and link to those? I'm currently trying this out with EGL and libEGL.so found in /system/lib. But with Android 2.0 there is also a libGLESv2.so file so we can extract that one and enable GLES2.
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

calsmurf2904 wrote:Alright, when linked its too large. But I found out that when putting it together in the apk files its smaller. Now I only need to get the adb install command to succeed.

One other thing I found out is that you can use the commands:

Code: Select all

adb pull /system/lib/<library name> <path>
To get the libraries the system has to your device. Which you could then link against. :)
So you could do:

Code: Select all

adb pull /system/lib/libEGL.so ./android-libs
to get the lib of the device/emulator and link against it so that you have full EGL support. :)
(You can get the EGL include files android used here: http://www.netmite.com/android/mydroid/ ... lude/GLES/)

Same thing can be done with libGLESv2.so :)
Not sure if the libs are in compatible format though, but it works to get them off the device. :)
This actually works :) I have successfully linked the libEGL to the rest and have now full EGL support for android. :)
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

CrystaX
Gnoblar
Posts: 2
Joined: Sat Feb 27, 2010 7:58 pm

Re: Port Ogre to Android?

Post by CrystaX »

Hi,

> I had some problems with the old version which I resolved by downloading the darwin function and just replace the executables with the windows ones. I guess thats about the same as you did, anyway...Thanks for this great work!

You actually have old (broken) windows version and new (fixed) darwin. Then you've mixed them and it became working. You are lucky guy :)
Downloading fixed windows version will get you into the more right state.

> I only had some issues with the build-toolchain.sh because on your website you state that you have uses a src.diff file to patch GCC after it has been downloaded, but I didn't have that one so build-toolchain.sh would always fail.

One of the things my patch (http://www.crystax.net/data/android-ndk ... ystax.diff) doing is creating of that src.diff :)
So just follow build instructions on my web-site - it should work. Note that diff also was changed since Feb 23 so re-download it again.

> BTW, have you ever looked into getting the libs from the android device itself and link to those? I'm currently trying this out with EGL and libEGL.so found in /system/lib. But with Android 2.0 there is also a libGLESv2.so file so we can extract that one and enable GLES2.

Yes, it definitely should work. The only drawback is that applications links to library with unstable ABI - it could be broken in next releases without notifications. It could be really annoying problem so my choice - thin Java wrapper for using such libraries

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

CrystaX wrote:Yes, it definitely should work. The only drawback is that applications links to library with unstable ABI - it could be broken in next releases without notifications. It could be really annoying problem so my choice - thin Java wrapper for using such libraries
Yes, I thought so too...but when looking at the egl.h android has in its core system its just the normal egl.h with some android extensions. When you use the normal EGL functions nothing is wrong. Same with the GLES2 headers. So I think when using GLES2 or EGL its quite stable when not using any android extensions.
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

User avatar
roguetreasure
Gnoblar
Posts: 1
Joined: Sun Feb 28, 2010 7:58 pm
Location: Oklahoma
Contact:

Re: Port Ogre to Android?

Post by roguetreasure »

Hi all,
I am working on creating a small commercial 3d game for android that is a bit more complex than a "roll a marble through the maze" game and requires a few explosion special effects etc.
I have compiled and played with the irrlicht port and with just a skybox and a single rotating globe I could only get 21 FPS in the emulator and 53 FPS on my Motorola Droid Phone which is a bit disappointing. I found a quake 3 android port but have not investigated using it.
I don't want to start a flame war of engine X is better than engine Y but do want opinions about the best/fastest 3D graphics engine for under $200.00. I am proficient with c++ and not a newbie to 3d graphics but my knowledge of optimizing opengl es is nill. Could someone point out where to go for more info on opengl es optimization or a graphics engine I can use or buy for under $200.00. Does the ogre port look like it might get completed in the next 2 months ?

irrlicht port
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=37235
quake 3 port
http://code.google.com/p/kwaak3/
android apps and games http://www.roguetreasure.com

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

Well, I actually got it linked etc. But its too large. I need to find some flags so that I can optimize and reduce the size of the compiled library. If thats done then I have a fully ogre port working (I think, need to look into how its working then). The android phones (atleast the newer ones) should have a graphics chip compliant or better then the iPhone graphics chip, and the Ogre iPhone port runs at good speed on it with GLES1. I'm currently also porting the renderer for the iPhone port (the GLES rendersystem) over to android. It should be running at good speed, if I can get the size down. The emulator only has an userdata space of 67mb, and the OgreAndroid wrapper is linked 107mb. So I need to get it below 67mb. This wrapper is linked with OgreMain and OgreGLESRenderSystem. It would become an issue when I'm porting over the GLES2 rendersystem since the wrapper needs to be linked to the RTShaderSystem and the GLES2RenderSystem which would increase the size more. I'm thinking about creating an OgreAndroidGLES and OgreAndroidGLES2 wrapper to overcome this problem. But first I need to get the size down. :)
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

ellis
Gnoblar
Posts: 3
Joined: Mon Mar 01, 2010 4:34 pm

Re: Port Ogre to Android?

Post by ellis »

Hello,

I'm working on Irrlicht Port on Android. The irrlicht library size is 4Mo without symbols and 25Mo with symbols. Do you have stripped your symbols?

Otherwise, there are several points that i want to share with you:
- Link with the java Part: now, i defined the GL context in java and call Irrlicht code in C with JNI. But there are painfull problems as the management of back and home keys which put GL context in space. My solutions is to rebuild the Irrlicht Context but it is possible that there is a better solution;
- data loading: i put data in assets directory and at program loading, i copy my data on sdcard. Assets data are not available to C part;
- Debug: with NDK, i haven't succeded to have symbols with gdbserver. So i use AOSP (Android Open Source ...) and put my code in vendor part. Now i have in emulator symbols and breakpoints and on my phone device symbols only. I don't understand why my gdb wouldn't stop at breakpoints.

I have made some apk to test Irrlicht Port on http://www.scigems.org/downloads/ and there is a shader test with OpenGL ES 2.0.

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

Hi Ellis,

The current LOCAL_CFLAGS variable is defined like this:

Code: Select all

LOCAL_CFLAGS = -DOgreMain_EXPORTS \
-DANDROID_NDK \
-DOGRE_NONCLIENT_BUILD \
-DFREEIMAGE_LIB \
-D_MT \
-D_USRDLL \
-I$(LOCAL_PATH)/OgreMain/include \
-I$(LOCAL_PATH)/include \
-I$(LOCAL_PATH)/OgreMain/include/Threading \
-I$(LOCAL_PATH)/OgreMain/src/nedmalloc \
-Os \
-s \
-DNDEBUG
So I don't think I can get it stripped down even more.
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

ellis
Gnoblar
Posts: 3
Joined: Mon Mar 01, 2010 4:34 pm

Re: Port Ogre to Android?

Post by ellis »

I'm not sure that CFLAGS are enough. Did you try the strip command? With NDK, all build finish by a strip command. Otherwise, on ARM, there is two modes:
- ARM: normal instructions set
- THUMB: instruction are compressed on 16bits
THUMB could be slower but the code would be smaller.

In Android.mk, you could set this with LOCAL_ARM_MODE := thumb (or arm).

ellis
Gnoblar
Posts: 3
Joined: Mon Mar 01, 2010 4:34 pm

Re: Port Ogre to Android?

Post by ellis »

Other point, i haven't try the iphone port of Ogre but you could compare with the size of library on iphone.

In this thread, there is a dmg (if you use a macinstosh) and there is probably a dylib.
http://www.ogre3d.org/forums/viewtopic. ... &start=250

I will try to download this at my work to find this size tomorrow.

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

ellis wrote:I'm not sure that CFLAGS are enough. Did you try the strip command? With NDK, all build finish by a strip command. Otherwise, on ARM, there is two modes:
- ARM: normal instructions set
- THUMB: instruction are compressed on 16bits
THUMB could be slower but the code would be smaller.

In Android.mk, you could set this with LOCAL_ARM_MODE := thumb (or arm).
Doesn't LOCAL_ARM_MODE default to thumb? when compiling I get Compile++ thumb, so I assumed it was using thumb?
I don't have a mac here, windows user. I'll look into it tomorrow to see what options I have to strip it down.
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

Using arm-eabi-strip --strip-unneeded reduces the size of libOgreMain.a from 325mb to 24mb!! :)
So I can get it running, but it crashes when creating the GLESRenderSystem.
This is my current OgreAndroid code:

Code: Select all

#include <jni.h>
#include <android/log.h>
#include "Ogre.h"
#include "OgreGLES/OgreGLESRenderSystem.h"

#define PRINT(A) {std::cout << A << std::endl; \
				  __android_log_print(ANDROID_LOG_INFO, "Ogre", A); \
				 }
Ogre::RenderWindow* renderWindow = 0;

extern "C"
{
void Java_com_Ogre_OgreRenderer_InitOgre(JNIEnv*  env)
{
	try{
		PRINT("***Initializing Ogre***");
		Ogre::Root* root = new Ogre::Root();
		PRINT("***Creating GLESRenderSystem***");
		Ogre::RenderSystem* rSystem = OGRE_NEW Ogre::GLESRenderSystem();
		PRINT("***Adding RenderSystem to root***");
		root->addRenderSystem(rSystem);
		PRINT("***Setting RenderSystem***");
		root->setRenderSystem(rSystem);
		PRINT("***Running OgreRoot->initialise***");
		root->initialise(false);
		PRINT("***Creating Renderwindow***");
		renderWindow = root->createRenderWindow("AndroidRenderWindow", 100, 100, false);
		PRINT("***Initialized Ogre***");
	}catch(Ogre::Exception& ex)
	{
		PRINT(ex.getFullDescription().c_str());
	}
}

void Java_com_Ogre_OgreRenderer_OgreWindowResize(JNIEnv* env, jint w, jint h)
{
	try{
		PRINT("***Resizing Window***");
		if(!renderWindow)
			return;

		renderWindow->resize(w, h);
	}catch(Ogre::Exception& ex)
	{
		PRINT(ex.getFullDescription().c_str());
	}
}

void Java_com_Ogre_OgreRenderer_RenderOgre(JNIEnv* env)
{
	try{
		PRINT("***Rendering***");
		if(!Ogre::Root::getSingletonPtr())
			return;

		Ogre::Root::getSingleton().renderOneFrame();
	}catch(Ogre::Exception& ex)
	{
		PRINT(ex.getFullDescription().c_str());
	}
}

void Java_com_Ogre_OgreRenderer_DeinitOgre(JNIEnv* env)
{
	//here the try/catch is probably not needed, but add it anyway
	try{
		PRINT("***Deinitializing Ogre***");
		if(!Ogre::Root::getSingletonPtr())
			return;

		delete Ogre::Root::getSingletonPtr();
	}catch(Ogre::Exception& ex)
	{
		PRINT(ex.getFullDescription().c_str());
	}
}
}
I added some prints to debug it.

[edit]
Last few lines in debugger regarding this:

Code: Select all

I/Ogre    (  394): ***Initializing Ogre***
I/Ogre    (  394): ***Creating GLESRenderSystem***
I/DEBUG   (   27): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (   27): Build fingerprint: 'generic/sdk/generic/:2.1/ERD79/22607:eng/test-keys'
I/DEBUG   (   27): pid: 394, tid: 400  >>> com.Ogre <<<
I/DEBUG   (   27): signal 11 (SIGSEGV), fault addr 00000000
I/DEBUG   (   27):  r0 00003038  r1 00003028  r2 00000000  r3 00000000
I/DEBUG   (   27):  r4 ffffffff  r5 00000000  r6 0035daf0  r7 00000001
I/DEBUG   (   27):  r8 47248cc8  r9 fff30cf0  10 4746a258  fp 815724ec
I/DEBUG   (   27):  ip 815726d0  sp 47248b78  lr 81443b83  pc ac7046ec  cpsr 80000030
I/DEBUG   (   27):          #00  pc 000046ec  /system/lib/libEGL.so
I/DEBUG   (   27):          #01  lr 81443b83  /data/data/com.Ogre/lib/libOgreAndroid.so
I/DEBUG   (   27):
I/DEBUG   (   27): code around pc:
I/DEBUG   (   27): ac7046dc 49614860 428ae004 1c2cd100 33083502
I/DEBUG   (   27): ac7046ec 4282681a 2c00d1f7 3502db57 1c2800ad
I/DEBUG   (   27): ac7046fc e8caf7fe 28001c07 9a03d106 49574851
I/DEBUG   (   27):
I/DEBUG   (   27): code around lr:
I/DEBUG   (   27): 81443b70 6c001c14 92002300 447d2200 f6451c0f
I/DEBUG   (   27): 81443b80 2800e8a6 4951d131 466aaf08 1c381869
I/DEBUG   (   27): 81443b90 f65d3227 494ee930 466aae07 1c301869
I/DEBUG   (   27):
I/DEBUG   (   27): stack:
I/DEBUG   (   27):     47248b38  00002bb4
I/DEBUG   (   27):     47248b3c  000000dc
I/DEBUG   (   27):     47248b40  4746a270
I/DEBUG   (   27):     47248b44  afe0b39b  /system/lib/libc.so
I/DEBUG   (   27):     47248b48  afe3bb74
I/DEBUG   (   27):     47248b4c  afe0f3b0  /system/lib/libc.so
I/DEBUG   (   27):     47248b50  00000000
I/DEBUG   (   27):     47248b54  afe0f2c0  /system/lib/libc.so
I/DEBUG   (   27):     47248b58  00000003
I/DEBUG   (   27):     47248b5c  afe3b9bc
I/DEBUG   (   27):     47248b60  0010f880  [heap]
I/DEBUG   (   27):     47248b64  c0000000
I/DEBUG   (   27):     47248b68  47248cc8
I/DEBUG   (   27):     47248b6c  afe0bca5  /system/lib/libc.so
I/DEBUG   (   27):     47248b70  df002777
I/DEBUG   (   27):     47248b74  e3a070ad
I/DEBUG   (   27): #00 47248b78  47248c3c
I/DEBUG   (   27):     47248b7c  00000004
I/DEBUG   (   27):     47248b80  ac708b14  /system/lib/libEGL.so
I/DEBUG   (   27):     47248b84  ac7087f8  /system/lib/libEGL.so
I/DEBUG   (   27):     47248b88  00000000
I/DEBUG   (   27):     47248b8c  00000000
I/DEBUG   (   27):     47248b90  0035db3c  [heap]
I/DEBUG   (   27):     47248b94  00000000
I/DEBUG   (   27):     47248b98  4746a258
I/DEBUG   (   27):     47248b9c  812b3d58  /data/data/com.Ogre/lib/libOgreAndroid.so
I/DEBUG   (   27):     47248ba0  47248cc8
I/DEBUG   (   27):     47248ba4  00000000
I/DEBUG   (   27):     47248ba8  0035db3c  [heap]
I/DEBUG   (   27):     47248bac  47248c18
I/DEBUG   (   27):     47248bb0  815724ec  /data/data/com.Ogre/lib/libOgreAndroid.so
I/DEBUG   (   27):     47248bb4  0035daf0  [heap]
I/DEBUG   (   27):     47248bb8  00000000
I/DEBUG   (   27):     47248bbc  81443b83  /data/data/com.Ogre/lib/libOgreAndroid.so
So it crashes in libEGL.so, so we can't use EGL directly like this or NDK 1.6 is incompatible with 2.1. (Which sounds not right...)
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

Maybe MasterFalcon can help me with this:
I need to create a PBuffer instance, but I don't have access to any EGL functions on android. (I get a crash when using EGL, so I need to be able to do this all without EGL). So could anyone with opengl es knowledge help me with this? Thanks!
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

User avatar
choofins
Gnoblar
Posts: 11
Joined: Thu Dec 04, 2008 10:32 pm

Re: Port Ogre to Android?

Post by choofins »

OpenGL ES 2.0 support has just been added to the official NDK, I'm not sure if this will help your efforts or not.

http://developer.android.com/sdk/ndk/index.html

User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3
Contact:

Re: Port Ogre to Android?

Post by Praetor »

It's possible the update might fix the EGL compatibility. One can hope...
Game Development, Engine Development, Porting
http://www.darkwindmedia.com

User avatar
masterfalcon
OGRE Team Member
OGRE Team Member
Posts: 4270
Joined: Sun Feb 25, 2007 4:56 am
Location: Bloomington, MN
x 126
Contact:

Re: Port Ogre to Android?

Post by masterfalcon »

calsmurf2904 wrote:Maybe MasterFalcon can help me with this:
I need to create a PBuffer instance, but I don't have access to any EGL functions on android. (I get a crash when using EGL, so I need to be able to do this all without EGL). So could anyone with opengl es knowledge help me with this? Thanks!
Sorry that I didn't respond sooner, I haven't been looking at this thread very closely. I'm pretty sure that you can't create a pbuffer without the EGL interface. Hopefully the new NDK will improve things.

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

mmm, I don't think they will expose EGL in the next NDK. So this is a no go? Maybe we can get the EGL functions without using the headers (I think a header mismatch is causing the EGL crash). Perhaps something with dlopen and dlsym to get the necessary functions.
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

User avatar
choofins
Gnoblar
Posts: 11
Joined: Thu Dec 04, 2008 10:32 pm

Re: Port Ogre to Android?

Post by choofins »

Any luck with the new NDK?

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

OgreMain runs :) But that isn't the problem, I don't have access to any of the EGL libs so porting the GLES rendersystem over is kinda hard since it really depends on it. I'm looking into workarounds, but haven't found any.
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

Seems they released a new NDK with GLES2 support, but still no EGL support.
Not sure what the possibilities are with this, since EGL is still java-only.
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

fredguinog
Gnoblar
Posts: 5
Joined: Tue Feb 02, 2010 3:51 am

Re: Port Ogre to Android?

Post by fredguinog »

Maybe this link can help you somehow.
http://zakattacktaylor.com/?tag=ndk

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

Well, I already got what he was talking about, but I also suffer from the EGL problems. (Causing us to not be able to generate the pbuffer from native code. (IE Ogre)).
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

fredguinog
Gnoblar
Posts: 5
Joined: Tue Feb 02, 2010 3:51 am

Re: Port Ogre to Android?

Post by fredguinog »

I found this post which an android developer justifies why the EGL is not exposed to the NDK. It seems that it will never be...

http://groups.google.com/group/android- ... 9e25e102f2?#

***********************************
De: David Turner <di...@android.com>
Data: Wed, 10 Mar 2010 22:15:39 -0800
Local: Qui 11 mar 2010 03:15
Assunto: Re: the using of GL_RENDERBUFFER_OES

Please let me clarify a few things:
- EGL is not currently exposed through the NDK for good reasons (ABI instability), don't call it directly from native code, this could break your app in the future.
- GLSurfaceView is indeed a utility class, you can use the Java GL calls directly to handle buffer swapping instead if you want to.
***********************************

It seems that the only current alternative is to use eglSwapBuffers as shown in the san-angeles demo.

User avatar
calsmurf2904
Orc
Posts: 401
Joined: Tue Sep 16, 2008 9:39 pm
Location: Netherlands

Re: Port Ogre to Android?

Post by calsmurf2904 »

Yes, but that doesn't apply for the PBuffer functions. Is it possible to run a JNI command from C++? (instead of the other way around).
If so then I can just make some callback functions which return an int specifying the ID of the buffer. While still being created in JNI.
Visit my blog at http://calsmurf2904.wordpress.com !
Got a Google Wave account? Add me as contact! (projectxgame <at> gmail <dot> com)
Image

fredguinog
Gnoblar
Posts: 5
Joined: Tue Feb 02, 2010 3:51 am

Re: Port Ogre to Android?

Post by fredguinog »

It is possible. Take a look at http://java.sys-con.com/node/45840

Post Reply