Procházet zdrojové kódy

changed captureRenderBuffer to pixels, implement in WebGL

ncannasse před 10 roky
rodič
revize
9102f63485

+ 1 - 1
h3d/impl/Driver.hx

@@ -92,7 +92,7 @@ class Driver {
 	public function clear( ?color : h3d.Vector, ?depth : Float, ?stencil : Int ) {
 	public function clear( ?color : h3d.Vector, ?depth : Float, ?stencil : Int ) {
 	}
 	}
 
 
-	public function captureRenderBuffer( bmp : hxd.BitmapData ) {
+	public function captureRenderBuffer( pixels : hxd.Pixels ) {
 	}
 	}
 
 
 	public function reset() {
 	public function reset() {

+ 13 - 0
h3d/impl/GlDriver.hx

@@ -355,6 +355,7 @@ class GlDriver extends Driver {
 			bits |= GL.STENCIL_BUFFER_BIT;
 			bits |= GL.STENCIL_BUFFER_BIT;
 		}
 		}
 		if( bits != 0 ) gl.clear(bits);
 		if( bits != 0 ) gl.clear(bits);
+		if( curTarget != null ) curTarget.flags.set(WasCleared);
 	}
 	}
 
 
 	override function resize(width, height) {
 	override function resize(width, height) {
@@ -388,6 +389,7 @@ class GlDriver extends Driver {
 		else if( t.flags.has(Fmt4_4_4_4) )
 		else if( t.flags.has(Fmt4_4_4_4) )
 			tt.fmt = GL.UNSIGNED_SHORT_4_4_4_4;
 			tt.fmt = GL.UNSIGNED_SHORT_4_4_4_4;
 		t.lastFrame = frame;
 		t.lastFrame = frame;
+		t.flags.unset(WasCleared);
 		gl.bindTexture(GL.TEXTURE_2D, tt.t);
 		gl.bindTexture(GL.TEXTURE_2D, tt.t);
 		var mipMap = t.flags.has(MipMapped) ? GL.LINEAR_MIPMAP_NEAREST : GL.LINEAR;
 		var mipMap = t.flags.has(MipMapped) ? GL.LINEAR_MIPMAP_NEAREST : GL.LINEAR;
 		gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, mipMap);
 		gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, mipMap);
@@ -480,6 +482,7 @@ class GlDriver extends Driver {
 		if( t.flags.has(MipMapped) ) gl.generateMipmap(GL.TEXTURE_2D);
 		if( t.flags.has(MipMapped) ) gl.generateMipmap(GL.TEXTURE_2D);
 		gl.bindTexture(GL.TEXTURE_2D, null);
 		gl.bindTexture(GL.TEXTURE_2D, null);
 		#end
 		#end
+		t.flags.set(WasCleared);
 	}
 	}
 
 
 	override function uploadTexturePixels( t : h3d.mat.Texture, pixels : hxd.Pixels, mipLevel : Int, side : Int ) {
 	override function uploadTexturePixels( t : h3d.mat.Texture, pixels : hxd.Pixels, mipLevel : Int, side : Int ) {
@@ -494,6 +497,7 @@ class GlDriver extends Driver {
 		#end
 		#end
 		if( t.flags.has(MipMapped) ) gl.generateMipmap(GL.TEXTURE_2D);
 		if( t.flags.has(MipMapped) ) gl.generateMipmap(GL.TEXTURE_2D);
 		gl.bindTexture(GL.TEXTURE_2D, null);
 		gl.bindTexture(GL.TEXTURE_2D, null);
+		t.flags.set(WasCleared);
 	}
 	}
 
 
 	override function uploadVertexBuffer( v : VertexBuffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
 	override function uploadVertexBuffer( v : VertexBuffer, startVertex : Int, vertexCount : Int, buf : hxd.FloatBuffer, bufPos : Int ) {
@@ -679,6 +683,15 @@ class GlDriver extends Driver {
 		}
 		}
 	}
 	}
 
 
+	override function captureRenderBuffer( pixels : hxd.Pixels ) {
+		if( curTarget == null )
+			throw "Can't capture main render buffer in GL";
+		#if js
+		gl.readPixels(0, 0, pixels.width, pixels.height, GL.RGBA, GL.UNSIGNED_BYTE, @:privateAccess pixels.bytes.b);
+		pixels.format = RGBA;
+		#end
+	}
+
 	static var TFILTERS = [
 	static var TFILTERS = [
 		[[GL.NEAREST,GL.NEAREST],[GL.LINEAR,GL.LINEAR]],
 		[[GL.NEAREST,GL.NEAREST],[GL.LINEAR,GL.LINEAR]],
 		[[GL.NEAREST,GL.NEAREST_MIPMAP_NEAREST],[GL.LINEAR,GL.LINEAR_MIPMAP_NEAREST]],
 		[[GL.NEAREST,GL.NEAREST_MIPMAP_NEAREST],[GL.LINEAR,GL.LINEAR_MIPMAP_NEAREST]],

+ 3 - 3
h3d/impl/LogDriver.hx

@@ -44,9 +44,9 @@ class LogDriver extends Driver {
 		d.clear(color, depth, stencil);
 		d.clear(color, depth, stencil);
 	}
 	}
 
 
-	override function captureRenderBuffer( bmp : hxd.BitmapData ) {
-		log('CaptureRenderBuffer ${bmp.width}x${bmp.height}');
-		d.captureRenderBuffer(bmp);
+	override function captureRenderBuffer( pixels : hxd.Pixels ) {
+		log('CaptureRenderBuffer ${pixels.width}x${pixels.height}');
+		d.captureRenderBuffer(pixels);
 	}
 	}
 
 
 	override function reset() {
 	override function reset() {

+ 2 - 2
h3d/impl/ScnDriver.hx

@@ -90,8 +90,8 @@ class ScnDriver extends Driver {
 		d.clear(color, depth, stencil);
 		d.clear(color, depth, stencil);
 	}
 	}
 
 
-	override function captureRenderBuffer( bmp : hxd.BitmapData ) {
-		d.captureRenderBuffer(bmp);
+	override function captureRenderBuffer( pixels : hxd.Pixels ) {
+		d.captureRenderBuffer(pixels);
 	}
 	}
 
 
 	override function reset() {
 	override function reset() {

+ 13 - 2
h3d/impl/Stage3dDriver.hx

@@ -185,8 +185,19 @@ class Stage3dDriver extends Driver {
 		ctx.clear( color == null ? 0 : color.r, color == null ? 0 : color.g, color == null ? 0 : color.b, color == null ? 1 : color.a, depth == null ? 1 : depth, stencil == null ? 0 : stencil, mask);
 		ctx.clear( color == null ? 0 : color.r, color == null ? 0 : color.g, color == null ? 0 : color.b, color == null ? 1 : color.a, depth == null ? 1 : depth, stencil == null ? 0 : stencil, mask);
 	}
 	}
 
 
-	override function captureRenderBuffer( bmp : hxd.BitmapData ) {
-		ctx.drawToBitmapData(bmp.toNative());
+	override function captureRenderBuffer( pixels : hxd.Pixels ) {
+		if( inTarget != null )
+			throw "Can't capture render target in flash";
+		var bmp = new flash.display.BitmapData(pixels.width, pixels.height, true, 0);
+		ctx.drawToBitmapData(bmp);
+
+		var pix = bmp.getPixels(bmp.rect);
+		bmp.dispose();
+		var b = pixels.bytes.getData();
+		b.position = 0;
+		b.writeBytes(pix, 0, pixels.width * pixels.height * 4);
+		pixels.format = ARGB;
+		pixels.flags.set(AlphaPremultiplied);
 	}
 	}
 
 
 	override function dispose() {
 	override function dispose() {

+ 16 - 5
h3d/mat/Texture.hx

@@ -179,7 +179,16 @@ class Texture {
 		Downloads the current texture data from the GPU. On some platforms, color might be premultiplied by Alpha.
 		Downloads the current texture data from the GPU. On some platforms, color might be premultiplied by Alpha.
 		Beware, this is a very slow operation that shouldn't be done during rendering.
 		Beware, this is a very slow operation that shouldn't be done during rendering.
 	**/
 	**/
-	public function captureBitmap() {
+	public function capturePixels() {
+		#if js
+
+		var e = h3d.Engine.getCurrent();
+		var old = e.setTarget(this);
+		var pixels = hxd.Pixels.alloc(width, height, RGBA);
+		e.driver.captureRenderBuffer(pixels);
+		e.setTarget(old);
+
+		#else
 		var e = h3d.Engine.getCurrent();
 		var e = h3d.Engine.getCurrent();
 		var oldW = e.width, oldH = e.height;
 		var oldW = e.width, oldH = e.height;
 		var oldF = filter, oldM = mipMap, oldWrap = wrap;
 		var oldF = filter, oldM = mipMap, oldWrap = wrap;
@@ -187,7 +196,8 @@ class Texture {
 			e.resize(width, height);
 			e.resize(width, height);
 		e.driver.clear(new h3d.Vector(0, 0, 0, 0),1,0);
 		e.driver.clear(new h3d.Vector(0, 0, 0, 0),1,0);
 		var s2d = new h2d.Scene();
 		var s2d = new h2d.Scene();
-		new h2d.Bitmap(h2d.Tile.fromTexture(this), s2d);
+		var b = new h2d.Bitmap(h2d.Tile.fromTexture(this), s2d);
+		b.blendMode = None;
 
 
 		mipMap = None;
 		mipMap = None;
 
 
@@ -197,13 +207,14 @@ class Texture {
 		mipMap = oldM;
 		mipMap = oldM;
 		wrap = oldWrap;
 		wrap = oldWrap;
 
 
-		var bmp = new hxd.BitmapData(width, height);
-		e.driver.captureRenderBuffer(bmp);
+		var pixels = hxd.Pixels.alloc(width, height, ARGB);
+		e.driver.captureRenderBuffer(pixels);
 		if( e.width != oldW || e.height != oldH )
 		if( e.width != oldW || e.height != oldH )
 			e.resize(oldW, oldH);
 			e.resize(oldW, oldH);
 		e.driver.clear(new h3d.Vector(0, 0, 0, 0));
 		e.driver.clear(new h3d.Vector(0, 0, 0, 0));
 		s2d.dispose();
 		s2d.dispose();
-		return bmp;
+		#end
+		return pixels;
 	}
 	}
 
 
 	public static function fromBitmap( bmp : hxd.BitmapData, ?allocPos : h3d.impl.AllocPos ) {
 	public static function fromBitmap( bmp : hxd.BitmapData, ?allocPos : h3d.impl.AllocPos ) {