Starling 1.7

Daniel Sperl on July 2, 2015

Hey guys,

it's hard to believe, but it's July already! So far, 2015 has been an extremely busy year for our little bird, so it's high time to release a new stable version. After all, you ought to be able to make use of all the features and improvements that found their way into the repository since the last release!

I'm proud to report that version 1.7 is ready to download — and, in all modesty, I think it turned out pretty well. But that's for you to decide!

As a long time Starling user, you know the drill: below you'll find an in-detail look at the major changes & additions that come with this release. I hope you like the new tricks Starling has learned!

Stencil Masks

This feature has been a long time coming. Starling has had rectangular masks for quite a while; those are very fast, but lack the flexibility you need in some situations. With this release, you don't need to constrain yourself any longer: you can now create masks with arbitrary shapes!

If you've used the "mask" property of the classic display list, you'll feel right at home with this feature. Just assign a display object to the new mask property, as shown below. Any display object can act as a mask, and it may or may not be part of the display list.

var sprite:Sprite = createSomeContent();
var quad:Quad = new Quad(100, 100);
quad.rotation = 0.5;
sprite.mask = quad; // <- use the quad as a mask

These masks work the following way: a pixel of a masked object will only be drawn if it is within the mask's polygons. This is crucial: the shape of the mask is defined by its polygons — not its texture! Thus, such a mask is purely binary: a pixel is either visible, or it is not.

Behind the scenes, masks use the "stencil buffer" of the GPU, making them very lightweight and fast. One mask requires two draw calls: one to draw the mask into the stencil buffer and one to remove it when all the masked content has been rendered.

Before I forget it: if we're talking about an AIR application, you'll need to activate the stencil buffer in the application descriptor; otherwise, your masks won't show up. But don't worry, Starling will trace out a warning if you forget to do so.


Canvas & Polygon

"This mask feature looks really nice", you might say, "but how the heck am I going to create those arbitrary shapes you were talking about?!" Well, I'm glad you ask!

Indeed: since masks rely purely on geometry, not on any textures, you need a way to draw your mask-shapes. In a funny coincidence, there are actually two new classes that can help you with exactly this task: "Canvas" and "Polygon". They go hand-in-hand with stencil masks.

The API of the Canvas class is similar to Flash's "Graphics" object. This will e.g. draw a red circle:

import starling.display.Canvas; // NEW!

var canvas:Canvas = new Canvas();
canvas.drawCircle(0, 0, 120);

There are also methods to draw an ellipse, a rectangle or an arbitrary Polygon. (The latter is another new class for the pure mathematical representation of a closed shape, somewhat analog to Flash's "Rectangle" class.)

In any case: the Canvas class is perfect for creating mask shapes! The "Masks" scene in the Starling demo shows a sample of a circular mask; click here to see it in action.

Finally, here's an insider tip for you: if a simple vector shape just doesn't cut it, there's an extension that allows you to use the alpha channel of a texture as a stencil mask: Texture Mask.

Video Textures

At the end of last year, Adobe introduced a video texture API for AIR. With each release, it's becoming available for more platforms, and now (with AIR 18) it's supported on all platforms, most notably iOS and Android (but not the Flash Player). To find out if your current platform supports video textures, simply call:

trace("video texture support?", SystemUtil.supportsVideoTexture);

To make it easy to use those textures, there are two new factory methods on the "Texture" class. Let's first look at displaying the video from the camera, since this is extremely straight-forward:

var camera:Camera = Camera.getCamera();
var texture:Texture = Texture.fromCamera(camera, 1, function():void
    addChild(new Image(texture));

Note the last argument of the method, which is a callback. The texture may only be used when that callback has executed.

To stream a video from a file or URL, you'll need a little bit more code; that's because Flash's "NetStream" API is a little clunky.

var nc:NetConnection = new NetConnection();

var file:File = File.applicationDirectory.resolvePath("lolcat.m4v");
var ns:NetStream = new NetStream(nc);;

var texture:Texture = Texture.fromNetStream(ns, 1, function():void
    addChild(new Image(texture));

Such a texture can be used just as any other one, and it even auto-restores on a context loss. Here's a quick sample of such a texture mapped to a rotating cube (in all its animated-gif-glory):

As for the supported video formats, the recommendation is to use H.264 with AAC audio encoding. Those videos should play on every conceivable device.

Other changes

Even if you don't plan on using any of the above features, an update to the new version is strongly recommended! Actually, the overwhelming part of the development time has been spent on fixing open issues, removing remaining memory leaks and bottlenecks, as well as making all those small little changes that make a developer's life easier.

Veterans will know where to find the full list of changes, but here are the ones that I deem most notable:

  • added property hints to tweening methods (providing easier animation of color and angle)
  • added ArrayUtil & VectorUtil classes (for insertion & removal of objects without allocations)
  • added 'reverseFrames' method to MovieClip
  • added 'leading' property to TextField class
  • added support for latest ATF file format updates (introduced with AIR 18)
  • when using 'baselineExtended' or higher, you will no longer suffer from additional state changes (draw calls) just because your images are tinted
  • optimized temporary object allocations in many cases by avoiding 'splice' and using the new 'Array-' or 'VectorUtil' instead
  • fixed numerous bugs and some memory leaks

A huge thanks to all the contributors of this release, be it via forum posts, GitHub reports or direct e-mails. You rock!

Now, head over to the download section and give the new version a try. And don't forget to add a comment below, I'm dying to hear what you think of this new release!

In the meantime, I'll get busy working on the next version, if you don't mind: two point oh! :)