Explorar o código

Merge heaps main

Nicolas Cannasse %!s(int64=11) %!d(string=hai) anos
pai
achega
dd49bea807
Modificáronse 7 ficheiros con 56 adicións e 37 borrados
  1. 1 5
      h3d/mat/Material.hx
  2. 6 1
      h3d/mat/Pass.hx
  3. 24 21
      h3d/pass/Base.hx
  4. 4 0
      h3d/scene/RenderContext.hx
  5. 10 10
      h3d/scene/Skin.hx
  6. 5 0
      hxsl/Cache.hx
  7. 6 0
      hxsl/RuntimeShader.hx

+ 1 - 5
h3d/mat/Material.hx

@@ -74,11 +74,7 @@ class Material {
 		#if debug
 		if( Type.getClass(m) != Type.getClass(this) ) throw this + " is missing clone()";
 		#end
-		var p = passes;
-		while( p != null ) {
-			m.addPass(p.clone());
-			p = p.nextPass;
-		}
+		// DO NOT clone passes (it's up to the superclass to recreate the shaders)
 		m.castShadows = castShadows;
 		m.receiveShadows = receiveShadows;
 		return m;

+ 6 - 1
h3d/mat/Pass.hx

@@ -14,6 +14,11 @@ class Pass {
 	var nextPass : Pass;
 
 	public var enableLights : Bool;
+	/**
+		Inform the pass system that the parameters will be modified in object draw() command,
+		so they will be manually uploaded by calling RenderContext.uploadParams.
+	**/
+	public var dynamicParameters : Bool;
 
 	@:bits public var culling : Face;
 	@:bits public var depthWrite : Bool;
@@ -26,7 +31,7 @@ class Pass {
 	@:bits public var blendAlphaOp : Operation;
 	@:bits(4) public var colorMask : Int;
 
-	public function new(name, shaders, ?parent) {
+	public function new(name, ?shaders, ?parent) {
 		this.parentPass = parent;
 		this.shaders = shaders;
 		setPassName(name);

+ 24 - 21
h3d/pass/Base.hx

@@ -41,17 +41,6 @@ class Base {
 		return manager.compileShaders(p.getShadersRec());
 	}
 
-	function initBuffer( s : hxsl.RuntimeShader, shaders : hxsl.ShaderList ) {
-		if( cachedBuffer == null )
-			cachedBuffer = new h3d.shader.Buffers(s);
-		else
-			cachedBuffer.grow(s);
-		var buf = cachedBuffer;
-		manager.fillGlobals(buf, s);
-		manager.fillParams(buf, s, shaders);
-		return buf;
-	}
-
 	@:access(h3d.scene)
 	function setupShaders( passes : Object ) {
 		var p = passes;
@@ -76,6 +65,12 @@ class Base {
 		return 0;
 	}
 
+	function uploadParams() {
+		manager.fillParams(cachedBuffer, ctx.drawPass.shader, ctx.drawPass.shaders);
+		ctx.engine.uploadShaderBuffers(cachedBuffer, Params);
+		ctx.engine.uploadShaderBuffers(cachedBuffer, Textures);
+	}
+
 	@:access(h3d.scene)
 	public function draw( ctx : h3d.scene.RenderContext, passes : Object ) {
 		this.ctx = ctx;
@@ -84,21 +79,29 @@ class Base {
 		setGlobals();
 		setupShaders(passes);
 		passes = haxe.ds.ListSort.sortSingleLinked(passes, sortByShader);
+		ctx.uploadParams = uploadParams;
 		var p = passes;
-		var curShaderID = -1;
+		var buf = cachedBuffer, prevShader = null;
 		while( p != null ) {
 			globalModelView = p.obj.absPos;
-			//if( p.shader.hasGlobal(globalModelViewInverseId) )
-			globalModelViewInverse = p.obj.getInvPos();
-			ctx.engine.selectShader(p.shader);
-			var buf = initBuffer(p.shader, p.shaders);
-			ctx.engine.selectMaterial(p.pass);
-			if( p.shader.id != curShaderID ) {
-				curShaderID = p.shader.id;
+			if( p.shader.hasGlobal(globalModelViewInverse_id.toInt()) )
+				globalModelViewInverse = p.obj.getInvPos();
+			if( prevShader != p.shader ) {
+				prevShader = p.shader;
+				ctx.engine.selectShader(p.shader);
+				ctx.engine.selectMaterial(p.pass);
+				if( buf == null )
+					buf = cachedBuffer = new h3d.shader.Buffers(p.shader);
+				else
+					buf.grow(p.shader);
+				manager.fillGlobals(buf, p.shader);
 				ctx.engine.uploadShaderBuffers(buf, Globals);
 			}
-			ctx.engine.uploadShaderBuffers(buf, Params);
-			ctx.engine.uploadShaderBuffers(buf, Textures);
+			if( !p.pass.dynamicParameters ) {
+				manager.fillParams(buf, p.shader, p.shaders);
+				ctx.engine.uploadShaderBuffers(buf, Params);
+				ctx.engine.uploadShaderBuffers(buf, Textures);
+			}
 			ctx.drawPass = p;
 			p.obj.draw(ctx);
 			p = p.next;

+ 4 - 0
h3d/scene/RenderContext.hx

@@ -13,6 +13,8 @@ class RenderContext {
 
 	public var sharedGlobals : Map<Int,Dynamic>;
 
+	public var uploadParams : Void -> Void;
+
 	var pool : ObjectPass;
 	var passes : ObjectPass;
 	var lights : Light;
@@ -38,6 +40,7 @@ class RenderContext {
 		drawPass = null;
 		passes = null;
 		lights = null;
+		uploadParams = null;
 		time += elapsedTime;
 		frame++;
 	}
@@ -62,6 +65,7 @@ class RenderContext {
 
 	public function done() {
 		drawPass = null;
+		uploadParams = null;
 		// move passes to pool, and erase data
 		var p = passes, prev = null;
 		while( p != null ) {

+ 10 - 10
h3d/scene/Skin.hx

@@ -120,8 +120,10 @@ class Skin extends MultiMaterial {
 		primitive = s.primitive;
 		skinShader = new h3d.shader.Skin();
 		for( m in materials )
-			if( m != null )
+			if( m != null ) {
 				m.mainPass.addShader(skinShader);
+				if( skinData.splitJoints != null ) m.mainPass.dynamicParameters = true;
+			}
 		currentRelPose = [];
 		currentAbsPose = [];
 		currentPalette = [];
@@ -156,7 +158,7 @@ class Skin extends MultiMaterial {
 				if( bid >= 0 )
 					currentPalette[bid].multiply3x4(j.transPos, m);
 			}
-			paletteChanged = true;
+			skinShader.bonesMatrixes = currentPalette;
 			if( jointsAbsPosInv != null ) jointsAbsPosInv._44 = 0; // mark as invalid
 			jointsUpdated = false;
 		} else
@@ -165,16 +167,14 @@ class Skin extends MultiMaterial {
 
 	override function draw( ctx : RenderContext ) {
 		if( splitPalette == null ) {
-			if( paletteChanged ) {
-				paletteChanged = false;
-				skinShader.bonesMatrixes = currentPalette;
-			}
 			super.draw(ctx);
 		} else {
-			var i = ctx.drawPass.index;
-			skinShader.bonesMatrixes = splitPalette[i];
-			primitive.selectMaterial(i);
-			super.draw(ctx);
+			for( i in 0...splitPalette.length ) {
+				skinShader.bonesMatrixes = splitPalette[i];
+				primitive.selectMaterial(i);
+				ctx.uploadParams();
+				primitive.render(ctx.engine);
+			}
 		}
 		if( showJoints )
 			throw "TODO"; //ctx.addPass(drawJoints);

+ 5 - 0
hxsl/Cache.hx

@@ -89,6 +89,11 @@ class Cache {
 		r.vertex = flattenShader(s.vertex, Vertex, paramVars);
 		r.vertex.vertex = true;
 		r.fragment = flattenShader(s.fragment, Fragment, paramVars);
+		r.globals = new Map();
+		for( v in r.vertex.globals )
+			r.globals.set(v.gid, true);
+		for( v in r.fragment.globals )
+			r.globals.set(v.gid, true);
 		c.linked = r;
 		return r;
 	}

+ 6 - 0
hxsl/RuntimeShader.hx

@@ -48,9 +48,15 @@ class RuntimeShader {
 	public var id : Int;
 	public var vertex : RuntimeShaderData;
 	public var fragment : RuntimeShaderData;
+	public var globals : Map<Int,Bool>;
 
 	public function new() {
 		id = UID++;
 	}
 
+	public inline function hasGlobal( gid : Int ) {
+		return globals.exists(gid);
+	}
+
+
 }