boostworthyisryantaylor

FP10: unloadAndStop And Limited Fullscreen Keyboard Access

Big news in the the Flash Player 10 beta 2 refresh! It previously looked as if Adobe wasn’t going to be able to resolve the major garbage collection issues that had us all very concerned. Fortunately, they have pulled through and added a new method that directly addresses this:

unloadAndStop — This new ActionScript 3.0 API adds unload functionality similar to the unload behavior in ActionScript 2.0. After calling unloadAndStop on loaded content it will be immediately removed stopping all audio, removing eventListeners, and becoming inaccessible through ActionScript.

Big props to the Adobe engineers for getting this added into version 10. From what I’ve heard, it wasn’t easy! They also snuck in limited fullscreen keyboard access for games and video controls:

Limited Fullscreen Keyboard Access — In Flash Player 10, key events are supported for non-printing keys such as arrows, shift, enter, tab, space, etc. Limited access to the keyboard will allow fullScreen games and video controls with keyboard access in a secure way.

Good stuff!

No comments

Upcoming Speaking Engagements

I have a bunch of upcoming speaking engagements which revolve heavily around Flash Player 10 and Pixel Bender, so I wanted to share the schedule with you in case you are interested in attending any of the presentations.


Adobe Flash Platform User Group of Atlanta

Adobe Flash Platform User Group of Atlanta
Tuesday, July 8th, 7:00pm - 9:00pm

Intro To Flash Player 10 and Pixel Bender

Flash Player 10 is upon us and with it comes an exciting array of powerful new features. The presentation will kick off with a walkthrough of how you can get started developing for Flash Player 10 using a recent build of the Flex SDK. From there, explorations of some of the core new features will take place, including the new Vector type, drawing API, and foundational 3D support. The night will end with an introduction to Pixel Bender, Adobe’s powerful new pixel shader language. Demonstrations of Pixel Bender kernels as Shaders for fills, filters, blend modes, and generic number crunchers in Flash will take place.

More info


Full Sail University

Full Sail University
Friday, July 18th, 2:00pm - 3:00pm

Graduation and Beyond

Life immediately after graduation is both exciting and frightening at the same time. Your first steps after graduation are important ones, so I will be starting off the presentation with a discussion about what has worked best for me - from the time that I first left Full Sail up until this very day. Following the opening discussion, the topic transitions to the modern Flash design and development workflows that are used by some of the top studios all over the world. An examination of one of the projects that is currently under development at Schematic will also take place. If time permits, a demonstration of some of the new features in Flash Player 10 will be included as well. Last, but not least, I am going to provide an overview of Schematic that includes our clients, latest projects, and our prestigious Flash group - the MPG. If you are a rockstar Flash designer or developer, stick around after the presentation for some possible recruiting.


Utah Flash Platform Developers' Group

Utah Flash Platform Developers’ Group
Tuesday, July 22nd, 7:00pm - 9:00pm

Intro To Flash Player 10 and Pixel Bender

Flash Player 10 is upon us and with it comes an exciting array of powerful new features. The presentation will kick off with a walkthrough of how you can get started developing for Flash Player 10 using a recent build of the Flex SDK. From there, explorations of some of the core new features will take place, including the new Vector type, drawing API, and foundational 3D support. The night will end with an introduction to Pixel Bender, Adobe’s powerful new pixel shader language. Demonstrations of Pixel Bender kernels as Shaders for fills, filters, blend modes, and generic number crunchers in Flash will take place.


Adobe MAX 2008 (San Francisco)

Adobe MAX 2008 (San Francisco)
Monday, November 17th, 5:00pm - 6:00pm

Pixel Bender Unleashed

Venture into the world of Pixel Bender, Adobe’s powerful new pixel shader language. We’ll introduce the language and its core concepts, as well as the toolkit used for development (available in preview release on Adobe Labs). We will then present demonstrations of practical implementations in Flash Player in the form of filters, fills, and blend modes. We’ll close with the use of Pixel Bender kernels as generic number crunchers.

More info


I’m especially excited about speaking at the Adobe MAX conference this year in San Francisco. Last year’s conference in Chicago was pretty darn good, and this year is shaping up to be equally amazing. I have a kick-ass presentation on Pixel Bender in the works, so I hope to see a lot of you there!

3 comments

FP10: Phase 2 Default Meta-Policy Change

Adobe announced awhile back that they were implementing changes for enforcing stricter policy files. Phase 1 of these changes began in release 9,0,115 with the addition of some log warnings such as this:

Warning: Domain www.boostworthy.com does not specify a meta-policy. Applying default meta-policy 'all'. This configuration is deprecated.

Phase 1 included some minor, immediate restrictions, but was mainly focused on spreading the word that stricter rules would result in errors in later versions (aka Phase 2). Well, Phase 2 is here and it is Flash Player 10.

In my mind, one of the most important changes to understand is the new default meta-policy. In the past, the default meta-policy for a master cross-domain policy file (the one in the root of the server) was 'all'. This meant that any policy file in any directory on the server could be used. In Phase 2, the master cross-domain file's default meta-policy will be 'master-only'. A meta-policy of 'master-only' means that only the master cross-domain policy file can be used as a policy file. Here is what that would look like if you were to actually specify it as such:

CODE:
  1. <cross-domain-policy>
  2.    <site-control permitted-cross-domain-policies="master-only" />
  3. </cross-domain-policy>

If any of your clients have a CDN or some other separate server that hosts resources used by a Flash application, be sure to work with them and explicitly add a meta-policy of 'all' or 'by-content-type' to the master cross-domain policy file if they have multiple policy files deployed.

Be sure to read this article on meta-policies if you aren't already familiar with them.

3 comments

FP10: ZBuffer Class For Sorting Depths

Flash Player 10 DisplayObjects include some very basic 3D properties, such as 'z' and 'rotationZ'. These properties simply handle basic affine transformations behind the scenes for you; a collection of DisplayObjects aren't actually getting projected into a scene per say. What this means is that a DisplayObject's 'z' property does not affect it's depth inside of a DisplayObjectContainer. Let's say that you have two DisplayObjects, childA and childB respectively, and childA is at depth index 0 and childB is at index 1. Even if childB is further down the Z axis than childA, childA will still be rendered behind it.

Since plenty of developers will likely take advantage of this basic 3D support to create a variety of simple effects (such as carousels), I decided to make a 'ZBuffer' class for conveniently handling the depth issue. My implementation is very straightforward; you have two methods to choose from - 'ZBuffer.sort' and 'ZBuffer.recursiveSort'. The 'sort' method accepts a DisplayObjectContainer and will loop through it's children and sort their depths accordingly based on their locations along the Z axis. The 'recursiveSort' method does the exact same thing, except it will also recursively sort each child's children if the child is a DisplayObjectContainer as well.

Here is a brief example of the 'ZBuffer' class in use:

ActionScript:
  1. // Create a new 'ZBuffer' instance.
  2.  
  3. var zBuffer:ZBuffer = new ZBuffer();
  4.  
  5. // Create and draw graphics for a few planes.
  6. // Offset their positions so that each one is visible.
  7.  
  8. var plane1:Sprite = new Sprite();
  9. var plane2:Sprite = new Sprite();
  10. var plane3:Sprite = new Sprite();
  11.  
  12. plane1.graphics.beginFill(0xFF0000);
  13. plane1.graphics.drawRect(0, 0, 200, 200);
  14. plane1.graphics.endFill();
  15.            
  16. plane2.graphics.beginFill(0x00FF00);
  17. plane2.graphics.drawRect(0, 0, 200, 200);
  18. plane2.graphics.endFill();
  19.  
  20. plane3.graphics.beginFill(0x0000FF);
  21. plane3.graphics.drawRect(0, 0, 200, 200);
  22. plane3.graphics.endFill();
  23.            
  24. plane1.x = 80;
  25. plane1.y = 50;
  26. plane1.z = 100;
  27.  
  28. plane2.x = 150;
  29. plane2.y = 100;
  30. plane2.z = 200;
  31.  
  32. plane3.x = 220;
  33. plane3.y = 150;
  34. plane3.z = 20;
  35.  
  36. // Add the planes to the display container.
  37.  
  38. addChild(plane1);
  39. addChild(plane2);
  40. addChild(plane3);
  41.  
  42. // Sort the display container's children (the planes).
  43. // The planes will now display at the correct depth
  44. // based on their location along the Z axis.
  45.  
  46. zBuffer.sort(this);

Included with the source files is an example which is similar to the example above, except the planes are animated to better demonstrate the sorting.

View the 'ZBuffer' example (Flash Player 10 required)

As usual, the class is licensed under the MIT license...so you can use it however you please.

Download 'boostworthy_zbuffer_src.zip'

Enjoy!

No comments

Flex 3 Cookbook

I meant to post about this a month ago when it officially went on sale. The Flex 3 Cookbook is out and has been receiving some pretty good reviews.

Flex 3 Cookbook

My contributions include:

21.7 - Install the Ant View in the Stand-Alone Version of Flex Builder
21.8 - Create an Ant Build File for Automating Common Tasks
21.9 - Compile A Flex Application by Using mxmlc and Ant
21.10 - Generate Documentation by Using ASDoc and Ant

Josh had also mentioned using some stuff from my color spectrums post, but I'm not sure if that ended up making it in or not. Anyway, Josh and Todd did a great job on this book and it is definitely worth picking up as a desk reference. You can purchase it on Amazon here.

2 comments

Versions (Mac Subversion Client) Public Beta Released

The long awaited Versions subversion client for OS X has finally gone public beta. I spent the day taking it for a test spin at work and, though it is certainly shaping up to be the best Mac subversion client, it still suffers from some missing functionality that we are all so spoiled to have in tools such as TortoiseSVN.

My biggest beef with it at the moment is that you cannot simply select 'commit' and be presented with a list of everything that is modified, added, missing, or unversioned. ZigVersion actually supports this behavior, though its UI also leaves a lot to be desired when compared to Versions. Having to spend extra time sorting through trees and making sure that I get everything added/deleted, ect. before a commit is something that I consider a deal breaker for any SVN client. For that reason, I prefer developing large projects under Windows simply so I can use TortoiseSVN and get things done quickly and without issues. I have voiced my feedback to the Pico / Sofa team, so hopefully they will make these important changes and ultimately release an application that finally fills the missing void of a good OS X SVN client.

On a positive note, the ability to use svn+ssh connections without SSH key pairs is amazing - especially if you host with Media Temple. I also like the integration with issue tracking software. We use Mantis at Schematic and it ties in nicely with their system for mapping issue numbers to a corresponding URL.

If you do any development under OS X, be sure to give Versions a try and voice any feedback that you have to their team.

11 comments

FP10: Pixel Bender AlphaMatteComposite

In most image editing applications, the use of an alpha matte for masking a layer or object is a common practice. Flash works a little differently; you can still create masks, but they simply perform a boolean AND (clipping) operation on the object. Flash 8 introduced the ability to take things a step further and include a mask's alpha in the masking process. Below is an example of this in action:

ActionScript:
  1. // Create a 300 x 300 box with a color fill.
  2.  
  3. var container:Sprite = new Sprite();
  4. container.graphics.beginFill(0x008822, 1);
  5. container.graphics.drawRect(0, 0, 300, 300);
  6. container.graphics.endFill();
  7. addChild(container);
  8.  
  9. // Create a matrix for defining the gradient region.
  10.  
  11. var gradientMatrix:Matrix = new Matrix();
  12. gradientMatrix.createGradientBox(300, 300, 0, 0, 0);
  13.  
  14. // Create a 300 x 300 box with a gradient fill.
  15. // Notice that the alpha is being ramped down from
  16. // left to right ([1, 0]).
  17.  
  18. var containerMask:Sprite = new Sprite();
  19. containerMask.graphics.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0x000000], [1, 0], [0, 255], gradientMatrix);
  20. containerMask.graphics.drawRect(0, 0, 300, 300);
  21. containerMask.graphics.endFill();
  22. addChild(containerMask);
  23.  
  24. // Note: This step is required. Both objects must be
  25. // using runtime bitmap caching in order for an alpha
  26. // channel to be used for masking. If this step is not
  27. // taken, the mask's shape will be used as a clipping
  28. // mask and alpha will be ignored.
  29.  
  30. container.cacheAsBitmap = true;
  31. containerMask.cacheAsBitmap = true;
  32.  
  33. // Apply the container mask to the container.
  34.    
  35. container.mask = containerMask;

In the past, the shape of the gradient alone would mask the container. Notice in the example that runtime bitmap caching ('cacheAsBitmap') is enabled for both objects - this is what allows the additional alpha processing to be done.

Flash 8 also introduced blend modes and they presented another option for performing more complex masking effects. By creating a container object and then setting its blend mode to 'LAYER', you are forcing the creation of a transparency group for that object. You can then create foreground and background display objects inside of the container and set the foreground's blend mode to 'ALPHA'. This will result in the background image inheriting the alpha values of each pixel from the foreground layer. As a result, the background layer will be masked by the foreground layer. Here is an example:

ActionScript:
  1. // Create a container for storing the background
  2. // and foreground objects.
  3.  
  4. var container:Sprite = new Sprite();
  5. addChild(container);
  6.  
  7. // Create a 300 x 300 box with a color fill.
  8.  
  9. var containerBackground:Sprite = new Sprite();
  10. containerBackground.graphics.beginFill(0x008822, 1);
  11. containerBackground.graphics.drawRect(0, 0, 300, 300);
  12. containerBackground.graphics.endFill();
  13. container.addChildAt(containerBackground, 0);
  14.  
  15. // Create a matrix for defining the gradient region.
  16.  
  17. var gradientMatrix:Matrix = new Matrix();
  18. gradientMatrix.createGradientBox(300, 300, 0, 0, 0);
  19.  
  20. // Create a 300 x 300 box with a gradient fill.
  21.  
  22. var containerForeground:Sprite = new Sprite();
  23. containerForeground.graphics.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0x000000], [1, 0], [0, 255], gradientMatrix);
  24. containerForeground.graphics.drawRect(0, 0, 300, 300);
  25. containerForeground.graphics.endFill();
  26. container.addChildAt(containerForeground, 1);
  27.  
  28. // The container's blend mode must be set to BlendMode.LAYER
  29. // in order for it's child objects to be able to use BlendMode.ALPHA.
  30. // This operation causes the background object's alpha to be replaced
  31. // by the alpha of the corresponding pixels in the foreground object.
  32.  
  33. container.blendMode = BlendMode.LAYER;
  34. containerForeground.blendMode = BlendMode.ALPHA;

That brings us to modern day Flash 10 development. Since we now have Pixel Bender at our disposal, we can create our own tools for compositing. Something that I have been wanting in Flash for many years is the ability to mask an image using an alpha matte, as you would in Photoshop or After Effects. For those of you who aren't familiar with what I am describing - an alpha matte is a grayscale image in which a pixel that is completely white represents 100% alpha, a pixel that is completely black represents 0% alpha, and everything in between represents smooth steps from 0% to 100%. Technically, you could accomplish this in the past by operating on BitmapData objects, but that can be costly and undesirable in many situations.

My solution was to create a simple Pixel Bender kernel for handling alpha matte compositing. It accepts two inputs; one for the source image and one for the alpha matte. The output is the resulting masked version of the source image. The inputs are both typed as image4 for maximum compatibility with Flash (for instance, using a shader as a blend mode requires two image4 inputs).

Here is the source:

CODE:
  1. // *****************************************************************************************
  2. // AlphaMatteComposite.pbk
  3. //
  4. // Copyright (c) 2008 Ryan Taylor | http://www.boostworthy.com
  5. //
  6. // Permission is hereby granted, free of charge, to any person
  7. // obtaining a copy of this software and associated documentation
  8. // files (the "Software"), to deal in the Software without
  9. // restriction, including without limitation the rights to use,
  10. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the
  12. // Software is furnished to do so, subject to the following
  13. // conditions:
  14. //
  15. // The above copyright notice and this permission notice shall be
  16. // included in all copies or substantial portions of the Software.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  20. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  22. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  23. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25. // OTHER DEALINGS IN THE SOFTWARE.
  26. // *****************************************************************************************
  27. //
  28. // +          +          +          +          +          +          +          +          +
  29. //
  30. // *****************************************************************************************
  31.  
  32. <languageVersion : 1.0;>
  33.  
  34. kernel AlphaMatteComposite
  35. <   
  36.     namespace   : "Boostworthy::Filters";
  37.     vendor      : "Ryan Taylor";
  38.     version     : 1;
  39.     description : "Given a source image and grayscale matte which represents alpha, a composite of the two will result in a masked source image.";
  40. >
  41. {
  42.     input       image4      source;
  43.     input       image4      alphaMatte;
  44.     output      pixel4      result;
  45.    
  46.     void evaluatePixel()
  47.     {
  48.         // Note: The 'alphaMatte' input is of type image4 rather
  49.         // than image1 for maximum compatibilty with Flash.
  50.        
  51.         pixel4 sampSource       = sampleNearest(source,     outCoord());
  52.         pixel4 sampAlphaMatte   = sampleNearest(alphaMatte, outCoord());
  53.         pixel1 alphaMatte       = (sampAlphaMatte.r + sampAlphaMatte.g + sampAlphaMatte.b) / 3.0;
  54.        
  55.         result = sampSource * alphaMatte;
  56.     }
  57. }

You can use this kernel in Flash as a fill, filter, or blend mode. In my previous posts, I have demonstrated the use of shaders as fills and filters, so this time around I will use one as a blend mode. Building off of the examples earlier in this post, I modified the previous example to use a shader representing the 'AlphaMattaComposite' byte code as it's blend mode. The one gotcha in this example is that you must enable runtime bitmap caching for the container object (the one that contains the background and foreground objects). Failure to do so will result in the background object's color values being pre-multiplied; as a result, the pixels will be black rather than transparent.

ActionScript:
  1. // Create a container for storing the background
  2. // and foreground objects.
  3. //
  4. // Note: Runtime bitmap caching must be enabled for
  5. // the container in order to avoid alpha being
  6. // pre-multiplied when the shader is applied to
  7. // it's child objects.
  8.  
  9. var container:Sprite = new Sprite();
  10. container.cacheAsBitmap = true;
  11. addChild(container);
  12.  
  13. // Create a 300 x 300 box with a color fill.
  14.  
  15. var containerBackground:Sprite = new Sprite();
  16. containerBackground.graphics.beginFill(0x008822, 1);
  17. containerBackground.graphics.drawRect(0, 0, 300, 300);
  18. containerBackground.graphics.endFill();
  19. container.addChildAt(containerBackground, 0);
  20.  
  21. // Create a matrix for defining the gradient region.
  22.  
  23. var gradientMatrix:Matrix = new Matrix();
  24. gradientMatrix.createGradientBox(300, 300, 0, 0, 0);
  25.  
  26. // Create a 300 x 300 box with a gradient fill.
  27.  
  28. var containerForeground:Sprite = new Sprite();
  29. containerForeground.graphics.beginGradientFill(GradientType.LINEAR, [0xFFFFFF, 0x000000], [1, 1], [0, 255], gradientMatrix);
  30. containerForeground.graphics.drawRect(0, 0, 300, 300);
  31. containerForeground.graphics.endFill();
  32. container.addChildAt(containerForeground, 1);
  33.  
  34. // Create a new shader for represnting the 'AlphaMatteComposite' byte code.
  35.  
  36. var shader:Shader = new Shader(new AlphaMatteComposite());
  37.  
  38. // Apply the shader to the foreground object. By doing this, the foreground
  39. // object will automatically be used as the source input and the background
  40. // object will automatically be used as the alphaMatte input.
  41.  
  42. containerForeground.blendShader = shader;

Here is an example of a source image, alpha matte, and the resulting composite.

Background:

Pixel Bender AlphaMatteComposite

Source image:

Pixel Bender AlphaMatteComposite

Alpha matte:

Pixel Bender AlphaMatteComposite

Final composite:

Pixel Bender AlphaMatteComposite

Also available on Adobe Labs.

No comments

FP10: Pixel Bender HSLFilter

Sometimes it is useful to adjust colors in the HSL (hue, saturation, lightness) color space rather than RGB color space. There is no convenient way to do this in Flash using ActionScript, though a handful of people including myself have created a ColorMatrix class in the past for handling this task. A Pixel Bender kernel is ideal for this type of manipulation, so I went ahead and created a filter specifically for performing HSL transformations.

The process is as follows:

1.) Sample a pixel's color value and convert it from RGB space to HSL space.
2.) Adjust the HSL values by the amount specified by the hue, saturation, and lightness parameters.
3.) Convert the HSL color back to RGB space.
4.) Apply the resulting RGB color value to the pixel.

As I mentioned in my DisplacementMapFilter post, you can apply this filter in Flash as a shader fill or shader filter; the ideal way being to create a HSLFilter class for interfacing with the shader. I'll probably update this post in the near future with an example of what I am talking about.

Here is the HSLFilter source:

CODE:
  1. // *****************************************************************************************
  2. // HSLFilter.pbk
  3. //
  4. // Copyright (c) 2008 Ryan Taylor | http://www.boostworthy.com
  5. //
  6. // Permission is hereby granted, free of charge, to any person
  7. // obtaining a copy of this software and associated documentation
  8. // files (the "Software"), to deal in the Software without
  9. // restriction, including without limitation the rights to use,
  10. // copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. // copies of the Software, and to permit persons to whom the
  12. // Software is furnished to do so, subject to the following
  13. // conditions:
  14. //
  15. // The above copyright notice and this permission notice shall be
  16. // included in all copies or substantial portions of the Software.
  17. //
  18. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  20. // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  21. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  22. // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  23. // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  25. // OTHER DEALINGS IN THE SOFTWARE.
  26. // *****************************************************************************************
  27. //
  28. // +          +          +          +          +          +          +          +          +
  29. //
  30. // *****************************************************************************************
  31.  
  32. <languageVersion : 1.0;>
  33.  
  34. kernel HSLFilter
  35. <   
  36.     namespace   : "Boostworthy::Filters";
  37.     vendor      : "Ryan Taylor";
  38.     version     : 1;
  39.     description : "Basic filter for adjusting the hue, saturation, and lightness of an image.";
  40. >
  41. {
  42.     parameter   float       hue
  43.     <
  44.         minValue        :  -180.0;
  45.         maxValue        :   180.0;
  46.         defaultValue    :   0.0;
  47.     >;
  48.    
  49.     parameter   float       saturation
  50.     <
  51.         minValue        :  -100.0;
  52.         maxValue        :   100.0;
  53.         defaultValue    :   0.0;
  54.     >;
  55.    
  56.     parameter   float       lightness
  57.     <
  58.         minValue        :