[Solved] Save / Load Material Problem

Hi,

I am trying to save and load a Map, that also holds its own Material.

I get the following Error:

[java]

java.lang.NullPointerException

at com.jme3.texture.Texture.read(Texture.java:593)

at com.jme3.texture.Texture2D.read(Texture2D.java:215)

at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:341)

at com.jme3.export.binary.BinaryInputCapsule.readSavable(BinaryInputCapsule.java:458)

at com.jme3.material.MatParam.read(MatParam.java:325)

at com.jme3.material.MatParamTexture.read(MatParamTexture.java:62)

at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:341)

at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:484)

at com.jme3.export.binary.BinaryInputCapsule.readStringSavableMap(BinaryInputCapsule.java:668)

at com.jme3.material.Material.read(Material.java:1122)

at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:341)

at com.jme3.export.binary.BinaryInputCapsule.readSavable(BinaryInputCapsule.java:458)

at VoxelFun.TileMap.read(TileMap.java:335)

at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:341)

at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:243)

at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:130)

at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:271)

at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:266)

at VoxelFun.MapAppState.loadMapFile(MapAppState.java:129)

at VoxelFun.MapAppState.loadMap(MapAppState.java:122)

at VoxelFun.MapAppState.onAction(MapAppState.java:108)

at com.jme3.input.InputManager.invokeActions(InputManager.java:168)

at com.jme3.input.InputManager.onKeyEventQueued(InputManager.java:425)

at com.jme3.input.InputManager.processQueue(InputManager.java:799)

at com.jme3.input.InputManager.update(InputManager.java:851)

at com.jme3.app.Application.update(Application.java:598)

at com.jme3.app.SimpleApplication.update(SimpleApplication.java:233)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)

at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:227)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)

at java.lang.Thread.run(Thread.java:722)

[/java]



I create the Material like this: ( the image is different version of this one: http://dwarffortresswiki.org/index.php/File:Phoebus_16x16.pn)

[java]

mat = new Material(getAssetManager(), “Common/MatDefs/Misc/Unshaded.j3md”);

mat.setTexture(“ColorMap”,

getAssetManager().loadTexture(“Textures/Phoebus_16x16_TextBackground.png”));

[/java]



and then save and load it here:

[java]

public void write(JmeExporter ex) throws IOException {

OutputCapsule capsule = ex.getCapsule(this);

[…]

capsule.write(MATERIAL, “material”, new Material());



}



public void read(JmeImporter im) throws IOException {

InputCapsule capsule = im.getCapsule(this);

[…]

MATERIAL = (Material) capsule.readSavable(“material”, new Material()); //Line 335

}

[/java]



Can anybody give me some pointers, maybe i am doing something horribly wrong?

The texture doesn’t seem to be available to the assetmanager in the loading call.

The AssetManager was null.

i added

[java]

importer.setAssetManager(app.getAssetManager());

[/java]

to set the AssetManager of the BinaryImporter to my Applications AssetManager and now it all works.

Just another configuration you just have to know you need to do.

@ingorm said:
The AssetManager was null.
i added
[java]
importer.setAssetManager(app.getAssetManager());
[/java]
to set the AssetManager of the BinaryImporter to my Applications AssetManager and now it all works.
Just another configuration you just have to know you need to do.


I think that's because you are using the importer directly so there is more setup involved... versus letting the asset manager load your asset. I think it's not an encouraged way which is why maybe this setup isn't documented that well.
1 Like

A bit of context: We are building a mapeditor for tilemaps (think Final Fantasy Tactics) with a single mesh, and we wanted to have different “tilesets” aka textures for different maps.

Saving the material with the map was the straightforward way of doing it.



I was fooled by the Save and Load Tutorial as the sample code also features a Material being saved and loaded. I think i’ll put some note there somewhere.

Read that tutorial again, its been corrected and theres no BinaryImporter used.

1 Like

Ah now i understand.

I overread the part about the userdata and i guess i should have said that i was using the binary importer in the first post :slight_smile:

Learned this one the hard way. Thanks for your time, both of you.