Browse Source

changed captureRenderBuffer to pixels, implement in WebGL

ncannasse 10 years ago
parent
commit
9102f63485
6 changed files with 48 additions and 13 deletions
  1. 1 1
      h3d/impl/Driver.hx
  2. 13 0
      h3d/impl/GlDriver.hx
  3. 3 3
      h3d/impl/LogDriver.hx
  4. 2 2
      h3d/impl/ScnDriver.hx
  5. 13 2
      h3d/impl/Stage3dDriver.hx
  6. 16 5
      h3d/mat/Texture.hx

+ 1 - 1
h3d/impl/Driver.hx

@@ -92,7 +92,7 @@ class Driver {
 	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() {

+ 13 - 0
h3d/impl/GlDriver.hx

@@ -355,6 +355,7 @@ class GlDriver extends Driver {
 			bits |= GL.STENCIL_BUFFER_BIT;
 		}
 		if( bits != 0 ) gl.clear(bits);
+		if( curTarget != null ) curTarget.flags.set(WasCleared);
 	}
 
 	override function resize(width, height) {
@@ -388,6 +389,7 @@ class GlDriver extends Driver {
 		else if( t.flags.has(Fmt4_4_4_4) )
 			tt.fmt = GL.UNSIGNED_SHORT_4_4_4_4;
 		t.lastFrame = frame;
+		t.flags.unset(WasCleared);
 		gl.bindTexture(GL.TEXTURE_2D, tt.t);
 		var mipMap = t.flags.has(MipMapped) ? GL.LINEAR_MIPMAP_NEAREST : GL.LINEAR;
 		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);
 		gl.bindTexture(GL.TEXTURE_2D, null);
 		#end
+		t.flags.set(WasCleared);
 	}
 
 	override function uploadTexturePixels( t : h3d.mat.Texture, pixels : hxd.Pixels, mipLevel : Int, side : Int ) {
@@ -494,6 +497,7 @@ class GlDriver extends Driver {
 		#end
 		if( t.flags.has(MipMapped) ) gl.generateMipmap(GL.TEXTURE_2D);
 		gl.bindTexture(GL.TEXTURE_2D, null);
+		t.flags.set(WasCleared);
 	}
 
 	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 = [
 		[[GL.NEAREST,GL.NEAREST],[GL.LINEAR,GL.LINEAR]],
 		[[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);
 	}
 
-	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() {

+ 2 - 2
h3d/impl/ScnDriver.hx

@@ -90,8 +90,8 @@ class ScnDriver extends Driver {
 		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() {

+ 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);
 	}
 
-	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() {

+ 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.
 		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 oldW = e.width, oldH = e.height;
 		var oldF = filter, oldM = mipMap, oldWrap = wrap;
@@ -187,7 +196,8 @@ class Texture {
 			e.resize(width, height);
 		e.driver.clear(new h3d.Vector(0, 0, 0, 0),1,0);
 		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;
 
@@ -197,13 +207,14 @@ class Texture {
 		mipMap = oldM;
 		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 )
 			e.resize(oldW, oldH);
 		e.driver.clear(new h3d.Vector(0, 0, 0, 0));
 		s2d.dispose();
-		return bmp;
+		#end
+		return pixels;
 	}
 
 	public static function fromBitmap( bmp : hxd.BitmapData, ?allocPos : h3d.impl.AllocPos ) {