extended some things from shader node system.

empirephoenix-patch-1
javasabr 7 years ago committed by Rémy Bouquet
parent 839ffdd4f2
commit 9578b0410e
  1. 15
      jme3-core/src/main/java/com/jme3/material/TechniqueDef.java
  2. 54
      jme3-core/src/main/java/com/jme3/shader/Glsl100ShaderGenerator.java
  3. 29
      jme3-core/src/main/java/com/jme3/shader/ShaderNodeVariable.java
  4. 58
      jme3-core/src/plugins/java/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java
  5. 7
      jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdTechniqueDefWriter.java

@ -188,6 +188,7 @@ public class TechniqueDef implements Savable, Cloneable {
defineTypes = new ArrayList<VarType>(); defineTypes = new ArrayList<VarType>();
paramToDefineId = new HashMap<String, Integer>(); paramToDefineId = new HashMap<String, Integer>();
definesToShaderMap = new HashMap<DefineList, Shader>(); definesToShaderMap = new HashMap<DefineList, Shader>();
worldBinds = new ArrayList<>();
} }
/** /**
@ -513,11 +514,9 @@ public class TechniqueDef implements Savable, Cloneable {
} }
} }
if (getWorldBindings() != null) { for (final UniformBinding binding : getWorldBindings()) {
for (UniformBinding binding : getWorldBindings()) {
shader.addUniformBinding(binding); shader.addUniformBinding(binding);
} }
}
return shader; return shader;
} }
@ -625,14 +624,10 @@ public class TechniqueDef implements Savable, Cloneable {
* to the list of world parameters, false otherwise. * to the list of world parameters, false otherwise.
*/ */
public boolean addWorldParam(String name) { public boolean addWorldParam(String name) {
if (worldBinds == null){
worldBinds = new ArrayList<UniformBinding>();
}
try { try {
worldBinds.add( UniformBinding.valueOf(name) ); worldBinds.add(UniformBinding.valueOf(name));
return true; return true;
} catch (IllegalArgumentException ex){ } catch (IllegalArgumentException ex) {
return false; return false;
} }
} }
@ -821,10 +816,8 @@ public class TechniqueDef implements Savable, Cloneable {
e.printStackTrace(); e.printStackTrace();
} }
if (worldBinds != null) {
clone.worldBinds = new ArrayList<>(worldBinds.size()); clone.worldBinds = new ArrayList<>(worldBinds.size());
clone.worldBinds.addAll(worldBinds); clone.worldBinds.addAll(worldBinds);
}
return clone; return clone;
} }

@ -50,7 +50,7 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
* the indentation characters tabulation characters * the indentation characters tabulation characters
*/ */
private final static String INDENTCHAR = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; private final static String INDENTCHAR = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
private ShaderNodeVariable inPosTmp; protected ShaderNodeVariable inPosTmp;
/** /**
* creates a Glsl100ShaderGenerator * creates a Glsl100ShaderGenerator
@ -110,7 +110,7 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
protected void generateVaryings(StringBuilder source, ShaderGenerationInfo info, ShaderType type) { protected void generateVaryings(StringBuilder source, ShaderGenerationInfo info, ShaderType type) {
source.append("\n"); source.append("\n");
for (ShaderNodeVariable var : info.getVaryings()) { for (ShaderNodeVariable var : info.getVaryings()) {
declareVarying(source, var, type == ShaderType.Vertex ? false : true); declareVarying(source, var, type != ShaderType.Vertex);
} }
} }
@ -141,7 +141,7 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
@Override @Override
protected void generateStartOfMainSection(StringBuilder source, ShaderGenerationInfo info, ShaderType type) { protected void generateStartOfMainSection(StringBuilder source, ShaderGenerationInfo info, ShaderType type) {
source.append("\n"); source.append("\n");
source.append("void main(){\n"); source.append("void main() {\n");
indent(); indent();
appendIndent(source); appendIndent(source);
if (type == ShaderType.Vertex) { if (type == ShaderType.Vertex) {
@ -237,27 +237,59 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
comment(source, shaderNode, "Begin"); comment(source, shaderNode, "Begin");
startCondition(shaderNode.getCondition(), source); startCondition(shaderNode.getCondition(), source);
List<String> declaredInputs = new ArrayList<String>(); final List<String> declaredInputs = new ArrayList<>();
for (VariableMapping mapping : shaderNode.getInputMapping()) { for (VariableMapping mapping : shaderNode.getInputMapping()) {
final ShaderNodeVariable rightVariable = mapping.getRightVariable();
final ShaderNodeVariable leftVariable = mapping.getLeftVariable();
//Variables fed with a sampler matparam or world param are replaced by the matparam itself //Variables fed with a sampler matparam or world param are replaced by the matparam itself
//It avoids issue with samplers that have to be uniforms. //It avoids issue with samplers that have to be uniforms.
if (isWorldOrMaterialParam(mapping.getRightVariable()) && mapping.getRightVariable().getType().startsWith("sampler")) { if (isWorldOrMaterialParam(rightVariable) && rightVariable.getType().startsWith("sampler")) {
nodeSource = replace(nodeSource, mapping.getLeftVariable(), mapping.getRightVariable().getPrefix() + mapping.getRightVariable().getName()); nodeSource = replace(nodeSource, leftVariable, rightVariable.getPrefix() + rightVariable.getName());
} else { } else {
if (mapping.getLeftVariable().getType().startsWith("sampler")) {
if (leftVariable.getType().startsWith("sampler")) {
throw new IllegalArgumentException("a Sampler must be a uniform"); throw new IllegalArgumentException("a Sampler must be a uniform");
} }
map(mapping, source); map(mapping, source);
String newName = shaderNode.getName() + "_" + mapping.getLeftVariable().getName(); }
String newName = shaderNode.getName() + "_" + leftVariable.getName();
if (!declaredInputs.contains(newName)) { if (!declaredInputs.contains(newName)) {
nodeSource = replace(nodeSource, mapping.getLeftVariable(), newName); nodeSource = replace(nodeSource, leftVariable, newName);
declaredInputs.add(newName); declaredInputs.add(newName);
} }
} }
final ShaderNodeDefinition definition = shaderNode.getDefinition();
for (final ShaderNodeVariable var : definition.getInputs()) {
if (var.getDefaultValue() == null) {
continue;
}
final String fullName = shaderNode.getName() + "_" + var.getName();
if (declaredInputs.contains(fullName)) {
continue;
}
final ShaderNodeVariable variable = new ShaderNodeVariable(var.getType(), shaderNode.getName(),
var.getName(), var.getMultiplicity());
if (!isVarying(info, variable)) {
declareVariable(source, variable, var.getDefaultValue(), true, null);
}
nodeSource = replaceVariableName(nodeSource, variable);
declaredInputs.add(fullName);
} }
for (ShaderNodeVariable var : shaderNode.getDefinition().getOutputs()) { for (ShaderNodeVariable var : definition.getOutputs()) {
ShaderNodeVariable v = new ShaderNodeVariable(var.getType(), shaderNode.getName(), var.getName(), var.getMultiplicity()); ShaderNodeVariable v = new ShaderNodeVariable(var.getType(), shaderNode.getName(), var.getName(), var.getMultiplicity());
if (!declaredInputs.contains(shaderNode.getName() + "_" + var.getName())) { if (!declaredInputs.contains(shaderNode.getName() + "_" + var.getName())) {
if (!isVarying(info, v)) { if (!isVarying(info, v)) {
@ -603,7 +635,7 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
* makes sure inPosition attribute is of type vec3 or vec4 * makes sure inPosition attribute is of type vec3 or vec4
* @param var the inPosition attribute * @param var the inPosition attribute
*/ */
private void fixInPositionType(ShaderNodeVariable var) { protected void fixInPositionType(ShaderNodeVariable var) {
if(!var.getType().equals("vec3") || !var.getType().equals("vec4")){ if(!var.getType().equals("vec3") || !var.getType().equals("vec4")){
var.setType("vec3"); var.setType("vec3");
} }

@ -50,8 +50,10 @@ public class ShaderNodeVariable implements Savable, Cloneable {
private String type; private String type;
private String nameSpace; private String nameSpace;
private String condition; private String condition;
private boolean shaderOutput = false;
private String multiplicity; private String multiplicity;
private String defaultValue;
private boolean shaderOutput = false;
/** /**
* creates a ShaderNodeVariable * creates a ShaderNodeVariable
@ -180,6 +182,24 @@ public class ShaderNodeVariable implements Savable, Cloneable {
this.nameSpace = nameSpace; this.nameSpace = nameSpace;
} }
/**
* Gets the default value of this variable.
*
* @return the default value of this variable.
*/
public String getDefaultValue() {
return defaultValue;
}
/**
* Sets the default value of this variable.
*
* @param defaultValue the default value of this variable.
*/
public void setDefaultValue(final String defaultValue) {
this.defaultValue = defaultValue;
}
@Override @Override
public int hashCode() { public int hashCode() {
int hash = 7; int hash = 7;
@ -230,7 +250,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
*/ */
@Override @Override
public void write(JmeExporter ex) throws IOException { public void write(JmeExporter ex) throws IOException {
OutputCapsule oc = (OutputCapsule) ex.getCapsule(this); OutputCapsule oc = ex.getCapsule(this);
oc.write(name, "name", ""); oc.write(name, "name", "");
oc.write(type, "type", ""); oc.write(type, "type", "");
oc.write(prefix, "prefix", ""); oc.write(prefix, "prefix", "");
@ -238,7 +258,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
oc.write(condition, "condition", null); oc.write(condition, "condition", null);
oc.write(shaderOutput, "shaderOutput", false); oc.write(shaderOutput, "shaderOutput", false);
oc.write(multiplicity, "multiplicity", null); oc.write(multiplicity, "multiplicity", null);
oc.write(defaultValue, "defaultValue", null);
} }
/** /**
@ -249,7 +269,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
*/ */
@Override @Override
public void read(JmeImporter im) throws IOException { public void read(JmeImporter im) throws IOException {
InputCapsule ic = (InputCapsule) im.getCapsule(this); InputCapsule ic = im.getCapsule(this);
name = ic.readString("name", ""); name = ic.readString("name", "");
type = ic.readString("type", ""); type = ic.readString("type", "");
prefix = ic.readString("pefix", ""); prefix = ic.readString("pefix", "");
@ -257,6 +277,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
condition = ic.readString("condition", null); condition = ic.readString("condition", null);
shaderOutput = ic.readBoolean("shaderOutput", false); shaderOutput = ic.readBoolean("shaderOutput", false);
multiplicity = ic.readString("multiplicity", null); multiplicity = ic.readString("multiplicity", null);
defaultValue = ic.readString("defaultValue", null);
} }
/** /**

@ -217,11 +217,15 @@ public class ShaderNodeLoaderDelegate {
* @throws IOException * @throws IOException
*/ */
protected ShaderNodeVariable readVariable(Statement statement) throws IOException { protected ShaderNodeVariable readVariable(Statement statement) throws IOException {
String line = statement.getLine().trim().replaceAll("\\s*\\[", "["); String line = statement.getLine().trim().replaceAll("\\s*\\[", "[");
String[] splitVar = line.split("\\s"); String[] splitVar = line.split("\\s");
if (splitVar.length != 2) {
throw new MatParseException("2 arguments", splitVar.length + "", statement); if (splitVar.length > 3) {
throw new MatParseException("More than 3 arguments", splitVar.length + "", statement);
} }
String defaultValue = splitVar.length > 2? splitVar[2] : null;
String varName = splitVar[1]; String varName = splitVar[1];
String varType = splitVar[0]; String varType = splitVar[0];
String multiplicity = null; String multiplicity = null;
@ -232,11 +236,17 @@ public class ShaderNodeLoaderDelegate {
varName = arr[0].trim(); varName = arr[0].trim();
multiplicity = arr[1].replaceAll("\\]", "").trim(); multiplicity = arr[1].replaceAll("\\]", "").trim();
} }
if (varNames.contains(varName + ";")) { if (varNames.contains(varName + ";")) {
throw new MatParseException("Duplicate variable name " + varName, statement); throw new MatParseException("Duplicate variable name " + varName, statement);
} }
varNames += varName + ";"; varNames += varName + ";";
return new ShaderNodeVariable(varType, "", varName, multiplicity);
final ShaderNodeVariable variable = new ShaderNodeVariable(varType, "", varName, multiplicity);
variable.setDefaultValue(defaultValue);
return variable;
} }
/** /**
@ -661,18 +671,12 @@ public class ShaderNodeLoaderDelegate {
} }
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) { if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) {
if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms, statement1)) { if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms, statement1)) {
updateMaterialTextureType(statement1, mapping, left, param);
storeVertexUniform(mapping.getRightVariable()); storeVertexUniform(mapping.getRightVariable());
} }
} else { } else {
if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms, statement1)) { if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms, statement1)) {
if (mapping.getRightVariable().getType().contains("|")) { updateMaterialTextureType(statement1, mapping, left, param);
String type = fixSamplerType(left.getType(), mapping.getRightVariable().getType());
if (type != null) {
mapping.getRightVariable().setType(type);
} else {
throw new MatParseException(param.getVarType().toString() + " can only be matched to one of " + param.getVarType().getGlslType().replaceAll("\\|", ",") + " found " + left.getType(), statement1);
}
}
storeFragmentUniform(mapping.getRightVariable()); storeFragmentUniform(mapping.getRightVariable());
} }
} }
@ -714,6 +718,32 @@ public class ShaderNodeLoaderDelegate {
return mapping; return mapping;
} }
/**
* Updated the material texture type of the variable mapping.
*
* @param statement the statement.
* @param mapping the variable mapping.
* @param left the left variable.
* @param param the material parameter.
* @throws MatParseException
*/
private void updateMaterialTextureType(final Statement statement, final VariableMapping mapping,
final ShaderNodeVariable left, final MatParam param) throws MatParseException {
if (!mapping.getRightVariable().getType().contains("|")) {
return;
}
final String type = fixSamplerType(left.getType(), mapping.getRightVariable().getType());
if (type != null) {
mapping.getRightVariable().setType(type);
} else {
throw new MatParseException(param.getVarType().toString() + " can only be matched to one of " +
param.getVarType().getGlslType().replaceAll("\\|", ",") + " found " + left.getType(), statement);
}
}
/** /**
* reads an output mapping * reads an output mapping
* *
@ -924,12 +954,12 @@ public class ShaderNodeLoaderDelegate {
dv.addNode(shaderNode); dv.addNode(shaderNode);
//if a variable is declared with the same name as an input and an output and is a varying, set it as a shader output so it's declared as a varying only once. //if a variable is declared with the same name as an input and an output and is a varying, set it as a shader output so it's declared as a varying only once.
for (VariableMapping variableMapping : node.getInputMapping()) { for (VariableMapping variableMapping : node.getInputMapping()) {
if (variableMapping.getLeftVariable().getName().equals(variable.getName())) { final ShaderNodeVariable leftVariable = variableMapping.getLeftVariable();
variableMapping.getLeftVariable().setShaderOutput(true); if (leftVariable.getName().equals(variable.getName())) {
leftVariable.setShaderOutput(true);
} }
} }
} }
} }
/** /**

@ -168,13 +168,13 @@ public class J3mdTechniqueDefWriter {
out.write(shaderNode.getDefinition().getPath()); out.write(shaderNode.getDefinition().getPath());
out.write("\n"); out.write("\n");
out.write(" InputMappings{\n"); out.write(" InputMappings {\n");
for (VariableMapping mapping : shaderNode.getInputMapping()) { for (VariableMapping mapping : shaderNode.getInputMapping()) {
writeVariableMapping(out, shaderNode, mapping, matParams); writeVariableMapping(out, shaderNode, mapping, matParams);
} }
out.write(" }\n"); out.write(" }\n");
out.write(" OutputMappings{\n"); out.write(" OutputMappings {\n");
for (VariableMapping mapping : shaderNode.getOutputMapping()) { for (VariableMapping mapping : shaderNode.getOutputMapping()) {
writeVariableMapping(out, shaderNode, mapping, matParams); writeVariableMapping(out, shaderNode, mapping, matParams);
} }
@ -288,7 +288,4 @@ public class J3mdTechniqueDefWriter {
} }
return null; return null;
} }
} }

Loading…
Cancel
Save