Sfoglia il codice sorgente

Add copy from TextureArray
Add copy into a specific layer of the target texture
Add support for PixelsFloat R32F format

ShiroSmith 5 anni fa
parent
commit
bb5728dbf8
2 ha cambiato i file con 87 aggiunte e 12 eliminazioni
  1. 58 2
      h3d/pass/Copy.hx
  2. 29 10
      hxd/Pixels.hx

+ 58 - 2
h3d/pass/Copy.hx

@@ -12,6 +12,62 @@ class Copy {
 
 #else
 
+private class ArrayCopyShader extends h3d.shader.ScreenShader {
+
+	static var SRC = {
+		@param var texture : Sampler2DArray;
+		@param var layer : Int;
+		function fragment() {
+			pixelColor = texture.get(vec3(calculatedUV, layer));
+		}
+	}
+}
+
+class ArrayCopy extends ScreenFx<ArrayCopyShader> {
+
+	public function new() {
+		super(new ArrayCopyShader());
+	}
+
+	public function apply( from : h3d.mat.TextureArray, fromLayer : Int, to, ?blend : h3d.mat.BlendMode, ?customPass : h3d.mat.Pass, ?layer : Int) {
+		if( to != null )
+			engine.pushTarget(to, layer != null ? layer : 0);
+		shader.texture = from;
+		shader.layer = fromLayer;
+		if( customPass != null ) {
+			var old = pass;
+			pass = customPass;
+			if( blend != null ) pass.setBlendMode(blend);
+			var h = shaders;
+			while( h.next != null )
+				h = h.next;
+			h.next = @:privateAccess pass.shaders;
+			render();
+			pass = old;
+			h.next = null;
+		} else {
+			pass.setBlendMode(blend == null ? None : blend);
+			render();
+		}
+		shader.texture = null;
+		shader.layer = 0;
+		if( to != null )
+			engine.popTarget();
+	}
+
+	public static function run( from : h3d.mat.TextureArray, fromLayer : Int, to : h3d.mat.Texture, ?blend : h3d.mat.BlendMode, ?pass : h3d.mat.Pass, ?layer : Int ) {
+		var engine = h3d.Engine.getCurrent();
+		if( to != null && from != null && (blend == null || blend == None) && pass == null && engine.driver.copyTexture(from, to) )
+			return;
+		var inst : ArrayCopy = @:privateAccess engine.resCache.get(ArrayCopy);
+		if( inst == null ) {
+			inst = new ArrayCopy();
+			@:privateAccess engine.resCache.set(ArrayCopy, inst);
+		}
+		return inst.apply(from, fromLayer, to, blend, pass, layer);
+	}
+}
+	
 private class CopyShader extends h3d.shader.ScreenShader {
 
 	static var SRC = {
@@ -52,7 +108,7 @@ class Copy extends ScreenFx<CopyShader> {
 			engine.popTarget();
 	}
 
-	public static function run( from : h3d.mat.Texture, to : h3d.mat.Texture, ?blend : h3d.mat.BlendMode, ?pass : h3d.mat.Pass ) {
+	public static function run( from : h3d.mat.Texture, to : h3d.mat.Texture, ?blend : h3d.mat.BlendMode, ?pass : h3d.mat.Pass, ?layer : Int ) {
 		var engine = h3d.Engine.getCurrent();
 		if( to != null && from != null && (blend == null || blend == None) && pass == null && engine.driver.copyTexture(from, to) )
 			return;
@@ -61,7 +117,7 @@ class Copy extends ScreenFx<CopyShader> {
 			inst = new Copy();
 			@:privateAccess engine.resCache.set(Copy, inst);
 		}
-		return inst.apply(from, to, blend, pass);
+		return inst.apply(from, to, blend, pass, layer);
 	}
 
 }

+ 29 - 10
hxd/Pixels.hx

@@ -25,28 +25,47 @@ abstract PixelsARGB(Pixels) to Pixels {
 	}
 }
 
-@:forward(bytes, width, height, offset, flags, clear, dispose, toPNG, clone, toVector, sub, blit)
+@:forward(bytes, format, width, height, offset, flags, clear, dispose, toPNG, clone, toVector, sub, blit)
 abstract PixelsFloat(Pixels) to Pixels {
 
-
 	public inline function getPixelF(x, y) {
-		var pix = ((x + y * this.width) << 4) + this.offset;
-		return new h3d.Vector(this.bytes.getFloat(pix),this.bytes.getFloat(pix+4),this.bytes.getFloat(pix+8),this.bytes.getFloat(pix+12));
+		switch(this.format) {
+			case R32F:
+				var pix = ((x + y * this.width) << 1) + this.offset;
+				return new h3d.Vector(this.bytes.getFloat(pix));
+			case RGBA32F:
+				var pix = ((x + y * this.width) << 4) + this.offset;
+				return new h3d.Vector(this.bytes.getFloat(pix),this.bytes.getFloat(pix+4),this.bytes.getFloat(pix+8),this.bytes.getFloat(pix+12));
+			default:
+				invalidFormat();
+				return null;
+		}
 	}
 
 	public inline function setPixelF(x, y, v:h3d.Vector) {
-		var pix = ((x + y * this.width) << 4) + this.offset;
-		this.bytes.setFloat(pix, v.x);
-		this.bytes.setFloat(pix + 4, v.y);
-		this.bytes.setFloat(pix + 8, v.z);
-		this.bytes.setFloat(pix + 12, v.w);
+		switch(this.format) {
+			case R32F:
+				var pix = ((x + y * this.width) << 1) + this.offset;
+				this.bytes.setFloat(pix, v.x);
+			case RGBA32F:
+				var pix = ((x + y * this.width) << 4) + this.offset;
+				this.bytes.setFloat(pix, v.x);
+				this.bytes.setFloat(pix + 4, v.y);
+				this.bytes.setFloat(pix + 8, v.z);
+				this.bytes.setFloat(pix + 12, v.w);
+			default:
+				invalidFormat();
+		}
 	}
 
 	@:from public static function fromPixels(p:Pixels) : PixelsFloat {
-		p.convert(RGBA32F);
 		p.setFlip(false);
 		return cast p;
 	}
+
+	function invalidFormat() {
+		throw "Unsupported format for this operation : " + this.format;
+	}
 }
 
 @:enum abstract Channel(Int) {