Implementing value mappings for shader nodes. (#786)
* implemented value mappings for shader nodes.
This commit is contained in:
parent
7e66911901
commit
a8c7a85fc1
@ -35,6 +35,7 @@ import com.jme3.asset.AssetManager;
|
|||||||
import com.jme3.material.ShaderGenerationInfo;
|
import com.jme3.material.ShaderGenerationInfo;
|
||||||
import com.jme3.material.plugins.ConditionParser;
|
import com.jme3.material.plugins.ConditionParser;
|
||||||
import com.jme3.shader.Shader.ShaderType;
|
import com.jme3.shader.Shader.ShaderType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
|
|||||||
* the indentation characters 1à tabulation characters
|
* the indentation characters 1à 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";
|
||||||
|
|
||||||
protected ShaderNodeVariable inPosTmp;
|
protected ShaderNodeVariable inPosTmp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,7 +248,7 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
|
|||||||
|
|
||||||
//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(rightVariable) && rightVariable.getType().startsWith("sampler")) {
|
if (rightVariable != null && isWorldOrMaterialParam(rightVariable) && rightVariable.getType().startsWith("sampler")) {
|
||||||
nodeSource = replace(nodeSource, leftVariable, rightVariable.getPrefix() + rightVariable.getName());
|
nodeSource = replace(nodeSource, leftVariable, rightVariable.getPrefix() + rightVariable.getName());
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -417,48 +419,63 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
|
|||||||
/**
|
/**
|
||||||
* Appends a mapping to the source, embed in a conditional block if needed,
|
* Appends a mapping to the source, embed in a conditional block if needed,
|
||||||
* with variables nameSpaces and swizzle.
|
* with variables nameSpaces and swizzle.
|
||||||
|
*
|
||||||
* @param mapping the VariableMapping to append
|
* @param mapping the VariableMapping to append
|
||||||
* @param source the StringBuilder to use
|
* @param source the StringBuilder to use
|
||||||
*/
|
*/
|
||||||
protected void map(VariableMapping mapping, StringBuilder source) {
|
protected void map(VariableMapping mapping, StringBuilder source) {
|
||||||
|
|
||||||
|
final ShaderNodeVariable leftVariable = mapping.getLeftVariable();
|
||||||
|
final ShaderNodeVariable rightVariable = mapping.getRightVariable();
|
||||||
|
final String rightExpression = mapping.getRightExpression();
|
||||||
|
|
||||||
startCondition(mapping.getCondition(), source);
|
startCondition(mapping.getCondition(), source);
|
||||||
appendIndent(source);
|
appendIndent(source);
|
||||||
if (!mapping.getLeftVariable().isShaderOutput()) {
|
if (!leftVariable.isShaderOutput()) {
|
||||||
source.append(mapping.getLeftVariable().getType());
|
source.append(leftVariable.getType());
|
||||||
source.append(" ");
|
source.append(" ");
|
||||||
}
|
}
|
||||||
source.append(mapping.getLeftVariable().getNameSpace());
|
source.append(leftVariable.getNameSpace());
|
||||||
source.append("_");
|
source.append("_");
|
||||||
source.append(mapping.getLeftVariable().getName());
|
source.append(leftVariable.getName());
|
||||||
if (mapping.getLeftVariable().getMultiplicity() != null){
|
if (leftVariable.getMultiplicity() != null){
|
||||||
source.append("[");
|
source.append("[");
|
||||||
source.append(mapping.getLeftVariable().getMultiplicity());
|
source.append(leftVariable.getMultiplicity());
|
||||||
source.append("]");
|
source.append("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
//left swizzle, the variable can't be declared and assigned on the same line.
|
// left swizzle, the variable can't be declared and assigned on the same line.
|
||||||
if (mapping.getLeftSwizzling().length() > 0) {
|
if (mapping.getLeftSwizzling().length() > 0) {
|
||||||
//initialize the declared variable to 0.0
|
//initialize the declared variable to 0.0
|
||||||
source.append(" = ");
|
source.append(" = ");
|
||||||
source.append(mapping.getLeftVariable().getType());
|
source.append(leftVariable.getType());
|
||||||
source.append("(0.0);\n");
|
source.append("(0.0);\n");
|
||||||
appendIndent(source);
|
appendIndent(source);
|
||||||
//assign the value on a new line
|
// assign the value on a new line
|
||||||
source.append(mapping.getLeftVariable().getNameSpace());
|
source.append(leftVariable.getNameSpace());
|
||||||
source.append("_");
|
source.append("_");
|
||||||
source.append(mapping.getLeftVariable().getName());
|
source.append(leftVariable.getName());
|
||||||
source.append(".");
|
source.append(".");
|
||||||
source.append(mapping.getLeftSwizzling());
|
source.append(mapping.getLeftSwizzling());
|
||||||
}
|
}
|
||||||
source.append(" = ");
|
source.append(" = ");
|
||||||
String namePrefix = getAppendableNameSpace(mapping.getRightVariable());
|
|
||||||
|
if (rightVariable != null) {
|
||||||
|
|
||||||
|
String namePrefix = getAppendableNameSpace(rightVariable);
|
||||||
source.append(namePrefix);
|
source.append(namePrefix);
|
||||||
source.append(mapping.getRightVariable().getPrefix());
|
source.append(rightVariable.getPrefix());
|
||||||
source.append(mapping.getRightVariable().getName());
|
source.append(rightVariable.getName());
|
||||||
|
|
||||||
if (mapping.getRightSwizzling().length() > 0) {
|
if (mapping.getRightSwizzling().length() > 0) {
|
||||||
source.append(".");
|
source.append(".");
|
||||||
source.append(mapping.getRightSwizzling());
|
source.append(mapping.getRightSwizzling());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
source.append(rightExpression);
|
||||||
|
}
|
||||||
|
|
||||||
source.append(";\n");
|
source.append(";\n");
|
||||||
endCondition(mapping.getCondition(), source);
|
endCondition(mapping.getCondition(), source);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,11 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
public abstract class ShaderGenerator {
|
public abstract class ShaderGenerator {
|
||||||
|
|
||||||
|
public static final String NAME_SPACE_GLOBAL = "Global";
|
||||||
|
public static final String NAME_SPACE_VERTEX_ATTRIBUTE = "Attr";
|
||||||
|
public static final String NAME_SPACE_MAT_PARAM = "MatParam";
|
||||||
|
public static final String NAME_SPACE_WORLD_PARAM = "WorldParam";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the asset manager
|
* the asset manager
|
||||||
*/
|
*/
|
||||||
|
@ -31,11 +31,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.shader;
|
package com.jme3.shader;
|
||||||
|
|
||||||
import com.jme3.export.InputCapsule;
|
import com.jme3.export.*;
|
||||||
import com.jme3.export.JmeExporter;
|
|
||||||
import com.jme3.export.JmeImporter;
|
|
||||||
import com.jme3.export.OutputCapsule;
|
|
||||||
import com.jme3.export.Savable;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -59,15 +56,16 @@ public class ShaderNode implements Savable, Cloneable {
|
|||||||
private String name;
|
private String name;
|
||||||
private ShaderNodeDefinition definition;
|
private ShaderNodeDefinition definition;
|
||||||
private String condition;
|
private String condition;
|
||||||
private List<VariableMapping> inputMapping = new ArrayList<VariableMapping>();
|
|
||||||
private List<VariableMapping> outputMapping = new ArrayList<VariableMapping>();
|
private List<VariableMapping> inputMapping = new ArrayList<>();
|
||||||
|
private List<VariableMapping> outputMapping = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a ShaderNode
|
* Creates a shader node.
|
||||||
*
|
*
|
||||||
* @param name the name
|
* @param name the name.
|
||||||
* @param definition the ShaderNodeDefinition
|
* @param definition the shader node definition.
|
||||||
* @param condition the condition to activate this node
|
* @param condition the condition to activate this node.
|
||||||
*/
|
*/
|
||||||
public ShaderNode(String name, ShaderNodeDefinition definition, String condition) {
|
public ShaderNode(String name, ShaderNodeDefinition definition, String condition) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -76,12 +74,13 @@ public class ShaderNode implements Savable, Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a ShaderNode
|
* Creates a shader node.
|
||||||
*/
|
*/
|
||||||
public ShaderNode() {
|
public ShaderNode() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the name of the node.
|
||||||
*
|
*
|
||||||
* @return the name of the node
|
* @return the name of the node
|
||||||
*/
|
*/
|
||||||
@ -90,82 +89,83 @@ public class ShaderNode implements Savable, Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the name of th node
|
* Sets the name of the node.
|
||||||
*
|
*
|
||||||
* @param name the name
|
* @param name the name of the node.
|
||||||
*/
|
*/
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the definition
|
* Returns the shader node definition.
|
||||||
*
|
*
|
||||||
* @return the ShaderNodeDefinition
|
* @return the shader node definition.
|
||||||
*/
|
*/
|
||||||
public ShaderNodeDefinition getDefinition() {
|
public ShaderNodeDefinition getDefinition() {
|
||||||
return definition;
|
return definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the definition
|
* Sets the shader node definition.
|
||||||
*
|
*
|
||||||
* @param definition the ShaderNodeDefinition
|
* @param definition the shader node definition.
|
||||||
*/
|
*/
|
||||||
public void setDefinition(ShaderNodeDefinition definition) {
|
public void setDefinition(ShaderNodeDefinition definition) {
|
||||||
this.definition = definition;
|
this.definition = definition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the condition.
|
||||||
*
|
*
|
||||||
* @return the condition
|
* @return the condition.
|
||||||
*/
|
*/
|
||||||
public String getCondition() {
|
public String getCondition() {
|
||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the condition
|
* Sets the condition.
|
||||||
*
|
*
|
||||||
* @param condition the condition
|
* @param condition the condition.
|
||||||
*/
|
*/
|
||||||
public void setCondition(String condition) {
|
public void setCondition(String condition) {
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return a list of VariableMapping representing the input mappings of this
|
* Returns a list of variable mapping representing the input mappings of this
|
||||||
* node
|
* node.
|
||||||
*
|
*
|
||||||
* @return the input mappings
|
* @return the input mappings.
|
||||||
*/
|
*/
|
||||||
public List<VariableMapping> getInputMapping() {
|
public List<VariableMapping> getInputMapping() {
|
||||||
return inputMapping;
|
return inputMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the input mappings
|
* Sets the input mappings.
|
||||||
*
|
*
|
||||||
* @param inputMapping the input mappings
|
* @param inputMapping the input mappings.
|
||||||
*/
|
*/
|
||||||
public void setInputMapping(List<VariableMapping> inputMapping) {
|
public void setInputMapping(List<VariableMapping> inputMapping) {
|
||||||
this.inputMapping = inputMapping;
|
this.inputMapping = inputMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* return a list of VariableMapping representing the output mappings of this
|
* Returns a list of variable mapping representing the output mappings of this
|
||||||
* node
|
* node.
|
||||||
*
|
*
|
||||||
* @return the output mappings
|
* @return the output mappings.
|
||||||
*/
|
*/
|
||||||
public List<VariableMapping> getOutputMapping() {
|
public List<VariableMapping> getOutputMapping() {
|
||||||
return outputMapping;
|
return outputMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the output mappings
|
* Sets the output mappings.
|
||||||
*
|
*
|
||||||
* @param outputMapping the output mappings
|
* @param outputMapping the output mappings.
|
||||||
*/
|
*/
|
||||||
public void setOutputMapping(List<VariableMapping> outputMapping) {
|
public void setOutputMapping(List<VariableMapping> outputMapping) {
|
||||||
this.outputMapping = outputMapping;
|
this.outputMapping = outputMapping;
|
||||||
@ -179,7 +179,7 @@ public class ShaderNode 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(definition, "definition", null);
|
oc.write(definition, "definition", null);
|
||||||
oc.write(condition, "condition", null);
|
oc.write(condition, "condition", null);
|
||||||
@ -195,7 +195,7 @@ public class ShaderNode 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", "");
|
||||||
definition = (ShaderNodeDefinition) ic.readSavable("definition", null);
|
definition = (ShaderNodeDefinition) ic.readSavable("definition", null);
|
||||||
condition = ic.readString("condition", null);
|
condition = ic.readString("condition", null);
|
||||||
@ -210,24 +210,48 @@ public class ShaderNode implements Savable, Cloneable {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "\nShaderNode{" + "\nname=" + name + ", \ndefinition=" + definition.getName() + ", \ncondition=" + condition + ", \ninputMapping=" + inputMapping + ", \noutputMapping=" + outputMapping + '}';
|
|
||||||
|
final StringBuilder builder = new StringBuilder("ShaderNode:");
|
||||||
|
builder.append("\n\tname=").append(name)
|
||||||
|
.append("\n\tdefinition=").append(definition.getName())
|
||||||
|
.append("\n\tcondition=").append(condition);
|
||||||
|
|
||||||
|
if (!inputMapping.isEmpty()) {
|
||||||
|
builder.append("\n\tinputMapping:\n");
|
||||||
|
for (final VariableMapping mapping : inputMapping) {
|
||||||
|
builder.append("\t\t").append(mapping).append('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outputMapping.isEmpty()) {
|
||||||
|
builder.append("\n\toutputMapping:\n");
|
||||||
|
for (final VariableMapping mapping : outputMapping) {
|
||||||
|
builder.append("\t\t").append(mapping).append('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builder.charAt(builder.length() - 1) == '\n') {
|
||||||
|
builder.delete(builder.length() - 1, builder.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ShaderNode clone() throws CloneNotSupportedException {
|
public ShaderNode clone() throws CloneNotSupportedException {
|
||||||
ShaderNode clone = (ShaderNode) super.clone();
|
ShaderNode clone = (ShaderNode) super.clone();
|
||||||
|
|
||||||
//No need to clone the definition.
|
// No need to clone the definition.
|
||||||
clone.definition = definition;
|
clone.definition = definition;
|
||||||
|
|
||||||
clone.inputMapping = new ArrayList<>();
|
clone.inputMapping = new ArrayList<>();
|
||||||
for (VariableMapping variableMapping : inputMapping) {
|
for (VariableMapping variableMapping : inputMapping) {
|
||||||
clone.inputMapping.add((VariableMapping) variableMapping.clone());
|
clone.inputMapping.add(variableMapping.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
clone.outputMapping = new ArrayList<>();
|
clone.outputMapping = new ArrayList<>();
|
||||||
for (VariableMapping variableMapping : outputMapping) {
|
for (VariableMapping variableMapping : outputMapping) {
|
||||||
clone.outputMapping.add((VariableMapping) variableMapping.clone());
|
clone.outputMapping.add(variableMapping.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
return clone;
|
return clone;
|
||||||
|
@ -299,7 +299,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "\n" + type + ' ' + (nameSpace != null ? (nameSpace + '.') : "") + name;
|
return type + ' ' + (nameSpace != null ? (nameSpace + '.') : "") + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,15 +31,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.shader;
|
package com.jme3.shader;
|
||||||
|
|
||||||
import com.jme3.export.InputCapsule;
|
import com.jme3.export.*;
|
||||||
import com.jme3.export.JmeExporter;
|
|
||||||
import com.jme3.export.JmeImporter;
|
|
||||||
import com.jme3.export.OutputCapsule;
|
|
||||||
import com.jme3.export.Savable;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* represents a mapping between 2 ShaderNodeVariables
|
* Represents a mapping between 2 shader node variables or a left shader node variable and a value expression.
|
||||||
*
|
*
|
||||||
* @author Nehon
|
* @author Nehon
|
||||||
*/
|
*/
|
||||||
@ -47,18 +45,19 @@ public class VariableMapping implements Savable, Cloneable {
|
|||||||
|
|
||||||
private ShaderNodeVariable leftVariable;
|
private ShaderNodeVariable leftVariable;
|
||||||
private ShaderNodeVariable rightVariable;
|
private ShaderNodeVariable rightVariable;
|
||||||
|
private String rightExpression;
|
||||||
private String condition;
|
private String condition;
|
||||||
private String leftSwizzling = "";
|
private String leftSwizzling = "";
|
||||||
private String rightSwizzling = "";
|
private String rightSwizzling = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a VariableMapping
|
* Creates a VariableMapping.
|
||||||
*/
|
*/
|
||||||
public VariableMapping() {
|
public VariableMapping() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a VariableMapping
|
* Creates a VariableMapping.
|
||||||
*
|
*
|
||||||
* @param leftVariable the left hand side variable of the expression
|
* @param leftVariable the left hand side variable of the expression
|
||||||
* @param leftSwizzling the swizzling of the left variable
|
* @param leftSwizzling the swizzling of the left variable
|
||||||
@ -66,49 +65,71 @@ public class VariableMapping implements Savable, Cloneable {
|
|||||||
* @param rightSwizzling the swizzling of the right variable
|
* @param rightSwizzling the swizzling of the right variable
|
||||||
* @param condition the condition for this mapping
|
* @param condition the condition for this mapping
|
||||||
*/
|
*/
|
||||||
public VariableMapping(ShaderNodeVariable leftVariable, String leftSwizzling, ShaderNodeVariable rightVariable, String rightSwizzling, String condition) {
|
public VariableMapping(ShaderNodeVariable leftVariable, String leftSwizzling, ShaderNodeVariable rightVariable,
|
||||||
|
String rightSwizzling, String condition) {
|
||||||
this.leftVariable = leftVariable;
|
this.leftVariable = leftVariable;
|
||||||
this.rightVariable = rightVariable;
|
this.rightVariable = rightVariable;
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
this.leftSwizzling = leftSwizzling;
|
this.leftSwizzling = Objects.requireNonNull(leftSwizzling);
|
||||||
this.rightSwizzling = rightSwizzling;
|
this.rightSwizzling = Objects.requireNonNull(rightSwizzling);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the left variable.
|
||||||
*
|
*
|
||||||
* @return the left variable
|
* @return the left variable.
|
||||||
*/
|
*/
|
||||||
public ShaderNodeVariable getLeftVariable() {
|
public ShaderNodeVariable getLeftVariable() {
|
||||||
return leftVariable;
|
return leftVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the left variable
|
* Sets the left variable.
|
||||||
*
|
*
|
||||||
* @param leftVariable the left variable
|
* @param leftVariable the left variable.
|
||||||
*/
|
*/
|
||||||
public void setLeftVariable(ShaderNodeVariable leftVariable) {
|
public void setLeftVariable(ShaderNodeVariable leftVariable) {
|
||||||
this.leftVariable = leftVariable;
|
this.leftVariable = leftVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the right variable.
|
||||||
*
|
*
|
||||||
* @return the right variable
|
* @return the right variable or null.
|
||||||
*/
|
*/
|
||||||
public ShaderNodeVariable getRightVariable() {
|
public ShaderNodeVariable getRightVariable() {
|
||||||
return rightVariable;
|
return rightVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the right variable
|
* Sets the right variable.
|
||||||
*
|
*
|
||||||
* @param rightVariable the right variable
|
* @param rightVariable the right variable.
|
||||||
*/
|
*/
|
||||||
public void setRightVariable(ShaderNodeVariable rightVariable) {
|
public void setRightVariable(ShaderNodeVariable rightVariable) {
|
||||||
this.rightVariable = rightVariable;
|
this.rightVariable = rightVariable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the right expression.
|
||||||
|
*
|
||||||
|
* @return the right expression or null.
|
||||||
|
*/
|
||||||
|
public String getRightExpression() {
|
||||||
|
return rightExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the right expression.
|
||||||
|
*
|
||||||
|
* @param rightExpression the right expression.
|
||||||
|
*/
|
||||||
|
public void setRightExpression(final String rightExpression) {
|
||||||
|
this.rightExpression = rightExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the condition.
|
||||||
*
|
*
|
||||||
* @return the condition
|
* @return the condition
|
||||||
*/
|
*/
|
||||||
@ -117,46 +138,48 @@ public class VariableMapping implements Savable, Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the condition
|
* Sets the condition.
|
||||||
*
|
*
|
||||||
* @param condition the condition
|
* @param condition the condition or null.
|
||||||
*/
|
*/
|
||||||
public void setCondition(String condition) {
|
public void setCondition(String condition) {
|
||||||
this.condition = condition;
|
this.condition = condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the left swizzle.
|
||||||
*
|
*
|
||||||
* @return the left swizzle
|
* @return the left swizzle or empty string.
|
||||||
*/
|
*/
|
||||||
public String getLeftSwizzling() {
|
public String getLeftSwizzling() {
|
||||||
return leftSwizzling;
|
return leftSwizzling;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the left swizzle
|
* Sets the left swizzle.
|
||||||
*
|
*
|
||||||
* @param leftSwizzling the left swizzle
|
* @param leftSwizzling the left swizzle.
|
||||||
*/
|
*/
|
||||||
public void setLeftSwizzling(String leftSwizzling) {
|
public void setLeftSwizzling(String leftSwizzling) {
|
||||||
this.leftSwizzling = leftSwizzling;
|
this.leftSwizzling = Objects.requireNonNull(leftSwizzling);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the right swizzle.
|
||||||
*
|
*
|
||||||
* @return the right swizzle
|
* @return the right swizzle or empty string.
|
||||||
*/
|
*/
|
||||||
public String getRightSwizzling() {
|
public String getRightSwizzling() {
|
||||||
return rightSwizzling;
|
return rightSwizzling;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sets the right swizzle
|
* Sets the right swizzle.
|
||||||
*
|
*
|
||||||
* @param rightSwizzling the right swizzle
|
* @param rightSwizzling the right swizzle.
|
||||||
*/
|
*/
|
||||||
public void setRightSwizzling(String rightSwizzling) {
|
public void setRightSwizzling(String rightSwizzling) {
|
||||||
this.rightSwizzling = rightSwizzling;
|
this.rightSwizzling = Objects.requireNonNull(rightSwizzling);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,9 +190,10 @@ public class VariableMapping 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(leftVariable, "leftVariable", null);
|
oc.write(leftVariable, "leftVariable", null);
|
||||||
oc.write(rightVariable, "rightVariable", null);
|
oc.write(rightVariable, "rightVariable", null);
|
||||||
|
oc.write(rightExpression, "rightExpression", null);
|
||||||
oc.write(condition, "condition", "");
|
oc.write(condition, "condition", "");
|
||||||
oc.write(leftSwizzling, "leftSwizzling", "");
|
oc.write(leftSwizzling, "leftSwizzling", "");
|
||||||
oc.write(rightSwizzling, "rightSwizzling", "");
|
oc.write(rightSwizzling, "rightSwizzling", "");
|
||||||
@ -183,9 +207,10 @@ public class VariableMapping 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);
|
||||||
leftVariable = (ShaderNodeVariable) ic.readSavable("leftVariable", null);
|
leftVariable = (ShaderNodeVariable) ic.readSavable("leftVariable", null);
|
||||||
rightVariable = (ShaderNodeVariable) ic.readSavable("rightVariable", null);
|
rightVariable = (ShaderNodeVariable) ic.readSavable("rightVariable", null);
|
||||||
|
rightExpression = ic.readString("rightExpression", null);
|
||||||
condition = ic.readString("condition", "");
|
condition = ic.readString("condition", "");
|
||||||
leftSwizzling = ic.readString("leftSwizzling", "");
|
leftSwizzling = ic.readString("leftSwizzling", "");
|
||||||
rightSwizzling = ic.readString("rightSwizzling", "");
|
rightSwizzling = ic.readString("rightSwizzling", "");
|
||||||
@ -193,16 +218,45 @@ public class VariableMapping implements Savable, Cloneable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "\n{" + leftVariable.toString() + (leftSwizzling.length() > 0 ? ("." + leftSwizzling) : "") + " = " + rightVariable.getType() + " " + rightVariable.getNameSpace() + "." + rightVariable.getName() + (rightSwizzling.length() > 0 ? ("." + rightSwizzling) : "") + " : " + condition + "}";
|
|
||||||
|
final StringBuilder builder = new StringBuilder(leftVariable.toString());
|
||||||
|
|
||||||
|
if (!leftSwizzling.isEmpty()) {
|
||||||
|
builder.append('.').append(leftSwizzling);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append(" = ");
|
||||||
|
|
||||||
|
if (rightVariable != null) {
|
||||||
|
|
||||||
|
builder.append(rightVariable.getType())
|
||||||
|
.append(' ')
|
||||||
|
.append(rightVariable.getNameSpace())
|
||||||
|
.append('.')
|
||||||
|
.append(rightVariable.getName());
|
||||||
|
|
||||||
|
if (!rightSwizzling.isEmpty()) {
|
||||||
|
builder.append('.').append(rightSwizzling);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (rightExpression != null) {
|
||||||
|
builder.append(rightExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (condition != null && !condition.isEmpty()) {
|
||||||
|
builder.append(" : ").append(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected VariableMapping clone() throws CloneNotSupportedException {
|
protected VariableMapping clone() throws CloneNotSupportedException {
|
||||||
VariableMapping clone = (VariableMapping) super.clone();
|
VariableMapping clone = (VariableMapping) super.clone();
|
||||||
|
|
||||||
clone.leftVariable = leftVariable.clone();
|
clone.leftVariable = leftVariable.clone();
|
||||||
|
if (rightVariable != null) {
|
||||||
clone.rightVariable = rightVariable.clone();
|
clone.rightVariable = rightVariable.clone();
|
||||||
|
}
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,15 +38,10 @@ import com.jme3.material.MatParam;
|
|||||||
import com.jme3.material.MaterialDef;
|
import com.jme3.material.MaterialDef;
|
||||||
import com.jme3.material.ShaderGenerationInfo;
|
import com.jme3.material.ShaderGenerationInfo;
|
||||||
import com.jme3.material.TechniqueDef;
|
import com.jme3.material.TechniqueDef;
|
||||||
import com.jme3.shader.Shader;
|
import com.jme3.shader.Shader.ShaderType;
|
||||||
import com.jme3.shader.ShaderNode;
|
import com.jme3.shader.*;
|
||||||
import com.jme3.shader.ShaderNodeDefinition;
|
|
||||||
import com.jme3.shader.ShaderNodeVariable;
|
|
||||||
import com.jme3.shader.ShaderUtils;
|
|
||||||
import com.jme3.shader.UniformBinding;
|
|
||||||
import com.jme3.shader.VarType;
|
|
||||||
import com.jme3.shader.VariableMapping;
|
|
||||||
import com.jme3.util.blockparser.Statement;
|
import com.jme3.util.blockparser.Statement;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -65,6 +60,9 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class ShaderNodeLoaderDelegate {
|
public class ShaderNodeLoaderDelegate {
|
||||||
|
|
||||||
|
private static final boolean[] IM_HAS_NAME_SPACE = {false, true};
|
||||||
|
private static final boolean[] OM_HAS_NAME_SPACE = {true, false};
|
||||||
|
|
||||||
protected Map<String, ShaderNodeDefinition> nodeDefinitions;
|
protected Map<String, ShaderNodeDefinition> nodeDefinitions;
|
||||||
protected Map<String, ShaderNode> nodes;
|
protected Map<String, ShaderNode> nodes;
|
||||||
protected ShaderNodeDefinition shaderNodeDefinition;
|
protected ShaderNodeDefinition shaderNodeDefinition;
|
||||||
@ -165,7 +163,7 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
|
|
||||||
if (line.startsWith("Type")) {
|
if (line.startsWith("Type")) {
|
||||||
String type = line.substring(line.lastIndexOf(':') + 1).trim();
|
String type = line.substring(line.lastIndexOf(':') + 1).trim();
|
||||||
shaderNodeDefinition.setType(Shader.ShaderType.valueOf(type));
|
shaderNodeDefinition.setType(ShaderType.valueOf(type));
|
||||||
} else if (line.startsWith("Shader ")) {
|
} else if (line.startsWith("Shader ")) {
|
||||||
readShaderStatement(statement);
|
readShaderStatement(statement);
|
||||||
shaderNodeDefinition.getShadersLanguage().add(shaderLanguage);
|
shaderNodeDefinition.getShadersLanguage().add(shaderLanguage);
|
||||||
@ -267,61 +265,86 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
protected void readShaderNode(List<Statement> statements) throws IOException {
|
protected void readShaderNode(List<Statement> statements) throws IOException {
|
||||||
|
|
||||||
|
final ShaderGenerationInfo generationInfo = techniqueDef.getShaderGenerationInfo();
|
||||||
|
final List<String> unusedNodes = generationInfo.getUnusedNodes();
|
||||||
|
|
||||||
for (Statement statement : statements) {
|
for (Statement statement : statements) {
|
||||||
|
|
||||||
String line = statement.getLine();
|
String line = statement.getLine();
|
||||||
String[] split = statement.getLine().split("[ \\{]");
|
String[] split = statement.getLine().split("[ \\{]");
|
||||||
|
|
||||||
if (line.startsWith("Definition")) {
|
if (line.startsWith("Definition")) {
|
||||||
ShaderNodeDefinition def = findDefinition(statement);
|
ShaderNodeDefinition def = findDefinition(statement);
|
||||||
shaderNode.setDefinition(def);
|
shaderNode.setDefinition(def);
|
||||||
if(def.isNoOutput()){
|
if(def.isNoOutput()){
|
||||||
techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(shaderNode.getName());
|
unusedNodes.remove(shaderNode.getName());
|
||||||
}
|
}
|
||||||
} else if (line.startsWith("Condition")) {
|
} else if (line.startsWith("Condition")) {
|
||||||
String condition = line.substring(line.lastIndexOf(":") + 1).trim();
|
String condition = line.substring(line.lastIndexOf(":") + 1).trim();
|
||||||
extractCondition(condition, statement);
|
extractCondition(condition, statement);
|
||||||
shaderNode.setCondition(conditionParser.getFormattedExpression());
|
shaderNode.setCondition(conditionParser.getFormattedExpression());
|
||||||
} else if (line.startsWith("InputMapping")) {
|
} else if (line.startsWith("InputMappings")) {
|
||||||
for (Statement statement1 : statement.getContents()) {
|
for (final Statement subStatement : statement.getContents()) {
|
||||||
VariableMapping mapping = readInputMapping(statement1);
|
|
||||||
techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(mapping.getRightVariable().getNameSpace());
|
VariableMapping mapping = readInputMapping(subStatement);
|
||||||
|
|
||||||
|
final ShaderNodeVariable rightVariable = mapping.getRightVariable();
|
||||||
|
if (rightVariable != null) {
|
||||||
|
unusedNodes.remove(rightVariable.getNameSpace());
|
||||||
|
}
|
||||||
|
|
||||||
shaderNode.getInputMapping().add(mapping);
|
shaderNode.getInputMapping().add(mapping);
|
||||||
}
|
}
|
||||||
} else if (line.startsWith("OutputMapping")) {
|
} else if (line.startsWith("OutputMappings")) {
|
||||||
for (Statement statement1 : statement.getContents()) {
|
for (Statement statement1 : statement.getContents()) {
|
||||||
VariableMapping mapping = readOutputMapping(statement1);
|
VariableMapping mapping = readOutputMapping(statement1);
|
||||||
techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(shaderNode.getName());
|
unusedNodes.remove(shaderNode.getName());
|
||||||
shaderNode.getOutputMapping().add(mapping);
|
shaderNode.getOutputMapping().add(mapping);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new MatParseException("ShaderNodeDefinition", split[0], statement);
|
throw new MatParseException("ShaderNodeDefinition", split[0], statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reads a mapping statement. Sets the nameSpace, name and swizzling of the
|
* Reads a mapping statement. Sets the nameSpace, name and swizzling of the
|
||||||
* left variable. Sets the name, nameSpace and swizzling of the right
|
* left variable. Sets the name, nameSpace and swizzling of the right
|
||||||
* variable types will be determined later.
|
* variable types will be determined later. Also, we can have the right part as expression.
|
||||||
|
* <pre>
|
||||||
|
* Format variable to variable: <nameSpace>.<varName>[.<swizzling>] = <nameSpace>.<varName>[.<swizzling>][:Condition]
|
||||||
|
* Format expression to variable: <nameSpace>.<varName>[.<swizzling>] = %% expression %% [:Condition]
|
||||||
|
* </pre>
|
||||||
*
|
*
|
||||||
* <code>
|
* @param statement the statement to read.
|
||||||
* Format : <nameSpace>.<varName>[.<swizzling>] =
|
* @return the read mapping.
|
||||||
* <nameSpace>.<varName>[.<swizzling>][:Condition]
|
* @throws MatParseException if the statement isn't valid.
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @param statement the statement to read
|
|
||||||
* @return the read mapping
|
|
||||||
*/
|
*/
|
||||||
protected VariableMapping parseMapping(Statement statement, boolean[] hasNameSpace) throws IOException {
|
protected VariableMapping parseMapping(Statement statement, boolean[] hasNameSpace) throws MatParseException {
|
||||||
|
|
||||||
VariableMapping mapping = new VariableMapping();
|
VariableMapping mapping = new VariableMapping();
|
||||||
String[] cond = statement.getLine().split(":");
|
String[] cond = statement.getLine().split(":");
|
||||||
|
|
||||||
String[] vars = cond[0].split("=");
|
String[] vars = cond[0].split("=");
|
||||||
|
|
||||||
checkMappingFormat(vars, statement);
|
checkMappingFormat(vars, statement);
|
||||||
|
|
||||||
ShaderNodeVariable[] variables = new ShaderNodeVariable[2];
|
ShaderNodeVariable[] variables = new ShaderNodeVariable[2];
|
||||||
String[] swizzle = new String[2];
|
String[] swizzle = new String[2];
|
||||||
|
String rightExpression = null;
|
||||||
|
|
||||||
for (int i = 0; i < vars.length; i++) {
|
for (int i = 0; i < vars.length; i++) {
|
||||||
String[] expression = vars[i].trim().split("\\.");
|
|
||||||
|
final String var = vars[i].trim();
|
||||||
|
|
||||||
|
// it seems that is expression, not variable
|
||||||
|
if (var.contains("%%")) {
|
||||||
|
rightExpression = var.substring(2, var.length() - 2);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] expression = var.split("\\.");
|
||||||
|
|
||||||
if (hasNameSpace[i]) {
|
if (hasNameSpace[i]) {
|
||||||
if (expression.length <= 3) {
|
if (expression.length <= 3) {
|
||||||
variables[i] = new ShaderNodeVariable("", expression[0].trim(), expression[1].trim());
|
variables[i] = new ShaderNodeVariable("", expression[0].trim(), expression[1].trim());
|
||||||
@ -337,13 +360,17 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
swizzle[i] = expression[1].trim();
|
swizzle[i] = expression[1].trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping.setLeftVariable(variables[0]);
|
mapping.setLeftVariable(variables[0]);
|
||||||
mapping.setLeftSwizzling(swizzle[0] != null ? swizzle[0] : "");
|
mapping.setLeftSwizzling(swizzle[0] != null ? swizzle[0] : "");
|
||||||
|
|
||||||
|
if (rightExpression != null) {
|
||||||
|
mapping.setRightExpression(rightExpression);
|
||||||
|
} else {
|
||||||
mapping.setRightVariable(variables[1]);
|
mapping.setRightVariable(variables[1]);
|
||||||
mapping.setRightSwizzling(swizzle[1] != null ? swizzle[1] : "");
|
mapping.setRightSwizzling(swizzle[1] != null ? swizzle[1] : "");
|
||||||
|
}
|
||||||
|
|
||||||
if (cond.length > 1) {
|
if (cond.length > 1) {
|
||||||
extractCondition(cond[1], statement);
|
extractCondition(cond[1], statement);
|
||||||
@ -401,11 +428,11 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* search a variable in the given list and updates its type and namespace
|
* Searches a variable in the given list and updates its type and namespace.
|
||||||
*
|
*
|
||||||
* @param var the variable to update
|
* @param var the variable to update.
|
||||||
* @param list the variables list
|
* @param list the variables list.
|
||||||
* @return true if the variable has been found and updated
|
* @return true if the variable has been found and updated.
|
||||||
*/
|
*/
|
||||||
protected boolean updateVariableFromList(ShaderNodeVariable var, List<ShaderNodeVariable> list) {
|
protected boolean updateVariableFromList(ShaderNodeVariable var, List<ShaderNodeVariable> list) {
|
||||||
for (ShaderNodeVariable shaderNodeVariable : list) {
|
for (ShaderNodeVariable shaderNodeVariable : list) {
|
||||||
@ -420,10 +447,10 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates the type of the right variable of a mapping from the type of the
|
* Updates the type of the right variable of a mapping from the type of the
|
||||||
* left variable
|
* left variable.
|
||||||
*
|
*
|
||||||
* @param mapping the mapping to consider
|
* @param mapping the mapping to consider.
|
||||||
*/
|
*/
|
||||||
protected void updateRightTypeFromLeftType(VariableMapping mapping) {
|
protected void updateRightTypeFromLeftType(VariableMapping mapping) {
|
||||||
String type = mapping.getLeftVariable().getType();
|
String type = mapping.getLeftVariable().getType();
|
||||||
@ -439,24 +466,25 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if once a mapping expression is split by "=" the resulting array
|
* Checks if once a mapping expression is split by "=" the resulting array
|
||||||
* have 2 elements
|
* have 2 elements.
|
||||||
*
|
*
|
||||||
* @param vars the array
|
* @param vars the array.
|
||||||
* @param statement the statement
|
* @param statement the statement.
|
||||||
* @throws IOException
|
* @throws MatParseException if the array isn't correct.
|
||||||
*/
|
*/
|
||||||
protected void checkMappingFormat(String[] vars, Statement statement) throws IOException {
|
protected void checkMappingFormat(String[] vars, Statement statement) throws MatParseException {
|
||||||
if (vars.length != 2) {
|
if (vars.length != 2) {
|
||||||
throw new MatParseException("Not a valid expression should be '<varName>[.<swizzling>] = <nameSpace>.<varName>[.<swizzling>][:Condition]'", statement);
|
throw new MatParseException("Not a valid expression should be '<varName>[.<swizzling>] = " +
|
||||||
|
"<nameSpace>.<varName>[.<swizzling>][:Condition]'", statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* finds a MatParam in the materialDef from the given name
|
* Finds a {@link MatParam} in the {@link MaterialDef} from the given name.
|
||||||
*
|
*
|
||||||
* @param varName the matparam name
|
* @param varName the material param name.
|
||||||
* @return the MatParam
|
* @return the found {@link MatParam} or null.
|
||||||
*/
|
*/
|
||||||
protected MatParam findMatParam(String varName) {
|
protected MatParam findMatParam(String varName) {
|
||||||
for (MatParam matParam : materialDef.getMaterialParams()) {
|
for (MatParam matParam : materialDef.getMaterialParams()) {
|
||||||
@ -493,6 +521,7 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
* @return true if the param was added to the map
|
* @return true if the param was added to the map
|
||||||
*/
|
*/
|
||||||
protected boolean updateRightFromUniforms(UniformBinding param, VariableMapping mapping, Map<String, DeclaredVariable> map) {
|
protected boolean updateRightFromUniforms(UniformBinding param, VariableMapping mapping, Map<String, DeclaredVariable> map) {
|
||||||
|
|
||||||
ShaderNodeVariable right = mapping.getRightVariable();
|
ShaderNodeVariable right = mapping.getRightVariable();
|
||||||
String name = param.toString();
|
String name = param.toString();
|
||||||
|
|
||||||
@ -513,60 +542,74 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates the right variable of the given mapping from a MatParam (a
|
* Updates the right variable of the given mapping from a {@link MatParam} (a
|
||||||
* WorldParam) it checks if the uniform hasn't already been loaded, add it
|
* WorldParam) it checks if the uniform hasn't already been loaded, add it
|
||||||
* to the maps if not.
|
* to the maps if not.
|
||||||
*
|
*
|
||||||
* @param param the MatParam
|
* @param param the mat param.
|
||||||
* @param mapping the mapping
|
* @param mapping the mapping.
|
||||||
* @param map the map of uniforms to search into
|
* @param map the map of uniforms to search into.
|
||||||
* @return true if the param was added to the map
|
* @return true if the param was added to the map.
|
||||||
*/
|
*/
|
||||||
public boolean updateRightFromUniforms(MatParam param, VariableMapping mapping, Map<String, DeclaredVariable> map, Statement statement) throws MatParseException {
|
public boolean updateRightFromUniforms(MatParam param, VariableMapping mapping, Map<String, DeclaredVariable> map,
|
||||||
ShaderNodeVariable right = mapping.getRightVariable();
|
Statement statement) throws MatParseException {
|
||||||
|
|
||||||
|
final ShaderNodeVariable left = mapping.getLeftVariable();
|
||||||
|
final ShaderNodeVariable right = mapping.getRightVariable();
|
||||||
|
|
||||||
DeclaredVariable dv = map.get(param.getName());
|
DeclaredVariable dv = map.get(param.getName());
|
||||||
|
|
||||||
if (dv == null) {
|
if (dv == null) {
|
||||||
|
|
||||||
right.setType(param.getVarType().getGlslType());
|
right.setType(param.getVarType().getGlslType());
|
||||||
right.setName(param.getName());
|
right.setName(param.getName());
|
||||||
right.setPrefix("m_");
|
right.setPrefix("m_");
|
||||||
if(mapping.getLeftVariable().getMultiplicity() != null){
|
|
||||||
if(!param.getVarType().name().endsWith("Array")){
|
if (left.getMultiplicity() != null) {
|
||||||
|
|
||||||
|
if (!param.getVarType().name().endsWith("Array")) {
|
||||||
throw new MatParseException(param.getName() + " is not of Array type", statement);
|
throw new MatParseException(param.getName() + " is not of Array type", statement);
|
||||||
}
|
}
|
||||||
String multiplicity = mapping.getLeftVariable().getMultiplicity();
|
|
||||||
|
String multiplicity = left.getMultiplicity();
|
||||||
try {
|
try {
|
||||||
Integer.parseInt(multiplicity);
|
Integer.parseInt(multiplicity);
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (final NumberFormatException nfe) {
|
||||||
//multiplicity is not an int attempting to find for a material parameter.
|
// multiplicity is not an int attempting to find for a material parameter.
|
||||||
MatParam mp = findMatParam(multiplicity);
|
MatParam mp = findMatParam(multiplicity);
|
||||||
if (mp != null) {
|
if (mp != null) {
|
||||||
//It's tied to a material param, let's create a define and use this as the multiplicity
|
// It's tied to a material param, let's create a define and use this as the multiplicity
|
||||||
addDefine(multiplicity, VarType.Int);
|
addDefine(multiplicity, VarType.Int);
|
||||||
multiplicity = multiplicity.toUpperCase();
|
multiplicity = multiplicity.toUpperCase();
|
||||||
mapping.getLeftVariable().setMultiplicity(multiplicity);
|
left.setMultiplicity(multiplicity);
|
||||||
//only declare the variable if the define is defined.
|
// only declare the variable if the define is defined.
|
||||||
mapping.getLeftVariable().setCondition(mergeConditions(mapping.getLeftVariable().getCondition(), "defined(" + multiplicity + ")", "||"));
|
left.setCondition(mergeConditions(left.getCondition(), "defined(" + multiplicity + ")", "||"));
|
||||||
} else {
|
} else {
|
||||||
throw new MatParseException("Wrong multiplicity for variable" + mapping.getLeftVariable().getName() + ". " + multiplicity + " should be an int or a declared material parameter.", statement);
|
throw new MatParseException("Wrong multiplicity for variable" + left.getName() + ". " +
|
||||||
|
multiplicity + " should be an int or a declared material parameter.", statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//the right variable must have the same multiplicity and the same condition.
|
|
||||||
|
// the right variable must have the same multiplicity and the same condition.
|
||||||
right.setMultiplicity(multiplicity);
|
right.setMultiplicity(multiplicity);
|
||||||
right.setCondition(mapping.getLeftVariable().getCondition());
|
right.setCondition(left.getCondition());
|
||||||
}
|
}
|
||||||
|
|
||||||
dv = new DeclaredVariable(right);
|
dv = new DeclaredVariable(right);
|
||||||
map.put(right.getName(), dv);
|
map.put(right.getName(), dv);
|
||||||
dv.addNode(shaderNode);
|
dv.addNode(shaderNode);
|
||||||
mapping.setRightVariable(right);
|
mapping.setRightVariable(right);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
dv.addNode(shaderNode);
|
dv.addNode(shaderNode);
|
||||||
mapping.setRightVariable(dv.var);
|
mapping.setRightVariable(dv.var);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updates a variable from the Attribute list
|
* Updates a variable from the attribute list.
|
||||||
*
|
*
|
||||||
* @param right the variable
|
* @param right the variable
|
||||||
* @param mapping the mapping
|
* @param mapping the mapping
|
||||||
@ -595,11 +638,11 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find a variable with the given name from the list of variable
|
* Finds a variable with the given name from the list of variable.
|
||||||
*
|
*
|
||||||
* @param vars a list of shaderNodeVariables
|
* @param vars the list of shader node variables.
|
||||||
* @param rightVarName the variable name to search for
|
* @param rightVarName the variable name to search for.
|
||||||
* @return the found variable or null is not found
|
* @return the found variable or null is not found.
|
||||||
*/
|
*/
|
||||||
public ShaderNodeVariable findNodeOutput(List<ShaderNodeVariable> vars, String rightVarName) {
|
public ShaderNodeVariable findNodeOutput(List<ShaderNodeVariable> vars, String rightVarName) {
|
||||||
ShaderNodeVariable var = null;
|
ShaderNodeVariable var = null;
|
||||||
@ -612,81 +655,95 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* extract and check a condition expression
|
* Extracts and checks a condition expression.
|
||||||
*
|
*
|
||||||
* @param cond the condition expression
|
* @param condition the condition expression.
|
||||||
* @param statement the statement being read
|
* @param statement the statement being read.
|
||||||
* @throws IOException
|
* @throws MatParseException if the condition isn't valid.
|
||||||
*/
|
*/
|
||||||
public void extractCondition(String cond, Statement statement) throws IOException {
|
public void extractCondition(String condition, Statement statement) throws MatParseException {
|
||||||
List<String> defines = conditionParser.extractDefines(cond);
|
List<String> defines = conditionParser.extractDefines(condition);
|
||||||
for (String string : defines) {
|
for (String string : defines) {
|
||||||
MatParam param = findMatParam(string);
|
MatParam param = findMatParam(string);
|
||||||
if (param != null) {
|
if (param != null) {
|
||||||
addDefine(param.getName(), param.getVarType());
|
addDefine(param.getName(), param.getVarType());
|
||||||
} else {
|
} else {
|
||||||
throw new MatParseException("Invalid condition, condition must match a Material Parameter named " + cond, statement);
|
throw new MatParseException("Invalid condition, condition must match a Material Parameter named " + condition, statement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reads an input mapping
|
* Reads an input mapping.
|
||||||
*
|
*
|
||||||
* @param statement1 the statement being read
|
* @param statement the statement being read.
|
||||||
* @return the mapping
|
* @return the variable mapping.
|
||||||
* @throws IOException
|
* @throws MatParseException if we have a problem with parsing input mapping statement.
|
||||||
*/
|
*/
|
||||||
public VariableMapping readInputMapping(Statement statement1) throws IOException {
|
public VariableMapping readInputMapping(Statement statement) throws MatParseException {
|
||||||
VariableMapping mapping = null;
|
|
||||||
|
VariableMapping mapping;
|
||||||
try {
|
try {
|
||||||
mapping = parseMapping(statement1, new boolean[]{false, true});
|
mapping = parseMapping(statement, IM_HAS_NAME_SPACE);
|
||||||
} catch (Exception e) {
|
} catch (final Exception e) {
|
||||||
throw new MatParseException("Unexpected mapping format", statement1, e);
|
throw new MatParseException("Unexpected mapping format", statement, e);
|
||||||
}
|
|
||||||
ShaderNodeVariable left = mapping.getLeftVariable();
|
|
||||||
ShaderNodeVariable right = mapping.getRightVariable();
|
|
||||||
if (!updateVariableFromList(left, shaderNode.getDefinition().getInputs())) {
|
|
||||||
throw new MatParseException(left.getName() + " is not an input variable of " + shaderNode.getDefinition().getName(), statement1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left.getType().startsWith("sampler") && !right.getNameSpace().equals("MatParam")) {
|
final ShaderNodeDefinition definition = shaderNode.getDefinition();
|
||||||
throw new MatParseException("Samplers can only be assigned to MatParams", statement1);
|
final ShaderNodeVariable left = mapping.getLeftVariable();
|
||||||
|
final ShaderNodeVariable right = mapping.getRightVariable();
|
||||||
|
final String expression = mapping.getRightExpression();
|
||||||
|
|
||||||
|
if (!updateVariableFromList(left, definition.getInputs())) {
|
||||||
|
throw new MatParseException(left.getName() + " is not an input variable of " + definition.getName(), statement);
|
||||||
|
} else if (left.getType().startsWith("sampler") && (right == null || !right.getNameSpace().equals(ShaderGenerator.NAME_SPACE_MAT_PARAM))) {
|
||||||
|
throw new MatParseException("Samplers can only be assigned to MatParams", statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right.getNameSpace().equals("Global")) {
|
if (right == null && expression == null) {
|
||||||
right.setType("vec4");//Globals are all vec4 for now (maybe forever...)
|
throw new MatParseException("The mapping doesn't have a right variable or a right expression.", statement);
|
||||||
storeGlobal(right, statement1);
|
}
|
||||||
|
|
||||||
} else if (right.getNameSpace().equals("Attr")) {
|
if (right == null) {
|
||||||
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Fragment) {
|
return mapping;
|
||||||
throw new MatParseException("Cannot have an attribute as input in a fragment shader" + right.getName(), statement1);
|
}
|
||||||
|
|
||||||
|
if (right.getNameSpace().equals(ShaderGenerator.NAME_SPACE_GLOBAL)) {
|
||||||
|
right.setType("vec4"); // Globals are all vec4 for now (maybe forever...)
|
||||||
|
storeGlobal(right, statement);
|
||||||
|
} else if (right.getNameSpace().equals(ShaderGenerator.NAME_SPACE_VERTEX_ATTRIBUTE)) {
|
||||||
|
if (definition.getType() == ShaderType.Fragment) {
|
||||||
|
throw new MatParseException("Cannot have an attribute as input in a fragment shader" + right.getName(), statement);
|
||||||
}
|
}
|
||||||
updateVarFromAttributes(mapping.getRightVariable(), mapping);
|
updateVarFromAttributes(mapping.getRightVariable(), mapping);
|
||||||
storeAttribute(mapping.getRightVariable());
|
storeAttribute(mapping.getRightVariable());
|
||||||
} else if (right.getNameSpace().equals("MatParam")) {
|
} else if (right.getNameSpace().equals(ShaderGenerator.NAME_SPACE_MAT_PARAM)) {
|
||||||
|
|
||||||
MatParam param = findMatParam(right.getName());
|
MatParam param = findMatParam(right.getName());
|
||||||
if (param == null) {
|
if (param == null) {
|
||||||
throw new MatParseException("Could not find a Material Parameter named " + right.getName(), statement1);
|
throw new MatParseException("Could not find a Material Parameter named " + right.getName(), statement);
|
||||||
}
|
}
|
||||||
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) {
|
|
||||||
if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms, statement1)) {
|
if (definition.getType() == ShaderType.Vertex) {
|
||||||
updateMaterialTextureType(statement1, mapping, left, param);
|
if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms, statement)) {
|
||||||
|
updateMaterialTextureType(statement, mapping, left, param);
|
||||||
storeVertexUniform(mapping.getRightVariable());
|
storeVertexUniform(mapping.getRightVariable());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms, statement1)) {
|
if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms, statement)) {
|
||||||
updateMaterialTextureType(statement1, mapping, left, param);
|
updateMaterialTextureType(statement, mapping, left, param);
|
||||||
storeFragmentUniform(mapping.getRightVariable());
|
storeFragmentUniform(mapping.getRightVariable());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (right.getNameSpace().equals("WorldParam")) {
|
} else if (right.getNameSpace().equals(ShaderGenerator.NAME_SPACE_WORLD_PARAM)) {
|
||||||
|
|
||||||
UniformBinding worldParam = findWorldParam(right.getName());
|
UniformBinding worldParam = findWorldParam(right.getName());
|
||||||
if (worldParam == null) {
|
if (worldParam == null) {
|
||||||
throw new MatParseException("Could not find a World Parameter named " + right.getName(), statement1);
|
throw new MatParseException("Could not find a World Parameter named " + right.getName(), statement);
|
||||||
}
|
}
|
||||||
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) {
|
|
||||||
|
if (definition.getType() == ShaderType.Vertex) {
|
||||||
if (updateRightFromUniforms(worldParam, mapping, vertexDeclaredUniforms)) {
|
if (updateRightFromUniforms(worldParam, mapping, vertexDeclaredUniforms)) {
|
||||||
storeVertexUniform(mapping.getRightVariable());
|
storeVertexUniform(mapping.getRightVariable());
|
||||||
}
|
}
|
||||||
@ -697,35 +754,43 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
ShaderNode node = nodes.get(right.getNameSpace());
|
ShaderNode node = nodes.get(right.getNameSpace());
|
||||||
|
|
||||||
if (node == null) {
|
if (node == null) {
|
||||||
throw new MatParseException("Undeclared node" + right.getNameSpace() + ". Make sure this node is declared before the current node", statement1);
|
throw new MatParseException("Undeclared node" + right.getNameSpace() +
|
||||||
|
". Make sure this node is declared before the current node", statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShaderNodeVariable var = findNodeOutput(node.getDefinition().getOutputs(), right.getName());
|
ShaderNodeVariable var = findNodeOutput(node.getDefinition().getOutputs(), right.getName());
|
||||||
|
|
||||||
if (var == null) {
|
if (var == null) {
|
||||||
throw new MatParseException("Cannot find output variable" + right.getName() + " form ShaderNode " + node.getName(), statement1);
|
throw new MatParseException("Cannot find output variable" + right.getName() +
|
||||||
|
" form ShaderNode " + node.getName(), statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
right.setNameSpace(node.getName());
|
right.setNameSpace(node.getName());
|
||||||
right.setType(var.getType());
|
right.setType(var.getType());
|
||||||
right.setMultiplicity(var.getMultiplicity());
|
right.setMultiplicity(var.getMultiplicity());
|
||||||
mapping.setRightVariable(right);
|
|
||||||
storeVaryings(node, mapping.getRightVariable());
|
|
||||||
|
|
||||||
|
mapping.setRightVariable(right);
|
||||||
|
|
||||||
|
storeVaryings(node, mapping.getRightVariable());
|
||||||
}
|
}
|
||||||
|
|
||||||
checkTypes(mapping, statement1);
|
checkTypes(mapping, statement);
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updated the material texture type of the variable mapping.
|
* Updates the material texture type of the variable mapping.
|
||||||
*
|
*
|
||||||
* @param statement the statement.
|
* @param statement the statement.
|
||||||
* @param mapping the variable mapping.
|
* @param mapping the variable mapping.
|
||||||
* @param left the left variable.
|
* @param left the left variable.
|
||||||
* @param param the material parameter.
|
* @param param the material parameter.
|
||||||
* @throws MatParseException
|
* @throws MatParseException if the texture type isn't valid.
|
||||||
*/
|
*/
|
||||||
private void updateMaterialTextureType(final Statement statement, final VariableMapping mapping,
|
private void updateMaterialTextureType(final Statement statement, final VariableMapping mapping,
|
||||||
final ShaderNodeVariable left, final MatParam param) throws MatParseException {
|
final ShaderNodeVariable left, final MatParam param) throws MatParseException {
|
||||||
@ -745,39 +810,41 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reads an output mapping
|
* Reads an output mapping.
|
||||||
*
|
*
|
||||||
* @param statement1 the statement being read
|
* @param statement the statement being read.
|
||||||
* @return the mapping
|
* @return the mapping
|
||||||
* @throws IOException
|
* @throws MatParseException if we have a problem with parsing the statement.
|
||||||
*/
|
*/
|
||||||
public VariableMapping readOutputMapping(Statement statement1) throws IOException {
|
public VariableMapping readOutputMapping(Statement statement) throws MatParseException {
|
||||||
VariableMapping mapping = null;
|
|
||||||
try {
|
|
||||||
mapping = parseMapping(statement1, new boolean[]{true, false});
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new MatParseException("Unexpected mapping format", statement1, e);
|
|
||||||
}
|
|
||||||
ShaderNodeVariable left = mapping.getLeftVariable();
|
|
||||||
ShaderNodeVariable right = mapping.getRightVariable();
|
|
||||||
|
|
||||||
|
VariableMapping mapping;
|
||||||
|
try {
|
||||||
|
mapping = parseMapping(statement, OM_HAS_NAME_SPACE);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new MatParseException("Unexpected mapping format", statement, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ShaderNodeDefinition definition = shaderNode.getDefinition();
|
||||||
|
final ShaderNodeVariable left = mapping.getLeftVariable();
|
||||||
|
final ShaderNodeVariable right = mapping.getRightVariable();
|
||||||
|
|
||||||
if (left.getType().startsWith("sampler") || right.getType().startsWith("sampler")) {
|
if (left.getType().startsWith("sampler") || right.getType().startsWith("sampler")) {
|
||||||
throw new MatParseException("Samplers can only be inputs", statement1);
|
throw new MatParseException("Samplers can only be inputs", statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left.getNameSpace().equals("Global")) {
|
if (left.getNameSpace().equals(ShaderGenerator.NAME_SPACE_GLOBAL)) {
|
||||||
left.setType("vec4");//Globals are all vec4 for now (maybe forever...)
|
left.setType("vec4"); // Globals are all vec4 for now (maybe forever...)
|
||||||
storeGlobal(left, statement1);
|
storeGlobal(left, statement);
|
||||||
} else {
|
} else {
|
||||||
throw new MatParseException("Only Global nameSpace is allowed for outputMapping, got" + left.getNameSpace(), statement1);
|
throw new MatParseException("Only Global nameSpace is allowed for outputMapping, got" + left.getNameSpace(), statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!updateVariableFromList(right, shaderNode.getDefinition().getOutputs())) {
|
if (!updateVariableFromList(right, definition.getOutputs())) {
|
||||||
throw new MatParseException(right.getName() + " is not an output variable of " + shaderNode.getDefinition().getName(), statement1);
|
throw new MatParseException(right.getName() + " is not an output variable of " + definition.getName(), statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkTypes(mapping, statement1);
|
checkTypes(mapping, statement);
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
@ -805,7 +872,6 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
shaderNode = new ShaderNode();
|
shaderNode = new ShaderNode();
|
||||||
shaderNode.setName(name);
|
shaderNode.setName(name);
|
||||||
techniqueDef.getShaderGenerationInfo().getUnusedNodes().add(name);
|
techniqueDef.getShaderGenerationInfo().getUnusedNodes().add(name);
|
||||||
|
|
||||||
readShaderNode(statement.getContents());
|
readShaderNode(statement.getContents());
|
||||||
nodes.put(name, shaderNode);
|
nodes.put(name, shaderNode);
|
||||||
techniqueDef.getShaderNodes().add(shaderNode);
|
techniqueDef.getShaderNodes().add(shaderNode);
|
||||||
@ -838,45 +904,54 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* stores a global output
|
* Stores a global output.
|
||||||
*
|
*
|
||||||
* @param var the variable to store
|
* @param var the variable to store.
|
||||||
* @param statement1 the statement being read
|
* @param varStatement the statement being read.
|
||||||
* @throws IOException
|
* @throws MatParseException if we have duplicates of a global vertex output variable.
|
||||||
*/
|
*/
|
||||||
public void storeGlobal(ShaderNodeVariable var, Statement statement1) throws IOException {
|
public void storeGlobal(ShaderNodeVariable var, Statement varStatement) throws MatParseException {
|
||||||
var.setShaderOutput(true);
|
var.setShaderOutput(true);
|
||||||
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) {
|
|
||||||
ShaderNodeVariable global = techniqueDef.getShaderGenerationInfo().getVertexGlobal();
|
final ShaderGenerationInfo generationInfo = techniqueDef.getShaderGenerationInfo();
|
||||||
|
final ShaderNodeDefinition definition = shaderNode.getDefinition();
|
||||||
|
|
||||||
|
if (definition.getType() == ShaderType.Vertex) {
|
||||||
|
|
||||||
|
ShaderNodeVariable global = generationInfo.getVertexGlobal();
|
||||||
|
|
||||||
if (global != null) {
|
if (global != null) {
|
||||||
|
|
||||||
if (!global.getName().equals(var.getName())) {
|
if (!global.getName().equals(var.getName())) {
|
||||||
throw new MatParseException("A global output is already defined for the vertex shader: " + global.getName() + ". vertex shader can only have one global output", statement1);
|
throw new MatParseException("A global output is already defined for the vertex shader: " +
|
||||||
|
global.getName() + ". vertex shader can only have one global output", varStatement);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
techniqueDef.getShaderGenerationInfo().setVertexGlobal(var);
|
generationInfo.setVertexGlobal(var);
|
||||||
}
|
}
|
||||||
} else if (shaderNode.getDefinition().getType() == Shader.ShaderType.Fragment) {
|
|
||||||
storeVariable(var, techniqueDef.getShaderGenerationInfo().getFragmentGlobals());
|
} else if (definition.getType() == ShaderType.Fragment) {
|
||||||
|
storeVariable(var, generationInfo.getFragmentGlobals());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* store an attribute
|
* Stores an attribute.
|
||||||
*
|
*
|
||||||
* @param var the variable to store
|
* @param var the variable to store.
|
||||||
*/
|
*/
|
||||||
public void storeAttribute(ShaderNodeVariable var) {
|
public void storeAttribute(ShaderNodeVariable var) {
|
||||||
storeVariable(var, techniqueDef.getShaderGenerationInfo().getAttributes());
|
storeVariable(var, techniqueDef.getShaderGenerationInfo().getAttributes());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* store a vertex uniform
|
* Stores a vertex uniform.
|
||||||
*
|
*
|
||||||
* @param var the variable to store
|
* @param var the variable to store.
|
||||||
*/
|
*/
|
||||||
public void storeVertexUniform(ShaderNodeVariable var) {
|
public void storeVertexUniform(ShaderNodeVariable var) {
|
||||||
storeVariable(var, techniqueDef.getShaderGenerationInfo().getVertexUniforms());
|
storeVariable(var, techniqueDef.getShaderGenerationInfo().getVertexUniforms());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -886,7 +961,6 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
*/
|
*/
|
||||||
public void storeFragmentUniform(ShaderNodeVariable var) {
|
public void storeFragmentUniform(ShaderNodeVariable var) {
|
||||||
storeVariable(var, techniqueDef.getShaderGenerationInfo().getFragmentUniforms());
|
storeVariable(var, techniqueDef.getShaderGenerationInfo().getFragmentUniforms());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -959,8 +1033,8 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
final ShaderNodeDefinition nodeDefinition = node.getDefinition();
|
final ShaderNodeDefinition nodeDefinition = node.getDefinition();
|
||||||
final ShaderNodeDefinition currentDefinition = shaderNode.getDefinition();
|
final ShaderNodeDefinition currentDefinition = shaderNode.getDefinition();
|
||||||
|
|
||||||
if (nodeDefinition.getType() != Shader.ShaderType.Vertex ||
|
if (nodeDefinition.getType() != ShaderType.Vertex ||
|
||||||
currentDefinition.getType() != Shader.ShaderType.Fragment) {
|
currentDefinition.getType() != ShaderType.Fragment) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,11 +1082,11 @@ public class ShaderNodeLoaderDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* search a variable in a list from its name and merge the conditions of the
|
* Searches a variable in a list from its name and merges the conditions of the
|
||||||
* variables
|
* variables.
|
||||||
*
|
*
|
||||||
* @param variable the variable
|
* @param variable the variable.
|
||||||
* @param varList the variable list
|
* @param varList the variable list.
|
||||||
*/
|
*/
|
||||||
public void storeVariable(ShaderNodeVariable variable, List<ShaderNodeVariable> varList) {
|
public void storeVariable(ShaderNodeVariable variable, List<ShaderNodeVariable> varList) {
|
||||||
for (ShaderNodeVariable var : varList) {
|
for (ShaderNodeVariable var : varList) {
|
||||||
|
@ -5,14 +5,17 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.material.plugin.export.materialdef;
|
package com.jme3.material.plugin.export.materialdef;
|
||||||
|
|
||||||
import com.jme3.material.*;
|
import com.jme3.material.MatParam;
|
||||||
|
import com.jme3.material.RenderState;
|
||||||
|
import com.jme3.material.TechniqueDef;
|
||||||
import com.jme3.shader.*;
|
import com.jme3.shader.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.regex.*;
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
import static java.util.regex.Pattern.compile;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author nehon
|
* @author nehon
|
||||||
@ -168,47 +171,79 @@ public class J3mdTechniqueDefWriter {
|
|||||||
out.write(shaderNode.getDefinition().getPath());
|
out.write(shaderNode.getDefinition().getPath());
|
||||||
out.write("\n");
|
out.write("\n");
|
||||||
|
|
||||||
|
final List<VariableMapping> inputMapping = shaderNode.getInputMapping();
|
||||||
|
final List<VariableMapping> outputMapping = shaderNode.getOutputMapping();
|
||||||
|
|
||||||
|
if (!inputMapping.isEmpty()) {
|
||||||
out.write(" InputMappings {\n");
|
out.write(" InputMappings {\n");
|
||||||
for (VariableMapping mapping : shaderNode.getInputMapping()) {
|
for (VariableMapping mapping : inputMapping) {
|
||||||
writeVariableMapping(out, shaderNode, mapping, matParams);
|
writeVariableMapping(out, shaderNode, mapping, matParams);
|
||||||
}
|
}
|
||||||
out.write(" }\n");
|
out.write(" }\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!outputMapping.isEmpty()) {
|
||||||
out.write(" OutputMappings {\n");
|
out.write(" OutputMappings {\n");
|
||||||
for (VariableMapping mapping : shaderNode.getOutputMapping()) {
|
for (VariableMapping mapping : outputMapping) {
|
||||||
writeVariableMapping(out, shaderNode, mapping, matParams);
|
writeVariableMapping(out, shaderNode, mapping, matParams);
|
||||||
}
|
}
|
||||||
out.write(" }\n");
|
out.write(" }\n");
|
||||||
|
}
|
||||||
|
|
||||||
out.write(" }\n");
|
out.write(" }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeVariableMapping(OutputStreamWriter out, ShaderNode shaderNode, VariableMapping mapping, Collection<MatParam> matParams) throws IOException {
|
private void writeVariableMapping(final OutputStreamWriter out, final ShaderNode shaderNode,
|
||||||
|
final VariableMapping mapping, final Collection<MatParam> matParams)
|
||||||
|
throws IOException {
|
||||||
|
|
||||||
|
final ShaderNodeVariable leftVar = mapping.getLeftVariable();
|
||||||
|
final ShaderNodeVariable rightVar = mapping.getRightVariable();
|
||||||
|
final String rightExpression = mapping.getRightExpression();
|
||||||
|
|
||||||
out.write(" ");
|
out.write(" ");
|
||||||
if(!mapping.getLeftVariable().getNameSpace().equals(shaderNode.getName())) {
|
|
||||||
out.write(mapping.getLeftVariable().getNameSpace());
|
if (!leftVar.getNameSpace().equals(shaderNode.getName())) {
|
||||||
|
out.write(leftVar.getNameSpace());
|
||||||
out.write(".");
|
out.write(".");
|
||||||
}
|
}
|
||||||
out.write(mapping.getLeftVariable().getName());
|
|
||||||
if(!mapping.getLeftSwizzling().equals("")){
|
out.write(leftVar.getName());
|
||||||
|
|
||||||
|
if (!mapping.getLeftSwizzling().equals("")) {
|
||||||
out.write(".");
|
out.write(".");
|
||||||
out.write(mapping.getLeftSwizzling());
|
out.write(mapping.getLeftSwizzling());
|
||||||
}
|
}
|
||||||
|
|
||||||
out.write(" = ");
|
out.write(" = ");
|
||||||
if(!mapping.getRightVariable().getNameSpace().equals(shaderNode.getName())) {
|
|
||||||
out.write(mapping.getRightVariable().getNameSpace());
|
if (rightVar != null) {
|
||||||
|
|
||||||
|
if (!rightVar.getNameSpace().equals(shaderNode.getName())) {
|
||||||
|
out.write(rightVar.getNameSpace());
|
||||||
out.write(".");
|
out.write(".");
|
||||||
}
|
}
|
||||||
out.write(mapping.getRightVariable().getName().replaceFirst("g_","").replaceFirst("m_",""));
|
|
||||||
if(!mapping.getRightSwizzling().equals("")){
|
String rightVarName = rightVar.getName();
|
||||||
|
if (rightVarName.startsWith("g_") || rightVarName.startsWith("m_")) {
|
||||||
|
rightVarName = rightVarName.substring(2, rightVarName.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(rightVarName);
|
||||||
|
|
||||||
|
if (!mapping.getRightSwizzling().equals("")) {
|
||||||
out.write(".");
|
out.write(".");
|
||||||
out.write(mapping.getRightSwizzling());
|
out.write(mapping.getRightSwizzling());
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
out.write("%%");
|
||||||
|
out.write(rightExpression);
|
||||||
|
out.write("%%");
|
||||||
|
}
|
||||||
|
|
||||||
if (mapping.getCondition() != null){
|
if (mapping.getCondition() != null) {
|
||||||
out.write(" : ");
|
out.write(" : ");
|
||||||
out.write(formatCondition(mapping.getCondition(),matParams));
|
out.write(formatCondition(mapping.getCondition(), matParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
out.write("\n");
|
out.write("\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user