Forráskód Böngészése

changed MeshBatch to allocate a single InstanceBuffer (require hldx 1.10)

Nicolas Cannasse 6 éve
szülő
commit
58730639ec
4 módosított fájl, 31 hozzáadás és 41 törlés
  1. 4 14
      h3d/impl/DirectXDriver.hx
  2. 9 12
      h3d/impl/GlDriver.hx
  3. 13 1
      h3d/impl/InstanceBuffer.hx
  4. 5 14
      h3d/scene/MeshBatch.hx

+ 4 - 14
h3d/impl/DirectXDriver.hx

@@ -125,9 +125,7 @@ class DirectXDriver extends h3d.impl.Driver {
 
 	public function new() {
 		window = @:privateAccess dx.Window.windows[0];
-		#if (hldx >= "1.6.0")
 		Driver.setErrorHandler(onDXError);
-		#end
 		reset();
 	}
 
@@ -182,9 +180,7 @@ class DirectXDriver extends h3d.impl.Driver {
 	}
 
 	override function dispose() {
-		#if (hldx >= "1.6.0")
 		Driver.disposeDriver(driver);
-		#end
 		driver = null;
 	}
 
@@ -653,12 +649,7 @@ class DirectXDriver extends h3d.impl.Driver {
 			var ref = st == null ? 0 : st.reference;
 			currentDepthState = depth;
 			currentStencilRef = ref;
-			#if (hldx < "1.7")
-			if( ref != 0 ) throw "DirectX Stencil support requires HL 1.7+";
-			Driver.omSetDepthStencilState(depth);
-			#else
 			Driver.omSetDepthStencilState(depth, ref);
-			#end
 		}
 
 		var rasterBits = bits & (Pass.culling_mask | SCISSOR_BIT | Pass.wireframe_mask);
@@ -1163,11 +1154,10 @@ class DirectXDriver extends h3d.impl.Driver {
 			currentIndex = ibuf;
 			dx.Driver.iaSetIndexBuffer(ibuf.res,ibuf.bits == 2,0);
 		}
-		#if (hldx >= "1.7")
-		dx.Driver.drawIndexedInstancedIndirect(commands.data, 0);
-		#else
-		throw "drawInstanced requires HL 1.7+";
-		#end
+		if( commands.data == null )
+			dx.Driver.drawIndexedInstanced(commands.indexCount, commands.commandCount, 0, 0, 0);
+		else
+			dx.Driver.drawIndexedInstancedIndirect(commands.data, 0);
 	}
 
 	static var COMPARE : Array<ComparisonFunc> = [

+ 9 - 12
h3d/impl/GlDriver.hx

@@ -193,7 +193,7 @@ class GlDriver extends Driver {
 		#if js
 		canvas = @:privateAccess hxd.Window.getInstance().canvas;
 		var options = {alpha:false,stencil:true,antialias:antiAlias>0};
-		if(ALLOW_WEBGL2) 
+		if(ALLOW_WEBGL2)
 			gl = cast canvas.getContext("webgl2",options);
 		if( gl == null )
 			gl = cast canvas.getContextWebGL(options);
@@ -1325,23 +1325,20 @@ class GlDriver extends Driver {
 			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.b);
 		}
 		#if !js
-		if( hasMultiIndirect ) {
+		if( hasMultiIndirect && commands.data != null ) {
 			gl.bindBuffer(GL2.DRAW_INDIRECT_BUFFER, commands.data);
-			if( ibuf.is32 )
-				gl.multiDrawElementsIndirect(drawMode, GL.UNSIGNED_INT, null, commands.commandCount, 0);
-			else
-				gl.multiDrawElementsIndirect(drawMode, GL.UNSIGNED_SHORT, null, commands.commandCount, 0);
+			gl.multiDrawElementsIndirect(drawMode, ibuf.is32 ? GL.UNSIGNED_INT : GL.UNSIGNED_SHORT, null, commands.commandCount, 0);
 			gl.bindBuffer(GL2.DRAW_INDIRECT_BUFFER, null);
 			return;
 		}
 		#end
 		var args : Array<Int> = commands.data;
-		var p = 0;
-		for( i in 0...Std.int(args.length/3) )
-			if( ibuf.is32 )
-				gl.drawElementsInstanced(drawMode, args[p++], GL.UNSIGNED_INT, args[p++], args[p++]);
-			else
-				gl.drawElementsInstanced(drawMode, args[p++], GL.UNSIGNED_SHORT, args[p++], args[p++]);
+		if( args != null ) {
+			var p = 0;
+			for( i in 0...Std.int(args.length/3) )
+				gl.drawElementsInstanced(drawMode, args[p++], ibuf.is32 ? GL.UNSIGNED_INT : GL.UNSIGNED_SHORT, args[p++], args[p++]);
+		} else
+			gl.drawElementsInstanced(drawMode, commands.indexCount, ibuf.is32 ? GL.UNSIGNED_INT : GL.UNSIGNED_SHORT, 0, commands.commandCount);
 	}
 
 	override function end() {

+ 13 - 1
h3d/impl/InstanceBuffer.hx

@@ -5,9 +5,19 @@ class InstanceBuffer {
 
 	var data : Dynamic;
 	var driver : h3d.impl.Driver;
+	public var indexCount(default,null) : Int = 0;
 	public var triCount(default,null) : Int = 0;
 	public var commandCount(default, null) : Int;
 
+	public function new() {
+	}
+
+	public function setCommand( commandCount : Int, indexCount : Int ) {
+		this.commandCount = commandCount;
+		this.indexCount = indexCount;
+		this.triCount = Std.int((commandCount * indexCount) / 3);
+	}
+
 	/**
 		Bytes are structures of 5 i32 with the following values:
 		- indexCount : number of indexes per instance
@@ -16,7 +26,8 @@ class InstanceBuffer {
 		- baseVertexLocation : offset in buffer
 		- startInstanceLocation : offset in per instance buffer
 	**/
-	public function new( commandCount : Int, bytes : haxe.io.Bytes ) {
+	public function setBuffer( commandCount : Int, bytes : haxe.io.Bytes ) {
+		dispose();
 
 		for( i in 0...commandCount ) {
 			var idxCount = bytes.getInt32(i * 20);
@@ -26,6 +37,7 @@ class InstanceBuffer {
 		}
 
 		this.commandCount = commandCount;
+		this.indexCount = 0;
 		driver = h3d.Engine.getCurrent().driver;
 		driver.allocInstanceBuffer(this, bytes);
 	}

+ 5 - 14
h3d/scene/MeshBatch.hx

@@ -25,11 +25,10 @@ class MeshBatch extends Mesh {
 	var instanced : h3d.prim.Instanced;
 	var curInstances : Int = 0;
 	var maxInstances : Int = 0;
-	var lastInstances : Int = 0;
 	var shaderInstances : Int = 0;
-	var commandBytes = haxe.io.Bytes.alloc(20);
 	var dataBuffer : h3d.Buffer;
 	var dataPasses : BatchData;
+	var indexCount : Int;
 	var modelViewID = hxsl.Globals.allocID("global.modelView");
 	var modelViewInverseID = hxsl.Globals.allocID("global.modelViewInverse");
 
@@ -46,11 +45,12 @@ class MeshBatch extends Mesh {
 
 	public function new( primitive, ?material, ?parent ) {
 		instanced = new h3d.prim.Instanced();
+		instanced.commands = new h3d.impl.InstanceBuffer();
 		instanced.setMesh(primitive);
 		super(instanced, material, parent);
 		for( p in this.material.getPasses() )
 			@:privateAccess p.batchMode = true;
-		commandBytes.setInt32(0, primitive.indexes == null ? primitive.triCount() * 3 : primitive.indexes.count);
+		indexCount = primitive.indexes == null ? primitive.triCount() * 3 : primitive.indexes.count;
 	}
 
 	override function onRemove() {
@@ -64,11 +64,7 @@ class MeshBatch extends Mesh {
 			dataPasses.buffer.dispose();
 			dataPasses = dataPasses.next;
 		}
-		if( instanced.commands != null ) {
-			instanced.commands.dispose();
-			instanced.commands = null;
-			lastInstances = 0;
-		}
+		instanced.commands.dispose();
 		shaderInstances = 0;
 		shadersChanged = true;
 	}
@@ -241,12 +237,7 @@ class MeshBatch extends Mesh {
 			p.buffer.uploadVector(p.data,0,curInstances * p.count);
 			p = p.next;
 		}
-		if( curInstances != lastInstances ) {
-			if( instanced.commands != null ) instanced.commands.dispose();
-			commandBytes.setInt32(4,curInstances);
-			instanced.commands = new h3d.impl.InstanceBuffer(1,commandBytes);
-			lastInstances = curInstances;
-		}
+		instanced.commands.setCommand(curInstances,indexCount);
 	}
 
 	override function emit(ctx:RenderContext) {