Przeglądaj źródła

extended some things from shader node system.

javasabr 7 lat temu
rodzic
commit
9578b0410e

+ 7 - 14
jme3-core/src/main/java/com/jme3/material/TechniqueDef.java

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

+ 47 - 15
jme3-core/src/main/java/com/jme3/shader/Glsl100ShaderGenerator.java

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

+ 26 - 5
jme3-core/src/main/java/com/jme3/shader/ShaderNodeVariable.java

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

+ 53 - 23
jme3-core/src/plugins/java/com/jme3/material/plugins/ShaderNodeLoaderDelegate.java

@@ -217,11 +217,15 @@ public class ShaderNodeLoaderDelegate {
      * @throws IOException
      */
     protected ShaderNodeVariable readVariable(Statement statement) throws IOException {
+
         String line = statement.getLine().trim().replaceAll("\\s*\\[", "[");
         String[] splitVar = line.split("\\s");
-        if (splitVar.length != 2) {
-            throw new MatParseException("2 arguments", splitVar.length + "", statement);
+
+        if (splitVar.length > 3) {
+            throw new MatParseException("More than 3 arguments", splitVar.length + "", statement);
         }
+
+        String defaultValue = splitVar.length > 2? splitVar[2] : null;
         String varName = splitVar[1];
         String varType = splitVar[0];
         String multiplicity = null;
@@ -230,13 +234,19 @@ public class ShaderNodeLoaderDelegate {
             //we have an array
             String[] arr = splitVar[1].split("\\[");
             varName = arr[0].trim();
-            multiplicity = arr[1].replaceAll("\\]", "").trim();          
+            multiplicity = arr[1].replaceAll("\\]", "").trim();
         }
+
         if (varNames.contains(varName + ";")) {
             throw new MatParseException("Duplicate variable name " + varName, statement);
         }
+
         varNames += varName + ";";
-        return new ShaderNodeVariable(varType, "", varName, multiplicity);
+
+        final ShaderNodeVariable variable = new ShaderNodeVariable(varType, "", varName, multiplicity);
+        variable.setDefaultValue(defaultValue);
+
+        return variable;
     }
 
     /**
@@ -262,7 +272,7 @@ public class ShaderNodeLoaderDelegate {
             String[] split = statement.getLine().split("[ \\{]");
             if (line.startsWith("Definition")) {
                 ShaderNodeDefinition def = findDefinition(statement);
-                shaderNode.setDefinition(def);                
+                shaderNode.setDefinition(def);
                 if(def.isNoOutput()){
                     techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(shaderNode.getName());
                 }
@@ -276,12 +286,12 @@ public class ShaderNodeLoaderDelegate {
                     techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(mapping.getRightVariable().getNameSpace());
                     shaderNode.getInputMapping().add(mapping);
                 }
-            } else if (line.startsWith("OutputMapping")) {                
+            } else if (line.startsWith("OutputMapping")) {
                 for (Statement statement1 : statement.getContents()) {
                     VariableMapping mapping = readOutputMapping(statement1);
                     techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(shaderNode.getName());
                     shaderNode.getOutputMapping().add(mapping);
-                }               
+                }
             } else {
                 throw new MatParseException("ShaderNodeDefinition", split[0], statement);
             }
@@ -298,7 +308,7 @@ public class ShaderNodeLoaderDelegate {
      * Format : <nameSpace>.<varName>[.<swizzling>] =
      * <nameSpace>.<varName>[.<swizzling>][:Condition]
      * </code>
-     * 
+     *
      * @param statement the statement to read
      * @return the read mapping
      */
@@ -660,19 +670,13 @@ 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, statement1)) {                  
+                if (updateRightFromUniforms(param, mapping, vertexDeclaredUniforms, statement1)) {
+                    updateMaterialTextureType(statement1, mapping, left, param);
                     storeVertexUniform(mapping.getRightVariable());
                 }
             } else {
                 if (updateRightFromUniforms(param, mapping, fragmentDeclaredUniforms, statement1)) {
-                    if (mapping.getRightVariable().getType().contains("|")) {
-                        String type = fixSamplerType(left.getType(), mapping.getRightVariable().getType());
-                        if (type != null) {
-                            mapping.getRightVariable().setType(type);
-                        } else {
-                            throw new MatParseException(param.getVarType().toString() + " can only be matched to one of " + param.getVarType().getGlslType().replaceAll("\\|", ",") + " found " + left.getType(), statement1);
-                        }
-                    }                
+                    updateMaterialTextureType(statement1, mapping, left, param);
                     storeFragmentUniform(mapping.getRightVariable());
                 }
             }
@@ -683,11 +687,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)) {                    
+                if (updateRightFromUniforms(worldParam, mapping, vertexDeclaredUniforms)) {
                     storeVertexUniform(mapping.getRightVariable());
                 }
             } else {
-                if (updateRightFromUniforms(worldParam, mapping, fragmentDeclaredUniforms)) {                    
+                if (updateRightFromUniforms(worldParam, mapping, fragmentDeclaredUniforms)) {
                     storeFragmentUniform(mapping.getRightVariable());
                 }
             }
@@ -704,7 +708,7 @@ public class ShaderNodeLoaderDelegate {
             right.setNameSpace(node.getName());
             right.setType(var.getType());
             right.setMultiplicity(var.getMultiplicity());
-            mapping.setRightVariable(right);            
+            mapping.setRightVariable(right);
             storeVaryings(node, mapping.getRightVariable());
 
         }
@@ -714,6 +718,32 @@ public class ShaderNodeLoaderDelegate {
         return mapping;
     }
 
+    /**
+     * Updated the material texture type of the variable mapping.
+     *
+     * @param statement the statement.
+     * @param mapping the variable mapping.
+     * @param left the left variable.
+     * @param param the material parameter.
+     * @throws MatParseException
+     */
+    private void updateMaterialTextureType(final Statement statement, final VariableMapping mapping,
+                                           final ShaderNodeVariable left, final MatParam param) throws MatParseException {
+
+        if (!mapping.getRightVariable().getType().contains("|")) {
+            return;
+        }
+
+        final String type = fixSamplerType(left.getType(), mapping.getRightVariable().getType());
+
+        if (type != null) {
+            mapping.getRightVariable().setType(type);
+        } else {
+            throw new MatParseException(param.getVarType().toString() + " can only be matched to one of " +
+                    param.getVarType().getGlslType().replaceAll("\\|", ",") + " found " + left.getType(), statement);
+        }
+    }
+
     /**
      * reads an output mapping
      *
@@ -924,12 +954,12 @@ public class ShaderNodeLoaderDelegate {
             dv.addNode(shaderNode);
             //if a variable is declared with the same name as an input and an output and is a varying, set it as a shader output so it's declared as a varying only once.
             for (VariableMapping variableMapping : node.getInputMapping()) {
-                if (variableMapping.getLeftVariable().getName().equals(variable.getName())) {
-                    variableMapping.getLeftVariable().setShaderOutput(true);
+                final ShaderNodeVariable leftVariable = variableMapping.getLeftVariable();
+                if (leftVariable.getName().equals(variable.getName())) {
+                    leftVariable.setShaderOutput(true);
                 }
             }
         }
-
     }
 
     /**

+ 3 - 6
jme3-plugins/src/main/java/com/jme3/material/plugin/export/materialdef/J3mdTechniqueDefWriter.java

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