private string InsertShad(StringBuilder properties, StringBuilder cgProperties, StringBuilder body, bool addDefines) { PreProcess(); if (addDefines) { cgProperties.AppendLine(ShaderDefs.GetHashFuncs(Hash1, Hash2, Hash3)); cgProperties.AppendLine(ShaderDefs.Functions); } //Emit properties in no particular order. foreach (Node n in nodes) { n.EmitProperties(properties); n.EmitDefs(cgProperties); } //Emit code for all nodes in proper order. List <Node> toProcess = new List <Node>(); Dictionary <int, bool> uidDoneYet = new Dictionary <int, bool>(); if (!Output.IsAConstant) { toProcess.Add(GetNode(Output.NodeID)); uidDoneYet.Add(Output.NodeID, false); } while (toProcess.Count > 0) { Node n = toProcess[toProcess.Count - 1]; //If the next node hasn't been processed yet, add its inputs to the stack. if (!uidDoneYet[n.UID]) { foreach (NodeInput ni in n.Inputs) { if (!ni.IsAConstant) { if (uidDoneYet.ContainsKey(ni.NodeID)) { //Move the node up to the top of the stack. Node n2 = GetNode(ni.NodeID); toProcess.Remove(n2); toProcess.Add(n2); } else { toProcess.Add(GetNode(ni.NodeID)); uidDoneYet.Add(ni.NodeID, false); } } } uidDoneYet[n.UID] = true; } //Otherwise, let the node emit its code and then remove it from the stack. else { toProcess.RemoveAt(toProcess.Count - 1); n.EmitCode(body); } } return(Output.GetExpression(this)); }