Pavel Alexandrov 3 years ago
parent
commit
d95a4b1bf0
2 changed files with 38 additions and 25 deletions
  1. 36 24
      h2d/Graphics.hx
  2. 2 1
      h2d/impl/BatchDrawState.hx

+ 36 - 24
h2d/Graphics.hx

@@ -1,4 +1,5 @@
 package h2d;
+import h2d.impl.BatchDrawState;
 import hxd.Math;
 import hxd.impl.Allocator;
 
@@ -30,8 +31,9 @@ private class GraphicsContent extends h3d.prim.Primitive {
 
 	var tmp : hxd.FloatBuffer;
 	var index : hxd.IndexBuffer;
+	var state : BatchDrawState;
 
-	var buffers : Array<{ buf : hxd.FloatBuffer, vbuf : h3d.Buffer, idx : hxd.IndexBuffer, ibuf : h3d.Indexes }>;
+	var buffers : Array<{ buf : hxd.FloatBuffer, vbuf : h3d.Buffer, idx : hxd.IndexBuffer, ibuf : h3d.Indexes, state : BatchDrawState }>;
 	var bufferDirty : Bool;
 	var indexDirty : Bool;
 	#if track_alloc
@@ -40,6 +42,7 @@ private class GraphicsContent extends h3d.prim.Primitive {
 
 	public function new() {
 		buffers = [];
+		state = new BatchDrawState();
 		#if track_alloc
 		this.allocPos = new hxd.impl.AllocPos();
 		#end
@@ -47,6 +50,7 @@ private class GraphicsContent extends h3d.prim.Primitive {
 
 	public inline function addIndex(i) {
 		index.push(i);
+		state.add(1);
 		indexDirty = true;
 	}
 
@@ -62,13 +66,20 @@ private class GraphicsContent extends h3d.prim.Primitive {
 		bufferDirty = true;
 	}
 
+	public function setTile( tile : h2d.Tile ) {	
+		state.setTile(tile);	
+	}
+
 	public function next() {
 		var nvect = tmp.length >> 3;
 		if( nvect < 1 << 15 )
 			return false;
-		buffers.push( { buf : tmp, idx : index, vbuf : null, ibuf : null } );
+		buffers.push( { buf : tmp, idx : index, vbuf : null, ibuf : null, state: state } );
 		tmp = new hxd.FloatBuffer();
 		index = new hxd.IndexBuffer();
+		var tex = state.currentTexture;
+		state = new BatchDrawState();
+		state.setTexture(tex);
 		super.dispose();
 		return true;
 	}
@@ -89,12 +100,11 @@ private class GraphicsContent extends h3d.prim.Primitive {
 		indexDirty = false;
 	}
 
-	override function render( engine : h3d.Engine ) {
-		if (index.length <= 0) return ;
+	public function doRender( ctx : h2d.RenderContext ) {
+		if ( index.length == 0 ) return;
 		flush();
-		for( b in buffers )
-			engine.renderIndexed(b.vbuf, b.ibuf);
-		super.render(engine);
+		for ( b in buffers ) b.state.drawIndexed(ctx, b.vbuf, b.ibuf);
+		state.drawIndexed(ctx, buffer, indexes);
 	}
 
 	public function flush() {
@@ -121,6 +131,7 @@ private class GraphicsContent extends h3d.prim.Primitive {
 			if( b.ibuf != null ) Allocator.get().disposeIndexBuffer(b.ibuf);
 			b.vbuf = null;
 			b.ibuf = null;
+			b.state.clear();
 		}
 
 		if( buffer != null ) {
@@ -131,6 +142,7 @@ private class GraphicsContent extends h3d.prim.Primitive {
 			Allocator.get().disposeIndexBuffer(indexes);
 			indexes = null;
 		}
+		state.clear();
 
 		super.dispose();
 	}
@@ -250,7 +262,8 @@ class Graphics extends Drawable {
 		var last = pts.length - 1;
 		var prev = pts[last];
 		var p = pts[0];
-
+		
+		content.setTile(h2d.Tile.fromColor(0xFFFFFF));
 		var closed = p.x == prev.x && p.y == prev.y;
 		var count = pts.length;
 		if( !closed ) {
@@ -369,6 +382,7 @@ class Graphics extends Drawable {
 			prev = p;
 			p = next;
 		}
+		content.setTile(tile);
 	}
 
 	static var EARCUT = null;
@@ -431,6 +445,8 @@ class Graphics extends Drawable {
 	**/
 	public function beginFill( color : Int = 0, alpha = 1.  ) {
 		flush();
+		tile = h2d.Tile.fromColor(0xFFFFFF);
+		content.setTile(tile);
 		setColor(color,alpha);
 		doFill = true;
 	}
@@ -453,22 +469,18 @@ class Graphics extends Drawable {
 		Previous tile is remembered across `Graphics.clear` calls.
 	**/
 	public function beginTileFill( ?dx : Float, ?dy : Float, ?scaleX : Float, ?scaleY : Float, ?tile : h2d.Tile ) {
-		beginFill(0xFFFFFF);
-		if( dx == null ) dx = 0;
-		if( dy == null ) dy = 0;
-		if( tile != null ) {
-			if( this.tile != null && tile.getTexture() != this.tile.getTexture() ) {
-				var tex = this.tile.getTexture();
-				if( tex.width != 1 || tex.height != 1 )
-					throw "All tiles must be of the same texture";
-				this.tile = tile;
-			}
-			if( this.tile == null  )
-				this.tile = tile;
-		} else
+		if ( tile == null )
 			tile = this.tile;
-		if( tile == null )
+		if ( tile == null )
 			throw "Tile not specified";
+		flush();
+		this.tile = tile;
+		content.setTile(tile);
+		setColor(0xFFFFFF);
+		doFill = true;
+
+		if( dx == null ) dx = 0;
+		if( dy == null ) dy = 0;
 		if( scaleX == null ) scaleX = 1;
 		if( scaleY == null ) scaleY = 1;
 		dx -= tile.x;
@@ -832,8 +844,8 @@ class Graphics extends Drawable {
 	}
 
 	override function draw(ctx:RenderContext) {
-		if( !ctx.beginDrawObject(this, tile.getTexture()) ) return;
-		content.render(ctx.engine);
+		if( !ctx.beginDrawBatchState(this) ) return;
+		content.doRender(ctx);
 	}
 
 	override function sync(ctx:RenderContext) {

+ 2 - 1
h2d/impl/BatchDrawState.hx

@@ -53,7 +53,8 @@ class BatchDrawState {
 			if ( tail.texture == null ) tail.texture = texture;
 			else if ( tail.texture != texture ) {
 				var cur = tail;
-				if ( cur.next == null ) cur.next = tail = new StateEntry(texture);
+				if ( cur.count == 0 ) cur.set(texture);
+				else if ( cur.next == null ) cur.next = tail = new StateEntry(texture);
 				else tail = cur.next.set(texture);
 			}
 		}