ShaderNodes : Array types are now properly supported and array size can be driven by an int constant or an int define

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10571 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 12 years ago
parent 06c4dcd7f7
commit f8faebb79e
  1. 58
      engine/src/core-plugins/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java
  2. 7
      engine/src/core/com/jme3/shader/Glsl100ShaderGenerator.java
  3. 39
      engine/src/core/com/jme3/shader/ShaderNodeVariable.java
  4. 27
      engine/src/core/com/jme3/shader/ShaderUtils.java
  5. 14
      engine/src/core/com/jme3/shader/VarType.java

@ -272,12 +272,23 @@ public class ShaderNodeLoaderDelegate {
* @throws IOException * @throws IOException
*/ */
protected ShaderNodeVariable readVariable(Statement statement) throws IOException { protected ShaderNodeVariable readVariable(Statement statement) throws IOException {
String[] splitVar = statement.getLine().trim().split("\\s"); String line = statement.getLine().trim().replaceAll("\\s*\\[", "[");
if (varNames.contains(splitVar[1] + ";")) { String[] splitVar = line.split("\\s");
throw new MatParseException("Duplicate variable name " + splitVar[1], statement); String varName = splitVar[1];
String varType = splitVar[0];
String multiplicity = null;
if (varName.contains("[")) {
//we have an array
String[] arr = splitVar[1].split("\\[");
varName = arr[0].trim();
multiplicity = arr[1].replaceAll("\\]", "").trim();
}
if (varNames.contains(varName + ";")) {
throw new MatParseException("Duplicate variable name " + varName, statement);
} }
varNames += splitVar[1] + ";"; varNames += varName + ";";
return new ShaderNodeVariable(splitVar[0], splitVar[1]); return new ShaderNodeVariable(varType, "", varName, multiplicity);
} }
/** /**
@ -437,6 +448,7 @@ public class ShaderNodeLoaderDelegate {
for (ShaderNodeVariable shaderNodeVariable : list) { for (ShaderNodeVariable shaderNodeVariable : list) {
if (shaderNodeVariable.getName().equals(var.getName())) { if (shaderNodeVariable.getName().equals(var.getName())) {
var.setType(shaderNodeVariable.getType()); var.setType(shaderNodeVariable.getType());
var.setMultiplicity(shaderNodeVariable.getMultiplicity());
var.setNameSpace(shaderNode.getName()); var.setNameSpace(shaderNode.getName());
return true; return true;
} }
@ -545,12 +557,31 @@ public class ShaderNodeLoaderDelegate {
* @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) { public boolean updateRightFromUniforms(MatParam param, VariableMapping mapping, Map<String, DeclaredVariable> map, Statement statement) throws MatParseException {
ShaderNodeVariable right = mapping.getRightVariable(); ShaderNodeVariable right = mapping.getRightVariable();
DeclaredVariable dv = map.get(param.getPrefixedName()); DeclaredVariable dv = map.get(param.getPrefixedName());
if (dv == null) { if (dv == null) {
right.setType(param.getVarType().getGlslType()); right.setType(param.getVarType().getGlslType());
right.setName(param.getPrefixedName()); right.setName(param.getPrefixedName());
if(mapping.getLeftVariable().getMultiplicity() != null){
if(!param.getVarType().name().endsWith("Array")){
throw new MatParseException(param.getName() + " is not of Array type", statement);
}
String multiplicity = mapping.getLeftVariable().getMultiplicity();
try {
Integer.parseInt(multiplicity);
} catch (NumberFormatException nfe) {
//multiplicity is not an int attempting to find for a material parameter.
MatParam mp = findMatParam(multiplicity);
if (mp != null) {
addDefine(multiplicity);
multiplicity = multiplicity.toUpperCase();
} else {
throw new MatParseException("Wrong multiplicity for variable" + mapping.getLeftVariable().getName() + ". " + multiplicity + " should be an int or a declared material parameter.", statement);
}
}
right.setMultiplicity(multiplicity);
}
dv = new DeclaredVariable(right); dv = new DeclaredVariable(right);
map.put(right.getName(), dv); map.put(right.getName(), dv);
dv.addNode(shaderNode); dv.addNode(shaderNode);
@ -669,12 +700,11 @@ public class ShaderNodeLoaderDelegate {
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(), statement1);
} }
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) { if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) {
if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms)) { if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms, statement1)) {
// updateCondition(mapping.getRightVariable(), mapping);
storeVertexUniform(mapping.getRightVariable()); storeVertexUniform(mapping.getRightVariable());
} }
} else { } else {
if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms)) { if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms, statement1)) {
if (mapping.getRightVariable().getType().contains("|")) { if (mapping.getRightVariable().getType().contains("|")) {
String type = fixSamplerType(left.getType(), mapping.getRightVariable().getType()); String type = fixSamplerType(left.getType(), mapping.getRightVariable().getType());
if (type != null) { if (type != null) {
@ -683,7 +713,6 @@ public class ShaderNodeLoaderDelegate {
throw new MatParseException(param.getVarType().toString() + " can only be matched to one of " + param.getVarType().getGlslType().replaceAll("\\|", ",") + " found " + left.getType(), statement1); throw new MatParseException(param.getVarType().toString() + " can only be matched to one of " + param.getVarType().getGlslType().replaceAll("\\|", ",") + " found " + left.getType(), statement1);
} }
} }
// updateCondition(mapping.getRightVariable(), mapping);
storeFragmentUniform(mapping.getRightVariable()); storeFragmentUniform(mapping.getRightVariable());
} }
} }
@ -695,12 +724,10 @@ public class ShaderNodeLoaderDelegate {
} }
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) { if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) {
if (updateRightFromUniforms(worldParam, mapping, vertexDeclaredUniforms)) { if (updateRightFromUniforms(worldParam, mapping, vertexDeclaredUniforms)) {
// updateCondition(mapping.getRightVariable(), mapping);
storeVertexUniform(mapping.getRightVariable()); storeVertexUniform(mapping.getRightVariable());
} }
} else { } else {
if (updateRightFromUniforms(worldParam, mapping, fragmentDeclaredUniforms)) { if (updateRightFromUniforms(worldParam, mapping, fragmentDeclaredUniforms)) {
// updateCondition(mapping.getRightVariable(), mapping);
storeFragmentUniform(mapping.getRightVariable()); storeFragmentUniform(mapping.getRightVariable());
} }
} }
@ -717,7 +744,6 @@ public class ShaderNodeLoaderDelegate {
right.setNameSpace(node.getName()); right.setNameSpace(node.getName());
right.setType(var.getType()); right.setType(var.getType());
mapping.setRightVariable(right); mapping.setRightVariable(right);
// updateCondition(mapping.getRightVariable(), mapping);
storeVaryings(node, mapping.getRightVariable()); storeVaryings(node, mapping.getRightVariable());
} }
@ -751,7 +777,6 @@ public class ShaderNodeLoaderDelegate {
if (left.getNameSpace().equals("Global")) { if (left.getNameSpace().equals("Global")) {
left.setType("vec4");//Globals are all vec4 for now (maybe forever...) left.setType("vec4");//Globals are all vec4 for now (maybe forever...)
// updateCondition(left, mapping);
storeGlobal(left, statement1); storeGlobal(left, statement1);
} 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(), statement1);
@ -1026,6 +1051,11 @@ public class ShaderNodeLoaderDelegate {
String rs = mapping.getRightSwizzling().length() == 0 ? "" : "." + mapping.getRightSwizzling(); String rs = mapping.getRightSwizzling().length() == 0 ? "" : "." + mapping.getRightSwizzling();
throw new MatParseException("Type mismatch, cannot convert" + mapping.getLeftVariable().getType() + ls + " to " + mapping.getRightVariable().getType() + rs, statement1); throw new MatParseException("Type mismatch, cannot convert" + mapping.getLeftVariable().getType() + ls + " to " + mapping.getRightVariable().getType() + rs, statement1);
} }
if (!ShaderUtils.multiplicityMatch(mapping)) {
String type1 = mapping.getLeftVariable().getType() + "[" + mapping.getLeftVariable().getMultiplicity() + "]";
String type2 = mapping.getRightVariable().getType() + "[" + mapping.getRightVariable().getMultiplicity() + "]";
throw new MatParseException("Type mismatch, cannot convert" + type1 + " to " + type2, statement1);
}
} }
private Map<String, ShaderNodeDefinition> getNodeDefinitions() { private Map<String, ShaderNodeDefinition> getNodeDefinitions() {

@ -49,7 +49,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"; 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";
/** /**
* creates a Glsl100ShaderGenerator * creates a Glsl100ShaderGenerator
@ -333,6 +333,11 @@ public class Glsl100ShaderGenerator extends ShaderGenerator {
source.append("_"); source.append("_");
} }
source.append(var.getName()); source.append(var.getName());
if (var.getMultiplicity() != null) {
source.append("[");
source.append(var.getMultiplicity().toUpperCase());
source.append("]");
}
if (value != null) { if (value != null) {
source.append(" = "); source.append(" = ");
source.append(value); source.append(value);

@ -50,6 +50,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
private String nameSpace; private String nameSpace;
private String condition; private String condition;
private boolean shaderOutput = false; private boolean shaderOutput = false;
private String multiplicity;
/** /**
* creates a ShaderNodeVariable * creates a ShaderNodeVariable
@ -62,6 +63,23 @@ public class ShaderNodeVariable implements Savable, Cloneable {
this.type = type; this.type = type;
} }
/**
* creates a ShaderNodeVariable
*
* @param type the glsl type of the variable
* @param nameSpace the nameSpace (can be the name of the shaderNode or
* Globel,Attr,MatParam,WorldParam)
* @param name the name of the variable
* @param multiplicity the number of element if this variable is an array. Can be an Int of a declared material parameter
*/
public ShaderNodeVariable(String type, String nameSpace, String name, String multiplicity) {
this.name = name;
this.nameSpace = nameSpace;
this.type = type;
this.multiplicity = multiplicity;
}
/** /**
* creates a ShaderNodeVariable * creates a ShaderNodeVariable
* *
@ -170,6 +188,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
oc.write(nameSpace, "nameSpace", ""); oc.write(nameSpace, "nameSpace", "");
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);
} }
@ -186,6 +205,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
nameSpace = ic.readString("nameSpace", ""); nameSpace = ic.readString("nameSpace", "");
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);
} }
/** /**
@ -231,4 +251,23 @@ public class ShaderNodeVariable implements Savable, Cloneable {
public void setShaderOutput(boolean shaderOutput) { public void setShaderOutput(boolean shaderOutput) {
this.shaderOutput = shaderOutput; this.shaderOutput = shaderOutput;
} }
/**
*
* @return the number of elements if this variable is an array
*/
public String getMultiplicity() {
return multiplicity;
}
/**
* sets the number of elements of this variable making it an array
* this value can be a number of can be a define
* @param multiplicity
*/
public void setMultiplicity(String multiplicity) {
this.multiplicity = multiplicity;
}
} }

@ -72,6 +72,33 @@ public class ShaderUtils {
return false; return false;
} }
/**
* Check if a mapping is valid by checking the multiplicity of both of
* the variables if they are arrays
*
* @param mapping the mapping
* @return true if this mapping is valid
*/
public static boolean multiplicityMatch(VariableMapping mapping) {
String leftMult = mapping.getLeftVariable().getMultiplicity();
String rightMult = mapping.getRightVariable().getMultiplicity();
if(leftMult == null){
if(rightMult != null){
return false;
}
}else{
if(rightMult == null){
return false;
}else{
if(!leftMult.equalsIgnoreCase(rightMult)){
return false;
}
}
}
return true;
}
/** /**
* return the cardinality of a type and a swizzle example : vec4 cardinality * return the cardinality of a type and a swizzle example : vec4 cardinality
* is 4 float cardinality is 1 vec4.xyz cardinality is 3. sampler2D * is 4 float cardinality is 1 vec4.xyz cardinality is 3. sampler2D

@ -38,19 +38,19 @@ public enum VarType {
Vector3("vec3"), Vector3("vec3"),
Vector4("vec4"), Vector4("vec4"),
IntArray(true,false,"int[]"), IntArray(true,false,"int"),
FloatArray(true,false,"float[]"), FloatArray(true,false,"float"),
Vector2Array(true,false,"vec2[]"), Vector2Array(true,false,"vec2"),
Vector3Array(true,false,"vec3[]"), Vector3Array(true,false,"vec3"),
Vector4Array(true,false,"vec4[]"), Vector4Array(true,false,"vec4"),
Boolean("bool"), Boolean("bool"),
Matrix3(true,false,"mat3"), Matrix3(true,false,"mat3"),
Matrix4(true,false,"mat4"), Matrix4(true,false,"mat4"),
Matrix3Array(true,false,"mat3[]"), Matrix3Array(true,false,"mat3"),
Matrix4Array(true,false,"mat4[]"), Matrix4Array(true,false,"mat4"),
TextureBuffer(false,true,"sampler1D|sampler1DShadow"), TextureBuffer(false,true,"sampler1D|sampler1DShadow"),
Texture2D(false,true,"sampler2D|sampler2DShadow"), Texture2D(false,true,"sampler2D|sampler2DShadow"),

Loading…
Cancel
Save