AIR Stage3D- confining GPU filter effects to portion of stage - actionscript-3

Using this library to create filter effects in an application. The problem I am having is that the effects are applied to the ENTIRE stage, instead of just a portion.
Does anyone know of a way to define a 'window' or 'viewport' on a Stage3D layer? I checked the documentation for Stage3D but nothing seems exposed that would help.

You can set the width and height in the configureBackBuffer method of Context3D and the x and y in the Stage3D instance:
stage3D.x = stage3D.y = 0;
context3D.configureBackBuffer(width, height, antiAlias, enableDepthAndStencil);
In the lib you're using the width and height is set to match stageWidth/stageHeight. Link to the specific line of code:
https://github.com/inspirit/GPUImage/blob/12d32dab0e479620fd6420dc3fa7fcfe726502d2/examples/GPUImageShowcase.as#L120
stageW = stage.stageWidth;
stageH = stage.stageHeight;
// Setup context
var stage3D:Stage3D = stage.stage3Ds[0];
stage3D.removeEventListener(Event.CONTEXT3D_CREATE, onContextCreated);
context3D = stage3D.context3D;
context3D.configureBackBuffer(
stageW,
stageH,
antiAlias,
enableDepthAndStencil
);

Related

How do I get the width of bitmap using createJS?

How do I get the width of a bitmap image in createJS? I need it to change only the width of the image to calculate the scaleX value. By the way, Is there any direct way to change the image width or do I need to use the scaleX property?
Every image is preloaded using preloadJS in the library.
piecesArray[0].val = Math.floor(Math.random() * 50)
piecesArray[0].sym = new lib["a"+ piecesArray[0].val]()
model = new createjs.Bitmap(piecesArray[0].sym);
(function to change width)
stage.addChild(model.image)
I've searched all the variables of model using the console and there is no getBounds(), nor width, nor height, nor nominalBounds...
P.S. This what happens when I test it using the console
model = new createjs.Bitmap(new lib["c"+ 1]());
a {_listeners: null, _captureListeners: null, alpha: 1, cacheCanvas: null, cacheID: 0…}
console.log(model.image)
VM281:2 lib.c1 {spriteSheet: a, paused: true, currentAnimationFrame: 0, _animation: null, currentAnimation: null…}
undefined
console.log(model.image.width)
VM282:2 undefined
undefined
You can get the size of the image via bitmap.image.width, so in your code it would be model.image.width. And no, there is no direct way to set the width of a bitmap - you have to set it via scaleX/scaleY.
Solved it by re-sizing before creating the Bitmap. I think the reason I couldn't get the width value was because the image comes from a spritesheet.
piecesArray[0].sym.scaleX = 232/piecesArray[0].sym.getBounds().width
piecesArray[0].sym.scaleY = 150/piecesArray[0].sym.getBounds().height
model = new createjs.Bitmap(piecesArray[0].sym);

AS3 Changing volume level on left/right speaker without affecting the other

I need to know if it is possible to changed the volume level of an individual stereo/sound channel using as3? Basically i need to be able to turn the right channel volume down without affecting the left channel?
I've already been looking at the pan method and rightToRight/rightToLeft methods available in the soundtransform class but i can't seem to get it to do what i want?
Any help on this one would be hugely appreciated!
Thanks
Adam
Since you didn't post any code showing how you are using the rightToRight/rightToLeft properties, I'll give it a stab with how I would do it:
var sound:Sound = new SomeSound();
var soundChannel:SoundChannel = sound.play();
var soundTX:SoundTransform = soundChannel.soundTransform;
soundTX.leftToLeft = .1; // set the volume lower on the left channel
soundTX.leftToRight = 0; // make sure the left channel is only playing on the left
soundTX.rightToLeft = 0; // (see above)
soundTX.rightToRight = .3; // set the volume to a slightly higher value than the left
soundChannel.soundTransform = soundTX; // apply the modified soundTransform on soundChannel

Resize as a function of distance between mc's

I hope this hasn't been asked too much before. When I search I only get questions pertaining to rescaling to window size.
Now my question. I got one space ship firing a beam against another ship. I want the beam to show for some time and I want it to "bridge" the two ships. In other words, I want the beam to extend its width between the two ships.
I try to do this with a dot movie clip that is 1 pixel wide and high (and aligned left edge). I try to resize it with the following code: (target is the ship to be fire at and owner is the ship firing)
dist.vx = target.x - owner.x;
dist.vy = target.y - owner.y;
dist.dist = Math.sqrt(dist.vx*dist.vx + dist.vy*dist.vy);
width = dist.dist;
x = owner.x;
y = owner.y;
rotation = Math.atan2(target.y-y, target.x-x)*180/Math.PI;
This doesn't work as intended because 1) dot also gets alot bigger in the other dimension - how can I "turn off" this behavior? and 2) sometimes it seems to get way to wide - but only in certain angles...
Any suggestions on either solving the heigh/width scaling or on another way to achieve the same effect?
(I'm new to coding and flash.) Thanks!
By resizing a dot, you will have a rectangle...
You can dynamically create a sprite covering both ships and moveTo the hit point of one ship then lineTo the other ship... You do not need distance calculation at all. What you have to do is being careful on the placement of the sprite. So that you can calculate relative hitting points by simple math.
Suppose you have mc space contining mc ship1 and mc ship2, and hit point coords on ships are named hx, hy and you will use sprite s, calculation will be as follows.
// calculate hit points relative to mc space
var s1HX:int = ship1.x + ship1.hx,
s1HY:int = ship1.y + ship1.hy,
s2HX:int = ship2.x + ship2.hx,
s2HY:int = ship2.y + ship2.hy,
// sprite relative moveTo lineTo coords will be these.
mX: int, mY: int,
lX: int, lY: int;
// top left of sprite will be minimum of the hit coords.
s.x = (s1HX <= s2HX)? s1HX : s2HX;
s.y = (s1HY <= s2HY)? s1HY : s2HY;
// now we can get sprite relative moveTo lineTo coordinates:
mX = s1HX - s.x;
mY = s1HY - s.y;
lX = s2HX - s.x;
lY = s2HY - s.y;
The rest is implementation with using these with fancy line styles etc...
To create a new sprite:
var s:Sprite = new Sprite();
Adding / removing it to/from mc space:
space.addChild(s);
space.removeChild(s);
For graphics use the graphics object of sprite.
s.graphics
For setting line styles you can use:
s.graphics.lineStyle(...) ,
s.graphics.lineBitmapStyle(...),
s.graphics.lineGradientStyle(...)
Functions, please read the manual for usage.
After setting the line style to draw the line use:
s.graphics.moveTo(mX,mY);
s.graphics.lineTo(lX,lY);
For pulsating effects you have to do a little more complicated things such as using tween class which you can read about here: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/fl/transitions/Tween.html
Note that:
Sprites are no complicated magic, they are like mc's but they do not have timelines etc.
Sprites try to scale when width or height change programmatically. So do not touch them, moveTo lineTo automatically sets the size of a sprite...

How can I resize bitmap data without having to edit the transform matrix and maintain good quality

I am trying to resize a bitmap for a project we are working on at work in as 3.0. Basically we have a bunch of sprites that get drawn on a bitmapData and then are stored in a vector. The data in the vector eventually gets stored in a bitmap object. Now I want to make the BitmapData sprites smaller but don't want to have to update 100 matrix to do it. Is there another way?
I had some success by scaling the bitmap that gets displayed but the image is a bit jagged looking and the models don't turn around just moon walk.
I have also tired Matrix.a = 0.4 and matrix.d = 0.4 but that did nothing.
When I did bitmap.scalex = 0.7 and the same for scaleY it made it smaller but now they are in the air as the x and y aren't right and the code for them to go in reverse was just doing scalX *= -1 which now doesn't seem to work either. Also I figured out how to get them out of the air but they are as said before jagged and moon walking. Please help as I am attempting to fix code that was written before I got here.
Bascially here is some code, I got approval from the CEO:
we have this:
var b:BitmapData = new BitmapData(CustomerRenderer.BLIT_WIDTH,
CustomerRenderer.BLIT_HEIGHT, true, 0x00000000);
for(var i:int=0; i<WRAPPER.numChildren; i++)
{
b.draw(Sprite(WRAPPER.getChildAt(i)),
WRAPPER.getChildAt(i).transform.matrix, null, null, b.rect, true);
}
_spriteSheet[_currentFrame] = b;
Then we use that data in
BAKED_BITMAP.bitmapData = _spriteSheet[_currentFrame];
to display it where BAKED_BITMAP is a Bitmap
then to flip all the person was doing was:
BAKED_BITMAP.scaleX *= -1;
BAKED_BITMAP.x = (BAKED_BITMAP.scaleX >= 0) ? 0 : BLIT_WIDTH;
thanks
You can try setting the smoothing property of the Bitmap object to see if it gives you the desired effect.

Is there a way to get the actual bounding box of a glyph in ActionScript?

I'm learning ActionScript/Flash. I love to play with text, and have done a lot of that kind of thing with the superb Java2D API.
One of the things I like to know is "where, exactly, are you drawing that glyph?" The TextField class provides the methods getBounds and getCharBoundaries, but these methods return rectangles that extend far beyond the actual bounds of the whole text object or the individual character, respectively.
var b:Sprite = new Sprite();
b.graphics.lineStyle(1,0xFF0000);
var r:Rectangle = text.getCharBoundaries(4);
r.offset(text.x, text.y);
b.graphics.drawRect(r.x,r.y,r.width,r.height);
addChild(b);
b = new Sprite();
b.graphics.lineStyle(1,0x00FF00);
r = text.getBounds(this);
b.graphics.drawRect(r.x,r.y,r.width,r.height);
addChild(b);
Is there any way to get more precise information about the actual visual bounds of text glyphs in ActionScript?
Richard is on the right track, but BitmapData.getColorBounds() is much faster and accurate... I've used it a couple of times, and optimized for your specific needs its not as slow as one might think.
Cory's suggestion of using flash.text.engine is probably the "correct" way to go, but I warn you that flash.text.engine is VERY (very!) hard to use compared to TextField.
Not reasonably possible in Flash 9 -- Richard's answer is a clever work-around, though probably completely unsuitable for production code (as he mentions) :)
If you have access to Flash 10, check out the new text engine classes, particularly TextLine.
I'm afraid all the methods that are available on TextField are supposed to do what you have already found them to do. Unless performance is key in your application (i.e. unless you intend to do this very often) maybe one option would be to draw the text field to a BitmapData, and find the topmost, leftmost, et c colored pixels within the bounding box retrieved by getCharBoundaries()?
var i : int;
var rect : Rectangle;
var top_left : Point;
var btm_right : Point;
var bmp : BitmapData = new BitmapData(tf.width, tf.height, false, 0xffffff);
bmp.draw(tf);
rect = tf.getCharBoundaries(4);
top_left = new Point(Infinity, Infinity);
btm_right = new Point(-Infinity, -Infinity);
for (i=rect.x; i<rect.right; i++) {
var j : int;
for (j=rect.y; j<rect.bottom; j++) {
var px : uint = bmp.getPixel(i, j);
// Check if pixel is black, i.e. belongs to glyph, and if so, whether it
// extends the previous bounds
if (px == 0) {
top_left.x = Math.min(top_left.x, i);
top_left.y = Math.min(top_left.y, j);
btm_right.x = Math.max(btm_right.x, i);
btm_right.y = Math.max(btm_right.y, j);
}
}
}
var actualRect : Rectangle = new Rectangle(top_left.x, top_left.y);
actualRect.width = btm_right.x - top_left.x;
actualRect.height = btm_right.y - top_left.y;
This code should loop through all the pixels that were deemed part of the glyph rectangle by getCharBoundaries(). If a pixel is not black, it gets discarded. If black, the code checks whether the pixels extends further up, down, right or left than any pixel that has previuosly been checked in the loop.
Obviously, this is not optimal code, with nested loops and unnecessary point objects. Hopefully though, the code is readable enough, and you are able to make out the parts that can most easily be optimized.
You might also want to introduce some threshold value instead of ignoring any pixel that is not pitch black.