Browse Source

added 32 bits indexes support

ncannasse 7 years ago
parent
commit
30536731ae

+ 3 - 1
h3d/Indexes.hx

@@ -6,11 +6,13 @@ class Indexes {
 
 	var mem : h3d.impl.MemoryManager;
 	var ibuf : h3d.impl.Driver.IndexBuffer;
+	public var is32(default,null) : Bool;
 	public var count(default,null) : Int;
 
-	public function new(count) {
+	public function new(count,is32=false) {
 		this.mem = h3d.Engine.getCurrent().mem;
 		this.count = count;
+		this.is32 = is32;
 		mem.allocIndexes(this);
 	}
 

+ 13 - 12
h3d/impl/DirectXDriver.hx

@@ -309,13 +309,14 @@ class DirectXDriver extends h3d.impl.Driver {
 		return { res : res, count : m.size, stride : m.stride };
 	}
 
-	override function allocIndexes( count : Int ) : IndexBuffer {
-		var res = dx.Driver.createBuffer(count << 1, Default, IndexBuffer, None, None, 0, null);
+	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
+		var bits = is32 ? 2 : 1;
+		var res = dx.Driver.createBuffer(count << bits, Default, IndexBuffer, None, None, 0, null);
 		if( res == null ) return null;
-		return { res : res, count : count };
+		return { res : res, count : count, bits : bits  };
 	}
 
-	override function allocDepthBuffer(b:h3d.mat.DepthBuffer):DepthBuffer {
+	override function allocDepthBuffer( b : h3d.mat.DepthBuffer ) : DepthBuffer {
 		var depthDesc = new Texture2dDesc();
 		depthDesc.width = b.width;
 		depthDesc.height = b.height;
@@ -452,12 +453,12 @@ class DirectXDriver extends h3d.impl.Driver {
 
 	override function uploadIndexBuffer(i:IndexBuffer, startIndice:Int, indiceCount:Int, buf:hxd.IndexBuffer, bufPos:Int) {
 		if( hasDeviceError ) return;
-		updateBuffer(i.res, hl.Bytes.getArray(buf.getNative()).offset(bufPos << 1), startIndice << 1, indiceCount << 1);
+		updateBuffer(i.res, hl.Bytes.getArray(buf.getNative()).offset(bufPos << i.bits), startIndice << i.bits, indiceCount << i.bits);
 	}
 
 	override function uploadIndexBytes(i:IndexBuffer, startIndice:Int, indiceCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
 		if( hasDeviceError ) return;
-		updateBuffer(i.res, @:privateAccess buf.b.offset(bufPos << 1), startIndice << 1, indiceCount << 1);
+		updateBuffer(i.res, @:privateAccess buf.b.offset(bufPos << i.bits), startIndice << i.bits, indiceCount << i.bits);
 	}
 
 	override function uploadVertexBuffer(v:VertexBuffer, startVertex:Int, vertexCount:Int, buf:hxd.FloatBuffer, bufPos:Int) {
@@ -471,16 +472,16 @@ class DirectXDriver extends h3d.impl.Driver {
 	}
 
 	override function readIndexBytes(v:IndexBuffer, startIndice:Int, indiceCount:Int, buf:haxe.io.Bytes, bufPos:Int) {
-		var tmp = dx.Driver.createBuffer(indiceCount << 1, Staging, None, CpuRead | CpuWrite, None, 0, null);
-		box.left = startIndice << 1;
+		var tmp = dx.Driver.createBuffer(indiceCount << v.bits, Staging, None, CpuRead | CpuWrite, None, 0, null);
+		box.left = startIndice << v.bits;
 		box.top = 0;
 		box.front = 0;
-		box.right = (startIndice + indiceCount) << 1;
+		box.right = (startIndice + indiceCount) << v.bits;
 		box.bottom = 1;
 		box.back = 1;
 		tmp.copySubresourceRegion(0, 0, 0, 0, v.res, 0, box);
 		var ptr = tmp.map(0, Read, true, null);
-		@:privateAccess buf.b.blit(bufPos, ptr, 0, indiceCount << 1);
+		@:privateAccess buf.b.blit(bufPos, ptr, 0, indiceCount << v.bits);
 		tmp.unmap(0);
 		tmp.release();
 	}
@@ -1099,7 +1100,7 @@ class DirectXDriver extends h3d.impl.Driver {
 			return;
 		if( currentIndex != ibuf ) {
 			currentIndex = ibuf;
-			dx.Driver.iaSetIndexBuffer(ibuf.res,false,0);
+			dx.Driver.iaSetIndexBuffer(ibuf.res,ibuf.bits == 2,0);
 		}
 		dx.Driver.drawIndexed(ntriangles * 3, startIndex, 0);
 	}
@@ -1118,7 +1119,7 @@ class DirectXDriver extends h3d.impl.Driver {
 			return;
 		if( currentIndex != ibuf ) {
 			currentIndex = ibuf;
-			dx.Driver.iaSetIndexBuffer(ibuf.res,false,0);
+			dx.Driver.iaSetIndexBuffer(ibuf.res,ibuf.bits == 2,0);
 		}
 		#if (hldx >= "1.7")
 		dx.Driver.drawIndexedInstancedIndirect(commands.data, 0);

+ 5 - 5
h3d/impl/Driver.hx

@@ -7,7 +7,7 @@ typedef Texture = flash.display3D.textures.TextureBase;
 typedef DepthBuffer = {};
 typedef Query = {};
 #elseif js
-typedef IndexBuffer = js.html.webgl.Buffer;
+typedef IndexBuffer = { b : js.html.webgl.Buffer, is32 : Bool };
 typedef VertexBuffer = { b : js.html.webgl.Buffer, stride : Int #if multidriver, driver : Driver #end };
 typedef Texture = { t : js.html.webgl.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int #if multidriver, driver : Driver #end };
 typedef DepthBuffer = { r : js.html.webgl.Renderbuffer #if multidriver, driver : Driver #end };
@@ -25,19 +25,19 @@ typedef Texture = { t : lime.graphics.opengl.GLTexture, width : Int, height : In
 typedef DepthBuffer = { r : lime.graphics.opengl.GLRenderbuffer };
 typedef Query = {};
 #elseif hlsdl
-typedef IndexBuffer = sdl.GL.Buffer;
+typedef IndexBuffer = { b : sdl.GL.Buffer, is32 : Bool };
 typedef VertexBuffer = { b : sdl.GL.Buffer, stride : Int };
 typedef Texture = { t : sdl.GL.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int };
 typedef DepthBuffer = { r : sdl.GL.Renderbuffer };
 typedef Query = { q : sdl.GL.Query, kind : QueryKind };
 #elseif usegl
-typedef IndexBuffer = haxe.GLTypes.Buffer;
+typedef IndexBuffer = { b : haxe.GLTypes.Buffer, is32 : Bool };
 typedef VertexBuffer = { b : haxe.GLTypes.Buffer, stride : Int };
 typedef Texture = { t : haxe.GLTypes.Texture, width : Int, height : Int, internalFmt : Int, pixelFmt : Int, bits : Int, bind : Int };
 typedef DepthBuffer = { r : haxe.GLTypes.Renderbuffer };
 typedef Query = { q : haxe.GLTypes.Query, kind : QueryKind };
 #elseif hldx
-typedef IndexBuffer = { res : dx.Resource, count : Int };
+typedef IndexBuffer = { res : dx.Resource, count : Int, bits : Int };
 typedef VertexBuffer = { res : dx.Resource, count : Int, stride : Int };
 typedef Texture = { res : dx.Resource, view : dx.Driver.ShaderResourceView, rt : Array<dx.Driver.RenderTargetView>, mips : Int };
 typedef DepthBuffer = { res : dx.Resource, view : dx.Driver.DepthStencilView };
@@ -237,7 +237,7 @@ class Driver {
 		return null;
 	}
 
-	public function allocIndexes( count : Int ) : IndexBuffer {
+	public function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
 		return null;
 	}
 

+ 30 - 21
h3d/impl/GlDriver.hx

@@ -941,16 +941,14 @@ class GlDriver extends Driver {
 		return { b : b, stride : m.stride #if multidriver, driver : this #end };
 	}
 
-	override function allocIndexes( count : Int ) : IndexBuffer {
+	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
 		var b = gl.createBuffer();
+		var size = is32 ? 4 : 2;
 		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, b);
 		#if js
-		gl.bufferData(GL.ELEMENT_ARRAY_BUFFER, count * 2, GL.STATIC_DRAW);
+		gl.bufferData(GL.ELEMENT_ARRAY_BUFFER, count * size, GL.STATIC_DRAW);
 		#elseif hl
-		gl.bufferDataSize(GL.ELEMENT_ARRAY_BUFFER, count * 2, GL.STATIC_DRAW);
-		#else
-		var tmp = new Uint16Array(count);
-		gl.bufferData(GL.ELEMENT_ARRAY_BUFFER, tmp, GL.STATIC_DRAW);
+		gl.bufferDataSize(GL.ELEMENT_ARRAY_BUFFER, count * size, GL.STATIC_DRAW);
 		#end
 		var outOfMem = gl.getError() == GL.OUT_OF_MEMORY;
 		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, null);
@@ -959,7 +957,7 @@ class GlDriver extends Driver {
 			gl.deleteBuffer(b);
 			return null;
 		}
-		return b;
+		return { b : b, is32 : is32 };
 	}
 
 	override function disposeTexture( t : h3d.mat.Texture ) {
@@ -973,7 +971,7 @@ class GlDriver extends Driver {
 	}
 
 	override function disposeIndexes( i : IndexBuffer ) {
-		gl.deleteBuffer(i);
+		gl.deleteBuffer(i.b);
 	}
 
 	override function disposeVertexes( v : VertexBuffer ) {
@@ -1127,27 +1125,29 @@ class GlDriver extends Driver {
 	}
 
 	override function uploadIndexBuffer( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : hxd.IndexBuffer, bufPos : Int ) {
-		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, i);
+		var bits = i.is32 ? 2 : 1;
+		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, i.b);
 		#if hl
 		var data = #if hl hl.Bytes.getArray(buf.getNative()) #else buf.getNative() #end;
-		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice * 2, streamData(data,bufPos*2,indiceCount*2), bufPos * 2 * STREAM_POS, indiceCount * 2);
+		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice << bits, streamData(data,bufPos << bits,indiceCount << bits), (bufPos << bits) * STREAM_POS, indiceCount << bits);
 		#else
 		var buf = new Uint16Array(buf.getNative());
-		var sub = new Uint16Array(buf.buffer, bufPos * 2, indiceCount);
-		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice * 2, sub);
+		var sub = new Uint16Array(buf.buffer, bufPos << bits, indiceCount);
+		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice << bits, sub);
 		#end
 		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, null);
 		curIndexBuffer = null;
 	}
 
 	override function uploadIndexBytes( i : IndexBuffer, startIndice : Int, indiceCount : Int, buf : haxe.io.Bytes , bufPos : Int ) {
-		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, i);
+		var bits = i.is32 ? 2 : 1;
+		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, i.b);
 		#if hl
-		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice * 2, streamData(buf.getData(),bufPos * 2, indiceCount * 2), bufPos * 2 * STREAM_POS, indiceCount * 2);
+		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice << bits, streamData(buf.getData(),bufPos << bits, indiceCount << bits), (bufPos << bits) * STREAM_POS, indiceCount << bits);
 		#else
 		var buf = bytesToUint8Array(buf);
-		var sub = new Uint8Array(buf.buffer, bufPos * 2, indiceCount * 2);
-		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice * 2, sub);
+		var sub = new Uint8Array(buf.buffer, bufPos << bits, indiceCount << bits);
+		gl.bufferSubData(GL.ELEMENT_ARRAY_BUFFER, startIndice << bits, sub);
 		#end
 		gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, null);
 		curIndexBuffer = null;
@@ -1229,9 +1229,12 @@ class GlDriver extends Driver {
 	override function draw( ibuf : IndexBuffer, startIndex : Int, ntriangles : Int ) {
 		if( ibuf != curIndexBuffer ) {
 			curIndexBuffer = ibuf;
-			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf);
+			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.b);
 		}
-		gl.drawElements(GL.TRIANGLES, ntriangles * 3, GL.UNSIGNED_SHORT, startIndex * 2);
+		if( ibuf.is32 )
+			gl.drawElements(GL.TRIANGLES, ntriangles * 3, GL.UNSIGNED_INT, startIndex * 4);
+		else
+			gl.drawElements(GL.TRIANGLES, ntriangles * 3, GL.UNSIGNED_SHORT, startIndex * 2);
 	}
 
 	override function allocInstanceBuffer( b : InstanceBuffer, bytes : haxe.io.Bytes ) {
@@ -1267,16 +1270,22 @@ class GlDriver extends Driver {
 	override function drawInstanced( ibuf : IndexBuffer, commands : InstanceBuffer ) {
 		if( ibuf != curIndexBuffer ) {
 			curIndexBuffer = ibuf;
-			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf);
+			gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, ibuf.b);
 		}
 		#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++]);
+			if( ibuf.is32 )
+				gl.drawElementsInstanced(GL.TRIANGLES, args[p++], GL.UNSIGNED_INT, args[p++], args[p++]);
+			else
+				gl.drawElementsInstanced(GL.TRIANGLES, args[p++], GL.UNSIGNED_SHORT, args[p++], args[p++]);
 		#elseif (!hlsdl || hlsdl >= "1.7")
 		gl.bindBuffer(GL2.DRAW_INDIRECT_BUFFER, commands.data);
-		gl.multiDrawElementsIndirect(GL.TRIANGLES, GL.UNSIGNED_SHORT, null, commands.commandCount, 0);
+		if( ibuf.is32 )
+			gl.multiDrawElementsIndirect(GL.TRIANGLES, GL.UNSIGNED_INT, null, commands.commandCount, 0);
+		else
+			gl.multiDrawElementsIndirect(GL.TRIANGLES, GL.UNSIGNED_SHORT, null, commands.commandCount, 0);
 		gl.bindBuffer(GL2.DRAW_INDIRECT_BUFFER, null);
 		#end
 	}

+ 3 - 3
h3d/impl/LogDriver.hx

@@ -301,9 +301,9 @@ class LogDriver extends Driver {
 		return d.allocTexture(t);
 	}
 
-	override function allocIndexes( count : Int ) : IndexBuffer {
-		log('AllocIndexes $count');
-		return d.allocIndexes(count);
+	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
+		log('AllocIndexes $count $is32');
+		return d.allocIndexes(count,is32);
 	}
 
 	override function allocVertexes( m : ManagedBuffer ) : VertexBuffer {

+ 3 - 3
h3d/impl/MemoryManager.hx

@@ -216,14 +216,14 @@ class MemoryManager {
 		indexes.remove(i);
 		driver.disposeIndexes(i.ibuf);
 		i.ibuf = null;
-		usedMemory -= i.count * 2;
+		usedMemory -= i.count * (i.is32 ? 4 : 2);
 	}
 
 	@:allow(h3d.Indexes)
 	function allocIndexes( i : Indexes ) {
-		i.ibuf = driver.allocIndexes(i.count);
+		i.ibuf = driver.allocIndexes(i.count,i.is32);
 		indexes.push(i);
-		usedMemory += i.count * 2;
+		usedMemory += i.count * (i.is32 ? 4 : 2);
 	}
 
 

+ 1 - 1
h3d/impl/NullDriver.hx

@@ -54,7 +54,7 @@ class NullDriver extends Driver {
 		return cast {};
 	}
 
-	override function allocIndexes( count : Int ) : IndexBuffer {
+	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
 		return cast {};
 	}
 

+ 3 - 1
h3d/impl/Stage3dDriver.hx

@@ -250,7 +250,9 @@ class Stage3dDriver extends Driver {
 		return new VertexWrapper(v, buf);
 	}
 
-	override function allocIndexes( count : Int ) : IndexBuffer {
+	override function allocIndexes( count : Int, is32 : Bool ) : IndexBuffer {
+		if( is32 )
+			throw "32 bit indexes are not supported";
 		try {
 			return ctx.createIndexBuffer(count);
 		} catch( e : flash.errors.Error ) {

+ 10 - 1
samples/ShaderAdvanced.hx

@@ -142,7 +142,8 @@ class ShaderAdvanced extends hxd.App {
 
 		var prim = new h3d.prim.Instanced();
 		var bytes = new haxe.io.BytesOutput();
-		bytes.writeInt32(cube.triCount() * 3);
+		var icount = cube.triCount() * 3;
+		bytes.writeInt32(icount);
 		bytes.writeInt32(16);
 		bytes.writeInt32(0);
 		bytes.writeInt32(0);
@@ -165,6 +166,14 @@ class ShaderAdvanced extends hxd.App {
 		var m = new h3d.scene.Mesh(prim, s3d);
 		m.material.mainPass.addShader(new InstancedOffsetShader());
 		m.material.shadows = false;
+
+		// 32 bits indices
+		var bytes = haxe.io.Bytes.alloc(icount * 4);
+		for( i in 0...icount )
+			bytes.setInt32(i<<2,i);
+		var indexes = new h3d.Indexes(icount,true);
+		indexes.uploadBytes(bytes,0,icount);
+		prim.indexes = indexes;
 	}
 
 	override function update(dt:Float) {