Javier Camacho
Javier Camacho

Reputation: 33

Libgdx: File not found error 'Internal' when opening external file

Here is a good one for you.

I'm trying to open a file using external.

FileHandle dirHandel = Gdx.files.external("MyApps/skanectModel.g3db");
boolean isDir = Gdx.files.external("MyApps/skanectModel.g3db").exists();

I know the file is there, and the bool tells me that in fact it is there.

The main problem is that I get this error.

Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error reading file: MyApps/skanectModel.png (Internal)

I have no idea why is doing that, I'm no looking for an internal file.

Out of curiosity I created the file on my assets folder just like this assets/MyApps/skanectModel.png and the code runs perfect, also the app can be played on my android.

But... I need to be able to read just the external. I'm building a simple 3D viewer for some friends and i'll be sending to them 3D models every now and then.

Here is the copy of the code:

package com.mygdx.game;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.loaders.ModelLoader;
import com.badlogic.gdx.Files;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.Model;

import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.g3d.loader.G3dModelLoader;
import com.badlogic.gdx.graphics.g3d.loader.ObjLoader;
import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.UBJsonReader;

public class MyGdxGame implements ApplicationListener {
    public Environment environment;
    public PerspectiveCamera cam;
    public CameraInputController camController;
    public ModelBatch modelBatch;
    public Model model;
    public ModelInstance instance;

@Override
public void create() {
    environment = new Environment();
    environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 1.4f, 1.4f, 1.4f, 5f));
    environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));

    cam = new PerspectiveCamera(75,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
    cam.position.set(50f, 1f, 50f);
    cam.lookAt(0,0,0);
    cam.near = 0.1f;
    cam.far = 500f;
    cam.update();

    modelBatch = new ModelBatch();
//      ModelLoader<?> loader = new ObjLoader();
    UBJsonReader jsonReader = new UBJsonReader();
    G3dModelLoader modelLoader = new G3dModelLoader(jsonReader);

//      model = modelLoader.loadModel(Gdx.files.getFileHandle("root/MyApps/skanectModel.g3db",Files.FileType.Absolute));
//      model = modelLoader.loadModel(Gdx.files.getFileHandle("skanectModel.g3db",Files.FileType.External));

    FileHandle dirHandel = Gdx.files.external("MyApps/skanectModel.g3db");
    boolean isDir = Gdx.files.external("MyApps/skanectModel.g3db").exists();
    Gdx.app.log("is it", String.valueOf(isDir));
//      for (FileHandle entry: dirHandel.list()){
//          Gdx.app.log("Path",entry.toString());
//      }
    model = modelLoader.loadModel(dirHandel);
//      model = modelLoader.loadModel(Gdx.files.getFileHandle("skanectModel.g3db",Files.FileType.External));
    instance = new ModelInstance(model);
    instance.transform.rotate(90f,0f,0,-90f);


    camController = new CameraInputController(cam);
    Gdx.input.setInputProcessor(camController);
}

@Override
public void render() {
    camController.update();

    Gdx.gl.glViewport(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
    Gdx.gl.glClearColor(.5f,1,1,1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

    modelBatch.begin(cam);
    modelBatch.render(instance, environment);
    modelBatch.end();
}

@Override
public void dispose() {
    modelBatch.dispose();
    model.dispose();
}

@Override
    public void resize(int width, int height) {
}

@Override
    public void pause() {
}

@Override
    public void resume() {
}
}

Please Help...!!!

EDIT: Here is the complete error log:

06-20 10:00:47.918    3205-3221/com.mygdx.game.android E/AndroidRuntime﹕    FATAL EXCEPTION: GLThread 39207
Process: com.mygdx.game.android, PID: 3205
com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load file:MyApps/skanectModel.png
at com.badlogic.gdx.graphics.Pixmap.<init>(Pixmap.java:140)
at com.badlogic.gdx.graphics.TextureData$Factory.loadFromFile(TextureData.java:98)  at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:100) 
at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:92)
at com.badlogic.gdx.graphics.g3d.utils.TextureProvider$FileTextureProvider.load(TextureProvider.java:34) 
at com.badlogic.gdx.graphics.g3d.Model.convertMaterial(Model.java:290)
at com.badlogic.gdx.graphics.g3d.Model.loadMaterials(Model.java:266)
at com.badlogic.gdx.graphics.g3d.Model.load(Model.java:107)
at com.badlogic.gdx.graphics.g3d.Model.<init>(Model.java:102)
at com.badlogic.gdx.assets.loaders.ModelLoader.loadModel(ModelLoader.java:54)
at com.badlogic.gdx.assets.loaders.ModelLoader.loadModel(ModelLoader.java:69)
at com.mygdx.game.MyGdxGame.create(MyGdxGame.java:65)
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:241)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Error reading file: MyApps/skanectModel.png (Internal)
at com.badlogic.gdx.backends.android.AndroidFileHandle.read(AndroidFileHandle.java:77)
at com.badlogic.gdx.files.FileHandle.readBytes(FileHandle.java:222)
at com.badlogic.gdx.graphics.Pixmap.<init>(Pixmap.java:137)
at com.badlogic.gdx.graphics.TextureData$Factory.loadFromFile(TextureData.java:98)
at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:100)
at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:92)
at com.badlogic.gdx.graphics.g3d.utils.TextureProvider$FileTextureProvider.load(TextureProvider.java:34)
at com.badlogic.gdx.graphics.g3d.Model.convertMaterial(Model.java:290)
at com.badlogic.gdx.graphics.g3d.Model.loadMaterials(Model.java:266)
at com.badlogic.gdx.graphics.g3d.Model.load(Model.java:107)
at com.badlogic.gdx.graphics.g3d.Model.<init>(Model.java:102)
at com.badlogic.gdx.assets.loaders.ModelLoader.loadModel(ModelLoader.java:54)
at com.badlogic.gdx.assets.loaders.ModelLoader.loadModel(ModelLoader.java:69)
at com.mygdx.game.MyGdxGame.create(MyGdxGame.java:65)
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:241)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
Caused by: java.io.FileNotFoundException: MyApps/skanectModel.png
at android.content.res.AssetManager.openAsset(Native Method)
at android.content.res.AssetManager.open(AssetManager.java:324)
at android.content.res.AssetManager.open(AssetManager.java:298)
at com.badlogic.gdx.backends.android.AndroidFileHandle.read(AndroidFileHandle.java:75)
at com.badlogic.gdx.files.FileHandle.readBytes(FileHandle.java:222)
at com.badlogic.gdx.graphics.Pixmap.<init>(Pixmap.java:137)
at com.badlogic.gdx.graphics.TextureData$Factory.loadFromFile(TextureData.java:98)
at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:100)
at com.badlogic.gdx.graphics.Texture.<init>(Texture.java:92)
at com.badlogic.gdx.graphics.g3d.utils.TextureProvider$FileTextureProvider.load(TextureProvider.java:34)
at com.badlogic.gdx.graphics.g3d.Model.convertMaterial(Model.java:290)
at com.badlogic.gdx.graphics.g3d.Model.loadMaterials(Model.java:266)
at com.badlogic.gdx.graphics.g3d.Model.load(Model.java:107)
at com.badlogic.gdx.graphics.g3d.Model.<init>(Model.java:102)
at com.badlogic.gdx.assets.loaders.ModelLoader.loadModel(ModelLoader.java:54)
at com.badlogic.gdx.assets.loaders.ModelLoader.loadModel(ModelLoader.java:69)
at com.mygdx.game.MyGdxGame.create(MyGdxGame.java:65)
at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphi cs.java:241)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)

******EDIT***** After a quick advise from MadEqua, This is how I implemented fix.

FileHandle dirHandel = Gdx.files.external("MyApps/skanectModel.g3db");
myT = new TextureProvider() {
@Override
public Texture load(String fileName) {
Texture result = new Texture(Gdx.files.external(fileName));
result.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
result.setWrap(Texture.TextureWrap.Repeat, Texture.TextureWrap.Repeat);
return result;
  }
};
myT.load("Myapps/skanectModel.png");
model = modelLoader.loadModel(dirHandel,myT);

Upvotes: 3

Views: 1162

Answers (2)

MadEqua
MadEqua

Reputation: 1142

After looking carefully at your stack trace it seems that the model file itself its loading properly.

The problem arises when loading the Textures of the model:

at com.badlogic.gdx.backends.android.AndroidFileHandle.read(AndroidFileHandle.java:75) at com.badlogic.gdx.files.FileHandle.readBytes(FileHandle.java:222) at com.badlogic.gdx.graphics.Pixmap.(Pixmap.java:137) at com.badlogic.gdx.graphics.TextureData$Factory.loadFromFile(TextureData.java:98) at com.badlogic.gdx.graphics.Texture.(Texture.java:100) at com.badlogic.gdx.graphics.Texture.(Texture.java:92) at com.badlogic.gdx.graphics.g3d.utils.TextureProvider$FileTextureProvider.load(TextureProvider.java:34) at com.badlogic.gdx.graphics.g3d.Model.convertMaterial(Model.java:290) at com.badlogic.gdx.graphics.g3d.Model.loadMaterials(Model.java:266)

I believe libGDX is trying to load the texture files from the wrong location (an internal location, explaining the error you get).

I've never worked with libDGX model functions but I think that you should use this method instead: loadModel(FileHandle fileHandle, TextureProvider textureProvider)

and pass in a TextureProvider that loads the Texture file from an external folder. (and make sure the texture file is there).

Should be easy to implement a custom TextureProvider that does exactly that, by looking at the FileTextureProvider.

Upvotes: 2

dCoder
dCoder

Reputation: 404

File handling Libgdx Wiki

From their wiki

External files paths are relative to the SD card root on Android and to the home directory of the current user on desktop systems.

and

Local files are stored relative to the application's root or working directory on desktops and relative to the internal (private) storage of the application on Android. Note that Local and internal are mostly the same on the desktop.

So if your file is in project root you should use local instead of external. Can you provide more info like test platform.

Upvotes: 1

Related Questions