とりあえず、描画関係のAPIから調べていこうと思う。
すでに以下のURLに素晴らしい解説が公開されているので、それを読んでみる。
http://www.senocular.com/flash/tutorials/flash10drawingapi/

追加されたメソッド

Flash Player 10では次のメソッドがGraphicsクラスに追加された

  • beginShaderFill(shader:Shader, matrix:Matrix):void
  • copyFrom(sourceGraphics:Graphics):void
  • drawGraphicsData(graphicsData:Vector.):void
  • drawPath(commands:Vector., data:Vector., winding:String):*
  • drawTriangles(vertices:Vector., indices:Vector., uvtData:Vector., culling:String):*
  • lineBitmapStyle(bitmap:BitmapData, matrix:Matrix, repeat:Boolean, smooth:Boolean):void;
  • lineShaderStyle(リリースノートによるとベータでは未実装)

ShaderよるFillとStroke

Pixel BlenderのサポートによりShaderを使った描画APIが追加された。Shaderとは、Pixel Benderのバイトコード(拡張子.pbj)をホストするクラスであり、Flasy PlayerはShaderを通じてPixel Benderにアクセスする。Shaderクラスのインスタンスは、Displayオブジェクトのフィルターやブレンドモード、描画メソッドと併せて使用される。

サンプル

package{
	import flash.display.MovieClip;
	import flash.display.Shader;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.events.Event;
	import flash.net.URLRequest;
	import mx.core.BitmapAsset;
	import flash.utils.getTimer;
	import flash.display.StageScaleMode;
	import flash.trace.Trace;
	[SWF(width="500", height="500")]
	/**
	* ...
	* @author $(DefaultUser)
	*/
	public class ShaderSample extends MovieClip{
		[Embed(source = 'assets/rose.jpg')]
		[Bindable]
		private var _srcImage:Class;
		private var _shader:Shader;
		private var _bmpAsset:BitmapAsset;
 
		public function ShaderSample() {
			super();
			_bmpAsset = new _srcImage() as BitmapAsset;
			stage.scaleMode = StageScaleMode.NO_SCALE;
 
			var shaderLoader:URLLoader = new URLLoader();
			shaderLoader.dataFormat = URLLoaderDataFormat.BINARY;
			shaderLoader.addEventListener(Event.COMPLETE, shaderLoaded);
			shaderLoader.load(new URLRequest("pbj/kaleidoscope.pbj"));
 
		}
 
		private function shaderLoaded(e:Event):void
		{
			var shaderLoader:URLLoader = e.target as URLLoader;
			try
			{
				_shader = new Shader();
				_shader.byteCode = shaderLoader.data;
				_shader.data.src.input = _bmpAsset.bitmapData;
				_shader.data.size.value = [80];
				_shader.data.fade.value = [1];
 
				addEventListener(Event.ENTER_FRAME, drawKaleidoscope);
			}catch (e:Error)
			{
				throw(e);
			}
		}
 
		private function drawKaleidoscope(e:Event):void
		{
			_shader.data.position.value = [mouseX,mouseY];
			_shader.data.angle.value = [getTimer() / 500];
			graphics.clear();
			graphics.beginShaderFill(_shader);
			graphics.drawRect(0, 0, 400, 400);
			graphics.endFill();
		}
	}
}

Vectorでパスを描画

Vector型

新しく加わったVector型は、Array型によく似ているが、次の点で少し異なる。

  • 要素すべてが同じ型でなければならない
  • fixedプロパティにより、vectorが収められる要素数の変更の不可を設定できる
  • Vectorのコンストラクタは、lengthとfixedの2つのオプションを引数に持つ
  • Arrayはブラケット([])で初期化できるが、Vectorではできない。

Vector型を使う理由は、型付けされた配列であるという点、これはパフォーマンスを得るのにとても有利で、特にNumberやintなどのプリミティブな型を要素を持つ時に効果を発揮する。

パスを描く
public function drawPath(command:Vector., data:Vector., winding:String="evenOdd");

drawPathメソッドは、これまでのmoveTo、lineTo、curveToなどの1つ1つ行っていたパスの描画操作をまとめて実行できる便利なメソッドです。第1引数のcommandsには、第2引数のdataに含まれる点それぞれに対応するコマンドを保持します。例えば、moveToなら1、lineToなら2と言うような感じです。この値はGraphicsPathCommandクラスのクラス変数として宣言されています。

public static const NO_OP:int = 0;
public static const MOVE_TO:int = 1;
public static const LINE_TO:int = 2;
public static const CURVE_TO:int = 3;
public static const WIDE_MOVE_TO = 4;
public static const WIDE_LINE_TO:int = 5;

第2引数のdataには各点の座標値を納めるわけですが、これはPoint型ではなくNumber型で宣言されています、Number型にすることでVectorによるパフォーマンス向上の恩恵を受けるわけです。

サンプル

_commands = new Vector.<int>();
_commands[0] = GraphicsPathCommand.MOVE_TO;
_commands[1] = GraphicsPathCommand.LINE_TO;
_commands[2] = GraphicsPathCommand.LINE_TO;
_commands[3] = GraphicsPathCommand.LINE_TO;
_commands[4] = GraphicsPathCommand.LINE_TO;

_data = new Vector.<Number>();
_data[0] = 10;   //x
_data[1] = 10;   //y
_data[2] = 100;
_data[3] = 10;
_data[4] = 100;
_data[5] = 100;
_data[6] = 10;
_data[7] = 100;
_data[8] = 10;
_data[9] = 10;

graphics.beginFill(0x800000);
graphics.drawPath(_commands, _data);
graphics.endFill();

以下ののような書き方もできる

graphics.beginFill(0x008000);
graphics.drawPath(
	Vector.<int>([1,2,2,2,2]),
	Vector.<Number>([110, 10,
		200, 10,
		200, 100,
		110, 100,
		110, 10]));
graphics.endFill();

Windingパラメータ

drawPahtメソッドの第3引数windingパラメータは、パスが交差したり重なり合った場合にどうふるまうかの動作を指定する。この値はGraphicsPathWindingにクラス変数が定義されている

public static const EVEN_ODD:String = "evenOdd";
public static const NON_ZERO:String = "nonZero";

windingはパスがどの方向に描かれているかで、描画される面をポジティブとネガティブに別けるというもので、時計回りにパスが描かれている場合はポジティブ、反時計回りにパスが描かれている場合はネガティブと判断する。

第3引数のwinding の値が"evenOdd" の場合の動作(デフォルト)は、パスが交差する部分の塗りつぶしは行われない。一方、値が"nonZero"の場合は、パスが交差する部分の塗りつぶしを行うかどうかは、windingの方向によって異なる。重なった領域のwindingが同じ方向だった場合は、塗りつぶしを行い、異なる場合、塗りつぶしを行わない。

第3引数windingを"nonZero"にすると、描画に必要なパスの数を減らすことができる。

以下の例では、星形の図形を描いているが、"evenOdd"を指定した場合、10本のラインをパスとして保持する必要があるが、"noneZero"を用いれば半分の5本のラインをパスとして持てばよい事になる。

Drawing Triangles

新しく加わった描画メソッドはdrawPathの他にdrawTraianglesがある。

public function drawTraiangles(vertices:Vector., indices:Vector.=null, uvtData:Vector.=null, culling:String="none");

このメソッドはdrawPathと同じようにVector型を引数に持ち各ポイントを指定する。だた、drawPathの場合はcommandごとに使用する点の個数が異なったが、drawTrianglesは引数に指定された値3点(6つの値)ごとに三角形を描画するのでcommandを必要としない。

このメソッドはPaperVisonなどの3Dエンジンで行われているような、三角メッシュの描画のため用意されたと言ってもいいだろう。

サンプル

 

投射変換

drawTrianglesメソッドは射影変換もサポートしている。uvtDataパラメータにUV値にくわえ、投射変換のスケールファクターTを加えるだけでよい。これまでアフィン変換で疑似的に画像を変形させていたが、これにより歪みなく変形を行えるようになった。

サンプル