浏览代码

Fixed node registration

Clement Espeute 2 年之前
父节点
当前提交
965f5ba2c0

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

@@ -289,7 +289,7 @@ class ShaderEditor extends hide.view.Graph {
 		editorMatrix.on("change", "input, select", function(ev) {
 			try {
 				var idBox = ev.target.closest(".box").id;
-				shaderGraph.nodeUpdated(idBox);
+				//shaderGraph.nodeUpdated(idBox);
 				afterChange();
 				launchCompileShader();
 			} catch (e : Dynamic) {
@@ -477,7 +477,7 @@ class ShaderEditor extends hide.view.Graph {
 				var paramShader = shaderGraph.getParameter(paramNode.parameterId);
 				paramNode.setName(paramShader.name);
 				setDisplayValue(paramNode, paramShader.type, paramShader.defaultValue);
-				shaderGraph.nodeUpdated(paramNode.id);
+				//shaderGraph.nodeUpdated(paramNode.id);
 				addBox(new Point(node.x, node.y), ShaderParam, paramNode);
 			} else {
 				addBox(new Point(node.x, node.y), std.Type.getClass(node.instance), node.instance);

+ 20 - 0
hrt/shgraph/Macros.hx

@@ -53,5 +53,25 @@ class Macros {
 		}
 		return fields;
 	}
+
+	static function autoRegisterNode() {
+		var fields = Context.getBuildFields();
+
+		var thisClass = Context.getLocalClass();
+		var cl = thisClass.get();
+		var clPath = cl.pack.copy();
+		clPath.push(cl.name);
+
+		#if editor
+		fields.push({
+			name: "_",
+			access: [Access.AStatic],
+			kind: FieldType.FVar(macro:Bool, macro ShaderNode.register($v{cl.name}, ${clPath.toFieldExpr()})),
+			pos: Context.currentPos(),
+		});
+		#end
+
+		return fields;
+	}
 	#end
 }

+ 24 - 17
hrt/shgraph/ShaderGraph.hx

@@ -137,7 +137,11 @@ class ShaderGraph {
 	public function addEdge(edge : Edge) {
 		var node = this.nodes.get(edge.idInput);
 		var output = this.nodes.get(edge.idOutput);
-		if (!output.instance.getOutputs2().exists(edge.nameOutput)) {
+
+		var inputs = node.instance.getInputs2();
+		var outputs = output.instance.getOutputs2();
+
+		if (!output.instance.getOutputs2().exists(edge.nameOutput) || !node.instance.getInputs2().exists(edge.nameInput)) {
 			return false;
 		}
 
@@ -149,8 +153,14 @@ class ShaderGraph {
 			removeEdge(edge.idInput, edge.nameInput, false);
 			return false;
 		}
+
+		var inputType = inputs[edge.nameInput].type;
+		var outputType = outputs[edge.nameOutput].type;
+
+		if (!areTypesCompatible(inputType, outputType)) {
+			removeEdge(edge.idInput, edge.nameInput);
+		}
 		try {
-			updateOutputs(output);
 		} catch (e : Dynamic) {
 			removeEdge(edge.idInput, edge.nameInput);
 			throw e;
@@ -159,17 +169,14 @@ class ShaderGraph {
 		return true;
 	}
 
-	public function nodeUpdated(idNode : Int) {
-		var node = this.nodes.get(idNode);
-		if (node != null) {
-			updateOutputs(node);
-		}
-	}
-
-	function updateOutputs(node : Node) {
-		node.instance.computeOutputs();
-		for (o in node.outputs) {
-			updateOutputs(o);
+	public function areTypesCompatible(input: hxsl.Ast.Type, output: hxsl.Ast.Type) : Bool {
+		return switch (input) {
+			case TFloat, TVec(_, VFloat):
+				switch (output) {
+					case TFloat, TVec(_, VFloat): true;
+					default: false;
+				}
+			default: haxe.EnumTools.EnumValueTools.equals(input, output);
 		}
 	}
 
@@ -178,9 +185,6 @@ class ShaderGraph {
 		this.nodes.get(node.instance.connections[nameInput].from.id).outputs.remove(node);
 
 		node.instance.connections.remove(nameInput);
-		if (update) {
-			updateOutputs(node);
-		}
 	}
 
 	public function setPosition(idNode : Int, x : Float, y : Float) {
@@ -303,6 +307,9 @@ class ShaderGraph {
 		function convertToType(targetType: hxsl.Ast.Type, sourceExpr: TExpr) : TExpr {
 			var sourceType = sourceExpr.t;
 
+			if (sourceType.equals(targetType))
+				return sourceExpr;
+
 			var sourceSize = switch (sourceType) {
 				case TFloat: 1;
 				case TVec(size, VFloat): size;
@@ -383,7 +390,7 @@ class ShaderGraph {
 								var shParam = Std.downcast(currentNode.instance, ShaderParam);
 								if (shParam != null) {
 									var id = getNewVarId();
-									var outVar = {id: id, name: nodeVar.name, type: nodeVar.type, kind : Param, qualifiers: [SgInput]};
+									var outVar = {id: id, name: nodeVar.name, type: nodeVar.type, kind : Param, qualifiers: nodeVar.qualifiers.copy()};
 									replacement = {e: TVar(outVar), p:pos, t: nodeVar.type};
 									graphInputVars.push(outVar);
 									externs.push(outVar);

+ 2 - 1
hrt/shgraph/ShaderNode.hx

@@ -5,6 +5,7 @@ using hxsl.Ast;
 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 };
 
+@:autoBuild(hrt.shgraph.Macros.autoRegisterNode())
 @:keepSub
 class ShaderNode {
 
@@ -21,7 +22,7 @@ class ShaderNode {
 
 
 	public function getShaderDef() : ShaderGraph.ShaderNodeDef {
-		throw "Shouln't be called";
+		throw "getShaderDef is not defined for class " + Type.getClassName(Type.getClass(this));
 		return {expr: null, inVars: [], outVars: [], inits: [], externVars: []};
 	}
 

+ 5 - 1
hrt/shgraph/ShaderParam.hx

@@ -15,7 +15,11 @@ class ShaderParam extends ShaderNode {
 	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 qual = [SgInput];
+		if (this.variable.type == TSampler2D) {
+			qual.push(Sampler(this.variable.name));
+		}
+		var inVar : TVar = {name: this.variable.name, id:0, type: this.variable.type, kind: Param, qualifiers: qual};
 		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};
 

+ 11 - 1
hrt/shgraph/nodes/Sampler.hx

@@ -5,7 +5,17 @@ using hxsl.Ast;
 @name("Sampler")
 @description("Get color from texture and UV")
 @group("Property")
-class Sampler extends ShaderNode {
+class Sampler extends ShaderNodeHxsl {
+
+	static var SRC = {
+		@sginput var texture : Sampler2D;
+		@sginput var uv : Vec2;
+		@sgoutput var output : Vec4;
+
+		function fragment() {
+			output = texture.get(uv);
+		}
+	}
 
 	// @input("Texture") var texture = SType.Sampler;
 	// @input("UV") var uv = SType.Vec2;