2
0
Эх сурвалжийг харах

Add selfShaders to h3d.mat.Pass. Fix mesh batch shaders added twice.

clementlandrin 2 жил өмнө
parent
commit
910ff9e71f
2 өөрчлөгдсөн 72 нэмэгдсэн , 11 устгасан
  1. 71 10
      h3d/mat/Pass.hx
  2. 1 1
      h3d/scene/MeshBatch.hx

+ 71 - 10
h3d/mat/Pass.hx

@@ -13,6 +13,9 @@ class Pass {
 	var bits : Int = 0;
 	var parentPass : Pass;
 	var parentShaders : hxsl.ShaderList;
+	var selfShaders(default, null) : hxsl.ShaderList;
+	var selfShadersChanged(default, null) : Bool;
+	var selfShadersCache : hxsl.ShaderList;
 	var shaders : hxsl.ShaderList;
 	var nextPass : Pass;
 
@@ -170,6 +173,13 @@ class Pass {
 		return s;
 	}
 
+	public function addSelfShader<T:hxsl.Shader>(s:T) : T {
+		if ( s == null ) return null;
+		selfShadersChanged = true;
+		selfShaders = hxsl.ShaderList.addSort(s, selfShaders);
+		return s;
+	}
+
 	/**
 		Can be used for internal usage
 	**/
@@ -212,6 +222,19 @@ class Pass {
 			prev = sl;
 			sl = sl.next;
 		}
+		sl = selfShaders;
+		prev = null;
+		while ( sl != null ) {
+			if ( sl.s == s ) {
+				if ( prev == null )
+					selfShaders = sl.next;
+				else
+					prev.next = sl.next;
+				return true;
+			}
+			prev = sl;
+			sl = sl.next;
+		}
 		return false;
 	}
 
@@ -228,11 +251,28 @@ class Pass {
 				prev = sl;
 			sl = sl.next;
 		}
+		sl = selfShaders;
+		prev = null;
+		while( sl != null ) {
+			if( hxd.impl.Api.isOfType(sl.s, t) ) {
+				if( prev == null )
+					selfShaders = sl.next;
+				else
+					prev.next = sl.next;
+			}
+			else
+				prev = sl;
+			sl = sl.next;
+		}
 	}
 
 	public function getShader< T:hxsl.Shader >(t:Class<T>) : T {
-		var s = shaders;
-		while( s != parentShaders ) {
+		var s = _getShader(t, shaders);
+		return s != null ? s : _getShader(t, selfShaders);
+	}
+
+	function _getShader< T:hxsl.Shader >(t:Class<T>, s : hxsl.ShaderList) : T {
+		while( s != null && s != parentShaders ) {
 			var sh = hxd.impl.Api.downcast(s.s, t);
 			if( sh != null )
 				return sh;
@@ -242,11 +282,15 @@ class Pass {
 	}
 
 	public function getShaderByName( name : String ) : hxsl.Shader {
-		var s = shaders;
-		while( s != parentShaders ) {
-			if( @:privateAccess s.s.shader.data.name == name )
-				return s.s;
-			s = s.next;
+		var s = _getShaderByName(name, shaders);
+		return s != null ? s : _getShaderByName(name, selfShaders);
+	}
+
+	function _getShaderByName( name : String, sl : hxsl.ShaderList ) : hxsl.Shader {
+		while( sl != null && sl != parentShaders ) {
+			if( @:privateAccess sl.s.shader.data.name == name )
+				return sl.s;
+			sl = sl.next;
 		}
 		return null;
 	}
@@ -255,9 +299,25 @@ class Pass {
 		return shaders.iterateTo(parentShaders);
 	}
 
-	function getShadersRec() {
-		if( parentPass == null || parentShaders == parentPass.shaders )
+	function selfShadersRec(rebuild : Bool) {
+		if ( selfShaders == null )
 			return shaders;
+		if ( !selfShadersChanged && !rebuild && shaders == selfShadersCache )
+			return selfShaders;
+		var sl = selfShaders, prev = null;
+		while ( sl != null && sl != selfShadersCache ) {
+			prev = sl;
+			sl = sl.next;
+		}
+		selfShadersCache = shaders;
+		prev.next = selfShadersCache;
+		return selfShaders;
+	}
+
+	function getShadersRec() {
+		if( parentPass == null || parentShaders == parentPass.shaders ) {
+			return selfShadersRec(false);
+		}
 		// relink to our parent shader list
 		var s = shaders, prev = null;
 		while( s != null && s != parentShaders ) {
@@ -269,11 +329,12 @@ class Pass {
 			shaders = parentShaders;
 		else
 			prev.next = parentShaders;
-		return shaders;
+		return selfShadersRec(true);
 	}
 
 	public function clone() {
 		var p = new Pass(name, shaders.clone());
+		p.selfShaders = selfShaders;
 		p.bits = bits;
 		p.enableLights = enableLights;
 		if (stencil != null) p.stencil = stencil.clone();

+ 1 - 1
h3d/scene/MeshBatch.hx

@@ -157,7 +157,7 @@ class MeshBatch extends MultiMaterial {
 		// add batch shaders
 		var p = dataPasses;
 		while( p != null ) {
-			p.pass.addShader(p.shader);
+			p.pass.addSelfShader(p.shader);
 			p = p.next;
 		}
 	}