Browse Source

cleanup, fixed problem with partial update

ncannasse 9 năm trước cách đây
mục cha
commit
b0b1a5f0cc
1 tập tin đã thay đổi với 53 bổ sung64 xóa
  1. 53 64
      h3d/mat/BigTexture.hx

+ 53 - 64
h3d/mat/BigTexture.hx

@@ -1,8 +1,9 @@
 package h3d.mat;
 
+@:access(h3d.mat.BigTexture)
 class BigTextureElement {
 	public var t : BigTexture;
-	public var q : QuadTree;
+	var q : QuadTree;
 	public var du : Float;
 	public var dv : Float;
 	public var su : Float;
@@ -17,11 +18,19 @@ class BigTextureElement {
 	}
 
 	public function set(tex : hxd.res.Image) {
-		t.set(tex, this);
+		if( q.texture == tex )
+			return;
+		q.texture = tex;
+		t.isDone = false;
+		if( tex != null ) tex.watch(t.rebuild);
 	}
 
 	public function setAlpha(tex : hxd.res.Image) {
-		t.setAlpha(tex, this);
+		if( q.alphaChannel == tex )
+			return;
+		q.alphaChannel = tex;
+		t.isDone = false;
+		if( tex != null ) tex.watch(t.rebuild);
 	}
 
 }
@@ -56,9 +65,7 @@ class BigTexture {
 	var size : Int;
 	var space : QuadTree;
 	var allPixels : hxd.Pixels;
-	var modified : Bool = true;
 	var isDone : Bool;
-	var isUploaded : Bool;
 	var pending : Array<{ t : hxd.res.Image, q : QuadTree, alpha : Bool, skip : Bool }>;
 	var waitTimer : haxe.Timer;
 	var lastEvent : Float;
@@ -69,6 +76,7 @@ class BigTexture {
 		space = new QuadTree(0,0,size,size);
 		tex = new h3d.mat.Texture(1, 1, allocPos);
 		tex.clear(bgColor);
+		tex.realloc = rebuild;
 		pending = [];
 	}
 
@@ -90,11 +98,6 @@ class BigTexture {
 		space = null;
 	}
 
-	function initPixels() {
-		if( allPixels == null )
-			allPixels = hxd.Pixels.alloc(size, size, h3d.mat.Texture.nativeFormat);
-	}
-
 	function findBest( q : QuadTree, w : Int, h : Int ) {
 		if( q == null || q.width < w || q.height < h ) return null;
 		if( !q.used ) return q;
@@ -140,32 +143,14 @@ class BigTexture {
 		return split(q, w2<<1, h2<<1, w, h);
 	}
 
-	public function set( t : hxd.res.Image, et : BigTextureElement ) {
-		et.q.texture = t;
-		upload(t, et.q, false);
-		t.watch(rebuild);
-	}
-
-	public function setAlpha( t : hxd.res.Image, et : BigTextureElement ) {
-		et.q.alphaChannel = t;
-		upload(t, et.q, true);
-		t.watch(rebuild);
-	}
-
 	function rebuild() {
-		function rebuildRec( q : QuadTree ) {
-			if( q == null ) return;
-			if( q.texture != null )
-				upload(q.texture, q, false);
-			if( q.alphaChannel != null )
-				upload(q.alphaChannel, q, true);
-			rebuildRec(q.tl);
-			rebuildRec(q.tr);
-			rebuildRec(q.bl);
-			rebuildRec(q.br);
-		}
-		rebuildRec(space);
-		flush();
+		var old = space;
+		var oldT = tex;
+		tex = null;
+		dispose();
+		tex = oldT;
+		space = old;
+		done();
 	}
 
 	public function add( t : hxd.res.Image ) {
@@ -173,18 +158,12 @@ class BigTexture {
 		var q = allocPos(tsize.width,tsize.height);
 		if( q == null )
 			return null;
-		upload(t, q, false);
-		if( isUploaded ) {
-			isUploaded = false;
-			rebuild();
-		}
-		q.texture = t;
-		t.watch(rebuild);
-		return new BigTextureElement(this, q, q.x / size, q.y / size, tsize.width / size, tsize.height / size);
+		var e = new BigTextureElement(this, q, q.x / size, q.y / size, tsize.width / size, tsize.height / size);
+		e.set(t);
+		return e;
 	}
 
 	function uploadPixels( pixels : hxd.Pixels, x : Int, y : Int, alphaChannel ) {
-		initPixels();
 		var bpp = hxd.Pixels.bytesPerPixel(allPixels.format);
 		if( alphaChannel ) {
 			var alphaPos = hxd.Pixels.getChannelOffset(allPixels.format, A);
@@ -205,7 +184,6 @@ class BigTexture {
 				allPixels.bytes.blit((x + (y + dy) * size) * bpp, pixels.bytes, dy * pixels.width * bpp, pixels.width * bpp);
 		}
 		pixels.dispose();
-		modified = true;
 	}
 
 	function upload( t : hxd.res.Image, q : QuadTree, alphaChannel ) {
@@ -231,19 +209,12 @@ class BigTexture {
 					if( !alphaChannel ) q.loadingColor = false;
 					lastEvent = haxe.Timer.stamp();
 					pending.remove(o);
-					#if heaps
 					var bmp = bmp.toBitmap();
 					var pixels = bmp.getPixels();
 					bmp.dispose();
-					#else
-					var pixels = bmp.getPixels();
-					#end
 					uploadPixels(pixels, q.x, q.y, alphaChannel);
 					loadCount--;
-					if( isDone )
-						done();
-					else
-						flush();
+					flush();
 				});
 			}
 			load();
@@ -251,8 +222,8 @@ class BigTexture {
 
 	}
 
-	function retry() {
-		if( isUploaded ) {
+	function retry( pixels ) {
+		if( allPixels != pixels ) {
 			waitTimer.stop();
 			waitTimer = null;
 			return;
@@ -269,33 +240,51 @@ class BigTexture {
 		}
 	}
 
-	public function flush() {
-		if( !modified || allPixels == null || loadCount > 0 )
+	function flush() {
+		if( allPixels == null || loadCount > 0 )
 			return;
 		if( tex.width != size ) tex.resize(size, size);
 		tex.uploadPixels(allPixels);
-		modified = false;
-		isUploaded = true;
+		allPixels.dispose();
+		allPixels = null;
+		if( waitTimer != null ) {
+			waitTimer.stop();
+			waitTimer = null;
+		}
 	}
 
 	public function done() {
+		if( isDone )
+			return;
 		isDone = true;
+		if( allPixels == null )
+			allPixels = hxd.Pixels.alloc(size, size, h3d.mat.Texture.nativeFormat);
+		// start loading all
+		function loadRec(q:QuadTree) {
+			if( q == null )
+				return;
+			if( q.texture != null )
+				upload(q.texture, q, false);
+			if( q.alphaChannel != null )
+				upload(q.alphaChannel, q, true);
+			loadRec(q.tl);
+			loadRec(q.tr);
+			loadRec(q.bl);
+			loadRec(q.br);
+		}
+		loadRec(space);
 		if( loadCount > 0 ) {
 			#if flash
 			// flash seems to sometime fail to load texture
 			if( waitTimer == null ) {
 				lastEvent = haxe.Timer.stamp();
 				waitTimer = new haxe.Timer(1000);
-				waitTimer.run = retry;
+				waitTimer.run = retry.bind(allPixels);
 			}
 			#end
 			return;
 		}
 		flush();
-		if( allPixels != null ) {
-			allPixels.dispose();
-			allPixels = null;
-		}
 	}
 
 }