瀏覽代碼

Big refacto and pain

Clement Espeute 2 年之前
父節點
當前提交
d43656dd88

+ 1 - 1
hide/view/shadereditor/ShaderEditor.hx

@@ -280,7 +280,7 @@ class ShaderEditor extends hide.view.Graph {
 		element.find("#displayGlsl").on("click", () -> displayCompiled("glsl"));
 		element.find("#displayGlsl").on("click", () -> displayCompiled("glsl"));
 		element.find("#displayHlsl").on("click", () -> displayCompiled("hlsl"));
 		element.find("#displayHlsl").on("click", () -> displayCompiled("hlsl"));
 
 
-		element.find("#display2").on("click", () -> {@:privateAccess info(hxsl.Printer.shaderToString(shaderGraph.compile2().shader.data));});
+		element.find("#display2").on("click", () -> {@:privateAccess info(hxsl.Printer.shaderToString(shaderGraph.compile2().shader.data, true));});
 
 
 		editorMatrix.on("click", "input, select", function(ev) {
 		editorMatrix.on("click", "input, select", function(ev) {
 			beforeChange();
 			beforeChange();

+ 1 - 1
hrt/shgraph/Operation.hx

@@ -2,7 +2,7 @@ package hrt.shgraph;
 
 
 using hxsl.Ast;
 using hxsl.Ast;
 
 
-class Operation extends ShaderNode {
+class Operation extends ShaderNodeHxsl {
 
 
 	@input("A", true) var a = SType.Number;
 	@input("A", true) var a = SType.Number;
 	@input("B", true) var b = SType.Number;
 	@input("B", true) var b = SType.Number;

+ 78 - 57
hrt/shgraph/ShaderGraph.hx

@@ -6,6 +6,14 @@ using hide.tools.Extensions.ArrayExtensions;
 using haxe.EnumTools.EnumValueTools;
 using haxe.EnumTools.EnumValueTools;
 using Lambda;
 using Lambda;
 
 
+typedef ShaderNodeDef = {
+	expr: TExpr,
+	inVars: Array<TVar>, // Variables that shows up as input of a node
+	outVars: Array<TVar>, // Variables that shows up as outputs of a node
+	externVars: Array<TVar>, // All the external variables of a shader, including sginput/sgoutputs
+	inits: Array<{variable: TVar, value: Dynamic}>, // Default values for some variables
+};
+
 typedef Node = {
 typedef Node = {
 	x : Float,
 	x : Float,
 	y : Float,
 	y : Float,
@@ -159,7 +167,14 @@ class ShaderGraph {
 		node.instance.setInput(edge.nameInput, new NodeVar(output.instance, edge.nameOutput));
 		node.instance.setInput(edge.nameInput, new NodeVar(output.instance, edge.nameOutput));
 		output.outputs.push(node);
 		output.outputs.push(node);
 
 
-		var connection : Connection = {from: output, fromName: edge.nameOutput, to: node, toName: edge.nameInput};
+		// pas du tout envie de mourrir
+		var fromGen = output.instance.getShaderDef();
+		var fromName = fromGen.outVars[output.instance.getOutputInfoKeys().indexOf(edge.nameOutput)].name;
+
+		var toGen = node.instance.getShaderDef();
+		var toName = toGen.inVars[node.instance.getInputInfoKeys().indexOf(edge.nameInput)].name;
+
+		var connection : Connection = {from: output, fromName: fromName, to: node, toName: toName};
 		var prevConn = node.instance.inputs2.get(edge.nameInput);
 		var prevConn = node.instance.inputs2.get(edge.nameInput);
 		if (prevConn != null)
 		if (prevConn != null)
 			connections.remove(prevConn);
 			connections.remove(prevConn);
@@ -250,7 +265,7 @@ class ShaderGraph {
 		return data;
 		return data;
 	}
 	}
 
 
-	public function generate2(?getNewVarId: () -> Int) : {expr: TExpr, inVars: Array<{variable: TVar, value: Dynamic}>, outVars: Array<TVar>} {
+	public function generate2(?getNewVarId: () -> Int) : ShaderNodeDef {
 		if (getNewVarId == null) {
 		if (getNewVarId == null) {
 			var varIdCount = 0;
 			var varIdCount = 0;
 			getNewVarId = function()
 			getNewVarId = function()
@@ -268,13 +283,13 @@ class ShaderGraph {
 			if (!nodeOutputs.exists(node)) {
 			if (!nodeOutputs.exists(node)) {
 				var outputs : Map<String, TVar> = [];
 				var outputs : Map<String, TVar> = [];
 
 
-				var shaderNodeOutputs = node.instance.getOutputs2();
-				for (name => output in shaderNodeOutputs) {
+				var def = node.instance.getShaderDef();
+				for (output in def.outVars) {
 					var type = output.type;
 					var type = output.type;
 					if (type == null) throw "no type";
 					if (type == null) throw "no type";
 					var id = getNewVarId();
 					var id = getNewVarId();
-					var output = {id: id, name: getNewVarName(node, id), type: type, kind : Local};
-					outputs.set(name, output);
+					var outVar = {id: id, name: getNewVarName(node, id), type: type, kind : Local};
+					outputs.set(output.name, outVar);
 				}
 				}
 
 
 				nodeOutputs.set(node, outputs);
 				nodeOutputs.set(node, outputs);
@@ -315,7 +330,8 @@ class ShaderGraph {
 		}
 		}
 
 
 		var graphInputVars : Array<TVar> = [];
 		var graphInputVars : Array<TVar> = [];
-		var graphOutputsVars : Array<TVar> = [];
+		var graphOutputVars : Array<TVar> = [];
+		var externs : Array<TVar> = [];
 
 
 		var nodeToExplore : Array<Node> = [];
 		var nodeToExplore : Array<Node> = [];
 
 
@@ -324,7 +340,6 @@ class ShaderGraph {
 				nodeToExplore.push(node);
 				nodeToExplore.push(node);
 		}
 		}
 
 
-
 		var sortedNodes : Array<Node> = [];
 		var sortedNodes : Array<Node> = [];
 
 
 		// Topological sort the nodes with Kahn's algorithm
 		// Topological sort the nodes with Kahn's algorithm
@@ -392,8 +407,6 @@ class ShaderGraph {
 			throw "unreachable";
 			throw "unreachable";
 		}
 		}
 
 
-		//sortedNodes.reverse();
-
 		// Actually build the final shader expression
 		// Actually build the final shader expression
 		var exprsReverse : Array<TExpr> = [];
 		var exprsReverse : Array<TExpr> = [];
 		for (currentNode in sortedNodes) {
 		for (currentNode in sortedNodes) {
@@ -409,6 +422,8 @@ class ShaderGraph {
 			var inputVars : Map<String, TVar> = [];
 			var inputVars : Map<String, TVar> = [];
 			for (input in currentNode.instance.inputs2) {
 			for (input in currentNode.instance.inputs2) {
 				if (input.to != currentNode) throw "node connection missmatch";
 				if (input.to != currentNode) throw "node connection missmatch";
+				if (input.from.type == "hrt.shgraph.nodes.Add")
+					trace("break");
 				var outputs = getOutputs(input.from);
 				var outputs = getOutputs(input.from);
 				var outputVar = outputs[input.fromName];
 				var outputVar = outputs[input.fromName];
 				if (outputVar == null) throw "null tvar";
 				if (outputVar == null) throw "null tvar";
@@ -416,26 +431,27 @@ class ShaderGraph {
 				inputVars.set(input.toName, outputVar);
 				inputVars.set(input.toName, outputVar);
 			}
 			}
 
 
-
-
-
-			if (Std.downcast(currentNode.instance, ShaderOutput) != null) {
+			/*if (Std.downcast(currentNode.instance, ShaderOutput) != null) {
 				var outputNode : ShaderOutput = cast currentNode.instance;
 				var outputNode : ShaderOutput = cast currentNode.instance;
-				var outVar : TVar = {name: outputNode.variable.name, id:getNewVarId(), type: TVec(4, VFloat), kind: Local};
+				var outVar : TVar = {name: outputNode.variable.name, id:getNewVarId(), type: TVec(4, VFloat), kind: Local, qualifiers: [SgOutput]};
 				var firstInput = inputVars.iterator().next();
 				var firstInput = inputVars.iterator().next();
 				var finalExpr : TExpr = {e: TBinop(OpAssign, {e: TVar(outVar), p: pos, t: outVar.type}, {e: TVar(firstInput), p: pos, t: outVar.type}), p: pos, t: outVar.type};
 				var finalExpr : TExpr = {e: TBinop(OpAssign, {e: TVar(outVar), p: pos, t: outVar.type}, {e: TVar(firstInput), p: pos, t: outVar.type}), p: pos, t: outVar.type};
 
 
 				exprsReverse.push(finalExpr);
 				exprsReverse.push(finalExpr);
-				graphOutputsVars.push(outVar);
+				externs.push(outVar);
+				graphOutputVars.push(outVar);
+
 			} else if (Std.downcast(currentNode.instance, ShaderParam) != null) {
 			} else if (Std.downcast(currentNode.instance, ShaderParam) != null) {
 				var inputNode : ShaderParam = cast currentNode.instance;
 				var inputNode : ShaderParam = cast currentNode.instance;
 
 
 
 
 				for (output in outputs) {
 				for (output in outputs) {
-					var inVar : TVar = {name: inputNode.variable.name, id:getNewVarId(), type: output.type, kind: Param};
+					var inVar : TVar = {name: inputNode.variable.name, id:getNewVarId(), type: output.type, kind: Param, qualifiers: [SgInput]};
 					var finalExpr : TExpr = {e: TVarDecl(output, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
 					var finalExpr : TExpr = {e: TVarDecl(output, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
 					exprsReverse.push(finalExpr);
 					exprsReverse.push(finalExpr);
+					externs.push(inVar);
 					graphInputVars.push(inVar);
 					graphInputVars.push(inVar);
+
 					var param = getParameter(inputNode.parameterId);
 					var param = getParameter(inputNode.parameterId);
 					inits.push({variable: inVar, value: param.defaultValue});
 					inits.push({variable: inVar, value: param.defaultValue});
 				}
 				}
@@ -455,7 +471,7 @@ class ShaderGraph {
 				// Patch inputs
 				// Patch inputs
 				for (inputName => tvar in inputVars) {
 				for (inputName => tvar in inputVars) {
 					var trueName = subgraph.getInputInfo(inputName).name;
 					var trueName = subgraph.getInputInfo(inputName).name;
-					var originalInput = gen.inVars.find((f) -> f.variable.name == trueName).variable;
+					var originalInput = gen.inVars.find((f) -> f.name == trueName);
 					var finalExpr : TExpr = {e: TVarDecl(originalInput, convertToType(originalInput.type, {e: TVar(tvar), p: pos, t: tvar.type})), p: pos, t: originalInput.type};
 					var finalExpr : TExpr = {e: TVarDecl(originalInput, convertToType(originalInput.type, {e: TVar(tvar), p: pos, t: tvar.type})), p: pos, t: originalInput.type};
 					finalExprs.push(finalExpr);
 					finalExprs.push(finalExpr);
 				}
 				}
@@ -467,51 +483,55 @@ class ShaderGraph {
 					var finalExpr : TExpr = {e: TVarDecl(output), p: pos, t: output.type};
 					var finalExpr : TExpr = {e: TVarDecl(output), p: pos, t: output.type};
 					exprsReverse.push(finalExpr);
 					exprsReverse.push(finalExpr);
 				}
 				}
-			}
-			else
+			}*/
+			/*else*/
 			{
 			{
-				var fullExpr : TExpr = null;
-
-				if (Std.downcast(currentNode.instance, hrt.shgraph.nodes.Add) != null) {
-					var unser = new hxsl.Serializer();
-					var shaderData = getShaderData(Type.getClass(currentNode.instance));
-					var fn = shaderData.funs[0]; // TODO : spec the function to use for shader node definitions
-					var expr = fn.expr;
-
-					var nodeShaderOutputs = currentNode.instance.getOutputs2();
-					for (outputName => output in outputs) {
-						var outputVar : TVar = nodeShaderOutputs.get(outputName);
-						expr = replaceVar(expr, outputVar, {e: TVar(output), p:pos, t: output.type});
-					}
-
-
-					for (shaderVar in shaderData.vars) {
-						if (shaderVar.qualifiers != null && shaderVar.qualifiers.has(SgInput)) {
-							var ourInputVar = inputVars.get(shaderVar.name);
+				var def = currentNode.instance.getShaderDef();
+				var expr = def.expr;
+
+				var outputDecls : Array<TVar> = [];
+				for (nodeVar in def.externVars) {
+					if (nodeVar.qualifiers != null) {
+						if (nodeVar.qualifiers.has(SgInput)) {
+							var ourInputVar = inputVars.get(nodeVar.name);
 							var replacement : TExpr = null;
 							var replacement : TExpr = null;
 							if (ourInputVar != null) {
 							if (ourInputVar != null) {
-								replacement = convertToType(shaderVar.type,  {e: TVar(ourInputVar), p:pos, t: ourInputVar.type});
+								replacement = convertToType(nodeVar.type,  {e: TVar(ourInputVar), p:pos, t: ourInputVar.type});
 							}
 							}
 							else {
 							else {
+								var id = getNewVarId();
+								var outVar = {id: id, name: nodeVar.name, type: nodeVar.type, kind : Param, qualifiers: [SgOutput]};
+								replacement = {e: TVar(outVar), p:pos, t: nodeVar.type};
+								graphInputVars.push(outVar);
+								externs.push(outVar);
+								inits.push({variable: outVar, value:new h3d.Vector()});
+							}
+							expr = replaceVar(expr, nodeVar, replacement);
 
 
-								replacement = convertToType(shaderVar.type, {e: TConst(CFloat(0.0)), p:pos, t: TFloat});
+						}
+						else if (nodeVar.qualifiers.has(SgOutput)) {
+							var outputVar : TVar = outputs.get(nodeVar.name);
+							if (outputVar == null) {
+								externs.push(nodeVar);
+							} else {
+								expr = replaceVar(expr, nodeVar, {e: TVar(outputVar), p:pos, t: nodeVar.type});
+								outputDecls.push(outputVar);
 							}
 							}
-							expr = replaceVar(expr, shaderVar, replacement);
+						}
+						else {
+							externs.push(nodeVar);
 						}
 						}
 					}
 					}
-
-					exprsReverse.push(expr);
-
-					for (outputName => output in outputs) {
-						if (output.type == null) throw "no type";
-						var finalExpr : TExpr = {e: TVarDecl(output), p: pos, t: output.type};
-						exprsReverse.push(finalExpr);
+					else {
+						externs.push(nodeVar);
 					}
 					}
-
-					fullExpr = null;
 				}
 				}
-				else {
-					throw "unsuported node";
+
+				exprsReverse.push(expr);
+
+				for (output in outputDecls) {
+					var finalExpr : TExpr = {e: TVarDecl(output), p: pos, t: output.type};
+					exprsReverse.push(finalExpr);
 				}
 				}
 			}
 			}
 		}
 		}
@@ -520,8 +540,10 @@ class ShaderGraph {
 
 
 		return {
 		return {
 			expr: {e: TBlock(exprsReverse), t:TVoid, p:pos},
 			expr: {e: TBlock(exprsReverse), t:TVoid, p:pos},
-			inVars: inits,
-			outVars: graphOutputsVars,
+			inVars: graphInputVars,
+			outVars: graphOutputVars,
+			externVars: externs,
+			inits: inits,
 		};
 		};
 	}
 	}
 
 
@@ -543,8 +565,7 @@ class ShaderGraph {
 			funs: [],
 			funs: [],
 		};
 		};
 
 
-		shaderData.vars.append(gen.inVars.map((f) -> f.variable));
-		shaderData.vars.append(gen.outVars);
+		shaderData.vars.append(gen.externVars);
 
 
 		shaderData.funs.push({
 		shaderData.funs.push({
 			ret : TVoid, kind : Fragment,
 			ret : TVoid, kind : Fragment,
@@ -566,7 +587,7 @@ class ShaderGraph {
 		var time = haxe.Timer.stamp() - start;
 		var time = haxe.Timer.stamp() - start;
 		trace("Shader compile2 in " + time * 1000 + " ms");
 		trace("Shader compile2 in " + time * 1000 + " ms");
 
 
-		return {shader : shared, inits: gen.inVars};
+		return {shader : shared, inits: gen.inits};
 	}
 	}
 
 
 	public function getParameter(id : Int) {
 	public function getParameter(id : Int) {

+ 5 - 1
hrt/shgraph/ShaderNode.hx

@@ -5,7 +5,6 @@ using hxsl.Ast;
 typedef InputInfo = { name : String, type : ShaderType.SType, hasProperty : Bool, isRequired : Bool, ?ids : Array<Int>, ?index : Int };
 typedef InputInfo = { name : String, type : ShaderType.SType, hasProperty : Bool, isRequired : Bool, ?ids : Array<Int>, ?index : Int };
 typedef OutputInfo = { name : String, type : ShaderType.SType, ?id : Int };
 typedef OutputInfo = { name : String, type : ShaderType.SType, ?id : Int };
 
 
-@:autoBuild(hrt.shgraph.Macros.buildNode())
 @:autoBuild(hrt.shgraph.ParseFieldsMacro.build())
 @:autoBuild(hrt.shgraph.ParseFieldsMacro.build())
 @:keepSub
 @:keepSub
 class ShaderNode {
 class ShaderNode {
@@ -40,6 +39,11 @@ class ShaderNode {
 		return outputs;
 		return outputs;
 	}
 	}
 
 
+	public function getShaderDef() : ShaderGraph.ShaderNodeDef {
+		throw "Shouln't be called";
+		return {expr: null, inVars: [], outVars: [], inits: [], externVars: []};
+	}
+
 	var inputs : Map<String, NodeVar> = [];
 	var inputs : Map<String, NodeVar> = [];
 	var outputs : Map<String, TVar> = [];
 	var outputs : Map<String, TVar> = [];
 
 

+ 49 - 0
hrt/shgraph/ShaderNodeHxsl.hx

@@ -0,0 +1,49 @@
+package hrt.shgraph;
+
+@:autoBuild(hrt.shgraph.Macros.buildNode())
+class ShaderNodeHxsl extends ShaderNode {
+
+	static var nodeCache : Map<String, ShaderGraph.ShaderNodeDef> = [];
+
+	override public function getShaderDef() : ShaderGraph.ShaderNodeDef {
+		var cl = Type.getClass(this);
+		var className = Type.getClassName(cl);
+		var def = nodeCache.get(className);
+		if (def == null) {
+
+			var unser = new hxsl.Serializer();
+			var toUnser = (cl:Dynamic).SRC;
+			if (toUnser == null) throw "Node " + className + " has no SRC";
+			var data = @:privateAccess unser.unserialize(toUnser);
+			var expr = data.funs[0].expr;
+			var inVars = [];
+			var outVars = [];
+			var externVars = [];
+
+			for (tvar in data.vars) {
+				if (tvar.qualifiers != null) {
+					var input = false;
+					var output = false;
+					if (tvar.qualifiers.contains(SgInput)) {
+						inVars.push(tvar);
+						// TODO : handle default values
+						input = true;
+					}
+					if (tvar.qualifiers.contains(SgOutput)) {
+						outVars.push(tvar);
+						output = true;
+					}
+					if (input && output) {
+						throw "Variable is both sginput and sgoutput";
+					}
+					externVars.push(tvar);
+				}
+			}
+
+			def = {expr: expr, inVars: inVars, outVars: outVars, externVars: externVars, inits: []};
+			nodeCache.set(className, def);
+		}
+
+		return def;
+	}
+}

+ 16 - 5
hrt/shgraph/ShaderOutput.hx

@@ -12,13 +12,24 @@ class ShaderOutput extends ShaderNode {
 
 
 	@prop("Variable") public var variable : TVar;
 	@prop("Variable") public var variable : TVar;
 
 
-	static var SRC = {
-		@sginput var input : Vec4;
-		function fragment() {
-		}
+	var components = [X, Y, Z, W];
+
+	override function getOutputs2():Map<String, TVar> {
+		return [];
 	}
 	}
 
 
-	var components = [X, Y, Z, W];
+	override function getShaderDef():hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
+
+		var inVar : TVar = {name: "input", id:0, type: this.variable.type, kind: Param, qualifiers: [SgInput]};
+		var output : TVar = {name: variable.name, id:1, type: this.variable.type, kind: Local, qualifiers: [SgOutput]};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
+
+		//var param = getParameter(inputNode.parameterId);
+		//inits.push({variable: inVar, value: param.defaultValue});
+
+		return {expr: finalExpr, inVars: [inVar], outVars:[], externVars: [inVar, output], inits: []};
+	}
 
 
 	override public function checkValidityInput(key : String, type : ShaderType.SType) : Bool {
 	override public function checkValidityInput(key : String, type : ShaderType.SType) : Bool {
 		return ShaderType.checkConversion(type, ShaderType.getSType(variable.type));
 		return ShaderType.checkConversion(type, ShaderType.getSType(variable.type));

+ 13 - 0
hrt/shgraph/ShaderParam.hx

@@ -19,6 +19,19 @@ class ShaderParam extends ShaderNode {
 		return outputs;
 		return outputs;
 	}
 	}
 
 
+	override function getShaderDef():hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var pos : Position = {file: "", min: 0, max: 0};
+
+		var inVar : TVar = {name: this.variable.name, id:0, type: this.variable.type, kind: Param, qualifiers: [SgInput]};
+		var output : TVar = {name: "output", id:1, type: this.variable.type, kind: Local, qualifiers: [SgOutput]};
+		var finalExpr : TExpr = {e: TBinop(OpAssign, {e:TVar(output), p:pos, t:output.type}, {e: TVar(inVar), p: pos, t: output.type}), p: pos, t: output.type};
+
+		//var param = getParameter(inputNode.parameterId);
+		//inits.push({variable: inVar, value: param.defaultValue});
+
+		return {expr: finalExpr, inVars: [], outVars:[output], externVars: [inVar, output], inits: []};
+	}
+
 	public var variable : TVar;
 	public var variable : TVar;
 
 
 	override public function computeOutputs() {
 	override public function computeOutputs() {

+ 16 - 2
hrt/shgraph/nodes/SubGraph.hx

@@ -27,15 +27,29 @@ class SubGraph extends ShaderNode {
 		var gen = shader.generate2();
 		var gen = shader.generate2();
 
 
 		// compatibility hack with prev version
 		// compatibility hack with prev version
-		var prefixSubGraph = "shgraph_" + id + "_";
+		/*var prefixSubGraph = "shgraph_" + id + "_";
 
 
 		for (i => outVar in gen.outVars) {
 		for (i => outVar in gen.outVars) {
 			outputs.set(prefixSubGraph + i, outVar);
 			outputs.set(prefixSubGraph + i, outVar);
-		}
+		}*/
 
 
 		return outputs;
 		return outputs;
 	}
 	}
 
 
+	override public function getShaderDef():hrt.shgraph.ShaderGraph.ShaderNodeDef {
+		var shader = new ShaderGraph(pathShaderGraph);
+		var gen = shader.generate2();
+
+		/*for (i => outVar in gen.outVars) {
+			var prefixSubGraph = "shgraph_" + id + "_";
+
+			outVar.name = prefixSubGraph + i;
+			outputs.set(prefixSubGraph + i, outVar);
+		}*/
+
+		return gen;
+	}
+
 	var inputsInfo : Map<String, ShaderNode.InputInfo>;
 	var inputsInfo : Map<String, ShaderNode.InputInfo>;
 	var inputInfoKeys : Array<String> = [];
 	var inputInfoKeys : Array<String> = [];
 	var outputsInfo : Map<String, ShaderNode.OutputInfo>;
 	var outputsInfo : Map<String, ShaderNode.OutputInfo>;