Hello.
There is a new version of OpenGL 2 renderer available in the repository.
To create and build your own android application, you might need to go through these steps.
1 ) checkout the latest source code and compile it:
ant clean default && ant -buildfile build-android.xml
2 ) create a basic android application using android sdk
3 ) Set the package in the AndroidManifest file to “jme3test.android”
4 ) Set the main activity in the AndroidManifest file to “AndroidActivity”
5 ) Set minSdkVersion to 8 in the AndroidManifest file.
6 ) copy build/jmonkeyengine3-.jar files into libs folder of the android project.
7 ) copy src/core-data/ folders into assets folder of the android project.
8 ) copy any texture into assets/icons/textured.png file (that texture will be used to draw the test meshes).
9 ) “release” the android project using “ant release” command.
10 ) Run the test on android 2.2 device.
A compiled version of the test is available here:
http://128.227.252.117/JMEAndroidTest-release.apk
MD5 checksum: f1d549104b7f8606cf853d95b4d3f8f0
The test should render nine rotating spheres with dynamic lighting.
The frames per second counter is printed using logging. USB connection to the computer running adb logcat is required to get this value.
Thanks.
And the crowd goes wild! :o
anyone tried this yet?
I’m curious to get a rough idea of the performance
I tried it on my Desire HD, I just got a black screen. It didn’t crash though.
Doesn’t seem to run on the emulator (which is the only thing I have to test :P)
I tried it on a rooted Motorola Droid running the UltimateDroid Rom (based on Cyanogen) with an overclocked 800 MHz kernel. This puts it just under the capabilities of the current top-of-the-line phones with 1 Ghz Snapdragon processors, but far above the current budget models with 528 MHz ARM11 processors. I got 33 fps fairly consistently, with some variation, but most framerates between 30 and 40 fps. So you can expect phones like the Nexus One, EVO 4G, and Droid 2 to get 40+ fps on this demo, and phones like the Hero, G1, and such to get 20 fps or less.
I’m going to play with this build some, and see if I can get it to render something a little more taxing, like a terrain, and see how it fares. Let me know if it’s not ready for something like that yet.
Keep up the good work! I’ve been checking back in on this off and on for a while. jMonkeyEngine just seems to be in the best position of any of the open source graphics engines to be a good fit for Android, since it’s already based on Java. I would love to see the jMonkeyPlatform support both mobile and desktop assets in the same project, so you could use one project and one codebase to develop mobile and desktop versions of the same game.
My eventual goal is to create a game with RTS, RPG, and MMO heritage all in a big sandbox world, but the first iteration will probably play out more like a Tower Defense game in a persistent world.
David
Just an update: the framerate quoted above was from the apk. I built it from source using the instructions in the OP and now I get 40-50 fps. I’m guessing the only difference is the choice of texture. I chose the 112 KB Monkey.png file from com/jme3/app.
…
Yeah, I chose the RockyTexture.png file from srctest-dataTexturesTerrainRocky (2048x2048 instead of 512/512 for the monkey), and it dropped the frame rate back down to 30 fps. So watch your texture sizes closely when you start building games for android.
kc5uyn said:Unfortunately the current emulator from the SDK does not support OpenGL ES 2.0. It's a darn shame :(
Doesn't seem to run on the emulator (which is the only thing I have to test :P)
@dpwhittaker we really appreciate the early testing, keep it up, there's more coming!
jMP is planned to have simulators for all deployment platforms, you will see some new exciting platform possibilities for jME, maybe sooner than you think
I wouldn’t recommend loading 512x512 terrain on a cellphone
That’s probably way too much for most devices.
You can probably reduce a lot of used memory by using VTF (vertex texture fetch) for accessing the heightmap directly in the vertex shader and then push that as verticies. I don’t know how well it would work on android devices though.
Experimentation with the Terrain so far has revealed a few not-so-surprising facts. The current implementation is not optimized for memory usage. I ended up with OutOfMemory exceptions on a 512x512 terrain. It would load about half of the TerrainQuads before running out of breathing room. This makes sense given that the Android platform supports a maximum heap size of 16 MB. (Which also makes sense given that the machine is only required to have a total of 64 MB of ram).
Each vertex requires:
3 floats - position
3 floats - normal
2 floats - texcoords
~2 int - index
that’s 40 bytes per vertex. 512 x 512 is 256k, times 40 bytes is 10 MB, over half of the available space. With the Bitmap (I made a BitmapBasedHeightmap class based on the ImageBasedHeightmap to remove the AWT dependency), splat textures and alpha map (they weigh in at about 7.5 MB in bitmap form), it’s no wonder it ran out of memory.
I wrote a low-memory terrain engine for Ogre once that uses closer to 4 bytes per vertex. I’ll post about it in the TerraMonkey forum and will probably start working on it for jME. My goals eventually require an infinite terrain with as large a view distance as possible, the ability to fly high over the terrain, then land and walk on the same one… maybe that’s a bit ambitious for a cell phone… maybe not Time and experimentation will tell.
All in all, it seems like the dream of building a platform that allows you to write the same game (with 2 separate GUIs) and publish it for PCs or mobiles may be a bit far-fetched. When the disparity between the architectures is the difference between 16MB and 4 GB of ram, it’s going to require more than just using lower detail models to make it run on the smaller device. Maybe a combination of low-memory architecture for terrains, scenes, etc. in combination with using lower detail models will make the dream a reality.
It would be nice to eventually see a jMonkeyPlatform that can simply resize it’s view window to mobile size, show the mobile GUI, and provide a few extra controls to simulate accelerometer and multi-touch. The lower LOD levels of the desktop models could be used for the mobile package. EIther way, there’s a lot of work to be done between here and there.
FYI: Tested today the compiled application (http://128.227.252.117/JMEAndroidTest-release.apk) on a phone and a tablet, and got the following results:
- Galaxy S I9000: 55 Fps
- Galaxy Tab: 60 Fps
Not so bad !
Hello,
I would like to start testing jme3 on an android device.
But I have failed at the very first step :
1 ) checkout the latest source code and compile it: → OK, I checked out
ant clean default && ant -buildfile build-android.xml → not OK
ant build with success build.xml, but it fails when I call -buildfile-android.xml
Here is the log :
[java]
BUILD SUCCESSFUL
Total time: 1 minute 32 seconds
Buildfile: D:workspacejme3build-android.xml
initialize:
[mkdir] Created dir: D:workspacejme3buildandroid
compile:
[javac] D:workspacejme3build-android.xml:33: warning: ‘includeantruntime’ was not set, defaulting to build.syscla
sspath=last; set to false for repeatable builds
[javac] Compiling 19 source files to D:workspacejme3buildandroid
[javac] D:workspacejme3srcandroidcomjme3systemandroidOGLESContext.java:261: warning: [deprecation] destroy(
) in com.jme3.system.JmeContext has been deprecated
[javac] public void destroy(){
[javac] ^
[javac] D:workspacejme3srcandroidcomjme3systemandroidOGLESContext.java:246: warning: [deprecation] create()
in com.jme3.system.JmeContext has been deprecated
[javac] public void create(){
[javac] ^
[javac] D:workspacejme3srcandroidcomjme3rendererandroidOGLESShaderRenderer.java:116: com.jme3.renderer.andr
oid.OGLESShaderRenderer is not abstract and does not override abstract method getCaps() in com.jme3.renderer.Renderer
[javac] public class OGLESShaderRenderer implements com.jme3.renderer.Renderer {
[javac] ^
[javac] D:workspacejme3srcandroidcomjme3rendererandroidOGLESShaderRenderer.java:140: getCaps() in com.jme3.
renderer.android.OGLESShaderRenderer cannot implement getCaps() in com.jme3.renderer.Renderer; attempting to use incompa
tible return type
[javac] found : java.util.Collection<com.jme3.renderer.Caps>
[javac] required: java.util.EnumSet<com.jme3.renderer.Caps>
[javac] public Collection getCaps() {
[javac] ^
[javac] D:workspacejme3srcandroidcomjme3rendererandroidOGLESRenderer.java:41: com.jme3.renderer.android.OGL
ESRenderer is not abstract and does not override abstract method getCaps() in com.jme3.renderer.Renderer
[javac] public final class OGLESRenderer implements Renderer {
[javac] ^
[javac] D:workspacejme3srcandroidcomjme3rendererandroidOGLESRenderer.java:106: getCaps() in com.jme3.render
er.android.OGLESRenderer cannot implement getCaps() in com.jme3.renderer.Renderer; attempting to use incompatible return
type
[javac] found : java.util.Collection<com.jme3.renderer.Caps>
[javac] required: java.util.EnumSet<com.jme3.renderer.Caps>
[javac] public Collection getCaps() {
[javac] ^
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[javac] 4 errors
[javac] 2 warnings
BUILD FAILED
D:workspacejme3build-android.xml:33: Compile failed; see the compiler error output for details.
Total time: 2 seconds
[/java]
Is anyone can help me?
Thank you.
Change the return type of getCaps from Collection to EnumSet in the OGLESRenderer and OGLESShaderRenderer classes. This should probably be checked in to the SVN by someone with access to do so.
I’d like to test the renderer, but i’m unfortunately stuck with 2.1 for a while longer…
Btw, there is a “demo” category in the android market. Have you considered dumping the apk there? It might create some additional hype. There is a compiled version of “nehe’s opengl tutorials”, so there are some dev people looking there.
I commited a fix to the OGLES{,Shader}Renderer.java files.
Right now everything should be buildable.
I’m planing to implement a test chooser for the Android version and add a couple test to it and then upload it to the market.
Thanks!
I also seem to be unable to build the SDK, though I’m getting different errors to dahoo.
Could someone please help me out with this?
Here is the build log:
[java]
>>> ant -buildfile build-android.xml
Buildfile: /home/george/jme3/jmonkeyengine-read-only/jme3/build-android.xml
initialize:
[mkdir] Created dir: /home/george/jme3/jmonkeyengine-read-only/jme3/build/android
compile:
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/build-android.xml:33: warning: ‘includeantruntime’ was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
[javac] Compiling 19 source files to /home/george/jme3/jmonkeyengine-read-only/jme3/build/android
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/system/android/OGLESContext.java:261: warning: [deprecation] destroy() in com.jme3.system.JmeContext has been deprecated
[javac] public void destroy(){
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/system/android/OGLESContext.java:246: warning: [deprecation] create() in com.jme3.system.JmeContext has been deprecated
[javac] public void create(){
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:116: com.jme3.renderer.android.OGLESShaderRenderer is not abstract and does not override abstract method deleteImage(com.jme3.texture.Image) in com.jme3.renderer.Renderer
[javac] public class OGLESShaderRenderer implements com.jme3.renderer.Renderer {
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:972: cannot find symbol
[javac] symbol : method isUpdateNeeded()
[javac] location: class com.jme3.texture.Texture
[javac] if (tex.isUpdateNeeded())
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:975: cannot find symbol
[javac] symbol : method getId()
[javac] location: class com.jme3.texture.Texture
[javac] int texId = tex.getId();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:978: incompatible types
[javac] found : com.jme3.texture.Image[]
[javac] required: com.jme3.texture.Texture[]
[javac] Texture[] textures = context.boundTextures;
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1009: cannot find symbol
[javac] symbol : method getId()
[javac] location: class com.jme3.texture.Texture
[javac] int texId = tex.getId();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1015: cannot find symbol
[javac] symbol : method setId(int)
[javac] location: class com.jme3.texture.Texture
[javac] tex.setId(texId);
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1016: registerForCleanup(com.jme3.renderer.GLObject) in com.jme3.renderer.GLObjectManager cannot be applied to (com.jme3.texture.Texture)
[javac] objManager.registerForCleanup(tex);
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1022: incomparable types: com.jme3.texture.Image and com.jme3.texture.Texture
[javac] if (context.boundTextures[0] != tex) {
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1029: incompatible types
[javac] found : com.jme3.texture.Texture
[javac] required: com.jme3.texture.Image
[javac] context.boundTextures[0] = tex;
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1072: cannot find symbol
[javac] symbol : method getImageDataIndex()
[javac] location: class com.jme3.texture.Texture
[javac] TextureUtil.uploadTexture(gl, img, tex.getImageDataIndex(), generateMips, powerOf2);
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1075: cannot find symbol
[javac] symbol : method clearUpdateNeeded()
[javac] location: class com.jme3.texture.Texture
[javac] tex.clearUpdateNeeded();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1146: cannot find symbol
[javac] symbol : method getId()
[javac] location: class com.jme3.texture.Texture
[javac] int texId = tex.getId();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1153: cannot find symbol
[javac] symbol : method resetObject()
[javac] location: class com.jme3.texture.Texture
[javac] tex.resetObject();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESShaderRenderer.java:1418: incompatible types
[javac] found : com.jme3.texture.Image[]
[javac] required: com.jme3.texture.Texture[]
[javac] Texture[] textures = context.boundTextures;
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:41: com.jme3.renderer.android.OGLESRenderer is not abstract and does not override abstract method deleteImage(com.jme3.texture.Image) in com.jme3.renderer.Renderer
[javac] public final class OGLESRenderer implements Renderer {
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:474: cannot find symbol
[javac] symbol : method getId()
[javac] location: class com.jme3.texture.Texture
[javac] int texId = tex.getId();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:479: cannot find symbol
[javac] symbol : method setId(int)
[javac] location: class com.jme3.texture.Texture
[javac] tex.setId(texId);
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:480: registerForCleanup(com.jme3.renderer.GLObject) in com.jme3.renderer.GLObjectManager cannot be applied to (com.jme3.texture.Texture)
[javac] objManager.registerForCleanup(tex);
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:485: incomparable types: com.jme3.texture.Image and com.jme3.texture.Texture
[javac] if (context.boundTextures[0] != tex){
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:492: incompatible types
[javac] found : com.jme3.texture.Texture
[javac] required: com.jme3.texture.Image
[javac] context.boundTextures[0] = tex;
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:526: cannot find symbol
[javac] symbol : method getImageDataIndex()
[javac] location: class com.jme3.texture.Texture
[javac] TextureUtil.uploadTexture(gl, img, tex.getImageDataIndex(), generateMips, powerOf2);
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:529: cannot find symbol
[javac] symbol : method clearUpdateNeeded()
[javac] location: class com.jme3.texture.Texture
[javac] tex.clearUpdateNeeded();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:543: cannot find symbol
[javac] symbol : method isUpdateNeeded()
[javac] location: class com.jme3.texture.Texture
[javac] if (tex.isUpdateNeeded())
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:546: cannot find symbol
[javac] symbol : method getId()
[javac] location: class com.jme3.texture.Texture
[javac] int texId = tex.getId();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:549: incompatible types
[javac] found : com.jme3.texture.Image[]
[javac] required: com.jme3.texture.Texture[]
[javac] Texture[] textures = context.boundTextures;
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:574: incompatible types
[javac] found : com.jme3.texture.Image[]
[javac] required: com.jme3.texture.Texture[]
[javac] Texture[] textures = context.boundTextures;
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:589: cannot find symbol
[javac] symbol : method getId()
[javac] location: class com.jme3.texture.Texture
[javac] int texId = tex.getId();
[javac] ^
[javac] /home/george/jme3/jmonkeyengine-read-only/jme3/src/android/com/jme3/renderer/android/OGLESRenderer.java:594: cannot find symbol
[javac] symbol : method resetObject()
[javac] location: class com.jme3.texture.Texture
[javac] tex.resetObject();
[javac] ^
[javac] Note: Some input files use unchecked or unsafe operations.
[javac] Note: Recompile with -Xlint:unchecked for details.
[javac] 28 errors
[javac] 2 warnings
BUILD FAILED
/home/george/jme3/jmonkeyengine-read-only/jme3/build-android.xml:33: Compile failed; see the compiler error output for details.
[/java]
Hello.
There were some changes to the JMonkeyEngine renderer architecture and the android renderer was not in sync.
Right now I commited the changes that made the Android renderer compile and work, but the Android renderer still needs some changes be merged from LwjglRenderer.
But for now it should work.
If you still have issues, let me know!
Thanks.
antonyudin said:
Hello.
There were some changes to the JMonkeyEngine renderer architecture and the android renderer was not in sync.
Right now I commited the changes that made the Android renderer compile and work, but the Android renderer still needs some changes be merged from LwjglRenderer.
But for now it should work.
If you still have issues, let me know!
Thanks.
Thanks for the help, the engine builds successfully now.
I tried it on my Desire HD, I just got a black screen. It didn’t crash though.
I tried the test of the compiled version on my Nexus One, I just got a black screen too. It didn’t crash though.
-Test version http://128.227.252.117/JMEAndroidTest-release.apk
-Android 2.2.1
-Compilation FRG83D