|
@@ -257,14 +257,22 @@ class Texture {
|
|
Downloads the current texture data from the GPU.
|
|
Downloads the current texture data from the GPU.
|
|
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 capturePixels( face = 0, mipLevel = 0 ) {
|
|
|
|
|
|
+ public function capturePixels( face = 0, mipLevel = 0 ) : hxd.Pixels {
|
|
#if flash
|
|
#if flash
|
|
|
|
+ if( flags.has(Cube) ) throw "Can't capture cube texture on this platform";
|
|
|
|
+ if( face != 0 || mipLevel != 0 ) throw "Can't capture face/mipLevel on this platform";
|
|
|
|
+ return capturePixelsFlash();
|
|
|
|
+ #else
|
|
|
|
+ var old = lastFrame;
|
|
|
|
+ preventAutoDispose();
|
|
|
|
+ var pix = mem.driver.capturePixels(this, face, mipLevel);
|
|
|
|
+ lastFrame = old;
|
|
|
|
+ return pix;
|
|
|
|
+ #end
|
|
|
|
+ }
|
|
|
|
|
|
- if( face != 0 || mipLevel != 0 )
|
|
|
|
- throw "Can't capture face/mipLevel";
|
|
|
|
-
|
|
|
|
- var twoPassCapture = true;
|
|
|
|
-
|
|
|
|
|
|
+ #if flash
|
|
|
|
+ function capturePixelsFlash() {
|
|
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;
|
|
@@ -273,11 +281,8 @@ class Texture {
|
|
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();
|
|
var b = new h2d.Bitmap(h2d.Tile.fromTexture(this), s2d);
|
|
var b = new h2d.Bitmap(h2d.Tile.fromTexture(this), s2d);
|
|
- var shader = null;
|
|
|
|
- if( twoPassCapture ) {
|
|
|
|
- shader = new h3d.shader.AlphaChannel();
|
|
|
|
- b.addShader(shader); // erase alpha
|
|
|
|
- }
|
|
|
|
|
|
+ var shader = new h3d.shader.AlphaChannel();
|
|
|
|
+ b.addShader(shader); // erase alpha
|
|
b.blendMode = None;
|
|
b.blendMode = None;
|
|
|
|
|
|
mipMap = None;
|
|
mipMap = None;
|
|
@@ -287,24 +292,22 @@ class Texture {
|
|
var pixels = hxd.Pixels.alloc(width, height, ARGB);
|
|
var pixels = hxd.Pixels.alloc(width, height, ARGB);
|
|
e.driver.captureRenderBuffer(pixels);
|
|
e.driver.captureRenderBuffer(pixels);
|
|
|
|
|
|
- if( twoPassCapture ) {
|
|
|
|
- shader.showAlpha = true;
|
|
|
|
- s2d.render(e); // render only alpha channel
|
|
|
|
- var alpha = hxd.Pixels.alloc(width, height, ARGB);
|
|
|
|
- e.driver.captureRenderBuffer(alpha);
|
|
|
|
- var alphaPos = hxd.Pixels.getChannelOffset(alpha.format, A);
|
|
|
|
- var redPos = hxd.Pixels.getChannelOffset(alpha.format, R);
|
|
|
|
- var bpp = hxd.Pixels.bytesPerPixel(alpha.format);
|
|
|
|
- for( y in 0...height ) {
|
|
|
|
- var p = y * width * bpp;
|
|
|
|
- for( x in 0...width ) {
|
|
|
|
- pixels.bytes.set(p + alphaPos, alpha.bytes.get(p + redPos)); // copy alpha value only
|
|
|
|
- p += bpp;
|
|
|
|
- }
|
|
|
|
|
|
+ shader.showAlpha = true;
|
|
|
|
+ s2d.render(e); // render only alpha channel
|
|
|
|
+ var alpha = hxd.Pixels.alloc(width, height, ARGB);
|
|
|
|
+ e.driver.captureRenderBuffer(alpha);
|
|
|
|
+ var alphaPos = hxd.Pixels.getChannelOffset(alpha.format, A);
|
|
|
|
+ var redPos = hxd.Pixels.getChannelOffset(alpha.format, R);
|
|
|
|
+ var bpp = hxd.Pixels.bytesPerPixel(alpha.format);
|
|
|
|
+ for( y in 0...height ) {
|
|
|
|
+ var p = y * width * bpp;
|
|
|
|
+ for( x in 0...width ) {
|
|
|
|
+ pixels.bytes.set(p + alphaPos, alpha.bytes.get(p + redPos)); // copy alpha value only
|
|
|
|
+ p += bpp;
|
|
}
|
|
}
|
|
- alpha.dispose();
|
|
|
|
- pixels.flags.unset(AlphaPremultiplied);
|
|
|
|
}
|
|
}
|
|
|
|
+ alpha.dispose();
|
|
|
|
+ pixels.flags.unset(AlphaPremultiplied);
|
|
|
|
|
|
if( e.width != oldW || e.height != oldH )
|
|
if( e.width != oldW || e.height != oldH )
|
|
e.resize(oldW, oldH);
|
|
e.resize(oldW, oldH);
|
|
@@ -314,41 +317,9 @@ class Texture {
|
|
filter = oldF;
|
|
filter = oldF;
|
|
mipMap = oldM;
|
|
mipMap = oldM;
|
|
wrap = oldWrap;
|
|
wrap = oldWrap;
|
|
-
|
|
|
|
- #else
|
|
|
|
-
|
|
|
|
- var e = h3d.Engine.getCurrent();
|
|
|
|
- e.pushTarget(this, face, mipLevel);
|
|
|
|
- @:privateAccess e.flushTarget();
|
|
|
|
- var pixels = hxd.Pixels.alloc(width, height, RGBA);
|
|
|
|
- e.driver.captureRenderBuffer(pixels);
|
|
|
|
- e.popTarget();
|
|
|
|
-
|
|
|
|
- #end
|
|
|
|
return pixels;
|
|
return pixels;
|
|
}
|
|
}
|
|
-
|
|
|
|
- /*
|
|
|
|
-
|
|
|
|
- // Seems unreliable on flash, not sure why...
|
|
|
|
- // eg :
|
|
|
|
- // var t = hxd.Res.tex1.toTexture();
|
|
|
|
- // t.onLoaded = function() { var s = hxd.Res.tex2.toTexture(); s.onLoaded = function() t.setChannel(A,s,R); }
|
|
|
|
- // using setChannel here will clear the texture, for no known reason
|
|
|
|
-
|
|
|
|
- public function setChannel( c : hxd.Pixels.Channel, with : h3d.mat.Texture, ?srcChannel : hxd.Pixels.Channel ) {
|
|
|
|
- if( t == null || with.t == null )
|
|
|
|
- throw "Can't set disposed or loading texture";
|
|
|
|
- var pass = new h3d.mat.Pass("");
|
|
|
|
- pass.colorMask = 1 << c.toInt();
|
|
|
|
- pass.depth(false, Always);
|
|
|
|
- pass.culling = None;
|
|
|
|
- if( srcChannel != null && srcChannel != c )
|
|
|
|
- pass.addShader(new h3d.shader.ChannelSelect(srcChannel.toInt()));
|
|
|
|
- h3d.pass.Copy.run(with, this, null, pass);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- */
|
|
|
|
|
|
+ #end
|
|
|
|
|
|
public static function fromBitmap( bmp : hxd.BitmapData, ?allocPos : h3d.impl.AllocPos ) {
|
|
public static function fromBitmap( bmp : hxd.BitmapData, ?allocPos : h3d.impl.AllocPos ) {
|
|
var t = new Texture(bmp.width, bmp.height, allocPos);
|
|
var t = new Texture(bmp.width, bmp.height, allocPos);
|