private void readTechnique(Statement techStat) throws IOException { isUseNodes = false; String[] split = techStat.getLine().split(whitespacePattern); if (split.length == 1) { technique = new TechniqueDef(null); } else if (split.length == 2) { String techName = split[1]; technique = new TechniqueDef(techName); } else { throw new IOException("Technique statement syntax incorrect"); } for (Statement statement : techStat.getContents()) { readTechniqueStatement(statement); } if (isUseNodes) { nodesLoaderDelegate.computeConditions(); // used for caching later, the shader here is not a file. technique.setShaderFile( technique.hashCode() + "", technique.hashCode() + "", "GLSL100", "GLSL100"); } if (shaderName.containsKey(Shader.ShaderType.Vertex) && shaderName.containsKey(Shader.ShaderType.Fragment)) { technique.setShaderFile(shaderName, shaderLanguage); } materialDef.addTechniqueDef(technique); technique = null; shaderLanguage.clear(); shaderName.clear(); }
// <DEFINENAME> [ ":" <PARAMNAME> ] private void readDefine(String statement) throws IOException { String[] split = statement.split(":"); if (split.length == 1) { String defineName = split[0].trim(); presetDefines.add(defineName); } else if (split.length == 2) { String defineName = split[0].trim(); String paramName = split[1].trim(); MatParam param = materialDef.getMaterialParam(paramName); if (param == null) { logger.log( Level.WARNING, "In technique ''{0}'':\n" + "Define ''{1}'' mapped to non-existent" + " material parameter ''{2}'', ignoring.", new Object[] {technique.getName(), defineName, paramName}); return; } VarType paramType = param.getVarType(); technique.addShaderParamDefine(paramName, paramType, defineName); } else { throw new IOException("Define syntax incorrect"); } }
/** * reads a list of ShaderNode{} blocks * * @param statements the list of statements to parse * @throws IOException */ protected void readShaderNode(List<Statement> statements) throws IOException { for (Statement statement : statements) { String line = statement.getLine(); String[] split = statement.getLine().split("[ \\{]"); if (line.startsWith("Definition")) { ShaderNodeDefinition def = findDefinition(statement); shaderNode.setDefinition(def); if (def.isNoOutput()) { techniqueDef.getShaderGenerationInfo().getUnusedNodes().remove(shaderNode.getName()); } } else if (line.startsWith("Condition")) { String condition = line.substring(line.lastIndexOf(":") + 1).trim(); extractCondition(condition, statement); shaderNode.setCondition(conditionParser.getFormattedExpression()); } else if (line.startsWith("InputMapping")) { for (Statement statement1 : statement.getContents()) { VariableMapping mapping = readInputMapping(statement1); techniqueDef .getShaderGenerationInfo() .getUnusedNodes() .remove(mapping.getRightVariable().getNameSpace()); shaderNode.getInputMapping().add(mapping); } } 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); } } }
/** * Reads alist of ShaderNodes * * @param statements the list of statements to read * @throws IOException */ public void readNodes(List<Statement> statements) throws IOException { if (techniqueDef.getShaderNodes() == null) { techniqueDef.setShaderNodes(new ArrayList<ShaderNode>()); techniqueDef.setShaderGenerationInfo(new ShaderGenerationInfo()); } for (Statement statement : statements) { String[] split = statement.getLine().split("[ \\{]"); if (statement.getLine().startsWith("ShaderNode ")) { String name = statement.getLine().substring("ShaderNode".length()).trim(); if (nodes == null) { nodes = new HashMap<String, ShaderNode>(); } if (!nodes.containsKey(name)) { shaderNode = new ShaderNode(); shaderNode.setName(name); techniqueDef.getShaderGenerationInfo().getUnusedNodes().add(name); readShaderNode(statement.getContents()); nodes.put(name, shaderNode); techniqueDef.getShaderNodes().add(shaderNode); } else { throw new MatParseException("ShaderNode " + name + " is already defined", statement); } } else { throw new MatParseException("ShaderNode", split[0], statement); } } }
// <DEFINENAME> [ ":" <PARAMNAME> ] private void readDefine(String statement) throws IOException { String[] split = statement.split(":"); if (split.length == 1) { // add preset define technique.addShaderPresetDefine(split[0].trim(), VarType.Boolean, true); } else if (split.length == 2) { technique.addShaderParamDefine(split[1].trim(), split[0].trim()); } else { throw new IOException("Define syntax incorrect"); } }
protected void computeConditions() { updateConditions(vertexDeclaredUniforms); updateConditions(fragmentDeclaredUniforms); updateConditions(varyings); for (DeclaredVariable v : varyings.values()) { for (ShaderNode sn : techniqueDef.getShaderNodes()) { if (sn.getDefinition().getType() == Shader.ShaderType.Vertex) { for (VariableMapping mapping : sn.getInputMapping()) { if (mapping.getLeftVariable().equals(v.var)) { if (mapping.getCondition() == null || v.var.getCondition() == null) { mapping.setCondition(v.var.getCondition()); } else { mapping.setCondition( "(" + mapping.getCondition() + ") || (" + v.var.getCondition() + ")"); } } } } } } updateConditions(attributes); // updateConditions(fragmentGlobals); // vertexGlobal.makeCondition(); }
private void readForcedRenderState(List<Statement> renderStates) throws IOException { renderState = new RenderState(); for (Statement statement : renderStates) { readRenderStateStatement(statement); } technique.setForcedRenderState(renderState); renderState = null; }
/** * finds an UniformBinding representing a WorldParam from the techniqueDef * * @param varName the name of the WorldParam * @return the corresponding UniformBinding to the WorldParam */ protected UniformBinding findWorldParam(String varName) { for (UniformBinding worldParam : techniqueDef.getWorldBindings()) { if (varName.equals(worldParam.toString())) { return worldParam; } } return null; }
// ShadowMode <MODE> private void readShadowMode(String statement) throws IOException { String[] split = statement.split(whitespacePattern); if (split.length != 2) { throw new IOException("ShadowMode statement syntax incorrect"); } ShadowMode sm = ShadowMode.valueOf(split[1]); technique.setShadowMode(sm); }
// LightMode <SPACE> private void readLightSpace(String statement) throws IOException { String[] split = statement.split(whitespacePattern); if (split.length != 2) { throw new IOException("LightSpace statement syntax incorrect"); } TechniqueDef.LightSpace ls = TechniqueDef.LightSpace.valueOf(split[1]); technique.setLightSpace(ls); }
/** * stores a global output * * @param var the variable to store * @param statement1 the statement being read * @throws IOException */ public void storeGlobal(ShaderNodeVariable var, Statement statement1) throws IOException { var.setShaderOutput(true); if (shaderNode.getDefinition().getType() == Shader.ShaderType.Vertex) { ShaderNodeVariable global = techniqueDef.getShaderGenerationInfo().getVertexGlobal(); if (global != null) { // global.setCondition(mergeConditions(global.getCondition(), // var.getCondition(), "||")); // var.setCondition(global.getCondition()); 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); } } else { techniqueDef.getShaderGenerationInfo().setVertexGlobal(var); } } else if (shaderNode.getDefinition().getType() == Shader.ShaderType.Fragment) { storeVariable(var, techniqueDef.getShaderGenerationInfo().getFragmentGlobals()); } }
private void readShaderDefinition( Shader.ShaderType shaderType, String name, String... languages) { shaderNames.put(shaderType, name); if (langSize != 0 && langSize != languages.length) { throw new AssetLoadException( "Technique " + technique.getName() + " must have the same number of languages for each shader type."); } langSize = languages.length; for (int i = 0; i < languages.length; i++) { if (i >= shaderLanguages.size()) { shaderLanguages.add(new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class)); } shaderLanguages.get(i).put(shaderType, languages[i]); } }
private void readTechniqueStatement(Statement statement) throws IOException { String[] split = statement.getLine().split("[ \\{]"); if (split[0].equals("VertexShader") || split[0].equals("FragmentShader") || split[0].equals("GeometryShader") || split[0].equals("TessellationControlShader") || split[0].equals("TessellationEvaluationShader")) { readShaderStatement(statement.getLine()); } else if (split[0].equals("LightMode")) { readLightMode(statement.getLine()); } else if (split[0].equals("LightSpace")) { readLightSpace(statement.getLine()); } else if (split[0].equals("ShadowMode")) { readShadowMode(statement.getLine()); } else if (split[0].equals("WorldParameters")) { readWorldParams(statement.getContents()); } else if (split[0].equals("RenderState")) { readRenderState(statement.getContents()); } else if (split[0].equals("ForcedRenderState")) { readForcedRenderState(statement.getContents()); } else if (split[0].equals("Defines")) { readDefines(statement.getContents()); } else if (split[0].equals("ShaderNodesDefinitions")) { initNodesLoader(); if (isUseNodes) { nodesLoaderDelegate.readNodesDefinitions(statement.getContents()); } } else if (split[0].equals("VertexShaderNodes")) { initNodesLoader(); if (isUseNodes) { nodesLoaderDelegate.readVertexShaderNodes(statement.getContents()); } } else if (split[0].equals("FragmentShaderNodes")) { initNodesLoader(); if (isUseNodes) { nodesLoaderDelegate.readFragmentShaderNodes(statement.getContents()); } } else if (split[0].equals("NoRender")) { technique.setNoRender(true); } else { throw new MatParseException(null, split[0], statement); } }
/** * store a varying * * @param node the shaderNode * @param variable the variable to store */ public void storeVaryings(ShaderNode node, ShaderNodeVariable variable) { variable.setShaderOutput(true); if (node.getDefinition().getType() == Shader.ShaderType.Vertex && shaderNode.getDefinition().getType() == Shader.ShaderType.Fragment) { DeclaredVariable dv = varyings.get(variable.getName()); if (dv == null) { techniqueDef.getShaderGenerationInfo().getVaryings().add(variable); dv = new DeclaredVariable(variable); varyings.put(variable.getName(), dv); } 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); } } } }
/** * Adds a define to the techniquedef * * @param paramName */ public void addDefine(String paramName, VarType paramType) { if (techniqueDef.getShaderParamDefine(paramName) == null) { techniqueDef.addShaderParamDefine(paramName, paramType, paramName.toUpperCase()); } }
private void readWorldParams(List<Statement> worldParams) throws IOException { for (Statement statement : worldParams) { technique.addWorldParam(statement.getLine()); } }
/** * store an attribute * * @param var the variable ot store */ public void storeAttribute(ShaderNodeVariable var) { storeVariable(var, techniqueDef.getShaderGenerationInfo().getAttributes()); }
/** * store a fragment uniform * * @param var the variable ot store */ public void storeFragmentUniform(ShaderNodeVariable var) { storeVariable(var, techniqueDef.getShaderGenerationInfo().getFragmentUniforms()); }
private void readTechnique(Statement techStat) throws IOException { isUseNodes = false; String[] split = techStat.getLine().split(whitespacePattern); String name; if (split.length == 1) { name = TechniqueDef.DEFAULT_TECHNIQUE_NAME; } else if (split.length == 2) { name = split[1]; } else { throw new IOException("Technique statement syntax incorrect"); } String techniqueUniqueName = materialDef.getAssetName() + "@" + name; technique = new TechniqueDef(name, techniqueUniqueName.hashCode()); for (Statement statement : techStat.getContents()) { readTechniqueStatement(statement); } technique.setShaderPrologue(createShaderPrologue(presetDefines)); switch (technique.getLightMode()) { case Disable: technique.setLogic(new DefaultTechniqueDefLogic(technique)); break; case MultiPass: technique.setLogic(new MultiPassLightingLogic(technique)); break; case SinglePass: technique.setLogic(new SinglePassLightingLogic(technique)); break; case StaticPass: technique.setLogic(new StaticPassLightingLogic(technique)); break; case SinglePassAndImageBased: technique.setLogic(new SinglePassAndImageBasedLightingLogic(technique)); break; default: throw new UnsupportedOperationException(); } List<TechniqueDef> techniqueDefs = new ArrayList<>(); if (isUseNodes) { nodesLoaderDelegate.computeConditions(); // used for caching later, the shader here is not a file. // KIRILL 9/19/2015 // Not sure if this is needed anymore, since shader caching // is now done by TechniqueDef. technique.setShaderFile( technique.hashCode() + "", technique.hashCode() + "", "GLSL100", "GLSL100"); techniqueDefs.add(technique); } else if (shaderNames.containsKey(Shader.ShaderType.Vertex) && shaderNames.containsKey(Shader.ShaderType.Fragment)) { if (shaderLanguages.size() > 1) { for (int i = 1; i < shaderLanguages.size(); i++) { TechniqueDef td = null; try { td = (TechniqueDef) technique.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } td.setShaderFile(shaderNames, shaderLanguages.get(i)); techniqueDefs.add(td); } } technique.setShaderFile(shaderNames, shaderLanguages.get(0)); techniqueDefs.add(technique); } else { technique = null; shaderLanguages.clear(); shaderNames.clear(); presetDefines.clear(); langSize = 0; logger.log(Level.WARNING, "Fixed function technique was ignored"); logger.log( Level.WARNING, "Fixed function technique ''{0}'' was ignored for material {1}", new Object[] {name, key}); return; } for (TechniqueDef techniqueDef : techniqueDefs) { materialDef.addTechniqueDef(techniqueDef); } technique = null; langSize = 0; shaderLanguages.clear(); shaderNames.clear(); presetDefines.clear(); }