Browse Source

added per scene texture cache

Nicolas Cannasse 8 years ago
parent
commit
f05875a50c
5 changed files with 43 additions and 21 deletions
  1. 39 17
      hide/comp/Scene.hx
  2. 1 1
      hide/comp/TextureSelect.hx
  3. 1 1
      hide/view/Image.hx
  4. 1 1
      hide/view/Particles2D.hx
  5. 1 1
      hide/view/Particles3D.hx

+ 39 - 17
hide/comp/Scene.hx

@@ -100,7 +100,7 @@ class SceneLoader extends h3d.impl.Serializable.SceneSerializer {
 		var path = resolvePath(path);
 		if( path == null )
 			return h3d.mat.Texture.fromColor(0xFF00FF);
-		return scene.loadTextureFile(scnPath, path);
+		return scene.loadTexture(scnPath, path);
 	}
 
 	function resolvePath( path : String ) {
@@ -123,6 +123,8 @@ class Scene extends Component implements h3d.IDrawable {
 	var canvas : js.html.CanvasElement;
 	var engine : h3d.Engine;
 	var hmdCache = new Map<String, hxd.fmt.hmd.Library>();
+	var texCache = new Map<String, h3d.mat.Texture>();
+	var cleanup = new Array<Void->Void>();
 	public var width(get, never) : Int;
 	public var height(get, never) : Int;
 	public var s2d : h2d.Scene;
@@ -144,6 +146,13 @@ class Scene extends Component implements h3d.IDrawable {
 		haxe.Timer.delay(delayedInit,0); // wait canvas added to window
 	}
 
+	public function dispose() {
+		for( c in cleanup )
+			c();
+		cleanup = [];
+		engine.dispose();
+	}
+
 	function delayedInit() {
 		canvas.id = "webgl";
 		stage = @:privateAccess new hxd.Stage(canvas);
@@ -214,23 +223,30 @@ class Scene extends Component implements h3d.IDrawable {
 		engine.render(this);
 	}
 
-	public function loadTexture( path : String, onReady : h3d.mat.Texture -> Void, ?target : h3d.mat.Texture ) {
+	function loadTextureData( path : String, onReady : h3d.mat.Texture -> Void, ?target : h3d.mat.Texture ) {
 		var path = ide.getPath(path);
 		var img = new Element('<img src="file://$path"/>');
-		img.on("load",function() {
+		img.on("load", function() {
 			setCurrent();
 			var bmp : js.html.ImageElement = cast img[0];
 			var t;
 			if( target == null )
-				t = new h3d.mat.Texture(bmp.width, bmp.height);
+				t = target = new h3d.mat.Texture(bmp.width, bmp.height);
 			else {
 				t = target;
 				target.resize(bmp.width, bmp.height);
 			}
 			untyped bmp.ctx = { getImageData : function(_) return bmp, canvas : { width : 0, height : 0 } };
 			engine.driver.uploadTextureBitmap(t, cast bmp, 0, 0);
-			onReady(t);
+			if( onReady != null ) {
+				onReady(t);
+				onReady = null;
+			}
+		});
+		var w = js.node.Fs.watch(path, function(_, _) {
+			img.attr("src", 'file://$path?t='+Date.now().getTime());
 		});
+		cleanup.push(w.close);
 	}
 
 	public function listAnims( path : String ) {
@@ -288,7 +304,7 @@ class Scene extends Component implements h3d.IDrawable {
 		if( StringTools.endsWith(path.toLowerCase(), ".scn") )
 			return loadSCN(path);
 		var lib = loadHMD(path,false);
-		var obj = lib.makeObject(loadTextureFile.bind(path));
+		var obj = lib.makeObject(loadTexture.bind(path));
 		initMaterials(obj, path);
 		return obj;
 	}
@@ -323,20 +339,26 @@ class Scene extends Component implements h3d.IDrawable {
 		return null;
 	}
 
-	public function loadTextureFile( modelPath : String, texturePath : String, ?onReady ) {
+	public function loadTexture( modelPath : String, texturePath : String, ?onReady : h3d.mat.Texture -> Void ) {
 		var path = resolvePath(modelPath, texturePath);
-		if( path != null ) {
-			var bytes = sys.io.File.getBytes(path);
-			var size = hxd.res.Any.fromBytes(path, bytes).toImage().getSize();
-			var t = new h3d.mat.Texture(size.width,size.height);
-			t.clear(0x102030);
-			t.name = ide.makeRelative(path);
-			if( onReady == null ) onReady = function(_) {};
-			loadTexture(path, onReady, t);
+		if( path == null ) {
+			ide.error("Could not load texture " + { modelPath : modelPath, texturePath : texturePath });
+			return null;
+		}
+		var t = texCache.get(path);
+		if( t != null ) {
+			if( onReady != null ) haxe.Timer.delay(onReady.bind(t), 1);
 			return t;
 		}
-		trace("Could not load texture " + { modelPath : modelPath, texturePath : texturePath });
-		return null;
+		var bytes = sys.io.File.getBytes(path);
+		var size = hxd.res.Any.fromBytes(path, bytes).toImage().getSize();
+		t = new h3d.mat.Texture(size.width,size.height);
+		t.clear(0x102030);
+		t.name = ide.makeRelative(path);
+		texCache.set(path, t);
+		if( onReady == null ) onReady = function(_) {};
+		loadTextureData(path, onReady, t);
+		return t;
 	}
 
 	function loadHMD( path : String, isAnimation : Bool ) {

+ 1 - 1
hide/comp/TextureSelect.hx

@@ -23,7 +23,7 @@ class TextureSelect extends FileSelect {
 		if( p == null )
 			value = null;
 		else if( value == null || value.name != p )
-			value = Scene.getNearest(root).loadTextureFile("", p);
+			value = Scene.getNearest(root).loadTexture("", p);
 		if( p == null )
 			preview.hide();
 		else {

+ 1 - 1
hide/view/Image.hx

@@ -8,7 +8,7 @@ class Image extends FileView {
 	override function onDisplay() {
 		scene = new hide.comp.Scene(root);
 		scene.onReady = function() {
-			scene.loadTexture(state.path, function(t) {
+			scene.loadTexture(state.path, state.path, function(t) {
 				bmp = new h2d.Bitmap(h2d.Tile.fromTexture(t), scene.s2d);
 				onResize();
 			});

+ 1 - 1
hide/view/Particles2D.hx

@@ -11,7 +11,7 @@ private class Particles extends h2d.Particles {
 	}
 
 	override function loadTexture( path : String ) {
-		return parts.scene.loadTextureFile(parts.state.path, path);
+		return parts.scene.loadTexture(parts.state.path, path);
 	}
 
 }

+ 1 - 1
hide/view/Particles3D.hx

@@ -11,7 +11,7 @@ class GpuParticles extends h3d.parts.GpuParticles {
 	}
 
 	override function loadTexture( path : String ) {
-		return parts.scene.loadTextureFile(parts.state.path, path);
+		return parts.scene.loadTexture(parts.state.path, path);
 	}
 
 }