فهرست منبع

working JS texture loading + Drawable

Nicolas Cannasse 12 سال پیش
والد
کامیت
c82fd0d585
5فایلهای تغییر یافته به همراه103 افزوده شده و 38 حذف شده
  1. 27 6
      h2d/Drawable.hx
  2. 2 0
      h3d/impl/Shader.hx
  3. 13 2
      h3d/impl/WebglDriver.hx
  4. 38 19
      hxd/res/EmbedFileSystem.hx
  5. 23 11
      hxd/res/FileTree.hx

+ 27 - 6
h2d/Drawable.hx

@@ -107,6 +107,24 @@ private class DrawableShader extends h3d.impl.Shader {
 		driver.setupTexture(tex, None, filter ? Linear : Nearest, tileWrap ? Repeat : Clamp);
 	}
 	
+	override function getConstants( vertex : Bool ) {
+		var cst = [];
+		if( vertex ) {
+			if( size != null ) cst.push("#define hasSize");
+			if( uvScale != null ) cst.push("#define hasUVScale");
+			if( uvPos != null ) cst.push("#define hasUVPos");
+		} else {
+			if( killAlpha ) cst.push("#define killAlpha");
+			if( hasColorKey ) cst.push("#define hasColorKey");
+			if( hasAlpha ) cst.push("#define hasAlpha");
+			if( colorMatrix != null ) cst.push("#define hasColorMatrix");
+			if( colorMul != null ) cst.push("#define hasColorMul");
+			if( colorAdd != null ) cst.push("#define hasColorAdd");
+		}
+		if( hasVertexAlpha ) cst.push("#define hasVertexAlpha");
+		return cst.join("\n");
+	}
+	
 	static var VERTEX = "
 	
 		attribute vec2 pos;
@@ -122,12 +140,15 @@ private class DrawableShader extends h3d.impl.Shader {
 		uniform lowp float zValue;
 		
 		uniform vec2 uvPos;
-		uniform vec3 uvScale;
+		uniform vec2 uvScale;
 		
 		varying lowp vec2 tuv;
 
 		void main(void) {
-			vec3 spos = vec3(pos.xy,1.0) * size;
+			vec3 spos = vec3(pos.xy, 1.0);
+			#if hasSize
+				spos = spos * size;
+			#end
 			vec4 tmp;
 			tmp.x = dot(spos,matA);
 			tmp.y = dot(spos,matB);
@@ -141,7 +162,7 @@ private class DrawableShader extends h3d.impl.Shader {
 			#if hasUVPos
 				t += uvPos;
 			#end
-			tuv = uv;
+			tuv = t;
 			#if hasVertexAlpha
 				talpha = alpha;
 			#end
@@ -180,13 +201,13 @@ private class DrawableShader extends h3d.impl.Shader {
 				col.a *= talpha;
 			#end
 			#if hasColorMatrix
-				c = colorMatrix * c;
+				col = colorMatrix * col;
 			#end
 			#if hasColorMul
-				c *= colorMul;
+				col *= colorMul;
 			#end
 			#if hasColorAdd
-				c += colorAdd;
+				col += colorAdd;
 			#end
 			gl_FragColor = col;
 		}

+ 2 - 0
h3d/impl/Shader.hx

@@ -103,9 +103,11 @@ class ShaderMacros {
 			case ["VERTEX", FVar(_,{ expr : EConst(CString(code)) }) ]:
 				hasVertex = true;
 				addUniforms(code);
+				f.meta.push( { name : ":keep", params : [], pos : pos } );
 			case ["FRAGMENT", FVar(_,{ expr : EConst(CString(code)) })]:
 				hasFragment = true;
 				addUniforms(code);
+				f.meta.push( { name : ":keep", params : [], pos : pos } );
 			default:
 			}
 		if( !hasVertex )

+ 13 - 2
h3d/impl/WebglDriver.hx

@@ -125,6 +125,18 @@ class WebglDriver extends Driver {
 	override function uploadTextureBytes( t : h3d.mat.Texture, bytes : haxe.io.Bytes, mipLevel : Int, side : Int ) {
 		gl.bindTexture(GL.TEXTURE_2D, t.t);
 		var pixels = new js.html.Uint8Array(bytes.getData());
+		// convert BGRA to RGBA
+		for( i in 0...t.width * t.height ) {
+			var p = i << 2;
+			var b = pixels[p + 0];
+			var g = pixels[p + 1];
+			var r = pixels[p + 2];
+			var a = pixels[p + 3];
+			pixels[p] = r;
+			pixels[p+1] = g;
+			pixels[p+2] = b;
+			pixels[p+3] = a;
+		}
 		gl.texImage2D(GL.TEXTURE_2D, mipLevel, GL.RGBA, t.width, t.height, 0, GL.RGBA, GL.UNSIGNED_BYTE, pixels);
 		gl.bindTexture(GL.TEXTURE_2D, null);
 	}
@@ -376,7 +388,6 @@ class WebglDriver extends Driver {
 		var w = TWRAP[Type.enumIndex(wrap)];
 		gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, w);
 		gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, w);
-		gl.bindTexture(GL.TEXTURE_2D, null);
 	}
 	
 	function setUniform( val : Dynamic, u : Shader.Uniform, t : Shader.ShaderType ) {
@@ -386,9 +397,9 @@ class WebglDriver extends Driver {
 			gl.uniformMatrix4fv(u.loc, false, new js.html.Float32Array(m.getFloats()));
 		case Tex2d:
 			var t : h3d.mat.Texture = val;
+			setupTexture(t, t.mipMap, t.filter, t.wrap);
 			gl.activeTexture(GL.TEXTURE0 + u.index);
 			gl.uniform1i(u.loc, u.index);
-			setupTexture(t, t.mipMap, t.filter, t.wrap);
 		case Float:
 			gl.uniform1f(u.loc, val);
 		case Vec2:

+ 38 - 19
hxd/res/EmbedFileSystem.hx

@@ -12,7 +12,9 @@ private class EmbedEntry extends FileEntry {
 	var data : Class<flash.utils.ByteArray>;
 	var bytes : flash.utils.ByteArray;
 	#else
-	var data : Dynamic;
+	var data : String;
+	var bytes : haxe.io.Bytes;
+	var readPos : Int;
 	#end
 
 	function new(fs, name, relPath, data) {
@@ -31,7 +33,10 @@ private class EmbedEntry extends FileEntry {
 		bytes.position = old;
 		return v;
 		#else
-		return 0;
+		var old = readPos;
+		open();
+		readPos = old;
+		return bytes.get(0) | (bytes.get(1) << 8) | (bytes.get(2) << 16) | (bytes.get(3) << 24);
 		#end
 	}
 	
@@ -41,7 +46,9 @@ private class EmbedEntry extends FileEntry {
 			open();
 		return haxe.io.Bytes.ofData(bytes);
 		#else
-		return null;
+		if( bytes == null )
+			open();
+		return bytes;
 		#end
 	}
 	
@@ -50,12 +57,20 @@ private class EmbedEntry extends FileEntry {
 		if( bytes == null )
 			bytes = Type.createInstance(data, []);
 		bytes.position = 0;
+		#else
+		if( bytes == null ) {
+			bytes = haxe.Resource.getBytes(data);
+			if( bytes == null ) throw "Missing resource " + data;
+		}
+		readPos = 0;
 		#end
 	}
 	
 	override function skip( nbytes : Int ) {
 		#if flash
 		bytes.position += nbytes;
+		#else
+		readPos += nbytes;
 		#end
 	}
 	
@@ -63,24 +78,30 @@ private class EmbedEntry extends FileEntry {
 		#if flash
 		return bytes.readUnsignedByte();
 		#else
-		return 0;
+		return bytes.get(readPos++);
 		#end
 	}
 	
 	override function read( out : haxe.io.Bytes, pos : Int, size : Int ) : Void {
 		#if flash
 		bytes.readBytes(out.getData(), pos, size);
+		#else
+		out.blit(pos, bytes, readPos, size);
+		readPos += size;
 		#end
 	}
 
 	override function close() {
 		#if flash
 		bytes = null;
+		#else
+		bytes = null;
+		readPos = 0;
 		#end
 	}
 	
 	override function load( ?onReady : Void -> Void ) : Void {
-		#if flash
+		#if (flash || js)
 		if( onReady != null ) haxe.Timer.delay(onReady, 1);
 		#end
 	}
@@ -100,15 +121,12 @@ private class EmbedEntry extends FileEntry {
 		open();
 		loader.loadBytes(bytes);
 		#else
+		throw "TODO";
 		#end
 	}
 	
 	override function get_isDirectory() {
-		#if flash
 		return fs.isDirectory(relPath);
-		#else
-		return false;
-		#end
 	}
 	
 	override function get_path() {
@@ -128,15 +146,13 @@ private class EmbedEntry extends FileEntry {
 		open();
 		return bytes.length;
 		#else
-		return 0;
+		open();
+		return bytes.length;
 		#end
 	}
 
 	override function iterator() {
-		#if flash
 		return new hxd.impl.ArrayIterator(fs.subFiles(relPath));
-		#else
-		#end
 	}
 	
 }
@@ -157,10 +173,10 @@ class EmbedFileSystem #if !macro implements FileSystem #end {
 		return new EmbedEntry(this,"root",null,null);
 	}
 
-	#if flash
+	#if (flash||js)
 	static var invalidChars = ~/[^A-Za-z0-9_]/g;
 	static function resolve( path : String ) {
-		return "hxd._res.R_"+invalidChars.replace(path,"_");
+		return #if flash "hxd._res." + #end "R_"+invalidChars.replace(path,"_");
 	}
 	#end
 	
@@ -175,6 +191,8 @@ class EmbedFileSystem #if !macro implements FileSystem #end {
 		return cl;
 	}
 	
+	#end
+
 	function subFiles( path : String ) : Array<FileEntry> {
 		var r = root;
 		for( p in path.split("/") )
@@ -190,14 +208,14 @@ class EmbedFileSystem #if !macro implements FileSystem #end {
 			r = Reflect.field(r, p);
 		return r != null;
 	}
-	#end
-	
+
 	public function exists( path : String ) {
 		#if flash
 		var f = open(path);
 		return f != null;
 		#else
-		return false;
+		var id = resolve(path);
+		return haxe.Resource.listNames().remove(id);
 		#end
 	}
 	
@@ -208,7 +226,8 @@ class EmbedFileSystem #if !macro implements FileSystem #end {
 			throw "File not found " + path;
 		return new EmbedEntry(this, path.split("/").pop(), path, f);
 		#else
-		return null;
+		var id = resolve(path);
+		return new EmbedEntry(this, path.split("/").pop(), path, id);
 		#end
 	}
 	

+ 23 - 11
hxd/res/FileTree.hx

@@ -13,6 +13,8 @@ class FileTree {
 	var ignoredDir : Map<String,Bool>;
 	var ignoredExt : Map<String,Bool>;
 	var options : EmbedOptions;
+	var isFlash : Bool;
+	var isJS : Bool;
 	
 	public function new(dir) {
 		this.path = resolvePath(dir);
@@ -25,6 +27,8 @@ class FileTree {
 		ignoredExt = new Map();
 		ignoredExt.set("gal", true); // graphics gale source
 		ignoredExt.set("lch", true); // labchirp source
+		isFlash = Context.defined("flash");
+		isJS = Context.defined("js");
 	}
 	
 	function resolvePath(dir:Null<String>) {
@@ -93,19 +97,24 @@ class FileTree {
 	static var invalidChars = ~/[^A-Za-z0-9_]/g;
 	function embedFile( file : String, ext : String, relPath : String, fullPath : String ) {
 		var name = "R" + invalidChars.replace(relPath, "_");
-		if( Context.defined("flash") ) {
-			switch( ext.toLowerCase() ) {
-			case "wav" if( options.compressSounds ):
-				var tmp = options.tmpDir + name + ".mp3";
-				if( getTime(tmp) < getTime(fullPath) ) {
-					if( Sys.command("lame", ["--silent","-h",fullPath,tmp]) != 0 )
-						Context.warning("Failed to run lame on " + path, pos);
-					else {
-						fullPath = tmp;
-					}
-				} else {
+		
+		switch( ext.toLowerCase() ) {
+		case "wav" if( options.compressSounds ):
+			var tmp = options.tmpDir + name + ".mp3";
+			if( getTime(tmp) < getTime(fullPath) ) {
+				if( Sys.command("lame", ["--silent","-h",fullPath,tmp]) != 0 )
+					Context.warning("Failed to run lame on " + path, pos);
+				else {
 					fullPath = tmp;
 				}
+			} else {
+				fullPath = tmp;
+			}
+		default:
+		}
+		
+		if( isFlash ) {
+			switch( ext.toLowerCase() ) {
 			case "ttf":
 				haxe.macro.Context.defineType({
 					pack : ["hxd","_res"],
@@ -136,6 +145,9 @@ class FileTree {
 				],
 				kind : TDClass({ pack : ["flash","utils"], name : "ByteArray", params : [] }),
 			});
+		} else if( isJS ) {
+			Context.addResource(name, sys.io.File.getBytes(fullPath));
+			return true;
 		} else {
 			return false;
 		}