Explorar el Código

fixed alpha correctness wrt filters (Add,Alpha only for now)
moved blendMode from Drawable+Filter to h2d.Object (allow post filter blend)

Nicolas Cannasse hace 6 años
padre
commit
ab2138bd30
Se han modificado 4 ficheros con 31 adiciones y 34 borrados
  1. 0 13
      h2d/Drawable.hx
  2. 16 14
      h2d/Object.hx
  3. 15 2
      h2d/RenderContext.hx
  4. 0 5
      h2d/filter/Filter.hx

+ 0 - 13
h2d/Drawable.hx

@@ -11,11 +11,6 @@ class Drawable extends Object {
 	**/
 	**/
 	public var color(default,default) : h3d.Vector;
 	public var color(default,default) : h3d.Vector;
 
 
-	/**
-		The blendMode of the object (default Alpha)
-	**/
-	public var blendMode : BlendMode;
-
 	/**
 	/**
 		By enabling smoothing, scaling the object up or down will use hardware bilinear filtering resulting in less crisp aspect.
 		By enabling smoothing, scaling the object up or down will use hardware bilinear filtering resulting in less crisp aspect.
 		By default smooth is null and then Scene.defaultSmooth value is used.
 		By default smooth is null and then Scene.defaultSmooth value is used.
@@ -46,7 +41,6 @@ class Drawable extends Object {
 
 
 	function new(parent : h2d.Object) {
 	function new(parent : h2d.Object) {
 		super(parent);
 		super(parent);
-		blendMode = Alpha;
 		color = new h3d.Vector(1, 1, 1, 1);
 		color = new h3d.Vector(1, 1, 1, 1);
 	}
 	}
 
 
@@ -190,13 +184,6 @@ class Drawable extends Object {
 		return false;
 		return false;
 	}
 	}
 
 
-	override function emitFilterTile( ctx, tile ) {
-		var oldBlend = blendMode;
-		if( filter.blendMode != null ) blendMode = filter.blendMode;
-		emitTile(ctx, tile);
-		if( filter.blendMode != null ) blendMode = oldBlend;
-	}
-
 	override function emitTile( ctx : RenderContext, tile : Tile ) {
 	override function emitTile( ctx : RenderContext, tile : Tile ) {
 		if( tile == null )
 		if( tile == null )
 			tile = new Tile(null, 0, 0, 5, 5);
 			tile = new Tile(null, 0, 0, 5, 5);

+ 16 - 14
h2d/Object.hx

@@ -69,6 +69,13 @@ class Object {
 	**/
 	**/
 	public var filter(default,set) : h2d.filter.Filter;
 	public var filter(default,set) : h2d.filter.Filter;
 
 
+	/**
+		The blendMode of the object (default Alpha). 
+		If there is no filter active, only apply to the current object (not inherited by children)  
+		If there is a filter active, tells how the filter is blended with background.
+	**/
+	public var blendMode : BlendMode;
+
 	var matA : Float;
 	var matA : Float;
 	var matB : Float;
 	var matB : Float;
 	var matC : Float;
 	var matC : Float;
@@ -86,6 +93,7 @@ class Object {
 	public function new( ?parent : Object ) {
 	public function new( ?parent : Object ) {
 		matA = 1; matB = 0; matC = 0; matD = 1; absX = 0; absY = 0;
 		matA = 1; matB = 0; matC = 0; matD = 1; absX = 0; absY = 0;
 		x = 0; y = 0; scaleX = 1; scaleY = 1; rotation = 0;
 		x = 0; y = 0; scaleX = 1; scaleY = 1; rotation = 0;
+		blendMode = Alpha;
 		posChanged = parent != null;
 		posChanged = parent != null;
 		visible = true;
 		visible = true;
 		children = [];
 		children = [];
@@ -725,21 +733,15 @@ class Object {
 		if( finalTile == null )
 		if( finalTile == null )
 			return;
 			return;
 
 
-		ctx.globalAlpha = oldAlpha * alpha;
-		emitFilterTile(ctx, finalTile);
-		ctx.globalAlpha = oldAlpha;
-		ctx.flush();
-	}
-
-	function emitFilterTile( ctx, tile ) {
-		if( filter.blendMode != null ) {
-			if( nullDrawable == null )
-				nullDrawable = @:privateAccess new h2d.Drawable(null);
-			nullDrawable.blendMode = filter.blendMode;
+		@:privateAccess {
+			ctx.currentBlend = null;
+			ctx.inFilterBlend = blendMode;
+			ctx.globalAlpha = oldAlpha * alpha;
+			emitTile(ctx, finalTile);
+			ctx.globalAlpha = oldAlpha;
+			ctx.flush();
+			ctx.inFilterBlend = null;
 		}
 		}
-		emitTile(ctx, tile);
-		if( filter.blendMode != null )
-			nullDrawable.blendMode = Alpha;
 	}
 	}
 
 
 	function drawRec( ctx : RenderContext ) {
 	function drawRec( ctx : RenderContext ) {

+ 15 - 2
h2d/RenderContext.hx

@@ -33,6 +33,7 @@ class RenderContext extends h3d.impl.RenderContext {
 	var hasUVPos : Bool;
 	var hasUVPos : Bool;
 	var filterStack : Array<h2d.Object>;
 	var filterStack : Array<h2d.Object>;
 	var inFilter : Object;
 	var inFilter : Object;
+	var inFilterBlend : BlendMode;
 
 
 	var curX : Int;
 	var curX : Int;
 	var curY : Int;
 	var curY : Int;
@@ -58,8 +59,6 @@ class RenderContext extends h3d.impl.RenderContext {
 		pass = new h3d.mat.Pass("",null);
 		pass = new h3d.mat.Pass("",null);
 		pass.depth(true, Always);
 		pass.depth(true, Always);
 		pass.culling = None;
 		pass.culling = None;
-		currentBlend = Alpha;
-		pass.setBlendMode(currentBlend);
 		baseShader = new h3d.shader.Base2d();
 		baseShader = new h3d.shader.Base2d();
 		baseShader.setPriority(100);
 		baseShader.setPriority(100);
 		baseShader.zValue = 0.;
 		baseShader.zValue = 0.;
@@ -179,6 +178,7 @@ class RenderContext extends h3d.impl.RenderContext {
 		curY = startY;
 		curY = startY;
 		curWidth = width;
 		curWidth = width;
 		curHeight = height;
 		curHeight = height;
+		currentBlend = null;
 		if( hasRenderZone ) clearRenderZone();
 		if( hasRenderZone ) clearRenderZone();
 	}
 	}
 
 
@@ -267,9 +267,22 @@ class RenderContext extends h3d.impl.RenderContext {
 		texture.wrap = currentObj.tileWrap && (currentObj.filter == null || inFilter != null) ? Repeat : Clamp;
 		texture.wrap = currentObj.tileWrap && (currentObj.filter == null || inFilter != null) ? Repeat : Clamp;
 		var blend = currentObj.blendMode;
 		var blend = currentObj.blendMode;
 		if( inFilter == currentObj && blend == Erase ) blend = Add; // add THEN erase
 		if( inFilter == currentObj && blend == Erase ) blend = Add; // add THEN erase
+		if( inFilterBlend != null ) blend = inFilterBlend;
 		if( blend != currentBlend ) {
 		if( blend != currentBlend ) {
 			currentBlend = blend;
 			currentBlend = blend;
 			pass.setBlendMode(blend);
 			pass.setBlendMode(blend);
+			#if flash
+			// flash does not allow blend separate operations
+			// this will get us good color but wrong alpha
+			#else
+			// accummulate correctly alpha values
+			if( blend == Alpha || blend == Add ) {
+				pass.blendAlphaSrc = One;
+				// when merging
+				if( inFilterBlend != null )
+					pass.blendSrc = One;
+			}
+			#end
 		}
 		}
 		manager.fillParams(buffers, compiledShader, currentShaders);
 		manager.fillParams(buffers, compiledShader, currentShaders);
 		engine.selectMaterial(pass);
 		engine.selectMaterial(pass);

+ 0 - 5
h2d/filter/Filter.hx

@@ -9,11 +9,6 @@ class Filter {
 	public var boundsExtend : Float = 0.;
 	public var boundsExtend : Float = 0.;
 	public var smooth = false;
 	public var smooth = false;
 
 
-	/**
-		When set, will use this blend mode when merging the filtered output to screen.
-	**/
-	public var blendMode : Null<h2d.BlendMode>;
-
 	function new() {
 	function new() {
 	}
 	}