Nicolas Cannasse 7 лет назад
Родитель
Сommit
0e7364221d
4 измененных файлов с 46 добавлено и 5 удалено
  1. 40 0
      h3d/impl/GlDriver.hx
  2. 2 3
      h3d/prim/Instanced.hx
  3. 2 0
      hxsl/GlslOut.hx
  4. 2 2
      samples/ShaderAdvanced.hx

+ 40 - 0
h3d/impl/GlDriver.hx

@@ -14,6 +14,7 @@ private typedef GL = js.html.webgl.GL;
 private extern class GL2 extends js.html.webgl.GL {
 	// webgl2
 	function drawBuffers( buffers : Array<Int> ) : Void;
+	function drawElementsInstanced( mode : Int, count : Int, type : Int, offset : Int, instanceCount : Int) : Void;
 	function getUniformBlockIndex( p : Program, name : String ) : Int;
 	function bindBufferBase( target : Int, index : Int, buffer : js.html.webgl.Buffer ) : Void;
 	function uniformBlockBinding( p : Program, blockIndex : Int, blockBinding : Int ) : Void;
@@ -1210,6 +1211,45 @@ class GlDriver extends Driver {
 		gl.drawElements(GL.TRIANGLES, ntriangles * 3, GL.UNSIGNED_SHORT, startIndex * 2);
 	}
 
+	override function allocInstanceBuffer( b : InstanceBuffer, bytes : haxe.io.Bytes ) {
+		#if js
+		var data = [];
+		for( i in 0...b.commandCount ) {
+			var p = i * 5 * 4;
+			var indexCount = bytes.getInt32(p);
+			var instanceCount = bytes.getInt32(p+4);
+			var offIndex = bytes.getInt32(p+8);
+			var offVertex = bytes.getInt32(p+12);
+			var offInstance = bytes.getInt32(p+16);
+			if( offVertex != 0 || offInstance != 0 )
+				throw "baseVertex and baseInstance must be zero in JS";
+			data.push(indexCount);
+			data.push(offIndex);
+			data.push(instanceCount);
+		}
+		b.data = data;
+		#end
+	}
+
+	override function disposeInstanceBuffer(b:InstanceBuffer) {
+		b.data = null;
+	}
+
+	override function drawInstanced( ibuf : IndexBuffer, commands : InstanceBuffer ) {
+		if( ibuf != curIndexBuffer ) {
+			curIndexBuffer = ibuf;
+			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf);
+		}
+		#if js
+		var args : Array<Int> = commands.data;
+		var p = 0;
+		for( i in 0...Std.int(args.length/3) )
+			gl.drawElementsInstanced(GL.TRIANGLES, args[p++], GL.UNSIGNED_SHORT, args[p++], args[p++]);
+		#elseif (!hlsdl || hsdl >= "1.7")
+			throw "TODO";
+		#end
+	}
+
 	override function end() {
 		// no gl finish or flush !
 	}

+ 2 - 3
h3d/prim/Instanced.hx

@@ -3,7 +3,6 @@ package h3d.prim;
 class Instanced extends MeshPrimitive {
 
 	public var commands : h3d.impl.InstanceBuffer;
-	public var instanceBuffer : h3d.Buffer;
 
 	public function new() {
 	}
@@ -20,8 +19,8 @@ class Instanced extends MeshPrimitive {
 		}
 	}
 
-	public function defineBuffer( name, offset, isInst = false ) {
-		addBuffer(name, isInst ? instanceBuffer : buffer, offset);
+	public override function addBuffer( name, buffer, offset = 0 ) {
+		super.addBuffer(name, buffer, offset);
 	}
 
 	override function render( engine : h3d.Engine ) {

+ 2 - 0
hxsl/GlslOut.hx

@@ -25,6 +25,8 @@ class GlslOut {
 		m.set(ToBool, "bool");
 		m.set(LReflect, "reflect");
 		m.set(Mat3x4, "_mat3x4");
+		m.set(VertexID, "gl_VertexID");
+		m.set(InstanceID, "gl_InstanceID");
 		for( g in m )
 			KWDS.set(g, true);
 		m;

+ 2 - 2
samples/ShaderAdvanced.hx

@@ -159,8 +159,8 @@ class ShaderAdvanced extends hxd.App {
 			buf.push(i * 0.4);
 			buf.push(i * 0.2);
 		}
-		prim.instanceBuffer = h3d.Buffer.ofFloats(buf,2);
-		prim.defineBuffer("offset",0,true);
+		var instanceBuffer = h3d.Buffer.ofFloats(buf,2);
+		prim.addBuffer("offset",instanceBuffer);
 
 		var m = new h3d.scene.Mesh(prim, s3d);
 		m.material.mainPass.addShader(new InstancedOffsetShader());