Hello,
I have a problem when I try to load a texture or anything else using the assetManager for an Android application.
I put my materials in the asset directory of my Android project, then in my test application I call (for example):
[java]
Texture tex = assetManager.loadTexture("Textures/Sky/Bright/BrightSky.dds");
[/java]
And it returns null.
If I try to load a texture that is in the commons/MatDefs/… of the jmonkeyengine3-android-dist.jar it works, but if the texture is in the android project asset directory it fails.
Do I have to do or call something ?
Thanks.
Well I guess you dont add the assets jar file to the classpath, if you generate it at all.
dds files are not supported, at least last time i tried to load a dds sky it failed because of the format.
jpg and png work for me, but i am using my own AndroidAssetManager which is derived from DesktopAssetManager.
Check the logcat output for errors.
If you want to give it a try use the following code:
[java]package com.jme3.asset;
import com.jme3.texture.Texture;
import com.jme3.texture.plugins.AndroidImageLoader;
import java.net.URL;
import java.util.logging.Logger;
import com.jme3.asset.plugins.AndroidLocator;
/**
- <code>AssetManager</code> is the primary method for managing and loading
- assets inside jME.
*
-
@author Kirill Vainer
*/
public class AndroidAssetManager extends DesktopAssetManager {
private static final Logger logger = Logger.getLogger(AndroidAssetManager.class.getName());
public AndroidAssetManager(){
this(null);
}
@Deprecated
public AndroidAssetManager(boolean loadDefaults){
//this(Thread.currentThread().getContextClassLoader().getResource("com/jme3/asset/Android.cfg"));
this(null);
}
/**
- AndroidAssetManager constructor
- If URL == null then a default list of locators and loaders for android is set
-
@param configFile
*/
public AndroidAssetManager(URL configFile)
{
super(configFile);
System.setProperty("org.xml.sax.driver","org.xmlpull.v1.sax2.Driver");
if (configFile == null)
{
// Set Default
this.registerLocator("", AndroidLocator.class);
this.registerLoader(AndroidImageLoader.class, "jpg", "bmp", "gif", "png", "jpeg");
this.registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3m");
this.registerLoader(com.jme3.material.plugins.J3MLoader.class, "j3md");
this.registerLoader(com.jme3.font.plugins.BitmapFontLoader.class, "fnt");
this.registerLoader(com.jme3.texture.plugins.DDSLoader.class, "dds");
this.registerLoader(com.jme3.texture.plugins.PFMLoader.class, "pfm");
this.registerLoader(com.jme3.texture.plugins.HDRLoader.class, "hdr");
this.registerLoader(com.jme3.texture.plugins.TGALoader.class, "tga");
this.registerLoader(com.jme3.export.binary.BinaryImporter.class, "j3o");
this.registerLoader(com.jme3.scene.plugins.OBJLoader.class, "obj");
this.registerLoader(com.jme3.scene.plugins.MTLLoader.class, "mtl");
this.registerLoader(com.jme3.scene.plugins.ogre.MeshLoader.class, "meshxml", "mesh.xml");
this.registerLoader(com.jme3.scene.plugins.ogre.SkeletonLoader.class, "skeletonxml", "skeleton.xml");
this.registerLoader(com.jme3.scene.plugins.ogre.MaterialLoader.class, "material");
this.registerLoader(com.jme3.scene.plugins.ogre.SceneLoader.class, "scene");
this.registerLoader(com.jme3.shader.plugins.GLSLLoader.class, "vert", "frag", "glsl", "glsllib");
}
logger.info("AndroidAssetManager created.");
}
/**
- Loads a texture.
*
-
@return
*/
@Override
public Texture loadTexture(TextureKey key){
Texture tex = (Texture) loadAsset(key);
// Needed for Android
tex.setMagFilter(Texture.MagFilter.Nearest);
tex.setAnisotropicFilter(0);
if (tex.getMinFilter().usesMipMapLevels()){
tex.setMinFilter(Texture.MinFilter.NearestNearestMipMap);
}else{
tex.setMinFilter(Texture.MinFilter.NearestNoMipMaps);
}
return tex;
}
}[/java]
@Normen
What is the assets jar file? I add this jar “jmonkeyengine3-android-dist.jar”, and with the assetManager I am able to load texture included in this jar.
But I can’t load texture included in the android project asset directory.
@larynx
Tomorow I will send my logcat output.
And I will try your class.
Thanks.
The DDS texture format is not supported on android. You will need to use JPEG/PNG images instead
Is that a class that I can found on the net?
import com.jme3.asset.plugins.AndroidLocator;
i forgot the AndroidLocator, here it is:
[java]
package com.jme3.asset.plugins;
import android.content.res.AssetManager;
import android.content.res.Resources;
import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetKey;
import com.jme3.asset.AssetLocator;
import com.jme3.system.JmeSystem;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AndroidLocator implements AssetLocator {
private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName());
private Resources resources;
private AssetManager androidManager;
private String rootPath = "";
private class AndroidAssetInfo extends AssetInfo {
private final InputStream in;
public AndroidAssetInfo(com.jme3.asset.AssetManager manager, AssetKey key,
InputStream in){
super(manager, key);
this.in = in;
}
@Override
public InputStream openStream() {
return in;
}
}
public AndroidLocator(){
resources = JmeSystem.getResources();
androidManager = resources.getAssets();
}
public void setRootPath(String rootPath)
{
this.rootPath = rootPath;
}
public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key) {
InputStream in = null;
String sAssetPath = rootPath + key.getName();
// Fix path issues
if (sAssetPath.startsWith("/"))
{
// Remove leading /
sAssetPath = sAssetPath.substring(1);
}
sAssetPath = sAssetPath.replace("//", "/");
try {
in = androidManager.open(sAssetPath);
if (in == null)
return null;
return new AndroidAssetInfo(manager, key, in);
} catch (IOException ex) {
if (in != null)
try {
in.close();
} catch (IOException ex1) {
}
logger.log(Level.WARNING, "Failed to locate {0} ", sAssetPath);
}
return null;
}
}
[/java]
Thank you for your respones.
When I try to run the Hello Collision tutorial on Android the project fails on the line
[java] assetManager.registerLocator(“town.zip”, ZipLocator.class.getName());
[/java]
The logcat is
[java]
08-15 22:03:01.184: ERROR/AndroidHarness(25073): com.jme3.asset.AssetLoadException: Failed to open zip file: town.zip
08-15 22:03:01.184: ERROR/AndroidHarness(25073): Exception thrown in Thread[GLThread 8,5,main]: com.jme3.asset.plugins.ZipLocator.setRootPath(78) com.jme3.asset.ImplHandler.tryLocate(120) com.jme3.asset.DesktopAssetManager.loadAsset(234) com.jme3.asset.DesktopAssetManager.loadModel(373) com.jme3.asset.DesktopAssetManager.loadModel(383) com.interstatewebgroup.JMonkeyAndroidApp.Game5.simpleInitApp(47) com.jme3.app.SimpleApplication.initialize(230) com.jme3.system.android.OGLESContext.initInThread(263) com.jme3.system.android.OGLESContext.onSurfaceCreated(214) android.opengl.GLSurfaceView$GLThread.guardedRun(1317) android.opengl.GLSurfaceView$GLThread.run(1116)
[/java]
I’ve tried putting the file in a few different places including the project root, the assets folder, etc. I’d like to stay away from custom classes that don’t come with the jmonkeyengine if I can help it.
Is there any known problems with the assetManager with Android?
Probably you have to specify a full path like /sdcard/town.zip and put the file in the root of the sdcard. Also make sure you specify the proper permission in your android manifest
That worked like a charm. Thanks! No special permissions were needed in the manifest. I think that is just for writing to the sdcard.
Does the ZipLocator not support zip files in the asset directory?
ZipLocator adds a new search root to the assetManager root, for directories a FileLocator is used. Having a FileLocator on a folder where a ZIP rests inside thus only exposes the zip file to any loader that might want to load the zip file directly.
There might be a way to support loading zip files inside the assets … although I don’t see the point. Thing is, your APK file is already compressed as zip so it doesn’t make much sense to put a zip file inside another zip file.
Not a big deal. I was just wondering. Thanks for the info.