Преглед изворни кода

finished hxsl v2 integration

ncannasse пре 12 година
родитељ
комит
b34d3f5c9a
7 измењених фајлова са 498 додато и 165 уклоњено
  1. 16 0
      h2d/Scene3D.hx
  2. 10 19
      h3d/Engine.hx
  3. 276 36
      h3d/Shader.hx
  4. 179 100
      h3d/impl/Macros.hx
  5. 5 0
      h3d/mat/MeshMaterial.hx
  6. 10 8
      h3d/mat/MeshTexture.hx
  7. 2 2
      h3d/scene/Mesh.hx

+ 16 - 0
h2d/Scene3D.hx

@@ -0,0 +1,16 @@
+package h2d;
+
+class Scene3D extends Sprite {
+	
+	public var scene : h3d.scene.Scene;
+	
+	public function new( scene, ?parent ) {
+		super(parent);
+		this.scene = scene;
+	}
+	
+	override function draw( engine ) {
+		scene.render(engine);
+	}
+	
+}

+ 10 - 19
h3d/Engine.hx

@@ -21,7 +21,7 @@ class Engine {
 	public var fullScreen(default, set) : Bool;
 
 	var curMatBits : Int;
-	var curShader : Shader.ShaderData;
+	var curShader : Shader.ShaderInstance;
 	var curBuffer : h3d.impl.MemoryManager.BigBuffer;
 	var curAttributes : Int;
 	var curTextures : Array<h3d.mat.Texture>;
@@ -85,42 +85,33 @@ class Engine {
 	}
 
 	public function selectShader( shader : Shader ) {
-		var s = shader.getData();
+		var s = shader.getInstance();
 		if( s.program == null ) {
 			s.program = ctx.createProgram();
-			var vdata = shader.getVertexProgram().getData();
-			var fdata = shader.getFragmentProgram().getData();
+			var vdata = s.vertexBytes.getData();
+			var fdata = s.fragmentBytes.getData();
 			vdata.endian = flash.utils.Endian.LITTLE_ENDIAN;
 			fdata.endian = flash.utils.Endian.LITTLE_ENDIAN;
 			s.program.upload(vdata,fdata);
 		}
 		if( s != curShader ) {
 			ctx.setProgram(s.program);
-			// changing the program is so much costly that reuploading the variables should not make big difference anyway
-			s.vertexVarsChanged = true;
-			s.fragmentVarsChanged = true;
+			s.varsChanged = true;
 			// unbind extra textures
 			var tcount : Int = s.textures.length;
 			while( curTextures.length > tcount ) {
 				curTextures.pop();
 				ctx.setTextureAt(curTextures.length, null);
 			}
-			s.texturesChanged = true;
 			// force remapping of vertex buffer
-			if( curShader == null || s.bufferFormat != curShader.bufferFormat || s.stride != curShader.stride )
+			if( curShader == null || s.bufferFormat != curShader.bufferFormat /*|| s.stride != curShader.stride*/ )
 				curBuffer = null;
 			curShader = s;
 		}
-		if( s.vertexVarsChanged ) {
-			s.vertexVarsChanged = false;
+		if( s.varsChanged ) {
+			s.varsChanged = false;
 			ctx.setProgramConstantsFromVector(flash.display3D.Context3DProgramType.VERTEX, 0, s.vertexVars);
-		}
-		if( s.fragmentVarsChanged ) {
-			s.fragmentVarsChanged = false;
 			ctx.setProgramConstantsFromVector(flash.display3D.Context3DProgramType.FRAGMENT, 0, s.fragmentVars);
-		}
-		if( s.texturesChanged ) {
-			s.texturesChanged = false;
 			for( i in 0...s.textures.length ) {
 				var t = s.textures[i];
 				if( t == null )
@@ -291,7 +282,7 @@ class Engine {
 		drawTriangles = 0;
 		drawCalls = 0;
 		curMatBits = -1;
-		curShader = null;
+//		curShader = null;
 		curBuffer = null;
 		curProjMatrix = null;
 		curTextures = [];
@@ -300,7 +291,7 @@ class Engine {
 
 	function reset() {
 		curMatBits = -1;
-		curShader = null;
+//		curShader = null;
 		curBuffer = null;
 		curProjMatrix = null;
 		for( i in 0...curAttributes )

+ 276 - 36
h3d/Shader.hx

@@ -1,68 +1,308 @@
 package h3d;
+import hxsl.Data.Tools;
 
 typedef FixedArray<T,Const> = Array<T>;
 
-typedef ShaderInfos = {
-	var stride : Int;
-	var format : Int;
-	var vertex : Array<Float>;
-	var fragment : Array<Float>;
-	var textures : Int;
-}
+class ShaderInstance {
 
-class ShaderData {
+	public var bits : Int;
 	
 	public var program : flash.display3D.Program3D;
-	public var stride(default, null) : Int;
-	public var bufferFormat(default, null) : Int;
-	
-	public var vertexVarsChanged : Bool;
-	public var fragmentVarsChanged : Bool;
-	public var texturesChanged : Bool;
+
+	public var bufferFormat : Int;
+	public var stride : Int;
+
 	public var vertexVars : flash.Vector<Float>;
 	public var fragmentVars : flash.Vector<Float>;
 	public var textures : flash.Vector<h3d.mat.Texture>;
+
+	public var vertexMap : flash.Vector<Int>;
+	public var fragmentMap : flash.Vector<Int>;
+	public var textureMap : flash.Vector<Int>;
+	
+	public var vertexBytes : haxe.io.Bytes;
+	public var fragmentBytes : haxe.io.Bytes;
+	
+	public var varsChanged : Bool;
+	
+	public function new() {
+	}
+	
+	public function updateVars( allVars : flash.Vector<Float>, allTex : flash.Vector<h3d.mat.Texture> ) {
+		varsChanged = true;
+		for( i in 0...vertexMap.length )
+			vertexVars[i] = allVars[vertexMap[i]];
+		for( i in 0...fragmentMap.length )
+			fragmentVars[i] = allVars[fragmentMap[i]];
+		for( i in 0...textureMap.length )
+			textures[i] = allTex[textureMap[i]];
+	}
+	
+}
+
+class ShaderGlobals {
+	
+	var data : hxsl.Data;
+	var instances : IntHash<ShaderInstance>;
+	var hparams : IntHash<hxsl.Data.Variable>;
+	public var allSize : Int;
+	public var texSize : Int;
+	
+	public function new( hxStr : String ) {
+		this.data = hxsl.Unserialize.unserialize(hxStr);
+		
+		hparams = new IntHash();
+		allSize = 0;
+		for( v in Tools.getAllVars(data) )
+			switch( v.kind ) {
+			case VConst, VParam:
+				if( v.type != TBool ) {
+					v.index = allSize;
+					allSize += hxsl.Data.Tools.floatSize(v.type);
+					hparams.set(v.id, v);
+				}
+			case VTexture:
+				v.index = texSize++;
+				hparams.set(v.id, v);
+			default:
+			}
+		allSize++; // last 0
+		
+		instances = new IntHash();
+	}
+	
+	function build( code : hxsl.Data.Code ) {
+			
+		// init map
+		var nregs = 0;
+		var map = new flash.Vector();
+		for( v in code.args ) {
+			var realV = hparams.get(v.id);
+			if( v == null ) throw "assert " + v.name;
+			var size = Tools.floatSize(v.type);
+			for( i in 0...size )
+				map.push(realV.index + i);
+			var regs = Tools.regSize(v.type);
+			nregs += regs;
+			for( i in size...regs * 4 )
+				map.push(allSize - 1);
+		}
+		
+		// add consts
+		var pos = nregs * 4;
+		nregs += code.consts.length;
+		var consts = new flash.Vector(nregs * 4);
+		for( c in code.consts ) {
+			for( v in c )
+				consts[pos++] = v;
+			for( i in c.length...4 )
+				consts[pos++] = 1.;
+		}
+		
+		var agal = new hxsl.AgalCompiler().compile(code);
+		var o = new haxe.io.BytesOutput();
+		new format.agal.Writer(o).write(agal);
+		return { bytes : o.getBytes(), consts : consts, map : map };
+	}
 	
-	public function new( infos : ShaderInfos ) {
-		this.stride = infos.stride;
-		this.bufferFormat = infos.format;
-		this.vertexVars = flash.Vector.ofArray(infos.vertex);
-		this.fragmentVars = flash.Vector.ofArray(infos.fragment);
-		this.textures = new flash.Vector(infos.textures);
+	public function getInstance( bits : Int ) {
+		var i = instances.get(bits);
+		if( i != null )
+			return i;
+		var r = new hxsl.RuntimeCompiler();
+		var consts = { };
+		var constCount = 0;
+		for( v in Tools.getAllVars(data) )
+			if( v.kind == VConst ) {
+				if( bits & (1 << constCount) != 0 ) {
+					var c : Dynamic;
+					if( v.type == TBool ) c = true else c = 0;
+					Reflect.setField(consts, v.name, c);
+				}
+				constCount++;
+			}
+		
+		var data2 = r.compile(data, consts);
+		i = new ShaderInstance();
+		i.bits = bits;
+		
+		var v = build(data2.vertex);
+		i.vertexBytes = v.bytes;
+		i.vertexMap = v.map;
+		i.vertexVars = v.consts;
+		
+		var f = build(data2.fragment);
+		i.fragmentBytes = f.bytes;
+		i.fragmentMap = f.map;
+		i.fragmentVars = f.consts;
+				
+		i.textureMap = new flash.Vector();
+		for( v in data2.vertex.tex.concat(data2.fragment.tex) ) {
+			if( v.kind != VTexture ) throw "assert";
+			var realV = hparams.get(v.id);
+			i.textureMap.push(realV.index);
+		}
+		i.textures = new flash.Vector(i.textureMap.length);
+		
+		
+		i.bufferFormat = 0;
+		i.stride = 0;
+		for( v in data2.globals )
+			switch( v.kind ) {
+			case VInput:
+				var size = Tools.floatSize(v.type);
+				switch( v.type ) {
+				case TInt:
+					// 0
+				case TFloat, TFloat2, TFloat3, TFloat4:
+					i.bufferFormat |= Tools.floatSize(v.type) << (3 * v.index);
+				default:
+					throw "Type not supported in input " + Type.enumConstructor(v.type).substr(1);
+				}
+				i.stride += size;
+			case VVar:
+				// ignore
+			default:
+				throw "assert " + v.kind;
+			}
+
+
+		instances.set(bits, i);
+		
+		return i;
 	}
 	
 }
 
+
 @:autoBuild(h3d.impl.Macros.buildShader())
 class Shader {
-	
-	var data : ShaderData;
+
+	var globals : ShaderGlobals;
+	var modified : Bool;
+	var constBits : Int;
+	var allParams : flash.Vector<Float>;
+	var allTextures : flash.Vector<h3d.mat.Texture>;
+	var instance : ShaderInstance;
 	
 	public function new() {
-		data = new ShaderData(getShaderInfos());
+		var c : { HXSL : String, GLOBALS : ShaderGlobals } = cast Type.getClass(this);
+		globals = c.GLOBALS;
+		if( globals == null ) {
+			globals = new ShaderGlobals(c.HXSL);
+			c.GLOBALS = globals;
+		}
+		allParams = new flash.Vector(globals.allSize);
+		allTextures = new flash.Vector(globals.texSize);
 	}
 	
-	public inline function getData() {
-		return data;
+	function updateParams() {
+		throw "assert"; // will be overriden in subclass
 	}
 	
-	public function getShaderInfos() : ShaderInfos {
-		throw "assert";
-		return null;
+	public function getInstance() : ShaderInstance {
+		if( instance == null || instance.bits != constBits )
+			instance = globals.getInstance(constBits);
+		if( modified )
+			updateParams();
+		instance.updateVars(allParams, allTextures);
+		return instance;
 	}
 	
-	public function getVertexProgram() : haxe.io.Bytes {
-		throw "assert";
-		return null;
+	inline function loadMatrixT( index : Int, r : Int, c : Int ) {
+		var m = new h3d.Matrix();
+		m.identity();
+		
+		var pos = index;
+		m._11 = allParams[pos++];
+		if( c > 1 ) m._21 = allParams[pos++];
+		if( c > 2 ) m._31 = allParams[pos++];
+		if( c > 3 ) m._41 = allParams[pos++];
+
+		if( r > 1 ) {
+			m._12 = allParams[pos++];
+			if( c > 1 ) m._22 = allParams[pos++];
+			if( c > 2 ) m._32 = allParams[pos++];
+			if( c > 3 ) m._42 = allParams[pos++];
+
+			if( r > 2 ) {
+				m._13 = allParams[pos++];
+				if( c > 1 ) m._23 = allParams[pos++];
+				if( c > 2 ) m._33 = allParams[pos++];
+				if( c > 3 ) m._43 = allParams[pos++];
+
+				if( r > 3 ) {
+					m._14 = allParams[pos++];
+					if( c > 1 ) m._24 = allParams[pos++];
+					if( c > 2 ) m._34 = allParams[pos++];
+					if( c > 3 ) m._44 = allParams[pos++];
+				}
+			}
+		}
+		
+		return m;
 	}
+	
+	inline function saveMatrixT( index : Int, m : h3d.Matrix, r : Int, c : Int ) {
+		var pos = index;
+		allParams[pos++] = m._11;
+		if( c > 1 ) allParams[pos++] = m._21;
+		if( c > 2 ) allParams[pos++] = m._31;
+		if( c > 3 ) allParams[pos++] = m._41;
+		
+		if( r > 1 ) {
+			allParams[pos++] = m._12;
+			if( c > 1 ) allParams[pos++] = m._22;
+			if( c > 2 ) allParams[pos++] = m._32;
+			if( c > 3 ) allParams[pos++] = m._42;
 
-	public function getFragmentProgram() : haxe.io.Bytes {
-		throw "assert";
-		return null;
+			if( r > 2 ) {
+				allParams[pos++] = m._13;
+				if( c > 1 ) allParams[pos++] = m._23;
+				if( c > 2 ) allParams[pos++] = m._33;
+				if( c > 3 ) allParams[pos++] = m._43;
+
+				if( r > 3 ) {
+					allParams[pos++] = m._14;
+					if( c > 1 ) allParams[pos++] = m._24;
+					if( c > 2 ) allParams[pos++] = m._34;
+					if( c > 3 ) allParams[pos++] = m._44;
+				}
+			}
+		}
+	}
+	
+	inline function loadFloats( index : Int, n : Int ) {
+		var v = new h3d.Vector();
+		var pos = index;
+		v.x = allParams[pos++];
+		v.y = allParams[pos++];
+		if( n > 2 ) v.z = allParams[pos++];
+		if( n > 3 ) v.w = allParams[pos++];
+		return v;
+	}
+
+	inline function saveFloats( index : Int, v : h3d.Vector, n : Int ) {
+		allParams[index] = v.x;
+		allParams[index + 1] = v.y;
+		if( n > 2 ) allParams[index + 2] = v.z;
+		if( n > 3 ) allParams[index + 3] = v.w;
+		return v;
+	}
+	
+	inline function saveInt( index : Int, v : Int ) {
+		allParams[index] = ((v >> 16) & 0xFF) / 255;
+		allParams[index + 1] = ((v >> 8) & 0xFF) / 255;
+		allParams[index + 2] = (v & 0xFF) / 255;
+		allParams[index + 3] = (v >>> 24) / 255;
+	}
+	
+	inline function saveFloat( index : Int, v : Float ) {
+		allParams[index] = v;
 	}
 	
-	public function dispose() {
-		if( data.program != null ) data.program.dispose();
+	inline function setConstFlag( n : Int, v : Bool ) {
+		if( v ) constBits |= 1 << n else constBits &= ~(1 << n);
 	}
 	
 	public function toString() {

+ 179 - 100
h3d/impl/Macros.hx

@@ -64,145 +64,224 @@ class Macros {
 			kind : FVar(null,{ expr : EConst(CString(hxsl.Serialize.serialize(data))), pos : pos }),
 			access : [AStatic],
 			pos : pos,
+			meta : [ { name:":keep", params : [], pos : pos } ],
+		});
+		fields.push( {
+			name : "GLOBALS",
+			kind : FVar(macro : h3d.Shader.ShaderGlobals),
+			access : [AStatic],
+			pos : pos,
+			meta : [ { name:":keep", params : [], pos : pos } ],
 		});
 		
 		// create all the variables accessors
-		var allVars = data.globals.concat(data.vertex.args).concat(data.fragment.args);
-		for( v in data.vertex.tex.concat(data.fragment.tex) )
-			allVars.push(v);
+		var allVars = Tools.getAllVars(data);
+		var constCount = 0, virtualIndex = 0, texCount = 0, updates = [];
+		
 		for( v in allVars ) {
+			var pos = v.pos;
 			switch( v.kind ) {
 			case VConst, VParam:
+				
+				v.index = virtualIndex;
+				if( v.type != TBool )
+					virtualIndex += Tools.floatSize(v.type);
+				
+				var t = realType(v.type, pos);
 				fields.push( {
 					name : v.name,
-					kind : FProp("never", "set", realType(v.type, v.pos)),
-					pos : v.pos,
+					kind : FProp("get", "set", t),
+					pos : pos,
 					access : [APublic],
 				});
-				/*
-				fields.push({
-					name : "get_" + v.name,
-					kind : FFun({
-					}),
-					pos : v.pos,
-					access : [AInline],
+				fields.push( {
+					name : v.name+"_",
+					kind : FVar(t),
+					pos : pos,
+					access : [],
 				});
+
+				var ev = { expr : EConst(CIdent("v")), pos : pos };
+				var evar = { expr : EConst(CIdent(v.name + "_")), pos : pos };
+				
+				var set = [
+					macro modified = true,
+					{ expr : EBinop(OpAssign,evar, ev), pos : pos },
+				];
+				if( v.name == "m2pos" )
+					trace(v.name+" "+v.kind);
+				if( v.kind == VConst ) {
+					if( constCount == 32 )
+						Context.error("Too many constants for this shader (max 32)", Context.currentPos());
+					var chk = v.type == TBool ? ev : { expr : EBinop(OpNotEq, ev, { expr : EConst(CIdent("null")), pos : pos } ), pos : pos };
+					var count = { expr : EConst(CInt(""+constCount)), pos : pos };
+					set.push(macro setConstFlag($count, $chk));
+					constCount++;
+				}
+				set.push(macro return v);
 				fields.push( {
 					name : "set_" + v.name,
 					kind : FFun( {
-						ret : null,
-						params : [ { ]],
-						expr :
+						ret : t,
+						params : [],
+						args : [{ name : "v",  type : t, opt : false }],
+						expr : {
+							expr : EBlock(set),
+							pos : pos,
+						},
+					}),
+					pos : pos,
+					access : [],
+				});
+				
+				var get = [];
+				switch( v.type ) {
+				case TInt, TFloat, TBool: // no allocation required
+				default:
+					function loadType( t : VarType, eindex, rec = 0 ) {
+						var args = [{ expr : eindex, pos : pos }];
+						var name = switch( t ) {
+						case TBool, TNull, TTexture(_): throw "assert";
+						case TInt: "Int";
+						case TFloat: "Float";
+						case TFloat2, TFloat3, TFloat4:
+							args.push( { expr : EConst(CInt(Tools.floatSize(v.type) + "")), pos : pos } );
+							"Floats";
+						case TMatrix(r, c, t):
+							args.push( { expr : EConst(CInt(r + "")), pos : pos } );
+							args.push( { expr : EConst(CInt(c + "")), pos : pos } );
+							if( t.t ) "MatrixT" else "Matrix";
+						case TArray(t, size):
+							var vi = "i" + rec;
+							var ei = { expr : EConst(CIdent(vi)), pos : pos };
+							var esize = { expr : EConst(CInt(size + "")), pos : pos };
+							var stride = Tools.regSize(t);
+							var load = loadType(t, EBinop(OpAdd, { expr : eindex, pos : pos }, { expr : EBinop(OpMult, { expr : EConst(CIdent(vi)), pos : pos }, { expr : EConst(CInt(stride + "")), pos : pos } ), pos : pos } ), rec + 1);
+							return macro {
+								var a = [];
+								for( $ei in 0...$esize )
+									a.push($load);
+								a;
+							}
+						}
+						return { expr : ECall( { expr : EConst(CIdent("load" + name)), pos : pos }, args), pos : pos };
+					}
+					var load = loadType(v.type, EConst(CInt(v.index + "")));
+					get.push(macro if( $evar == null ) { $evar = $load; modified = true; });
+				}
+				get.push(macro return $evar);
+				
+				if( v.type != TBool ) {
+					function saveType( t : VarType, eindex, evar, rec = 0 ) {
+						var args = [{ expr : eindex, pos : pos }, evar];
+						var name = switch( t ) {
+						case TBool, TNull, TTexture(_): throw "assert";
+						case TInt: "Int";
+						case TFloat: "Float";
+						case TFloat2, TFloat3, TFloat4:
+							args.push( { expr : EConst(CInt(Tools.floatSize(v.type) + "")), pos : pos } );
+							"Floats";
+						case TMatrix(r, c, t):
+							args.push( { expr : EConst(CInt(r + "")), pos : pos } );
+							args.push( { expr : EConst(CInt(c + "")), pos : pos } );
+							if( t.t ) "MatrixT" else "Matrix";
+						case TArray(t, size):
+							var vi = "i" + rec, vk = "k" + rec;
+							var ei = { expr : EConst(CIdent(vi)), pos : pos };
+							var ek = { expr : EConst(CIdent(vk)), pos : pos };
+							var esize = { expr : EConst(CInt(size + "")), pos : pos };
+							var stride = Tools.regSize(t);
+							var save = saveType(
+								t,
+								EBinop(OpAdd, { expr : eindex, pos : pos }, { expr : EBinop(OpMult, { expr : EConst(CIdent(vi)), pos : pos }, { expr : EConst(CInt(stride + "")), pos : pos } ), pos : pos } ),
+								ek,
+								rec + 1
+							);
+							return macro {
+								for( $ei in 0...$esize ) {
+									var $vk = $evar[$ei];
+									if( $ek == null ) break;
+									$save;
+								}
+							}
+						}
+						return { expr : ECall( { expr : EConst(CIdent("save" + name)), pos : pos }, args), pos : pos };
+					}
+					var save = saveType(v.type, EConst(CInt(v.index + "")), evar);
+					switch( v.type ) {
+					case TFloat, TInt:
+						updates.push(save);
+					default:
+						updates.push(macro if( $evar != null ) { $save; $evar = null; });
+					}
+				}
+				
+				fields.push({
+					name : "get_" + v.name,
+					kind : FFun( {
+						ret : t,
+						params : [],
+						args : [],
+						expr : { expr : EBlock(get), pos : pos },
 					}),
 					pos : v.pos,
-					access : [AInline],
+					access : [],
 				});
-				*/
+				
 			case VTexture:
+				var t = realType(v.type, pos);
+				var tid = { expr : EConst(CInt("" + texCount++)), pos : pos };
+				
 				fields.push( {
 					name : v.name,
-					kind : FProp("never", "set", realType(v.type, v.pos)),
-					pos : v.pos,
+					kind : FProp("get","set",t),
+					pos : pos,
 					access : [APublic],
 				});
-				/*
-				fields.push( {
+				
+				fields.push({
+					name : "get_" + v.name,
+					kind : FFun( {
+						ret : t,
+						params : [],
+						args : [],
+						expr : macro return allTextures[$tid],
+					}),
+					pos : v.pos,
+					access : [AInline],
+				});
+
+				fields.push({
 					name : "set_" + v.name,
-					kind : FFun({
+					kind : FFun( {
+						ret : t,
+						params : [],
+						args : [{ name : "v", type : t, opt : false }],
+						expr : macro { allTextures[$tid] = v; return v; },
 					}),
 					pos : v.pos,
 					access : [AInline],
 				});
-				*/
+			
 			case VInput, VVar, VOut:
 				// skip
 			default:
-				Context.warning(v.name, v.pos);
+				Context.warning(v.name, pos);
 				throw "assert";
 			}
 		}
 		
-		
-		
-		/*
-		var stride = 0;
-		var fmt = 0;
-		var pos = 0;
-		for( i in v ) {
-			function add(size) {
-				fmt |= size << (pos * 3);
-				pos++;
-				stride += size;
-			}
-			function addType(t:VarType) {
-				switch( t ) {
-				case TMatrix(r, c, t):
-					if( t.t ) {
-						var tmp = r;
-						r = c;
-						c = tmp;
-					}
-					for( i in 0...r )
-						add(c);
-				case TInt:
-					add(0);
-					stride++;
-				case TFloat: add(1);
-				case TFloat2: add(2);
-				case TFloat3: add(3);
-				case TFloat4: add(4);
-				case TArray(t, size):
-					for( i in 0...size )
-						addType(t);
-				case TTexture(_): throw "assert";
-				}
-			}
-			addType(i.type);
-		}
-		var max = 8;
-		if( pos > max )
-			Context.error("This shader uses to many input components, only " + max + " are allowed by Flash11", v.vertex.pos);
-		
-		var vvars = makeShaderVars(v.vertex,fields);
-		var fvars = makeShaderVars(v.fragment, fields);
-		
-		fields.push( {
-			name : "getShaderInfos",
-			pos : cl.pos,
-			access : [APublic,AOverride],
+		fields.push({
+			name : "updateParams",
 			kind : FFun( {
+				ret : null,
 				args : [],
 				params : [],
-				expr : Context.parse("return {stride:" + stride + ",format:"+fmt+",vertex:"+vvars+",fragment:"+fvars+",textures:"+v.fragment.tex.length+"}", cl.pos),
-				ret : TPath({ sub : "ShaderInfos", name : "Shader", pack : ["h3d"], params : [] }),
-			}),
-		});
-		
-		var tbytes = TPath( { pack : ["haxe", "io"], name : "Bytes", params : [] } );
-		fields.push( {
-			name : "getVertexProgram",
-			pos : cl.pos,
-			access : [APublic, AOverride],
-			kind : FFun( {
-				args : [],
-				params : [],
-				expr : Context.parse("return haxe.Unserializer.run('" + vsbytes + "')", cl.pos),
-				ret : tbytes,
-			}),
-		});
-		fields.push( {
-			name : "getFragmentProgram",
-			pos : cl.pos,
-			access : [APublic, AOverride],
-			kind : FFun( {
-				args : [],
-				params : [],
-				expr : Context.parse("return haxe.Unserializer.run('" + fsbytes + "')", cl.pos),
-				ret : tbytes,
+				expr : { expr : EBlock(updates), pos : pos },
 			}),
+			access : [AOverride],
+			pos : pos,
 		});
-		*/
-		
 		
 		return fields;
 	}

+ 5 - 0
h3d/mat/MeshMaterial.hx

@@ -2,6 +2,11 @@ package h3d.mat;
 
 class MeshMaterial extends Material {
 	
+	// make constructor private (is abstract class)
+	function new(shader) {
+		super(shader);
+	}
+	
 	public function setMatrixes( mpos : h3d.Matrix, mproj : h3d.Matrix ) {
 		throw "Not implemented";
 	}

+ 10 - 8
h3d/mat/MeshTexture.hx

@@ -11,20 +11,22 @@ private class MeshShader extends h3d.Shader {
 		
 		var tuv : Float2;
 		
-		var useMatrixPos : Bool;
 		var uvScale : Float2;
 		var uvDelta : Float2;
 		
 		function vertex( mpos : Matrix, mproj : Matrix ) {
-			out = if( useMatrixPos ) (pos.xyzw * mpos) * mproj else pos.xyzw * mproj;
-			var t = uv;
+			out = if( mpos != null ) (pos.xyzw * mpos) * mproj else pos.xyzw * mproj;
+			var t = uv + 0.0001;
 			if( uvScale != null ) t *= uvScale;
 			if( uvDelta != null ) t += uvDelta;
 			tuv = t;
 		}
 		
-		function fragment( tex : Texture, killAlpha : Bool, colorDelta : Float4, colorMult : Float4, colorMatrix : M44 ) {
-			var c = tex.get(tuv.xy);
+		var killAlpha : Bool;
+		var texNearest : Bool;
+		
+		function fragment( tex : Texture, colorDelta : Float4, colorMult : Float4, colorMatrix : M44 ) {
+			var c = tex.get(tuv.xy,filter=!(killAlpha || texNearest));
 			if( killAlpha ) kill(c.a - 0.001);
 			if( colorDelta != null ) c += colorDelta;
 			if( colorMult != null ) c = c * colorMult;
@@ -48,8 +50,8 @@ class MeshTexture extends MeshMaterial {
 
 	public var killAlpha(get,set) : Bool;
 
-	public var colorDelta(get,set) : Null<h3d.Color>;
-	public var colorMult(get,set) : Null<h3d.Color>;
+	public var colorDelta(get,set) : Null<h3d.Vector>;
+	public var colorMult(get,set) : Null<h3d.Vector>;
 	public var colorMatrix(get,set) : Null<h3d.Matrix>;
 	
 	public function new(texture) {
@@ -58,7 +60,7 @@ class MeshTexture extends MeshMaterial {
 		this.texture = texture;
 		useMatrixPos = true;
 	}
-	
+		
 	public override function setMatrixes( mpos, mproj ) {
 		mshader.mpos = useMatrixPos ? mpos : null;
 		mshader.mproj = mproj;

+ 2 - 2
h3d/scene/Mesh.hx

@@ -1,9 +1,9 @@
 package h3d.scene;
 
-class Mesh extends Object {
+class Mesh<M:h3d.mat.MeshMaterial> extends Object {
 
 	public var primitive : h3d.prim.Primitive;
-	public var material : h3d.mat.MeshMaterial;
+	public var material : M;
 	
 	public function new( prim, mat, ?parent ) {
 		super(parent);