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. 72
      engine/src/core-plugins/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java
  2. 7
      engine/src/core/com/jme3/shader/Glsl100ShaderGenerator.java
  3. 41
      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
*/
protected ShaderNodeVariable readVariable(Statement statement) throws IOException {
String[] splitVar = statement.getLine().trim().split("\\s");
if (varNames.contains(splitVar[1] + ";")) {
throw new MatParseException("Duplicate variable name " + splitVar[1], statement);
String line = statement.getLine().trim().replaceAll("\\s*\\[", "[");
String[] splitVar = line.split("\\s");
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();
}
varNames += splitVar[1] + ";";
return new ShaderNodeVariable(splitVar[0], splitVar[1]);
if (varNames.contains(varName + ";")) {
throw new MatParseException("Duplicate variable name " + varName, statement);
}
varNames += varName + ";";
return new ShaderNodeVariable(varType, "", varName, multiplicity);
}
/**
@ -437,6 +448,7 @@ public class ShaderNodeLoaderDelegate {
for (ShaderNodeVariable shaderNodeVariable : list) {
if (shaderNodeVariable.getName().equals(var.getName())) {
var.setType(shaderNodeVariable.getType());
var.setMultiplicity(shaderNodeVariable.getMultiplicity());
var.setNameSpace(shaderNode.getName());
return true;
}
@ -545,18 +557,37 @@ public class ShaderNodeLoaderDelegate {
* @param map the map of uniforms to search into
* @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();
DeclaredVariable dv = map.get(param.getPrefixedName());
if (dv == null) {
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);
map.put(right.getName(), dv);
dv.addNode(shaderNode);
dv.addNode(shaderNode);
mapping.setRightVariable(right);
return true;
}
}
dv.addNode(shaderNode);
mapping.setRightVariable(dv.var);
return false;
@ -669,12 +700,11 @@ public class ShaderNodeLoaderDelegate {
throw new MatParseException("Could not find a Material Parameter named " + right.getName(), statement1);
}
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) {
if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms)) {
// updateCondition(mapping.getRightVariable(), mapping);
if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms, statement1)) {
storeVertexUniform(mapping.getRightVariable());
}
} else {
if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms)) {
if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms, statement1)) {
if (mapping.getRightVariable().getType().contains("|")) {
String type = fixSamplerType(left.getType(), mapping.getRightVariable().getType());
if (type != null) {
@ -682,8 +712,7 @@ public class ShaderNodeLoaderDelegate {
} else {
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());
}
}
@ -694,13 +723,11 @@ public class ShaderNodeLoaderDelegate {
throw new MatParseException("Could not find a World Parameter named " + right.getName(), statement1);
}
if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) {
if (updateRightFromUniforms(worldParam, mapping, vertexDeclaredUniforms)) {
// updateCondition(mapping.getRightVariable(), mapping);
if (updateRightFromUniforms(worldParam, mapping, vertexDeclaredUniforms)) {
storeVertexUniform(mapping.getRightVariable());
}
} else {
if (updateRightFromUniforms(worldParam, mapping, fragmentDeclaredUniforms)) {
// updateCondition(mapping.getRightVariable(), mapping);
if (updateRightFromUniforms(worldParam, mapping, fragmentDeclaredUniforms)) {
storeFragmentUniform(mapping.getRightVariable());
}
}
@ -716,8 +743,7 @@ public class ShaderNodeLoaderDelegate {
}
right.setNameSpace(node.getName());
right.setType(var.getType());
mapping.setRightVariable(right);
// updateCondition(mapping.getRightVariable(), mapping);
mapping.setRightVariable(right);
storeVaryings(node, mapping.getRightVariable());
}
@ -751,7 +777,6 @@ public class ShaderNodeLoaderDelegate {
if (left.getNameSpace().equals("Global")) {
left.setType("vec4");//Globals are all vec4 for now (maybe forever...)
// updateCondition(left, mapping);
storeGlobal(left, statement1);
} else {
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();
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() {

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

@ -50,6 +50,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
private String nameSpace;
private String condition;
private boolean shaderOutput = false;
private String multiplicity;
/**
* creates a ShaderNodeVariable
@ -61,6 +62,23 @@ public class ShaderNodeVariable implements Savable, Cloneable {
this.name = name;
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
@ -170,6 +188,7 @@ public class ShaderNodeVariable implements Savable, Cloneable {
oc.write(nameSpace, "nameSpace", "");
oc.write(condition, "condition", null);
oc.write(shaderOutput, "shaderOutput", false);
oc.write(multiplicity, "multiplicity", null);
}
@ -184,8 +203,9 @@ public class ShaderNodeVariable implements Savable, Cloneable {
name = ic.readString("name", "");
type = ic.readString("type", "");
nameSpace = ic.readString("nameSpace", "");
condition = ic.readString("condition", null);
condition = ic.readString("condition", null);
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) {
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;
}
}

@ -71,6 +71,33 @@ public class ShaderUtils {
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

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

Loading…
Cancel
Save