浏览代码

more work on js : drawshader compiles (not yet tested), added texture wrap support

Nicolas Cannasse 12 年之前
父节点
当前提交
26ae71792f
共有 4 个文件被更改,包括 115 次插入10 次删除
  1. 75 3
      h2d/Drawable.hx
  2. 5 1
      h3d/impl/Shader.hx
  3. 31 6
      h3d/impl/WebglDriver.hx
  4. 4 0
      hxd/System.hx

+ 75 - 3
h2d/Drawable.hx

@@ -62,7 +62,10 @@ private class DrawableShader extends h3d.impl.Shader {
 
 		function fragment( tex : Texture ) {
 			var col = tex.get(sinusDeform != null ? [tuv.x + sin(tuv.y * sinusDeform.y + sinusDeform.x) * sinusDeform.z, tuv.y] : tuv, filter = ! !filter, wrap = tileWrap);
-			if( hasColorKey ) kill(abs(col.rgb - colorKey.rgb).length() - 0.001);
+			if( hasColorKey ) {
+				var cdiff = col.rgb - colorKey.rgb;
+				kill(cdiff.dot(cdiff) - 0.001);
+			}
 			if( killAlpha ) kill(col.a - 0.001);
 			if( hasVertexAlpha ) col.a *= talpha;
 			if( hasVertexColor ) col *= tcolor;
@@ -80,16 +83,47 @@ private class DrawableShader extends h3d.impl.Shader {
 	
 	#elseif js
 	
+	public var hasColorKey : Bool;
+	
+	// not supported
+	public var skew : Float;
+	public var sinusDeform : h3d.Vector;
+	public var hasAlphaMap : Bool;
+	public var hasMultMap : Bool;
+	public var multMap : h3d.mat.Texture;
+	public var multUV : h3d.Vector;
+	public var multMapFactor : Float;
+	public var alphaMap : h3d.mat.Texture;
+	public var alphaUV : h3d.Vector;
+	// --
+	
+	public var filter : Bool;
+	public var tileWrap : Bool;
+	public var killAlpha : Bool;
+	public var hasAlpha : Bool;
+	public var hasVertexAlpha : Bool;
+	
+	override function customSetup(driver:h3d.impl.WebglDriver) {
+		driver.setupTexture(tex, None, filter ? Linear : Nearest, tileWrap ? Repeat : Clamp);
+	}
+	
 	static var VERTEX = "
 	
 		attribute vec2 pos;
 		attribute vec2 uv;
+		#if hasVertexAlpha
+		attribute float alpha;
+		varying lowp float talpha;
+		#end
 
 		uniform vec3 size;
 		uniform vec3 matA;
 		uniform vec3 matB;
 		uniform lowp float zValue;
 		
+		uniform vec2 uvPos;
+		uniform vec3 uvScale;
+		
 		varying lowp vec2 tuv;
 
 		void main(void) {
@@ -100,7 +134,17 @@ private class DrawableShader extends h3d.impl.Shader {
 			tmp.z = zValue;
 			tmp.w = 1.;
 			gl_Position = tmp;
+			vec2 t = uv;
+			#if hasUVScale
+				t *= uvScale;
+			#end
+			#if hasUVPos
+				t += uvPos;
+			#end
 			tuv = uv;
+			#if hasVertexAlpha
+				talpha = alpha;
+			#end
 		}
 
 	";
@@ -110,12 +154,40 @@ private class DrawableShader extends h3d.impl.Shader {
 		varying lowp vec2 tuv;
 		uniform sampler2D tex;
 		
-		const bool hasAlpha = true;
+		#if hasVertexAlpha
+		varying lowp float talpha;
+		#end
+		
 		uniform lowp float alpha;
+		uniform lowp vec3 colorKey/*byte4*/;
 	
+		uniform lowp vec4 colorAdd;
+		uniform lowp vec4 colorMul;
+		uniform mediump mat4 colorMatrix;
+
 		void main(void) {
 			lowp vec4 col = texture2D(tex, tuv);
-			if( hasAlpha ) col.w *= alpha;
+			#if killAlpha
+				if( c.a - 0.001 ) discard;
+			#end
+			#if hasColorKey
+				if( col.rgb == colorKey ) discard;
+			#end
+			#if hasAlpha
+				col.w *= alpha;
+			#end
+			#if hasVertexAlpha
+				col.a *= talpha;
+			#end
+			#if hasColorMatrix
+				c = colorMatrix * c;
+			#end
+			#if hasColorMul
+				c *= colorMul;
+			#end
+			#if hasColorAdd
+				c += colorAdd;
+			#end
 			gl_FragColor = col;
 		}
 			

+ 5 - 1
h3d/impl/Shader.hx

@@ -17,6 +17,7 @@ enum ShaderType {
 	Mat4;
 	Tex2d;
 	TexCube;
+	Byte3;
 	Byte4;
 	Struct( field : String, t : ShaderType );
 	Index( index : Int, t : ShaderType );
@@ -43,6 +44,9 @@ class Shader {
 	public function new() {
 	}
 	
+	function customSetup( driver : WebglDriver ) {
+	}
+	
 	function getConstants( vertex : Bool ) {
 		return "";
 	}
@@ -74,7 +78,7 @@ class ShaderMacros {
 				code = r_uni.matchedRight();
 				var t = switch( type ) {
 				case "float": macro : Float;
-				case "vec4" if( hint == "byte4" ): macro : Int;
+				case "vec4", "vec3" if( hint == "byte4" ): macro : Int;
 				case "vec2", "vec3", "vec4": macro : h3d.Vector;
 				case "mat3", "mat4": macro : h3d.Matrix;
 				case "sampler2D", "samplerCube": macro : h3d.mat.Texture;

+ 31 - 6
h3d/impl/WebglDriver.hx

@@ -9,7 +9,7 @@ private typedef GL = js.html.webgl.GL;
 class WebglDriver extends Driver {
 
 	var canvas : js.html.CanvasElement;
-	var gl : js.html.webgl.RenderingContext;
+	public var gl : js.html.webgl.RenderingContext;
 	
 	var curAttribs : Int;
 	var curShader : Shader.ShaderInstance;
@@ -189,7 +189,7 @@ class WebglDriver extends Driver {
 	
 	function typeSize( t : Shader.ShaderType ) {
 		return switch( t ) {
-		case Float, Byte4: 1;
+		case Float, Byte4, Byte3: 1;
 		case Vec2: 2;
 		case Vec3: 3;
 		case Vec4: 4;
@@ -297,6 +297,14 @@ class WebglDriver extends Driver {
 			switch( t ) {
 			case Tex2d, TexCube:
 				texIndex++;
+			case Vec3:
+				var r = new EReg(inf.name + "[ \\t]*\\/\\*([A-Za-z0-9_]+)\\*\\/", "");
+				if( r.match(allCode) )
+					switch( r.matched(1) ) {
+					case "byte4":
+						t = Byte3;
+					default:
+					}
 			case Vec4:
 				var r = new EReg(inf.name + "[ \\t]*\\/\\*([A-Za-z0-9_]+)\\*\\/", "");
 				if( r.match(allCode) )
@@ -355,10 +363,22 @@ class WebglDriver extends Driver {
 			if( val == null ) throw "Missing shader value " + u.name;
 			setUniform(val, u, u.type);
 		}
+		shader.customSetup(this);
 		
 		return change;
 	}
 	
+	public function setupTexture( t : h3d.mat.Texture, mipMap : h3d.mat.Data.MipMap, filter : h3d.mat.Data.Filter, wrap : h3d.mat.Data.Wrap ) {
+		gl.bindTexture(GL.TEXTURE_2D, t.t);
+		var flags = TFILTERS[Type.enumIndex(mipMap)][Type.enumIndex(filter)];
+		gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, flags[0]);
+		gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, flags[1]);
+		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 ) {
 		switch( t ) {
 		case Mat4:
@@ -367,11 +387,8 @@ class WebglDriver extends Driver {
 		case Tex2d:
 			var t : h3d.mat.Texture = val;
 			gl.activeTexture(GL.TEXTURE0 + u.index);
-			gl.bindTexture(GL.TEXTURE_2D, t.t);
-			var flags = TFILTERS[Type.enumIndex(t.mipMap)][Type.enumIndex(t.filter)];
-			gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, flags[0]);
-			gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, flags[1]);
 			gl.uniform1i(u.loc, u.index);
+			setupTexture(t, t.mipMap, t.filter, t.wrap);
 		case Float:
 			gl.uniform1f(u.loc, val);
 		case Vec2:
@@ -394,6 +411,9 @@ class WebglDriver extends Driver {
 		case Byte4:
 			var v : Int = val;
 			gl.uniform4f(u.loc, ((v >> 16) & 0xFF) / 255, ((v >> 8) & 0xFF) / 255, (v & 0xFF) / 255, (v >>> 24) / 255);
+		case Byte3:
+			var v : Int = val;
+			gl.uniform3f(u.loc, ((v >> 16) & 0xFF) / 255, ((v >> 8) & 0xFF) / 255, (v & 0xFF) / 255);
 		default:
 			throw "Unsupported uniform " + u.type;
 		}
@@ -433,6 +453,11 @@ class WebglDriver extends Driver {
 		[[GL.NEAREST,GL.NEAREST_MIPMAP_LINEAR],[GL.LINEAR,GL.LINEAR_MIPMAP_LINEAR]],
 	];
 	
+	static var TWRAP = [
+		GL.CLAMP_TO_EDGE,
+		GL.REPEAT,
+	];
+	
 	static var FACES = [
 		0,
 		GL.FRONT, // front/back reversed wrt stage3d

+ 4 - 0
hxd/System.hx

@@ -140,6 +140,10 @@ class System {
 		throw "TODO";
 	}
 	
+	static function get_lang() {
+		return "en";
+	}
+	
 	static function get_screenDPI() {
 		return 72.;
 	}