Browse Source

added shader extends and @:import syntax.

Nicolas Cannasse 11 years ago
parent
commit
b04d8c1f48
7 changed files with 69 additions and 36 deletions
  1. 1 13
      h3d/pass/Copy.hx
  2. 1 12
      h3d/shader/Blur.hx
  3. 21 0
      h3d/shader/ScreenShader.hx
  4. 1 1
      hxsl/Ast.hx
  5. 31 8
      hxsl/Checker.hx
  6. 8 1
      hxsl/MacroParser.hx
  7. 6 1
      hxsl/Macros.hx

+ 1 - 13
h3d/pass/Copy.hx

@@ -1,22 +1,10 @@
 package h3d.pass;
 
-private class CopyShader extends hxsl.Shader {
+private class CopyShader extends h3d.shader.ScreenShader {
 
 	static var SRC = {
-		@input var input : {
-			position : Vec2,
-			uv : Vec2,
-		};
-		var output : {
-			position : Vec4,
-			color : Vec4,
-		};
-
 		@param var texture : Sampler2D;
 
-		function vertex() {
-			output.position = vec4(input.position, 0, 1);
-		}
 		function fragment() {
 			output.color = texture.get(input.uv);
 		}

+ 1 - 12
h3d/shader/Blur.hx

@@ -1,16 +1,8 @@
 package h3d.shader;
 
-class Blur extends hxsl.Shader {
+class Blur extends ScreenShader {
 
 	static var SRC = {
-		@input var input : {
-			position : Vec2,
-			uv : Vec2,
-		};
-		var output : {
-			position : Vec4,
-			color : Vec4,
-		};
 
 		@param var texture : Sampler2D;
 		@param @const var Quality : Int;
@@ -18,9 +10,6 @@ class Blur extends hxsl.Shader {
 		@param var values : Array<Float,Quality>;
 		@param var pixel : Vec2;
 
-		function vertex() {
-			output.position = vec4(input.position, 0, 1);
-		}
 		function fragment() {
 			if( isDepth ) {
 				var val = 0.;

+ 21 - 0
h3d/shader/ScreenShader.hx

@@ -0,0 +1,21 @@
+package h3d.shader;
+
+class ScreenShader extends hxsl.Shader {
+
+	static var SRC = {
+		@input var input : {
+			position : Vec2,
+			uv : Vec2,
+		};
+
+		var output : {
+			position : Vec4,
+			color : Vec4,
+		};
+
+		function vertex() {
+			output.position = vec4(input.position, 0, 1);
+		}
+	};
+
+}

+ 1 - 1
hxsl/Ast.hx

@@ -178,7 +178,7 @@ enum TGlobal {
 	Cross;
 	Normalize;
 	//Faceforward;
-	//Reflect;
+	LReflect;
 	//Refract;
 	//MatrixCompMult;
 	//Any;

+ 31 - 8
hxsl/Checker.hx

@@ -43,6 +43,8 @@ class Checker {
 			case Radians, Degrees, Cos, Sin, Tan, Asin, Acos, Exp, Log, Exp2, Log2, Sqrt, Inversesqrt, Abs, Sign, Floor, Ceil, Fract: genFloat;
 			case Atan: genFloat.concat(genFloat2);
 			case Pow: genFloat2;
+			case LReflect:
+				genFloat2;
 			case Mod, Min, Max:
 				genFloat2.concat(genWithFloat);
 			case Saturate:
@@ -109,6 +111,8 @@ class Checker {
 		}
 		globals.set("int", globals.get("toInt"));
 		globals.set("float", globals.get("toFloat"));
+		globals.set("reflect", globals.get("lReflect"));
+		globals.remove("lReflect");
 		globals.remove("toInt");
 		globals.remove("toFloat");
 	}
@@ -127,7 +131,7 @@ class Checker {
 		inLoop = false;
 
 		var funs = [];
-		checkExpr(shader, funs);
+		checkExpr(shader, funs, false, false);
 		var tfuns = [];
 		for( f in funs ) {
 			var pos = f.p, f = f.f;
@@ -508,15 +512,18 @@ class Checker {
 		}
 	}
 
-	function checkExpr( e : Expr, funs : Array<{ f : FunDecl, p : Position }>, isIncluded = false ) {
+	function checkExpr( e : Expr, funs : Array<{ f : FunDecl, p : Position, inherit : Bool }>, isImport, isExtends ) {
 		switch( e.expr ) {
 		case EBlock(el):
 			for( e in el )
-				checkExpr(e,funs, isIncluded);
+				checkExpr(e,funs, isImport, isExtends);
 		case EFunction(f):
-			if( isIncluded )
+			if( isImport )
 				return;
-			funs.push({ f : f, p : e.pos });
+			for( f2 in funs )
+				if( f2.f.name == f.name && f2.inherit )
+					funs.remove(f2);
+			funs.push({ f : f, p : e.pos, inherit : isExtends });
 		case EVars(vl):
 			for( v in vl ) {
 				if( v.kind == null ) {
@@ -532,11 +539,11 @@ class Checker {
 				if( v.type == null ) error("Type required for variable declaration", e.pos);
 				if( vars.exists(v.name) ) error("Duplicate var decl '" + v.name + "'", e.pos);
 				var v = makeVar(v, e.pos);
-				if( isIncluded && (v.kind == Param || v.kind == Var) )
+				if( isImport && (v.kind == Param || v.kind == Var) )
 					continue;
 				vars.set(v.name, v);
 			}
-		case ECall( { expr : EIdent("include") }, [e]):
+		case ECall( { expr : EIdent("import") }, [e]):
 			var path = [];
 			function loop( e : Expr ) {
 				switch( e.expr ) {
@@ -550,7 +557,23 @@ class Checker {
 			var sexpr = null;
 			try sexpr = loadShader(path.join(".")) catch( err : Dynamic ) error(Std.string(err), e.pos);
 			if( sexpr != null )
-				checkExpr(sexpr, funs, true);
+				checkExpr(sexpr, funs, true, isExtends);
+		case ECall( { expr : EIdent("extends") }, [e]):
+			var path = [];
+			function loop( e : Expr ) {
+				switch( e.expr ) {
+				case EIdent(n): path.push(n);
+				case EField(e, f): loop(e); path.push(f);
+				case EConst(CString(s)): path.push(s);
+				default:
+					error("Should be a shader type path", e.pos);
+				}
+			}
+			loop(e);
+			var sexpr = null;
+			try sexpr = loadShader(path.join(".")) catch( err : Dynamic ) error(Std.string(err), e.pos);
+			if( sexpr != null )
+				checkExpr(sexpr, funs, isImport, true);
 		default:
 			error("This expression is not allowed at shader declaration level", e.pos);
 		}

+ 8 - 1
hxsl/MacroParser.hx

@@ -122,7 +122,14 @@ class MacroParser {
 					applyMeta(m, v);
 				e2.expr;
 			default:
-				error("Qualifier only supported before 'var'", e.pos);
+				switch( m.name ) {
+				case ":extends":
+					ECall({ expr : EIdent("extends"), pos : m.pos }, [e2]);
+				case ":import":
+					ECall({ expr : EIdent("import"), pos : m.pos }, [e2]);
+				default:
+					error("Qualifier only supported before 'var'", e.pos);
+				}
 			}
 		case EVars(vl):
 			EVars([for( v in vl ) {

+ 6 - 1
hxsl/Macros.hx

@@ -254,7 +254,12 @@ class Macros {
 					Context.getLocalClass().get().meta.add(":src", [expr], pos);
 					try {
 						var shader = new MacroParser().parseExpr(expr);
-						var name = Std.string(Context.getLocalClass());
+						var c = Context.getLocalClass();
+						var sup = Std.string(c.get().superClass.t);
+						// add auto extends
+						if( sup != "hxsl.Shader" )
+							shader = { expr : EBlock([ { expr : ECall( { expr : EIdent("extends"), pos : pos }, [ { expr : EConst(CString(sup)), pos : pos } ]), pos : pos }, shader]), pos : pos };
+						var name = Std.string(c);
 						var check = new Checker();
 						check.loadShader = loadShader;
 						var shader = check.check(name,shader);