@Override
    @SuppressWarnings("unchecked")
    public void read(JmeImporter im) throws IOException {
        InputCapsule ic = im.getCapsule(this);

        name = ic.readString("name", null);
        additionalState = (RenderState) ic.readSavable("render_state", null);
        transparent = ic.readBoolean("is_transparent", false);

        // Load the material def
        String defName = ic.readString("material_def", null);
        HashMap<String, MatParam> params = (HashMap<String, MatParam>) ic.readStringSavableMap("parameters", null);

        boolean enableVertexColor = false;
        boolean separateTexCoord = false;
        boolean applyDefaultValues = false;
        boolean guessRenderStateApply = false;

        int ver = ic.getSavableVersion(Material.class);
        if (ver < 1) {
            applyDefaultValues = true;
        }
        if (ver < 2) {
            guessRenderStateApply = true;
        }
        if (im.getFormatVersion() == 0) {
            // Enable compatibility with old models
            if (defName.equalsIgnoreCase("Common/MatDefs/Misc/VertexColor.j3md")) {
                // Using VertexColor, switch to Unshaded and set VertexColor=true
                enableVertexColor = true;
                defName = "Common/MatDefs/Misc/Unshaded.j3md";
            } else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/SimpleTextured.j3md")
                    || defName.equalsIgnoreCase("Common/MatDefs/Misc/SolidColor.j3md")) {
                // Using SimpleTextured/SolidColor, just switch to Unshaded
                defName = "Common/MatDefs/Misc/Unshaded.j3md";
            } else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/WireColor.j3md")) {
                // Using WireColor, set wireframe render state = true and use Unshaded
                getAdditionalRenderState().setWireframe(true);
                defName = "Common/MatDefs/Misc/Unshaded.j3md";
            } else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/Unshaded.j3md")) {
                // Uses unshaded, ensure that the proper param is set
                MatParam value = params.get("SeperateTexCoord");
                if (value != null && ((Boolean) value.getValue()) == true) {
                    params.remove("SeperateTexCoord");
                    separateTexCoord = true;
                }
            }
            assert applyDefaultValues && guessRenderStateApply;
        }

        def = im.getAssetManager().loadAsset(new AssetKey<MaterialDef>(defName));
        paramValues = new ListMap<String, MatParam>();

        // load the textures and update nextTexUnit
        for (Map.Entry<String, MatParam> entry : params.entrySet()) {
            MatParam param = entry.getValue();
            if (param instanceof MatParamTexture) {
                MatParamTexture texVal = (MatParamTexture) param;
                // the texture failed to load for this param
                // do not add to param values
                if (texVal.getTextureValue() == null || texVal.getTextureValue().getImage() == null) {
                    continue;
                }
                checkTextureParamColorSpace(texVal.getName(), texVal.getTextureValue());
            }

            if (im.getFormatVersion() == 0 && param.getName().startsWith("m_")) {
                // Ancient version of jME3 ...
                param.setName(param.getName().substring(2));
            }

            if (def.getMaterialParam(param.getName()) == null) {
                logger.log(Level.WARNING, "The material parameter is not defined: {0}. Ignoring..",
                                          param.getName());
            } else {
                checkSetParam(param.getVarType(), param.getName());
                paramValues.put(param.getName(), param);
            }
        }

        if (applyDefaultValues) {
            // compatibility with old versions where default vars were not available
            for (MatParam param : def.getMaterialParams()) {
                if (param.getValue() != null && paramValues.get(param.getName()) == null) {
                    setParam(param.getName(), param.getVarType(), param.getValue());
                }
            }
        }
        if (guessRenderStateApply && additionalState != null) {
            // Try to guess values of "apply" render state based on defaults
            // if value != default then set apply to true
            additionalState.applyPolyOffset = additionalState.offsetEnabled;
            additionalState.applyBlendMode = additionalState.blendMode != BlendMode.Off;
            additionalState.applyColorWrite = !additionalState.colorWrite;
            additionalState.applyCullMode = additionalState.cullMode != FaceCullMode.Back;
            additionalState.applyDepthTest = !additionalState.depthTest;
            additionalState.applyDepthWrite = !additionalState.depthWrite;
            additionalState.applyStencilTest = additionalState.stencilTest;
            additionalState.applyWireFrame = additionalState.wireframe;
        }
        if (enableVertexColor) {
            setBoolean("VertexColor", true);
        }
        if (separateTexCoord) {
            setBoolean("SeparateTexCoord", true);
        }
    }
Called by {@link RenderManager} to render the geometry by
using this material.

Note that this version of the render method
does not perform light filtering.

@param geom The geometry to render
@param rm The render manager requesting the rendering
jme3-core/src/main/java/com/jme3/material/Material.java