/** * Searches a variable in the given list and updates its type and namespace. * * @param var the variable to update. * @param list the variables list. * @return true if the variable has been found and updated. */ protected boolean updateVariableFromList(ShaderNodeVariable var, List<ShaderNodeVariable> list) { for (ShaderNodeVariable shaderNodeVariable : list) { if (shaderNodeVariable.getName().equals(var.getName())) { var.setType(shaderNodeVariable.getType()); var.setMultiplicity(shaderNodeVariable.getMultiplicity()); var.setNameSpace(shaderNode.getName()); return true; } } return false; }
startCondition(var.getCondition(), source); appendIndent(source); if (modifier != null) { source.append(var.getType()); source.append(" "); if (appendNameSpace) { source.append(var.getNameSpace()); source.append("_"); source.append(var.getPrefix()); source.append(var.getName()); if (var.getMultiplicity() != null) { source.append("["); source.append(var.getMultiplicity().toUpperCase()); source.append("]"); endCondition(var.getCondition(), source);
if (var.getType().startsWith("sampler")) { continue; final String fullName = shaderNode.getName() + "_" + var.getName(); final ShaderNodeVariable variable = new ShaderNodeVariable(var.getType(), shaderNode.getName(), var.getName(), var.getMultiplicity()); declareVariable(source, variable, var.getDefaultValue(), true, null); final ShaderNodeVariable leftVariable = mapping.getLeftVariable(); String newName = shaderNode.getName() + "_" + leftVariable.getName(); boolean isDeclared = declaredInputs.contains(newName); if (rightVariable != null && isWorldOrMaterialParam(rightVariable) && rightVariable.getType().startsWith("sampler")) { nodeSource = replace(nodeSource, leftVariable, rightVariable.getPrefix() + rightVariable.getName()); } else { if (leftVariable.getType().startsWith("sampler")) { throw new IllegalArgumentException("a Sampler must be a uniform"); ShaderNodeVariable v = new ShaderNodeVariable(var.getType(), shaderNode.getName(), var.getName(), var.getMultiplicity()); if (!declaredInputs.contains(shaderNode.getName() + "_" + var.getName())) { if (!isVarying(info, v)) { declareVariable(source, v);
/** * Append a variable initialization to the code * * @param source the StringBuilder to use * @param var the variable to initialize * @param initValue the init value to assign to the variable */ protected void initVariable(StringBuilder source, ShaderNodeVariable var, String initValue) { appendIndent(source); source.append(var.getNameSpace()); source.append("_"); source.append(var.getName()); source.append(" = "); source.append(initValue); source.append(";\n"); } }
right.setType(param.getVarType().getGlslType()); right.setName(param.getName()); right.setPrefix("m_"); if (left.getMultiplicity() != null) { String multiplicity = left.getMultiplicity(); try { Integer.parseInt(multiplicity); left.setMultiplicity(multiplicity); left.setCondition(mergeConditions(left.getCondition(), "defined(" + multiplicity + ")", "||")); } else { throw new MatParseException("Wrong multiplicity for variable" + left.getName() + ". " + multiplicity + " should be an int or a declared material parameter.", statement); right.setMultiplicity(multiplicity); right.setCondition(left.getCondition()); map.put(right.getName(), dv); dv.addNode(shaderNode); mapping.setRightVariable(right);
if (!leftVariable.isShaderOutput() && declare) { source.append(leftVariable.getType()); source.append(" "); source.append(leftVariable.getNameSpace()); source.append("_"); source.append(leftVariable.getName()); if (leftVariable.getMultiplicity() != null){ source.append("["); source.append(leftVariable.getMultiplicity()); source.append("]"); source.append(leftVariable.getType()); source.append("(0.0);\n"); appendIndent(source); source.append(leftVariable.getNameSpace()); source.append("_"); source.append(leftVariable.getName()); source.append("."); source.append(mapping.getLeftSwizzling()); source.append(rightVariable.getPrefix()); source.append(rightVariable.getName());
@Override public String toString() { 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(); }
final ShaderNodeVariable right = mapping.getRightVariable(); if (left.getType().startsWith("sampler") || right.getType().startsWith("sampler")) { throw new MatParseException("Samplers can only be inputs", statement); if (left.getNameSpace().equals(ShaderGenerator.NAME_SPACE_GLOBAL)) { left.setType("vec4"); // Globals are all vec4 for now (maybe forever...) storeGlobal(left, statement); } else { throw new MatParseException("Only Global nameSpace is allowed for outputMapping, got" + left.getNameSpace(), statement); throw new MatParseException(right.getName() + " is not an output variable of " + definition.getName(), statement);
/** * replaced a variable name in a source code with the given name * @param nodeSource the source to use * @param var the variable * @param newName the new name of the variable * @return the modified source code */ protected String replace(String nodeSource, ShaderNodeVariable var, String newName) { nodeSource = nodeSource.replaceAll("(?<=\\W)" + var.getName() + "(?=\\W)", newName); return nodeSource; }
/** * updates the right variable of the given mapping from a UniformBinding (a * WorldParam) it checks if the uniform hasn't already been loaded, add it * to the maps if not. * * @param param the WorldParam UniformBinding * @param mapping the mapping * @param map the map of uniforms to search into * @return true if the param was added to the map */ protected boolean updateRightFromUniforms(UniformBinding param, VariableMapping mapping, Map<String, DeclaredVariable> map) { ShaderNodeVariable right = mapping.getRightVariable(); String name = param.toString(); DeclaredVariable dv = map.get(name); if (dv == null) { right.setType(param.getGlslType()); right.setName(name); right.setPrefix("g_"); dv = new DeclaredVariable(right); map.put(right.getName(), dv); dv.addNode(shaderNode); mapping.setRightVariable(right); return true; } dv.addNode(shaderNode); mapping.setRightVariable(dv.var); return false; }
variable.setShaderOutput(true); final String fullName = node.getName() + "." + variable.getName(); if (leftVariable.getName().equals(variable.getName())) { leftVariable.setShaderOutput(true);
/** * {@inheritDoc} * * attributes are all declared, inPosition is declared even if it's not in * the list and its condition is nulled. */ @Override protected void generateAttributes(StringBuilder source, ShaderGenerationInfo info) { source.append("\n"); boolean inPosition = false; for (ShaderNodeVariable var : info.getAttributes()) { if (var.getName().equals("inPosition")) { inPosition = true; var.setCondition(null); fixInPositionType(var); //keep track on the InPosition variable to avoid iterating through attributes again inPosTmp = var; } declareAttribute(source, var); } if (!inPosition) { inPosTmp = new ShaderNodeVariable("vec3", "inPosition"); declareAttribute(source, inPosTmp); } }
/** * Finds if a variable is a world or a material parameter * @param var the variable * @return true if the variable is a Word or material parameter */ protected boolean isWorldOrMaterialParam(ShaderNodeVariable var) { return var.getNameSpace().equals("MatParam") || var.getNameSpace().equals("WorldParam"); }
/** * check the types of a mapping, left type must match right type take the * swizzle into account * * @param mapping the mapping * @param statement1 the statement being read * @throws MatParseException */ protected void checkTypes(VariableMapping mapping, Statement statement1) throws MatParseException { if (!ShaderUtils.typesMatch(mapping)) { String ls = mapping.getLeftSwizzling().length() == 0 ? "" : "." + mapping.getLeftSwizzling(); String rs = mapping.getRightSwizzling().length() == 0 ? "" : "." + mapping.getRightSwizzling(); throw new MatParseException("Type mismatch, cannot convert " + mapping.getRightVariable().getType() + rs + " to " + mapping.getLeftVariable().getType() + ls, 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); } }
/** * declare and assign the global position in the vertex shader. * @param info the shader generation info * @param source the shader source being generated */ protected void declareGlobalPosition(ShaderGenerationInfo info, StringBuilder source) { if(inPosTmp.getType().equals(info.getVertexGlobal().getType())){ declareVariable(source, info.getVertexGlobal(), "inPosition"); }else{ declareVariable(source, info.getVertexGlobal(), "vec4(inPosition,1.0)"); } } }
final ShaderNodeVariable variable = new ShaderNodeVariable(varType, "", varName, multiplicity); variable.setDefaultValue(defaultValue);
/** * 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; }
/** * Finds if a variable is a varying * @param info the ShaderGenerationInfo * @param v the variable * @return true is the given variable is a varying */ protected boolean isVarying(ShaderGenerationInfo info, ShaderNodeVariable v) { boolean isVarying = false; for (ShaderNodeVariable shaderNodeVariable : info.getVaryings()) { if (shaderNodeVariable.equals(v)) { isVarying = true; } } return isVarying; }