Save Terrain Alphamap to file

Hi
I made an Mapeditor like the jme3-terraineditor. It works quit nice. But I don’t know how to save the painted alpha map.

There is the JmeSystem.writeImageFile() I think. The code is here: https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/system/JmeSystem.java?r=9571

Theres also the Image Painter plugin, though I’m not too familiar with that plugin.

Is your alpha map a JME image or a Java image? We need more information to answer properly without throwing out wild guesses, I guess.


mat = new Material(assetManager, "Common/MatDefs/Terrain/TerrainLighting.j3md");
mat.setBoolean("useTriPlanarMapping", false);
mat.setBoolean("WardIso", true);
mat.setBoolean("isTerrainGrid", false);
mat.setTexture("AlphaMap", assetManager.loadTexture("Alpha0.png"));
mat.setTexture("AlphaMap_1", assetManager.loadTexture("Alpha1.png"));
mat.setTexture("AlphaMap_2", assetManager.loadTexture("Alpha2.png"));
                
tex = assetManager.loadTexture("Default.png");
tex.setWrap(Texture.WrapMode.Repeat);
terrain[i].setTexture("DiffuseMap",tex);
terrain[i].setTexture("DiffuseMap_1");
terrain[i].setTexture("DiffuseMap_2");
terrain[i].setTexture("DiffuseMap_3");
...
terrain[i].setFloat("DiffuseMap_0_scale", 128f);
terrain[i].setFloat("DiffuseMap_1_scale", 128f);
terrain[i].setFloat("DiffuseMap_2_scale", 128f);
...

terrain.setMaterial(mat);

Not the real code because it’s have a lot of loops and other shit

I paint on this Image`
mat.setTexture(“AlphaMap”, assetManager.loadTexture(“Alpha0.png”));



How can I save it to an png file?

//why is the code block so buggy

How do you paint on that image?

 
public void paintTexture(Vector3f markerLocation, float toolRadius, float toolWeight, int selectedTextureIndex) {
        if (selectedTextureIndex < 0 || markerLocation == null)
            return;
        
        int alphaIdx = selectedTextureIndex/4; // 4 = rgba = 4 textures
        Texture tex = getAlphaTexture(alphaIdx);
        Image image = tex.getImage();

        Vector2f UV = getPointPercentagePosition(currentTerrainQuad, markerLocation);
        
        int index = Integer.parseInt(terra.getChild(currentTerrainQuad.getName()).getName()) / 4;
        
        
        UV.setY(UV.getY() + index * 2);
        System.out.println("pos: " + UV);
        // get the radius of the brush in pixel-percent
        float brushSized = toolRadius/(terra.getTerrainSize()*((Node)terra).getLocalScale().x);
        int texIndex = selectedTextureIndex - ((selectedTextureIndex/4)*4); // selectedTextureIndex/4 is an int floor, do not simplify the equation
        boolean erase = toolWeight<0;
        if (erase) {
            toolWeight *= -1;
        }

        doPaintAction(texIndex, image, UV, true, brushSized, erase, toolWeight);
        
        tex.getImage().setUpdateNeeded();
    }
    
    public Vector2f getPointPercentagePosition(Terrain terrain, Vector3f worldLoc) {
        Vector2f uv = new Vector2f(worldLoc.x,-worldLoc.z);
        float scale = ((Node)terrain).getLocalScale().x;
        
        uv.subtractLocal(((Node)terrain).getWorldTranslation().x*scale, ((Node)terrain).getWorldTranslation().z*scale); // center it on 0,0
        float scaledSize = terrain.getTerrainSize()*scale;
        uv.addLocal(scaledSize/2, scaledSize/2); // shift the bottom left corner up to 0,0
        uv.divideLocal(scaledSize); // get the location as a percentage
        
        return uv;
    }
    
    private Texture getAlphaTexture(int alphaLayer) {
        if(terra == null) return null;
        MatParam matParam = null;
        System.out.println(terra.getChild(currentTerrainQuad.getName()) + " l:" + terrain.length );
        if (alphaLayer == 0) {
            matParam = terrain[Integer.parseInt(terra.getChild(currentTerrainQuad.getName()).getName())].getParam("AlphaMap");
        }
        else if(alphaLayer == 1) {
            matParam = terrain[Integer.parseInt(terra.getChild(currentTerrainQuad.getName()).getName())].getParam("AlphaMap_1");
        }
        else if(alphaLayer == 2) {
            matParam = terrain[Integer.parseInt(terra.getChild(currentTerrainQuad.getName()).getName())].getParam("AlphaMap_2");
        }
        
        if (matParam == null || matParam.getValue() == null) {
            System.out.println("return null;");
            return null;
        }
        Texture tex = (Texture) matParam.getValue();
        return tex;
    }

//EDIT < code > blocks are replaced to ` ???

Ugh, post code in code blocks please - much easier to read.

Also try and bring out just the relevant bit.

To write to the image really you should use ImageRaster (in the core) or if you need more advanced features ImagePainter is available as a plugin,

Then you already have your answer:

@8Keep123 said: There is the JmeSystem.writeImageFile() I think. The code is here: https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/system/JmeSystem.java?r=9571
<cite>@8Keep123 said:</cite> There is the JmeSystem.writeImageFile() I think. The code is here: https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/core/com/jme3/system/JmeSystem.java?r=9571

Theres also the Image Painter plugin, though I’m not too familiar with that plugin.

This is not my Problem. How can I get the Alpha Map from an Material.

@th3cr0wl3r said: This is not my Problem. How can I get the Alpha Map from an Material.

Well you set it, its coming from you.

If I want to save the Texture with JmeSystem.writeImageFile()
the Image has a size of 0 bytes.

Texture tex = assetManager.loadTexture("/Alpha2.png")
JmeSystem.writeImageFile(new FileOutputStream(“image.png”), Image.Format.ABGR8.toString(), tex.getImage().getData(0), 128, 128);

so somethings wrong I guess.

@normen

You made the jme3-terraineditor. How do you save the painted texture to an file?

@th3cr0wl3r said: @normen

You made the jme3-terraineditor. How do you save the painted texture to an file?

No I didn’t.

For retrieving the Alphamap see https://code.google.com/p/jmonkeyengine/source/browse/trunk/sdk/jme3-terrain-editor/src/com/jme3/gde/terraineditor/tools/PaintTerrainToolAction.java


private Texture getAlphaTexture(Terrain terrain, int alphaLayer) {
if (terrain == null)
return null;
MatParam matParam = null;
if (alphaLayer == 0)
matParam = terrain.getMaterial(null).getParam("AlphaMap");
else if(alphaLayer == 1)
matParam = terrain.getMaterial(null).getParam("AlphaMap_1");
else if(alphaLayer == 2)
matParam = terrain.getMaterial(null).getParam("AlphaMap_2");

    if (matParam == null || matParam.getValue() == null) {
        return null;
    }
    Texture tex = (Texture) matParam.getValue();
    return tex;
}

For writing PNG files I use libpngj as it makes it easier.
Cheers

edit: PS it appears the html tags and codes are broken again. and I don’t have any toolbar above the text box for them either
so I apologise for the above ugliness …

edit: PSS: also remember to convert texture to image.

1 Like

An easier way would be to just have a Texture variable that you load the alpha map into, and then set the material alpha map as the texture, so you still have the texture variable that you can do whatever you want with.

That’s pretty basic java, though.

@th3cr0wl3r said: If I want to save the Texture with JmeSystem.writeImageFile() the Image has a size of 0 bytes.

Texture tex = assetManager.loadTexture(“/Alpha2.png”)
JmeSystem.writeImageFile(new FileOutputStream(“image.png”), Image.Format.ABGR8.toString(), tex.getImage().getData(0), 128, 128);

“/Alpha2.png” looks like an invalid image location. Unless you’ve setup to load from disk or something, it seems unlikely that is a valid asset location. Also, the format they are looking for is “PNG”, I think. It has no other way of guessing what file format you are trying to write. There is no way so specify the actual image data so it’s required to already be in the format of what Screenshots.convertScreenShot(imageData, awtImage) expects. I think loading from a source PNG would be fine, though… it it is actually getting loaded.