MatDef is not Savable anymore. Kind of reverted previous commit and implemented and very straight forward exporter for J3mds that doesn't use the Savable process of jme3 since it's designed to save the whole graph and not only subparts of it like materials and material defs. The API stays the same though

define_list_fix
Nehon 9 years ago
parent 81053352ac
commit 8d01c5a26f
  1. 58
      jme3-core/src/main/java/com/jme3/material/MaterialDef.java
  2. 53
      jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdExporter.java
  3. 101
      jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatDefOutputCapsule.java
  4. 151
      jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatParamOutputCapsule.java
  5. 77
      jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdMatParamWriter.java
  6. 255
      jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdOutputCapsuleAdapter.java
  7. 294
      jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdTechniqueDefWriter.java
  8. 69
      jme3-plugins/src/test/java/com/jme3/material/plugin/TestMaterialDefWrite.java
  9. 423
      jme3-plugins/src/test/resources/example.j3md

@ -33,7 +33,6 @@ package com.jme3.material;
import com.jme3.asset.AssetManager;
import com.jme3.export.*;
import com.jme3.renderer.Caps;
import com.jme3.shader.VarType;
import com.jme3.texture.image.ColorSpace;
@ -47,7 +46,7 @@ import java.util.logging.Logger;
*
* @author Kirill Vainer
*/
public class MaterialDef implements Savable{
public class MaterialDef{
private static final Logger logger = Logger.getLogger(MaterialDef.class.getName());
@ -189,57 +188,12 @@ public class MaterialDef implements Savable{
return techniques.get(name);
}
@Override
public void write(JmeExporter ex) throws IOException {
OutputCapsule out = ex.getCapsule(this);
out.write(name, "name" , null);
out.writeStringSavableMap(matParams, "matParams", null);
Map<String, SavableListWrapper> wrapper = new HashMap<String, SavableListWrapper>();
for (String key : techniques.keySet()) {
List<TechniqueDef> defs = techniques.get(key);
wrapper.put(key, new SavableListWrapper(defs));
}
out.writeStringSavableMap(wrapper, "techniques", null);
}
@Override
public void read(JmeImporter im) throws IOException {
InputCapsule in = im.getCapsule(this);
name = in.readString("name", null);
matParams = (Map<String, MatParam>)in.readStringSavableMap("matPrams", null);
Map<String, SavableListWrapper> wrapper = (Map<String, SavableListWrapper>)in.readStringSavableMap("techniques", null);
techniques = new HashMap<String, List<TechniqueDef>>();
for (String key : wrapper.keySet()) {
SavableListWrapper w = wrapper.get(key);
techniques.put(key, w.defs);
}
}
/**
* A wrapper to be able to save a List<TechniqueDef> to save the Map<String, List<TechniqueDefs>>
*
* @return the list of all the technique definitions names.
*/
public static class SavableListWrapper implements Savable{
List<TechniqueDef> defs;
public SavableListWrapper(List<TechniqueDef> defs) {
this.defs = defs;
}
@Override
public void write(JmeExporter ex) throws IOException {
OutputCapsule out = ex.getCapsule(this);
out.writeSavableArrayList((ArrayList)defs, "defs", null);
}
@Override
public void read(JmeImporter im) throws IOException {
InputCapsule in = im.getCapsule(this);
defs = in.readSavableArrayList("defs", null);
}
public Collection<String> getTechniqueDefsNames(){
return techniques.keySet();
}
}

@ -11,6 +11,7 @@ import com.jme3.export.Savable;
import com.jme3.material.*;
import java.io.*;
import java.util.List;
/**
* Saves a Material to a j3m file with proper formatting.
@ -26,47 +27,53 @@ import java.io.*;
* @author tsr
* @author nehon (documentation and safety check)
*/
public class J3mdExporter implements JmeExporter {
public class J3mdExporter {
private final J3mdMatDefOutputCapsule rootCapsule;
/**
* Create a J3mdExporter
*/
public J3mdExporter() {
rootCapsule = new J3mdMatDefOutputCapsule(this);
}
@Override
public void save(Savable object, OutputStream f) throws IOException {
if (!(object instanceof MaterialDef)) {
throw new IllegalArgumentException("J3mdExporter can only save com.jme3.material.MaterialDef class");
}
public void save(MaterialDef matDef, OutputStream f) throws IOException {
OutputStreamWriter out = new OutputStreamWriter(f);
J3mdMatParamWriter paramWriter = new J3mdMatParamWriter();
J3mdTechniqueDefWriter techniqueWriter = new J3mdTechniqueDefWriter();
rootCapsule.clear();
object.write(this);
rootCapsule.writeToStream(out);
// for (MatParam matParam : matDef.getMaterialParams()) {
// System.err.println(matParam.toString());
// }
//
// for (String key : matDef.getTechniqueDefsNames()) {
// System.err.println(matDef.getTechniqueDefs(key).toString());
// }
out.flush();
}
out.write("MaterialDef " + matDef.getName() + " {\n");
out.write(" MaterialParameters {\n");
for (MatParam matParam : matDef.getMaterialParams()) {
paramWriter.write(matParam, out);
}
out.write(" }\n\n");
@Override
public void save(Savable object, File f) throws IOException {
try (FileOutputStream fos = new FileOutputStream(f)) {
save(object, fos);
for (String key : matDef.getTechniqueDefsNames()) {
List<TechniqueDef> defs = matDef.getTechniqueDefs(key);
for (TechniqueDef def : defs) {
techniqueWriter.write(def, matDef.getMaterialParams(), out);
}
}
out.write("}\n");
out.flush();
}
@Override
public OutputCapsule getCapsule(Savable object) {
if (object instanceof MaterialDef) {
return rootCapsule;
}
return rootCapsule.getCapsule(object);
public void save(MaterialDef matDef, File f) throws IOException {
try (FileOutputStream fos = new FileOutputStream(f)) {
save(matDef, fos);
}
}
}

@ -1,101 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.material.plugin.export.materialdef;
import com.jme3.export.*;
import com.jme3.material.*;
import java.io.*;
import java.util.*;
/**
* @author nehon
*/
public class J3mdMatDefOutputCapsule extends J3mdOutputCapsuleAdapter {
//private final HashMap<Savable, J3mdOutputCapsuleAdapter> outCapsules;
private String name;
private List<J3mdOutputCapsuleAdapter> matParams = new ArrayList<J3mdOutputCapsuleAdapter>();
boolean textureParam= false;
public J3mdMatDefOutputCapsule(J3mdExporter exporter) {
super(exporter);
}
@Override
public void clear() {
super.clear();
name = "";
matParams.clear();
}
public OutputCapsule getCapsule(Savable object) {
if(object instanceof MatParam){
if(object instanceof MatParamTexture && textureParam){
textureParam = false;
return matParams.get(matParams.size() - 1);
}
if( object instanceof MatParamTexture){
textureParam = true;
}
J3mdMatParamOutputCapsule matParamCapsule = new J3mdMatParamOutputCapsule(exporter);
matParams.add(matParamCapsule);
return matParamCapsule;
}
throw new IllegalArgumentException("Unsupported type : " + object.getClass().getName());
}
@Override
public void writeToStream(OutputStreamWriter out) throws IOException {
out.write("MaterialDef " + name + " {\n");
out.write(" MaterialParameters {\n");
for (J3mdOutputCapsuleAdapter matParam : matParams) {
matParam.writeToStream(out);
}
out.write(" }\n\n");
//
// for (J3mdOutputCapsule c : outCapsules.values()) {
// c.writeToStream(out);
// }
out.write("}\n");
}
@Override
public void write(String value, String name, String defVal) throws IOException {
switch (name) {
case "name":
this.name = value;
break;
default:
throw new UnsupportedOperationException(name + " string material parameter not supported yet");
}
}
@Override
public void write(Savable object, String name, Savable defVal) throws IOException {
object.write(exporter);
}
@Override
public void writeStringSavableMap(Map<String, ? extends Savable> map, String name, Map<String, ? extends Savable> defVal) throws IOException {
switch (name) {
case "matParams":
for (Savable savable : map.values()) {
savable.write(exporter);
}
break;
case "techniques":
//nothing for now
break;
default:
throw new UnsupportedOperationException(name + " string material parameter not supported yet");
}
}
}

@ -1,151 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.material.plugin.export.materialdef;
import com.jme3.export.*;
import com.jme3.math.*;
import com.jme3.texture.image.ColorSpace;
import java.io.*;
import java.util.*;
import static com.jme3.shader.VarType.Vector2;
import static com.jme3.shader.VarType.Vector3;
import static com.jme3.shader.VarType.Vector4;
/**
* @author nehon
*/
public class J3mdMatParamOutputCapsule extends J3mdOutputCapsuleAdapter {
private String name;
private String varType;
private String value;
private String space;
public J3mdMatParamOutputCapsule(J3mdExporter exporter) {
super(exporter);
}
@Override
public void clear() {
super.clear();
name = "";
varType = "";
value = "";
space = "";
}
@Override
public void writeToStream(OutputStreamWriter out) throws IOException {
out.write(" ");
out.write(varType);
out.write(" ");
out.write(name);
if(space != null) {
out.write(" ");
out.write(space);
}
if(value != null){
out.write(" : ");
out.write(value);
}
out.write("\n");
}
@Override
public void write(String value, String name, String defVal) throws IOException {
switch (name) {
case "name":
this.name = value;
break;
default:
throw new UnsupportedOperationException(name + " string material parameter not supported yet");
}
}
@Override
public void write(Savable object, String name, Savable defVal) throws IOException {
if(name.equals("texture")){
return;
}
if(name.equals("value_savable")){
if(object instanceof Vector2f) {
Vector2f v = (Vector2f)object;
this.value = v.getX() + " " + v.getY();
} else if (object instanceof Vector3f) {
Vector3f v = (Vector3f)object;
this.value = v.getX() + " " + v.getY()+ " " + v.getZ();
} else if (object instanceof Vector4f ) {
Vector4f v = (Vector4f)object;
this.value = v.getX() + " " + v.getY()+ " " + v.getZ()+ " " + v.getW();
} else if (object instanceof ColorRGBA) {
ColorRGBA v = (ColorRGBA)object;
this.value = v.getRed() + " " + v.getGreen() + " " + v.getBlue() + " " + v.getAlpha();
} else {
throw new UnsupportedOperationException(object.getClass() + " Unsupported type");
}
} else {
throw new UnsupportedOperationException(name + " string material parameter not supported yet");
}
}
@Override
public void write(Enum value, String name, Enum defVal) throws IOException {
switch (name) {
case "varType":
this.varType = value.name();
break;
case "colorSpace":
space = value == ColorSpace.Linear?"-LINEAR":null;
break;
default:
throw new UnsupportedOperationException(name + " string material parameter not supported yet");
}
}
@Override
public void write(boolean value, String name, boolean defVal) throws IOException {
if(name.equals("value_bool")){
this.value = Boolean.toString(value);
} else {
throw new UnsupportedOperationException(name + " string material parameter not supported yet");
}
}
@Override
public void write(float value, String name, float defVal) throws IOException {
if(name.equals("value_float")){
this.value = Float.toString(value);
} else {
throw new UnsupportedOperationException(name + " string material parameter not supported yet");
}
}
@Override
public void write(int value, String name, int defVal) throws IOException {
if(name.equals("texture_unit")){
return;
}
if(name.equals("value_int")){
this.value = Integer.toString(value);
} else {
throw new UnsupportedOperationException(name + " string material parameter not supported yet");
}
}
}

@ -0,0 +1,77 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.material.plugin.export.materialdef;
import com.jme3.export.*;
import com.jme3.material.*;
import com.jme3.math.*;
import com.jme3.texture.image.ColorSpace;
import java.io.*;
import java.util.*;
import static com.jme3.shader.VarType.Vector2;
import static com.jme3.shader.VarType.Vector3;
import static com.jme3.shader.VarType.Vector4;
/**
* @author nehon
*/
public class J3mdMatParamWriter {
public J3mdMatParamWriter() {
}
public void write(MatParam param, OutputStreamWriter out) throws IOException {
out.write(" ");
out.write(param.getVarType().name());
out.write(" ");
out.write(param.getName());
if (param instanceof MatParamTexture) {
MatParamTexture paramTex = (MatParamTexture) param;
String space = paramTex.getColorSpace() == ColorSpace.Linear ? "-LINEAR" : null;
if (space != null) {
out.write(" ");
out.write(space);
}
}
String value = formatValue(param);
if (value != null) {
out.write(" : ");
out.write(value);
}
out.write("\n");
}
private String formatValue(MatParam param) {
Object value = param.getValue();
if (value == null) {
return null;
}
switch (param.getVarType()) {
case Vector2:
Vector2f v2 = (Vector2f) value;
return v2.getX() + " " + v2.getY();
case Vector3:
Vector3f v3 = (Vector3f) value;
return v3.getX() + " " + v3.getY() + " " + v3.getZ();
case Vector4:
if (value instanceof ColorRGBA) {
ColorRGBA c = (ColorRGBA) value;
return c.getRed() + " " + c.getGreen() + " " + c.getBlue() + " " + c.getAlpha();
} else {
Vector4f v4 = (Vector4f) value;
return v4.getX() + " " + v4.getY() + " " + v4.getZ() + " " + v4.getW();
}
default:
return value.toString();
}
}
}

@ -1,255 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.material.plugin.export.materialdef;
import com.jme3.asset.TextureKey;
import com.jme3.export.*;
import com.jme3.material.*;
import com.jme3.math.*;
import com.jme3.shader.VarType;
import com.jme3.texture.Texture;
import com.jme3.texture.Texture.WrapMode;
import com.jme3.util.IntMap;
import java.io.*;
import java.nio.*;
import java.util.*;
/**
*
* @author tsr
*/
public abstract class J3mdOutputCapsuleAdapter implements OutputCapsule {
protected final J3mdExporter exporter;
public J3mdOutputCapsuleAdapter(J3mdExporter exporter) {
this.exporter = exporter;
}
public void writeToStream(OutputStreamWriter out) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
protected void writeParameter(OutputStreamWriter out, String name, String value) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
public void clear() {
}
protected void putParameter(String name, String value) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void write(boolean value, String name, boolean defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void writeStringSavableMap(Map<String, ? extends Savable> map, String name, Map<String, ? extends Savable> defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void write(Enum value, String name, Enum defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void write(float value, String name, float defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void write(float[] value, String name, float[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void write(float[][] value, String name, float[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(double value, String name, double defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(double[] value, String name, double[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(double[][] value, String name, double[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(long value, String name, long defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(long[] value, String name, long[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(long[][] value, String name, long[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(short value, String name, short defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(short[] value, String name, short[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(short[][] value, String name, short[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(boolean[] value, String name, boolean[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(boolean[][] value, String name, boolean[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(String value, String name, String defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(String[] value, String name, String[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(String[][] value, String name, String[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(BitSet value, String name, BitSet defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(Savable object, String name, Savable defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(Savable[] objects, String name, Savable[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(Savable[][] objects, String name, Savable[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void writeSavableArrayList(ArrayList array, String name, ArrayList defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void writeSavableArrayListArray(ArrayList[] array, String name, ArrayList[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void writeSavableArrayListArray2D(ArrayList[][] array, String name, ArrayList[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void writeFloatBufferArrayList(ArrayList<FloatBuffer> array, String name, ArrayList<FloatBuffer> defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void writeByteBufferArrayList(ArrayList<ByteBuffer> array, String name, ArrayList<ByteBuffer> defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void writeSavableMap(Map<? extends Savable, ? extends Savable> map, String name, Map<? extends Savable, ? extends Savable> defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void writeIntSavableMap(IntMap<? extends Savable> map, String name, IntMap<? extends Savable> defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(FloatBuffer value, String name, FloatBuffer defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(IntBuffer value, String name, IntBuffer defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(ByteBuffer value, String name, ByteBuffer defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(ShortBuffer value, String name, ShortBuffer defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(byte value, String name, byte defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(byte[] value, String name, byte[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(byte[][] value, String name, byte[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(int value, String name, int defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(int[] value, String name, int[] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void write(int[][] value, String name, int[][] defVal) throws IOException {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

@ -0,0 +1,294 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.jme3.material.plugin.export.materialdef;
import com.jme3.material.*;
import com.jme3.shader.*;
import java.io.*;
import java.util.Collection;
import java.util.regex.*;
import static java.util.regex.Pattern.compile;
/**
* @author nehon
*/
public class J3mdTechniqueDefWriter {
public J3mdTechniqueDefWriter() {
}
public void write(TechniqueDef techniqueDef, Collection<MatParam> matParams, OutputStreamWriter out) throws IOException {
out.write(" Technique");
if(!techniqueDef.getName().equals("Default")) {
out.write(" ");
out.write(techniqueDef.getName());
}
out.write(" {\n");
//Light mode
if(techniqueDef.getLightMode() != TechniqueDef.LightMode.Disable ){
out.write(" LightMode ");
out.write(techniqueDef.getLightMode().name());
out.write("\n\n");
}
//Shadow mode
if(techniqueDef.getShadowMode() != TechniqueDef.ShadowMode.Disable ){
out.write(" ShadowMode ");
out.write(techniqueDef.getShadowMode().name());
out.write("\n\n");
}
//Shaders
if(!techniqueDef.isUsingShaderNodes()) {
writeShaders(techniqueDef, out);
}
//World params
if(!techniqueDef.getWorldBindings().isEmpty()){
writeWorldParams(techniqueDef, out);
}
//ShaderNodes
if(techniqueDef.isUsingShaderNodes()){
writeShaderNodes(techniqueDef, matParams, out);
} else {
//When we have ShaderNodes, Defines are handled differently so we don't have to write them.
//Defines
if (techniqueDef.getDefineNames().length != 0) {
writeDefines(techniqueDef, matParams, out);
}
}
//render state
RenderState rs = techniqueDef.getRenderState();
if(rs != null){
out.write(" RenderState {\n");
writeRenderState(rs, out);
out.write(" }\n\n");
}
//forced render state
rs = techniqueDef.getForcedRenderState();
if(rs != null){
out.write(" ForcedRenderState {\n");
writeRenderState(rs, out);
out.write(" }\n\n");
}
//no render
if(techniqueDef.isNoRender()){
out.write(" NoRender\n\n");
}
out.write(" }\n");
}
private void writeDefines(TechniqueDef techniqueDef, Collection<MatParam> matParams, OutputStreamWriter out) throws IOException {
out.write(" Defines {\n");
for (int i = 0; i < techniqueDef.getDefineNames().length; i++) {
String matParamName = getMatParamNameForDefineId(techniqueDef, matParams, i);
if (matParamName != null) {
String defineName = techniqueDef.getDefineNames()[i];
out.write(" ");
out.write(defineName);
out.write(": ");
out.write(matParamName);
out.write("\n");
}
}
out.write(" }\n\n");
}
private void writeShaderNodes(TechniqueDef techniqueDef, Collection<MatParam> matParams, OutputStreamWriter out) throws IOException {
out.write(" VertexShaderNodes {\n");
for (ShaderNode shaderNode : techniqueDef.getShaderNodes()) {
if(shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex){
writeShaderNode(out, shaderNode, matParams);
}
}
out.write(" }\n\n");
out.write(" FragmentShaderNodes {\n");
for (ShaderNode shaderNode : techniqueDef.getShaderNodes()) {
if(shaderNode.getDefinition().getType() == Shader.ShaderType.Fragment){
writeShaderNode(out, shaderNode, matParams);
}
}
out.write(" }\n\n");
}
private void writeWorldParams(TechniqueDef techniqueDef, OutputStreamWriter out) throws IOException {
out.write(" WorldParameters {\n");
for (UniformBinding uniformBinding : techniqueDef.getWorldBindings()) {
out.write(" ");
out.write(uniformBinding.toString());
out.write("\n");
}
out.write(" }\n\n");
}
private void writeShaders(TechniqueDef techniqueDef, OutputStreamWriter out) throws IOException {
if (techniqueDef.getShaderProgramNames().size() > 0) {
for (Shader.ShaderType shaderType : techniqueDef.getShaderProgramNames().keySet()) {
// System.err.println(shaderType + " " +techniqueDef.getShaderProgramNames().get(shaderType) + " " +techniqueDef.getShaderProgramLanguage(shaderType))
out.write(" ");
out.write(shaderType.name());
out.write("Shader ");
out.write(techniqueDef.getShaderProgramLanguage(shaderType));
out.write(": ");
out.write(techniqueDef.getShaderProgramNames().get(shaderType));
out.write("\n");
}
out.write("\n");
}
}
private void writeShaderNode( OutputStreamWriter out, ShaderNode shaderNode, Collection<MatParam> matParams) throws IOException {
out.write(" ShaderNode ");
out.write(shaderNode.getName());
out.write(" {\n");
if (shaderNode.getCondition() != null){
out.write(" Condition: ");
out.write(formatCondition(shaderNode.getCondition(), matParams));
out.write("\n");
}
out.write(" Definition: ");
out.write(shaderNode.getDefinition().getName());
out.write(": ");
out.write(shaderNode.getDefinition().getPath());
out.write("\n");
out.write(" InputMappings{\n");
for (VariableMapping mapping : shaderNode.getInputMapping()) {
writeVariableMapping(out, shaderNode, mapping, matParams);
}
out.write(" }\n");
out.write(" OutputMappings{\n");
for (VariableMapping mapping : shaderNode.getOutputMapping()) {
writeVariableMapping(out, shaderNode, mapping, matParams);
}
out.write(" }\n");
out.write(" }\n");
}
private void writeVariableMapping(OutputStreamWriter out, ShaderNode shaderNode, VariableMapping mapping, Collection<MatParam> matParams) throws IOException {
out.write(" ");
if(!mapping.getLeftVariable().getNameSpace().equals(shaderNode.getName())) {
out.write(mapping.getLeftVariable().getNameSpace());
out.write(".");
}
out.write(mapping.getLeftVariable().getName());
if(!mapping.getLeftSwizzling().equals("")){
out.write(".");
out.write(mapping.getLeftSwizzling());
}
out.write(" = ");
if(!mapping.getRightVariable().getNameSpace().equals(shaderNode.getName())) {
out.write(mapping.getRightVariable().getNameSpace());
out.write(".");
}
out.write(mapping.getRightVariable().getName().replaceFirst("g_","").replaceFirst("m_",""));
if(!mapping.getRightSwizzling().equals("")){
out.write(".");
out.write(mapping.getRightSwizzling());
}
if (mapping.getCondition() != null){
out.write(" : ");
out.write(formatCondition(mapping.getCondition(),matParams));
}
out.write("\n");
}
private String formatCondition(String condition, Collection<MatParam> matParams){
//condition = condition.replaceAll("defined\\(","");
String res = condition;
Pattern pattern = Pattern.compile("defined\\(([A-Z0-9]*)\\)");
Matcher m = pattern.matcher(condition);
while(m.find()){
String match = m.group(0);
String defineName = m.group(1).toLowerCase();
for (MatParam matParam : matParams) {
if(matParam.getName().toLowerCase().equals(defineName)){
res = res.replace(match, matParam.getName());
}
}
}
return res;
}
private void writeRenderStateAttribute(OutputStreamWriter out, String name, String value) throws IOException {
out.write(" ");
out.write(name);
out.write(" ");
out.write(value);
out.write("\n");
}
private void writeRenderState(RenderState rs, OutputStreamWriter out) throws IOException {
RenderState defRs = RenderState.DEFAULT;
if(rs.getBlendMode() != defRs.getBlendMode()) {
writeRenderStateAttribute(out, "Blend", rs.getBlendMode().name());
}
if(rs.isWireframe() != defRs.isWireframe()) {
writeRenderStateAttribute(out, "Wireframe", rs.isWireframe()?"On":"Off");
}
if(rs.getFaceCullMode() != defRs.getFaceCullMode()) {
writeRenderStateAttribute(out, "FaceCull", rs.getFaceCullMode().name());
}
if(rs.isDepthWrite() != defRs.isDepthWrite()) {
writeRenderStateAttribute(out, "DepthWrite", rs.isDepthWrite()?"On":"Off");
}
if(rs.isDepthTest() != defRs.isDepthTest()) {
writeRenderStateAttribute(out, "DepthTest", rs.isDepthTest()?"On":"Off");
}
if(rs.getBlendEquation() != defRs.getBlendEquation()) {
writeRenderStateAttribute(out, "BlendEquation", rs.getBlendEquation().name());
}
if(rs.getBlendEquationAlpha() != defRs.getBlendEquationAlpha()) {
writeRenderStateAttribute(out, "BlendEquationAlpha", rs.getBlendEquationAlpha().name());
}
if(rs.getPolyOffsetFactor() != defRs.getPolyOffsetFactor() || rs.getPolyOffsetUnits() != defRs.getPolyOffsetUnits()) {
writeRenderStateAttribute(out, "PolyOffset", rs.getPolyOffsetFactor() + " " + rs.getPolyOffsetUnits());
}
if(rs.isColorWrite() != defRs.isColorWrite()) {
writeRenderStateAttribute(out, "ColorWrite", rs.isColorWrite()?"On":"Off");
}
if(rs.getDepthFunc() != defRs.getDepthFunc()) {
writeRenderStateAttribute(out, "DepthFunc", rs.getDepthFunc().name());
}
if(rs.getLineWidth() != defRs.getLineWidth()) {
writeRenderStateAttribute(out, "LineWidth", Float.toString(rs.getLineWidth()));
}
}
private String getMatParamNameForDefineId(TechniqueDef techniqueDef, Collection<MatParam> matParams, int defineId) {
for (MatParam matParam : matParams) {
Integer id = techniqueDef.getShaderParamDefineId(matParam.getName());
if(id !=null && id == defineId){
return matParam.getName();
}
}
return null;
}
}

@ -35,11 +35,15 @@ import com.jme3.asset.*;
import com.jme3.material.*;
import com.jme3.material.plugin.export.materialdef.J3mdExporter;
import com.jme3.material.plugins.J3MLoader;
import com.jme3.shader.UniformBinding;
import com.jme3.system.JmeSystem;
import org.junit.*;
import java.io.*;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class TestMaterialDefWrite {
@ -58,26 +62,7 @@ public class TestMaterialDefWrite {
@Test
public void testWriteMat() throws Exception {
Material mat = new Material(assetManager,"Common/MatDefs/Light/Lighting.j3md");
//
// mat.setBoolean("UseMaterialColors", true);
// mat.setColor("Diffuse", ColorRGBA.White);
// mat.setColor("Ambient", ColorRGBA.DarkGray);
// mat.setFloat("AlphaDiscardThreshold", 0.5f);
//
// mat.setFloat("Shininess", 2.5f);
//
// Texture tex = assetManager.loadTexture("Common/Textures/MissingTexture.png");
// tex.setMagFilter(Texture.MagFilter.Nearest);
// tex.setMinFilter(Texture.MinFilter.BilinearNoMipMaps);
// tex.setWrap(Texture.WrapAxis.S, Texture.WrapMode.Repeat);
// tex.setWrap(Texture.WrapAxis.T, Texture.WrapMode.MirroredRepeat);
//
// mat.setTexture("DiffuseMap", tex);
// mat.getAdditionalRenderState().setDepthWrite(false);
// mat.getAdditionalRenderState().setDepthTest(false);
// mat.getAdditionalRenderState().setLineWidth(5);
// mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
Material mat = new Material(assetManager,"example.j3md");
final ByteArrayOutputStream stream = new ByteArrayOutputStream();
@ -88,7 +73,7 @@ public class TestMaterialDefWrite {
e.printStackTrace();
}
// System.err.println(stream.toString());
System.err.println(stream.toString());
J3MLoader loader = new J3MLoader();
AssetInfo info = new AssetInfo(assetManager, new AssetKey("test")) {
@ -100,11 +85,47 @@ public class TestMaterialDefWrite {
MaterialDef matDef = (MaterialDef)loader.load(info);
MaterialDef ref = mat.getMaterialDef();
for (MatParam matParam : matDef.getMaterialParams()) {
MatParam refParam = ref.getMaterialParam(matParam.getName());
for (MatParam refParam : ref.getMaterialParams()) {
MatParam matParam = matDef.getMaterialParam(refParam.getName());
assertTrue(refParam != null);
assertTrue(refParam.equals(matParam));
assertEquals(refParam,matParam);
}
for (String key : ref.getTechniqueDefsNames()) {
List<TechniqueDef> refDefs = ref.getTechniqueDefs(key);
List<TechniqueDef> defs = matDef.getTechniqueDefs(key);
assertNotNull(defs);
assertTrue(refDefs.size() == defs.size());
for (int i = 0; i < refDefs.size(); i++) {
assertEqualTechniqueDefs(refDefs.get(i), defs.get(i));
}
}
}
private void assertEqualTechniqueDefs(TechniqueDef def1, TechniqueDef def2){
assertEquals(def1.getName(), def2.getName());
assertEquals(def1.getLightMode(), def2.getLightMode());
assertEquals(def1.getShadowMode(), def2.getShadowMode());
assertEquals(def1.getShaderProgramNames().size(), def2.getShaderProgramNames().size());
//World params
assertEquals(def1.getWorldBindings().size(), def2.getWorldBindings().size());
for (UniformBinding uniformBinding : def1.getWorldBindings()) {
assertTrue(def2.getWorldBindings().contains(uniformBinding));
}
//defines
assertEquals(def1.getDefineNames().length, def2.getDefineNames().length);
//renderState
assertEquals(def1.getRenderState(), def2.getRenderState());
//forced renderState
assertEquals(def1.getForcedRenderState(), def2.getForcedRenderState());
//no render
assertEquals(def1.isNoRender(), def2.isNoRender());
}
}

@ -0,0 +1,423 @@
MaterialDef Example Lighting {
MaterialParameters {
// Compute vertex lighting in the shader
// For better performance
Boolean VertexLighting
// Alpha threshold for fragment discarding
Float AlphaDiscardThreshold
// Use the provided ambient, diffuse, and specular colors
Boolean UseMaterialColors
// Use vertex color as an additional diffuse color.
Boolean UseVertexColor
// Ambient color
Color Ambient
// Diffuse color
Color Diffuse
// Specular color
Color Specular
// Specular power/shininess
Float Shininess : 1
// Diffuse map
Texture2D DiffuseMap
// Normal map
Texture2D NormalMap -LINEAR
// Specular/gloss map
Texture2D SpecularMap
// Parallax/height map
Texture2D ParallaxMap -LINEAR
//Set to true is parallax map is stored in the alpha channel of the normal map
Boolean PackedNormalParallax
//Sets the relief height for parallax mapping
Float ParallaxHeight : 0.05
//Set to true to activate Steep Parallax mapping
Boolean SteepParallax
// Texture that specifies alpha values
Texture2D AlphaMap -LINEAR
// Color ramp, will map diffuse and specular values through it.
Texture2D ColorRamp
// Texture of the glowing parts of the material
Texture2D GlowMap
// Set to Use Lightmap
Texture2D LightMap
// Set to use TexCoord2 for the lightmap sampling
Boolean SeparateTexCoord
// The glow color of the object
Color GlowColor
// Parameters for fresnel
// X = bias
// Y = scale
// Z = power
Vector3 FresnelParams
// Env Map for reflection
TextureCubeMap EnvMap
// the env map is a spheremap and not a cube map
Boolean EnvMapAsSphereMap
//shadows
Int FilterMode
Boolean HardwareShadows
Texture2D ShadowMap0
Texture2D ShadowMap1
Texture2D ShadowMap2
Texture2D ShadowMap3
//pointLights
Texture2D ShadowMap4
Texture2D ShadowMap5
Float ShadowIntensity
Vector4 Splits
Vector2 FadeInfo
Matrix4 LightViewProjectionMatrix0
Matrix4 LightViewProjectionMatrix1
Matrix4 LightViewProjectionMatrix2
Matrix4 LightViewProjectionMatrix3
//pointLight
Matrix4 LightViewProjectionMatrix4
Matrix4 LightViewProjectionMatrix5
Vector3 LightPos
Vector3 LightDir
Float PCFEdge
Float ShadowMapSize
// For hardware skinning
Int NumberOfBones
Matrix4Array BoneMatrices
//For instancing
Boolean UseInstancing
Boolean BackfaceShadows : false
Color Color
}
Technique ShaderNodeTechnique {
WorldParameters {
WorldViewProjectionMatrix
}
VertexShaderNodes {
ShaderNode CommonVert {
Condition: (LightMap || SeparateTexCoord) && (!Color || ShadowMapSize)
Definition : CommonVert : Common/MatDefs/ShaderNodes/Common/CommonVert.j3sn
InputMappings {
worldViewProjectionMatrix = WorldParam.WorldViewProjectionMatrix
modelPosition = Global.position.xyz: BackfaceShadows
}
OutputMappings {
Global.position = projPosition
}
}
}
FragmentShaderNodes {
ShaderNode ColorMult {
Definition : ColorMult : Common/MatDefs/ShaderNodes/Basic/ColorMult.j3sn
InputMappings {
color1 = MatParam.Color
color2 = Global.color
}
OutputMappings {
Global.color = outColor
}
}
}
}
Technique {
LightMode SinglePass
ShadowMode InPass
VertexShader GLSL100: Common/MatDefs/Light/SPLighting.vert
FragmentShader GLSL100: Common/MatDefs/Light/SPLighting.frag
WorldParameters {
WorldViewProjectionMatrix
NormalMatrix
WorldViewMatrix
ViewMatrix
CameraPosition
WorldMatrix
ViewProjectionMatrix
}
Defines {
VERTEX_COLOR : UseVertexColor
VERTEX_LIGHTING : VertexLighting
MATERIAL_COLORS : UseMaterialColors
DIFFUSEMAP : DiffuseMap
NORMALMAP : NormalMap
SPECULARMAP : SpecularMap
PARALLAXMAP : ParallaxMap
NORMALMAP_PARALLAX : PackedNormalParallax
STEEP_PARALLAX : SteepParallax
ALPHAMAP : AlphaMap
COLORRAMP : ColorRamp
LIGHTMAP : LightMap
SEPARATE_TEXCOORD : SeparateTexCoord
DISCARD_ALPHA : AlphaDiscardThreshold
USE_REFLECTION : EnvMap
SPHERE_MAP : EnvMapAsSphereMap
NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
}
}
Technique {
LightMode MultiPass
ShadowMode PostPass
VertexShader GLSL100: Common/MatDefs/Light/Lighting.vert
FragmentShader GLSL100: Common/MatDefs/Light/Lighting.frag
WorldParameters {
WorldViewProjectionMatrix
NormalMatrix
WorldViewMatrix
ViewMatrix
CameraPosition
WorldMatrix
ViewProjectionMatrix
}
Defines {
VERTEX_COLOR : UseVertexColor
VERTEX_LIGHTING : VertexLighting
MATERIAL_COLORS : UseMaterialColors
DIFFUSEMAP : DiffuseMap
NORMALMAP : NormalMap
SPECULARMAP : SpecularMap
PARALLAXMAP : ParallaxMap
NORMALMAP_PARALLAX : PackedNormalParallax
STEEP_PARALLAX : SteepParallax
ALPHAMAP : AlphaMap
COLORRAMP : ColorRamp
LIGHTMAP : LightMap
SEPARATE_TEXCOORD : SeparateTexCoord
DISCARD_ALPHA : AlphaDiscardThreshold
USE_REFLECTION : EnvMap
SPHERE_MAP : EnvMapAsSphereMap
NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
}
}
Technique PreShadow {
VertexShader GLSL100 : Common/MatDefs/Shadow/PreShadow.vert
FragmentShader GLSL100 : Common/MatDefs/Shadow/PreShadow.frag
WorldParameters {
WorldViewProjectionMatrix
WorldViewMatrix
ViewProjectionMatrix
ViewMatrix
}
Defines {
DISCARD_ALPHA : AlphaDiscardThreshold
NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
}
}
Technique PostShadow {
VertexShader GLSL150: Common/MatDefs/Shadow/PostShadow.vert
FragmentShader GLSL150: Common/MatDefs/Shadow/PostShadow.frag
WorldParameters {
WorldViewProjectionMatrix
WorldMatrix
ViewProjectionMatrix
ViewMatrix
NormalMatrix
}
Defines {
HARDWARE_SHADOWS : HardwareShadows
FILTER_MODE : FilterMode
PCFEDGE : PCFEdge
DISCARD_ALPHA : AlphaDiscardThreshold
SHADOWMAP_SIZE : ShadowMapSize
FADE : FadeInfo
PSSM : Splits
POINTLIGHT : LightViewProjectionMatrix5
NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
BACKFACE_SHADOWS: BackfaceShadows
}
RenderState {
Blend Alpha
DepthWrite Off
PolyOffset -0.1 0
Wireframe On
FaceCull Back
DepthWrite On
DepthTest On
BlendEquation ReverseSubtract
BlendEquationAlpha InheritColor
ColorWrite Off
DepthFunc GreaterOrEqual
LineWidth 3.0
}
ForcedRenderState {
Blend Modulate
DepthWrite Off
PolyOffset -0.1 0
}
}
Technique PostShadow{
VertexShader GLSL100: Common/MatDefs/Shadow/PostShadow.vert
FragmentShader GLSL100: Common/MatDefs/Shadow/PostShadow.frag
WorldParameters {
WorldViewProjectionMatrix
WorldMatrix
ViewProjectionMatrix
ViewMatrix
NormalMatrix
}
Defines {
HARDWARE_SHADOWS : HardwareShadows
FILTER_MODE : FilterMode
PCFEDGE : PCFEdge
DISCARD_ALPHA : AlphaDiscardThreshold
SHADOWMAP_SIZE : ShadowMapSize
FADE : FadeInfo
PSSM : Splits
POINTLIGHT : LightViewProjectionMatrix5
NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
}
ForcedRenderState {
Blend Modulate
DepthWrite Off
PolyOffset -0.1 0
}
}
Technique PreNormalPass {
VertexShader GLSL100 : Common/MatDefs/SSAO/normal.vert
FragmentShader GLSL100 : Common/MatDefs/SSAO/normal.frag
WorldParameters {
WorldViewProjectionMatrix
WorldViewMatrix
NormalMatrix
ViewProjectionMatrix
ViewMatrix
}
Defines {
DIFFUSEMAP_ALPHA : DiffuseMap
NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
}
}
Technique PreNormalPassDerivative {
VertexShader GLSL100 : Common/MatDefs/MSSAO/normal.vert
FragmentShader GLSL100 : Common/MatDefs/MSSAO/normal.frag
WorldParameters {
WorldViewProjectionMatrix
WorldViewMatrix
NormalMatrix
ViewProjectionMatrix
ViewMatrix
}
Defines {
DIFFUSEMAP_ALPHA : DiffuseMap
NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
}
}
Technique GBuf {
VertexShader GLSL100: Common/MatDefs/Light/GBuf.vert
FragmentShader GLSL100: Common/MatDefs/Light/GBuf.frag
WorldParameters {
WorldViewProjectionMatrix
NormalMatrix
WorldViewMatrix
WorldMatrix
}
Defines {
VERTEX_COLOR : UseVertexColor
MATERIAL_COLORS : UseMaterialColors
DIFFUSEMAP : DiffuseMap
NORMALMAP : NormalMap
SPECULARMAP : SpecularMap
PARALLAXMAP : ParallaxMap
}
}
Technique Glow {
VertexShader GLSL100: Common/MatDefs/Misc/Unshaded.vert
FragmentShader GLSL100: Common/MatDefs/Light/Glow.frag
WorldParameters {
WorldViewProjectionMatrix
ViewProjectionMatrix
ViewMatrix
}
Defines {
NEED_TEXCOORD1
HAS_GLOWMAP : GlowMap
HAS_GLOWCOLOR : GlowColor
NUM_BONES : NumberOfBones
INSTANCING : UseInstancing
}
}
}
Loading…
Cancel
Save