Rasterizing/Drawing Vector in Haxe/NME

1,214 views
Skip to first unread message

Ashiq A.

unread,
Sep 11, 2012, 5:26:35 PM9/11/12
to haxe...@googlegroups.com
Hi All,

Mr. Nibbles (mr-nibbles.com) just came out. It was made in Haxe, and Mike used Flash to generate the (vector) art, but also somehow rasterized it, since NME draws vector stuff slowly (no GPU help).

Does anyone know how to do this? Right now, I'm trying to have three sizes of all graphics assets to fit different resolutions. Vector seems more ideal, and I do have access to Flash. 

But how would I go about turning my Flash vector art into something raster that NME can crunch? Has anyone else done this before?

I bugged Mike for more information, so hopefully he'll reveal it when he's less busy.

--Ashiq

Tarwin Stroh-Spijer

unread,
Sep 11, 2012, 5:29:22 PM9/11/12
to haxe...@googlegroups.com
I'm guessing he's storing the vector, and drawing everything to bitmaps before the game is started? Can take a second to do, but you get a lot smaller download (as well is making it easier to target different resolution displays).


Tarwin Stroh-Spijer
_______________________

Touch My Pixel
http://www.touchmypixel.com/
cell: +1 650 842 0920
_______________________



Ashiq A.

unread,
Sep 11, 2012, 6:15:08 PM9/11/12
to haxe...@googlegroups.com
@Tarwin how do you draw to bitmaps? And how do you deal with the issue of vectors not having a size?

Can you explain, maybe with references to some of the APIs?

I can understand having a large image and drawing a scaled-down version.

--Ashiq

Raoul Duke

unread,
Sep 11, 2012, 6:21:42 PM9/11/12
to haxe...@googlegroups.com
maybe somethng like:

each spite has a .graphics, you draw into that. then you could put
those into a tilesheet somehow ideally performance-wise.

* assume a standard sprite size e.g. 16x16
* make a giant sprite that is (16*16)*(# of sprites) - however you
want them laid out, long strip, or 2d grid.
* loop through all the vector images and render them into little
rectangular sub-regions (i*16, j*16+(i*16)) or whatever the right math
is :-)
* grab the grapics as bitmap data.
* upload the large bitmap into the drawtiles 'storage'.
* use drawtiles functions to draw individual sprites out of the whole big thing.

Joshua Granick

unread,
Sep 11, 2012, 6:25:59 PM9/11/12
to haxe...@googlegroups.com
Use bitmapData.draw to flatten display objects into a bitmap

You should be able to scale the objects first, then draw to a bitmap

Tarwin Stroh-Spijer

unread,
Sep 11, 2012, 6:33:02 PM9/11/12
to haxe...@googlegroups.com
If you want animated sprites these might help you:  http://code.google.com/p/touchmypixel/source/browse/#svn%2Ftrunk%2Fhaxe%2Fsrc%2Ftouchmypixel%2Fbitmap 

They use swapping of bitmaps rather than tilesheets though so may be a little slower ?



Tarwin Stroh-Spijer
_______________________

Touch My Pixel
http://www.touchmypixel.com/
cell: +1 650 842 0920
_______________________


Joshua Granick

unread,
Sep 11, 2012, 6:44:08 PM9/11/12
to haxe...@googlegroups.com
That's the method I use in the "spritesheet" library

Depending on what you create, its the fastest rendering method for Flash. It gets good performance on native, similar to the normal display list, but not quite as fast as using a batch rendering method.

The primary downside with using separate objects is it requires more memory. This isn't a problem on most platforms, but Apple gives a significantly smaller amount of allowed memory on their mobile devices, so it can become an issue if you need a lot of animations

Bruno Garcia

unread,
Sep 11, 2012, 8:00:42 PM9/11/12
to haxe...@googlegroups.com
On 09/11/2012 02:26 PM, Ashiq A. wrote:
> But how would I go about turning my Flash vector art into something
> raster that NME can crunch? Has anyone else done this before?

You might be interested in Flump, which converts FLAs into texture
atlases (not sprite sheets): https://github.com/threerings/flump

We're using it for a few different games at Three Rings. Here are a
couple Haxe demos that use it:
https://github.com/aduros/flambe-demos/tree/master/monster
https://github.com/aduros/flambe-demos/tree/master/horses

There's no NME lib for it, but it should be pretty easy to port the one
from Flambe or Starling.

Bruno

Ashiq A.

unread,
Sep 12, 2012, 5:04:57 PM9/12/12
to haxe...@googlegroups.com
@Joshua where are the docs for it? I can't find anything on it on Google.

I assume I still need some other mechanism to load the SWF -- or whatever vector format -- into NME/Haxe in the first place.

--Ashiq

Ashiq A.

unread,
Sep 12, 2012, 10:58:28 PM9/12/12
to haxe...@googlegroups.com
I figured out the SWF stuff (using the SWF library). I just need to rasterize to a bitmap somehow.
Message has been deleted

JLM

unread,
Sep 13, 2012, 8:15:17 AM9/13/12
to haxe...@googlegroups.com

You may need to explore bitmapdata and bitmap methods in NME/flash more, copypixels may not be ideal for speed,
but fairly sure it will work but you maybe able to modify code to be faster in NME, but will give you a start.
Although I have not tested this specific example, based on my own code this example should work ( assumes standard NME structure )
 
 
private function init(e)
 
{
   
// entry point
   
var swf = new SWF ( Assets.getBytes ("img/asset.swf") );
   
//name of linkage MovieClip in asset swf is assumed to be MyMovieNeedingRastering
   
var mc = swf.createMovieClip ("MyMovieNeedingRastering");

    addChild
( new Bitmap( copyToBitmapWithTransparency( mc ), PixelSnapping.ALWAYS, true )) ;

 
}
 
 
private function copyToBitmapWithTransparency( sp: Sprite ): BitmapData
 
{
   mc
.cacheAsBitmap = true; var wide: Int = Std.int( mc.width );
   
var hi = Std.int( mc.height );
   
var point = new Point( 0, 0 );
   
var rect = new Rectangle( 0 , 0, wide, hi );
   
var abitmap = new BitmapData( wide, hi, true, #if flash 0xff000000 #else BitmapData.createColor( 0x00,
 
0x000000 ) #end );
   abitmap
.draw( sp ); abitmap.copyPixels( abitmap, rect, point, abitmap, point, false );
   
return abitmap;
}

Cheers

Justin

Ashiq A.

unread,
Sep 13, 2012, 8:27:08 AM9/13/12
to haxe...@googlegroups.com
Hi Justin,

Your init function has an instance of SWF from swf.creteMovieClip (in mc), and your copy method takes a parameter that's a Sprite instance. Is this an implicit typecast? Does this actually work?

I have similar code, I'm just trying to figure out how to make it work. I have type issues right now (SWF is not IBitmapDrawable, nor is the bitmap data for some reason).

--Ashiq

Tom

unread,
Sep 13, 2012, 10:16:05 AM9/13/12
to haxe...@googlegroups.com
Hi!

I just tried the similar things - maybe with some more complicated swf. :) - for windows, and flash target.
I found one problem in nme 3.4.3 (windows target): nme.net.URLLoader  with Event.COMPLETE event crash on windows 7, 64 bit. (Progress event does not work.)
Workaround: in ENTER_FRAME event check the URRLoader.data.length, and if it not change, then it is loaded.

The solution what I used to convert one mc from the loaded SWF into bitmap: (i did not use any extra function, 'coz this was a fast code, sorry)


        var swf:SWF = new SWF(swfLoader.data);
       
       
var cl:MovieClip = swf.createMovieClip(""); // if no given name, then the whole loaded SWF will be created
        cl
.cacheAsBitmap = true;
       
       
var bdata:BitmapData = new BitmapData(Std.int(cl.width), Std.int(cl.height), true, 0), bmp:Bitmap = new Bitmap(bdata, PixelSnapping.ALWAYS, true);
        bdata
.draw(cl);
       
        bmp
.x = 100;
        bmp
.y = 100;
       
       
Lib.current.addChild(bmp);

Tom

unread,
Sep 13, 2012, 12:01:05 PM9/13/12
to haxe...@googlegroups.com
One more thing. Can be improved the closed path rendering? Because any path with hole is fully filled.

JLM

unread,
Sep 13, 2012, 12:22:03 PM9/13/12
to haxe...@googlegroups.com

package net.justinfront.kitty;
import nme.display.Sprite;
import nme.display.Bitmap;
import nme.display.BitmapData;
import nme.geom.Matrix;
import nme.geom.Point;
import nme.geom.Rectangle;
import nme.Assets;
import format.SWF;
import nme.display.PixelSnapping;
import neash.display.BitmapInt32;
/**
 * ...
 * @author JLM
 */


class Kitty
{
   
   
private var scope: Sprite;
   
   
public function new( scope_: Sprite )
   
{
       
        scope
= scope_;
       
var swf = new SWF ( Assets.getBytes ("img/KittyCS4.swf") );

       
       
       
//name of linkage MovieClip in asset swf is assumed to be MyMovieNeedingRastering

       
var mc = swf.createMovieClip ("Kitten");
        scope
.addChild( mc );
       
var bd =  copyToBitmapWithTransparency( mc );
       
var bm = new Bitmap( bd, PixelSnapping.ALWAYS, true );
        bm
.x = 100;
        bm
.y = 100;
        scope
.addChild( bm ) ;
       
   
}
 
   
private function copyToBitmapWithTransparency( mc: Sprite ): BitmapData
   
{
       
        mc
.cacheAsBitmap = true;
       
var wide    = Std.int( mc.width );
       
var hi      = Std.int( mc.height );
       
var point   = new Point( 0, 0 );
       
var rect    = new Rectangle( 0 , 0, wide, hi );
       
var abitmap = new BitmapData( wide, hi, true, #if flash 0x00000000 #else BitmapData.createColor( 0xff,
 
0xff0000 ) #end );
        abitmap
.draw( mc ); abitmap.copyPixels( abitmap, rect, point, abitmap, point, false );
       
return abitmap;
       
   
}
   
   
}
<?xml version="1.0" encoding="utf-8"?>
<project>
   
<!-- NMML reference: https://gist.github.com/1763850 -->
   
   
<!-- metadata, make sure 'package' is at least 3 segments (ie. com.mycompany.myproject) -->
   
<meta title="Kitty" package="net.justinfront.kitty.Kitty" version="1.0.0" company="JLM" />
   
   
<!-- output -->
   
<app main="net.justinfront.kitty.Main" file="Kitty" path="bin" />
   
   
<window background="#ffffff" fps="60" />
   
<window width="800" height="480" unless="mobile" />
   
<window orientation="landscape" vsync="true" antialiasing="0" if="cpp" />
   
   
<!-- classpath, haxe libs -->
   
<source path="src" />
   
<haxelib name="nme" />
   
<haxelib name="swf" />
   
<haxelib name="format" />
   
<!-- assets -->
   
<icon path="assets/nme.svg" />
   
<assets path="assets/img" rename="img" />
   
   
<!-- DLLs -->
   
<ndll name="std" />
   
<ndll name="regexp" />
   
<ndll name="zlib" />
   
<ndll name="nme" haxelib="nme" />

   
<!-- optimize JS output -->
   
<haxeflag name="--dead-code-elimination" if="html5" />
   
<haxeflag name="--js-modern" if="html5" />
   
</project>


But the kitty does not seem to render properly in windows.

j...@justinfront.net

unread,
Sep 13, 2012, 12:36:29 PM9/13/12
to haxe...@googlegroups.com
Ashiq and NME community.

The code I posted will work, just it seems the swf parser is not working as well as I hoped, I tried balloon test and the fills were separated by a one pixel gap and in this kitty example half the lines are not rendered properly?  

Can someone take a look in windows target, the kitty does not seem to render correctly, most of the lines do not seem to render only the fills?  I will upgrade my copy of NME if the kitty renders fine in latest but suspect it won't and I prefer not to risk changing if still broken.


KittyCS4.fla
KittyCS4.swf

Ashiq A.

unread,
Sep 13, 2012, 2:29:50 PM9/13/12
to haxe...@googlegroups.com
@JLM

The lines seem to be rendering ultra-thin. Here's what it looks like rasterized at 2.25x magnification:


Flash looks okay.

My lines showed up okay, but I used a line width of three, not 1; maybe that has something to do with it?

I did see very slight artifacts, but it's nothing unforgivable.

--Ashiq





Below is the code called from main so very easy to set the project up just add this to the main class.

new Kitty( this );

and enclosed the application nmml with the project setup.  Does any one have any advice on how I need to modify my test kitty to make sure he is rendered on android properly or any changes I need to make in the nmml?

Many Thanks

Justin
 
PS you can remove the scope.addChild( mc ); line it was just there for checking if the render was same as bitmap version.
But the kitty does not seem to render properly in windows.

Ashiq A.

unread,
Sep 17, 2012, 12:16:12 PM9/17/12
to haxe...@googlegroups.com
Hi Justin,

What do you need to use CopyPixels for?

I use a matrix which I scale/rotate (code I got from Mike Cann -- thanks Mike!), and only call draw, passing in the matrix as the second parameter.

Are there any real differences here, other than syntax? Performance maybe? I'm not familiar enough with the drawing API to know.

--Ashiq


On Thu, Sep 13, 2012 at 8:15 AM, JLM <j...@justinfront.net> wrote:

Emiliano Angelini

unread,
Sep 17, 2012, 10:46:10 PM9/17/12
to haxe...@googlegroups.com
Hi guys,

You may find some inspiration in this Starling extension I made quite a while. It's AS3 and Starling Texture Atlasses, but should be easy enough to be ported to Haxe / Spritesheet or TileLayer


Cheers,

Emi

Michael Cann

unread,
Sep 18, 2012, 3:14:37 AM9/18/12
to haxe...@googlegroups.com
You're welcome Ashiq ;)

Yes Emiliano that sort of thing is what I would have gone for with a little more time, plus the SWF rasteriser is rather slow at the moment so it could take quite a long time to generate entire sprite sheets dynamically. It was good enough for the occasional menu screen, to generate lots of animation frames however, it probably would have taken a long time.

Mike

Ashiq A.

unread,
Sep 18, 2012, 10:23:11 AM9/18/12
to haxe...@googlegroups.com
Wait, what? Slow? I'm planning to use it to generate a bunch of images, but I don't think atlasing will work, because I need to rasterize based on the actual screen size of the hardware at runtime -- I can't detect this at compile-time.

--Ashiq

Emiliano Angelini

unread,
Sep 18, 2012, 10:27:09 AM9/18/12
to haxe...@googlegroups.com
The code I shared creates a TextureAtlas at runtime. Of course it takes some time depending on the ammount and size of the swf assets.

Michael Cann

unread,
Sep 18, 2012, 10:36:11 AM9/18/12
to haxe...@googlegroups.com
Yes, unfortunately in my testing, the SWF rasterisation was rather slow, hence why I had to generate and cache my menu screens before the game loads.

You may want to run a few tests first before you go full-ball at it. Failing that you can just do what I did and generate the sprite sheets pre-runtime via a tool like TexturePacker or perhaps by some clever macro usage ;)

Mike

Tony Polinelli

unread,
Sep 19, 2012, 12:27:25 AM9/19/12
to haxe...@googlegroups.com

Ashiq A.

unread,
Sep 19, 2012, 7:01:58 AM9/19/12
to haxe...@googlegroups.com
@Tony SpriteLoq rasterizes or retains the symbols as vectors?
Reply all
Reply to author
Forward
0 new messages