Adobe AIR 2.7 버전이 정식 배포되었습니다. 개발자를 위한 SDK와 Runtime이 함께 배포되었습니다. Adobe AIR 2.7은 데스크탑 또는 모바일 환경 모두 동작하며 모바일의 경우 안드로이드 2.2 이상, BlackBerry Tablet OS, iOS 4.0 이상에서 동작합니다. 

현재 Flash Builder 4.5는 아직 Flex기반 iOS 어플 개발이 불가능하지만 Flash builder 4.5가 이번 달에 새로 배포되면 AIR 2.7이 같이 탑재되면서 Flex로 iOS 어플 개발이 가능하게 됩니다. 현재 Flash Builder 4.5에 AIR 2.7이 없어서 Flex로 iOS 개발을 막아놓았던 것 같네요.

iOS를 위한 AIR 어플은 CPU모드에서 4배이상 빠른 렌더링을 지원합니다. 기존에 Flex로 iOS기반 어플을 만들게 되면 퍼포먼스 문제가 있었는데 이 부분이 말끔하게 해결된 듯합니다. 다음 동영상을 보세요. 

Adobe AIR 2.7 : Faster app performance on iOS  http://goo.gl/VJxnR 

 iOS에서 디버깅 및 테스팅 환경이 많이 개선되었다고 합니다. 또한 Android기반에서 SD카드에 AIR 런타임을 설치할 수 있게 되었습니다. 

데스크탑환경에서 Media Measurement를 위한 통합기반이 지원됩니다. Adobe Flash Player 10.3에서 부터 지원되었으면 AIR 2.7에서도 이것을 지원합니다. 관련된 내용은 아래 링크를 참고하세요.

Measuring video consumption in Flash : http://goo.gl/wPcf0 

또한 Acoustic Echo Cancellation를 지원합니다. Flash Player 10.3에서도 지원하고 있습니다. 여기에 관련된 API가 도입됨에 따라 헤드셋없이도 애코조절이 훨씬 원할해집니다.

그리고 HTMLLoader에서 HTML 컨텐츠에 대한 로케이션 제어 권한이 훨씬 향상되었습니다. 과거에 이 부분때문에 고생한 적이 생각난다는..... 

다음 사이트들을 둘러보시면 AIR 2.7을 이해하는데 더욱 도움이 될 것입니다. 

Adobe AIR 2.7 Now Available : iOS apps 4x Faster! : http://goo.gl/5IEIz 
Adobe AIR 2.7 Developer Release Notes : http://kb2.adobe.com/cps/906/cpsid_90612.html 
Adobe AIR 공식페이지 : http://www.adobe.com/products/air/
Download Adobe AIR SDK : http://www.adobe.com/products/air/ 
Adobe Flash Builder : http://www.adobe.com/products/flash-builder.html

글쓴이 : 지돌스타(http://blog.jidolstar.com
지난 2011년 2월말에 Flash Player 11 Incubator 버전이 배포됨에 따라서 3D GPU 가속 렌더링을 위한 Molehill을 미리 경험할 수 있게 되었다. 하지만 Molehill의 등장은 반드시 3D GPU 가속 및 3D 표현 향상만을 의미하지 않는다. 이 관점은 3D 렌더링 엔진을 이용해 2D 렌더링 형태로 활용해도 된다는 관점에서 이해될 수 있다. 기존(현재) Flash Player 10 이하에서 렌더링은 2D를 표현하기 위해 CPU를 이용한 계산으로 렌더링을 하지만 Molehill을 이용하면 이것 조차 GPU를 적용할 수 있으니 기존 2D 게임을 Molehill버전으로 바꿔주면 더욱 쾌적하고 빠른 게임이 될 수 있다.

이 글의 목적은 Molehill을 이용한 2D 그래픽 GPU 가속에 대한 내용을 소개하는데 있다. 그럼 먼저 Molehill에 대해서 간단하게 소개하고 2D 렌더링 속도에 어떤 장점이 있는지 살펴보도록 하겠다.

참고로 아래 글을 통해 Molehill관련 데모와 개발환경 구축방법을 볼 수 있겠다.

Adobe Flash Player 11 Incubator의 "Molehill" 3D를 활용하기 위한 개발환경 만들기http://blog.jidolstar.com/759 



1. Molehill을 이해하기
Flash Player 10.1 이후로 3D API가 공개되었다. 이것은 flash.display.Stage위에 flash.display.DisplayObject기반에서 3D를 다룰 수 있는 API를 추가적으로 제공해준 형태이다. 하지만 완벽한 GPU렌더링을 하지 않으며 z-sort, clipping등과 같은 3D 렌더링을 위한 주요 기능은 전부 배제되었기 때문에 몇몇사람들은 2.5D라고 불렀다.

Molehill에서 3D는 flash.display.Stage위에서 렌더링되는 것이 아니다. 전혀 다른 영역에서 그려지며 flash.display.Stage와는 철저하게 물리적으로 분리되어 있다. 즉 DisplayObject기반으로 돌아가는 것이 아니며 그것과 전혀 연관없는 다른 stage위에서 동작한다. 이와 비슷한 개념은 본인의 블로그의 StageVideo 개념에 대해서 설명하면서 이야기 한바 있다.(StageVideo는 이미 현재 공식배포중인 Flash Player 10.2 기반에서 동작되어지는 부분이다.) StageVideo처럼 별도의 영역에서 렌더링 되어진다는 것이 Molehill에서 지원하는 GPU가속의 비밀(?)인 것이다. 아래 링크를 통해 StageVideo에 대해서 이해할 수 있다.

Flash Player 10.2의 StageVideo에 대해http://blog.jidolstar.com/743

Molehill의 렌더링 영역과 기존 Stage 렌더링 영역이 물리적으로 분리되어 있다는 것은 결국 Molehill만의 별도의 API가 있다는 것을 의미한다. 구체적으로 flash.display.Stage 대신 flash.display.Stage3D 가 존재한다.


위 그림은 Stage3D의 Stage의 관계를 묘사하고 있다. Flash 2D graphics는 Stage 영역을 말하며 Stage3D[0], Stage3D[1]은 Stage3D 영역이다. Stage3D는 Stage위에 올라올 수 없으며 항상 아래에 있다. Stage가 투명인 경우에 Stage3D를 보여줄 수 있다는 점을 말하고 있다. Stage3D는 Stage속성의 stage3Ds.<Vector>를 참고하여 stage.stage3Ds[0] 형태로 접근이 가능하다. 이와는 별도로 StageVideo는 Stage3D 아래에 위치한다. Stage위에 존재할 수 있는 DisplayObject는 Stage3D위에 올라올 수 없다는 점도 기억해둘 필요 있다.

아래 그림은 Stage3D API문서의 일부분을 캡쳐한 것이다.



Stage3D는 flash.display3d.Context3D의 렌더링 영역이며 Stage3D로부터 Context3D를 참조할 수 있다.  Context3D는 일종의 메모리 공간으로 3D 객체를 다루는 데이터 영역이다. (Stage3D와 Context3D의 관계를 이해하기 위해 Bitmap과 BitmapData와의 관계처럼 해석해도 무방할 듯 싶다.) Context3D에서는 z-buffer, back buffer, Color, blend mode, pixel 및 vertex shader 프로그램, vertex stream, vertext indeices, texture 등과 같은 다양한 3D 기능이 담겨있다. 즉 진정한 3D 기능이 모두 주어진 셈이다. 참고로 아래그림은 flash.display3D 패키지에 포함되어있는 Context3D 관련 클래스들이다. 



Molehill API에 익숙해지기 위해 한글문서만큼 좋은 것은 없을 것이다. 아직 초반 기술이라 Adobe에서 제공하는 별도의 한글문서가 없지만 검색해보면 응용형태로 API를 이해해 볼 수 있도록 정리한 고마운 글도 있으니 참고바란다.

Molehill Getting Started :  http://blog.naver.com/q3korea/120126463667


위 문서에 있는 코드를 보면서 느끼겠지만 Molehill API는 매우 저수준의 언어로 구성되어 있다. 결국 학습하기가 어려울 뿐아니라 코딩하는 양도 만만치 않다. 이 때문에 Molehill API를 고수준의 언어로 랩핑(wapping)해준 새로운 3D 라이브러리를 찾기 마련이다. 이미 Away3D, Alternative3D와 같은 유명한 Flash 3D 라이브러리는 기존 Flash Player 9, 10 기반에서 제공하는 API의 인터페이스를 크게 변경하지 않고 Molehill을 경험할 수 있도록 제공하고 있다.


2. 기존 방식과 Molehill과의 2D 렌더링 속도 비교

제목에서 기존방식이라 함은 flash.display.Stage 기반의 렌더링 방식을 의미한다. 기존방식의 렌더링을 위해서는 GPU 도움을 받기 어렵다. 결국 이 기반에서 수많은 렌더링 대상 객체의 수는 제한적일 수 밖에 없었다. 물론 그 안에서도 적절한 최적화를 통해 훌륭한 게임이 많이 나올 수 있었지만 제약은 분명히 있었다.

Molehill을 2D로 표현한다는 것은 실제로는 3D지만 2D처럼 이용한다는 말과 동일하다. 


위 그림은 3D 상에서 사각형을 표현하기 위한 방법을 묘사하고 있다. 기본적으로 3D 객체는 Vertext 3개로 구성된 삼각형 모양의 조각들의 조합으로 이뤄진다. 위처럼 사각형을 하나 만든다면 삼각형 두 조각이 필요한 샘이다. 두개의 삼각형이 한개의 사각형을 이룬다는 점은 하나의 2D 객체 한개를 표현하기 위한 방법으로 사각형 하나면 되고 화면의 시선방향에 대해 사각형의 면이 직각을 이루면 그것이 2D인 것이다. 표현하는 방법은 약간 복잡하더라도 GPU 가속의 큰 도움을 받을 수 있기 때문에 그 정도는 감수할 수 있다.

2.1 기존방식 예제
작년에 필자는 Flash 어플의 속도 개선을 위한 다양한 실험을 했었다. 

Flash 속도 개선을 위한 실험 - 10만개 입자 유체 시뮬레이션 연장전!http://blog.jidolstar.com/671

어떤 언어든 당연한 이야기 이겠지만 ActionScript 3.0으로 만들어지는 코드 한줄 한줄이 Flash 어플 속도에 얼마나 영향을 미칠 수 있는가 알 수 있다. 이외에도 계산이든 렌더링이든지 속도를 향상시킬 수 있는 방법은 여전히 많다. 가령 Pixel Bender, Shader 등을 이용해서 더 빠른 속도를 만들어 낼 수 있다. 하지만 그것도 기존에 나와 있는 다양한 3D 게임들을 따라올법만한 속도는 아닐것이다. 

아래에 위 실험을 통해 사용된 코드를 볼 수 있다.

이 코드를 컴파일 하기 위해 아래 라이브러리 및 클래스가 미리 준비되어야 한다.

com.adobe.utils.AGALMiniAssembler : http://goo.gl/ITcrn 
net.hires.debug.Stats : http://goo.gl/EgZ1s


//출처 : http://wonderfl.net/c/c0Gi/read , http://clockmaker.jp
package 
{
	/**
	 * 수많은 화살표 데모
	 * 고속화를 위한 테스트 
	 * 화살표 1000개 
	 * @author Yasu
	 */
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.utils.*;
	
	import net.hires.debug.Stats;
	
	[SWF(width="465", height="465", backgroundColor="0xFFFFFF")]
	public class NoMolehillTest extends Sprite {
		private const NUM_PARTICLE:uint = 1000;
		private const ROT_STEPS:int = 120;
		
		private var forceMap:BitmapData = new BitmapData( 233, 233, false, 0x000000 );
		private var randomSeed:uint = Math.floor( Math.random() * 0xFFFF );
		private var particleList:Vector.<Arrow> = new Vector.<Arrow>(NUM_PARTICLE, true);
		private var rect:Rectangle = new Rectangle( 0, 0, 465, 465 );
		private var seed:Number = Math.floor( Math.random() * 0xFFFF );
		private var offset:Array = [new Point(), new Point()];
		private var timer:Timer;
		private var world:Sprite = new Sprite();
		private var rotArr:Vector.<BitmapData> = new Vector.<BitmapData>(ROT_STEPS, true);
		
		public function NoMolehillTest() {
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.quality = StageQuality.BEST;
			stage.frameRate = 110;
			
			addChild(world);
			
			// 포스 맵의 초기화를 행합니다
			resetFunc();
			
			// 루프 처리
			addEventListener( Event.ENTER_FRAME, loop );
			
			//시간차이로 포스(force)맵과 색변화의 상태를 변경할 것임
			var timer:Timer = new Timer(1000)
			timer.addEventListener(TimerEvent.TIMER, resetFunc);
			timer.start();
			
			//화살표를 생성
			var dummy:Sprite = new Sprite();
			dummy.graphics.beginFill(0xFFFFFF, 1);
			dummy.graphics.lineStyle(1, 0x0, 1);
			dummy.graphics.moveTo(2, 4);
			dummy.graphics.lineTo(8, 4);
			dummy.graphics.lineTo(8, 0);
			dummy.graphics.lineTo(20, 7);
			dummy.graphics.lineTo(8, 14);
			dummy.graphics.lineTo(8, 10);
			dummy.graphics.lineTo(2, 10);
			dummy.graphics.lineTo(2, 4);
			
			var matrix:Matrix;
			var i:int = ROT_STEPS;
			while (i--)
			{
				matrix = new Matrix();
				matrix.translate( -11, -11);
				matrix.rotate( ( 360 / ROT_STEPS * i )* Math.PI / 180);
				matrix.translate( 11, 11);
				rotArr[i] = new BitmapData(22, 22, true, 0x0);
				rotArr[i].draw(dummy, matrix);
			}
			
			// 파티클을 생성
			for (i = 0; i < NUM_PARTICLE; i++) {
				var px:Number = Math.random() * 465;
				var py:Number = Math.random() * 465;
				particleList[i] = new Arrow(px, py);
				world.addChild(particleList[i]);
			}
			
			// 상태표시 
			addChild(new Stats);
		}
		
		private function loop( e:Event ):void {
			
			var len:uint = particleList.length;
			var col:Number;
			
			for (var i:uint = 0; i < len; i++) {
				
				var arrow:Arrow = particleList[i];
				
				var oldX:Number = arrow.x;
				var oldY:Number = arrow.y;
				
				col = forceMap.getPixel( arrow.x >> 1, arrow.y >> 1);
				arrow.ax += ( (col      & 0xff) - 0x80 ) * .0005;
				arrow.ay += ( (col >> 8 & 0xff) - 0x80 ) * .0005;
				arrow.vx += arrow.ax;
				arrow.vy += arrow.ay;
				arrow.x += arrow.vx;
				arrow.y += arrow.vy;
				
				var _posX:Number = arrow.x;
				var _posY:Number = arrow.y;
				
				var rot:Number = - Math.atan2((_posX - oldX), (_posY - oldY)) * 180 / Math.PI + 90;
				var angle:int = rot / 360 * ROT_STEPS | 0;
				// Math.abs보다 더 빠른 계산을 위해 
				angle = (angle ^ (angle >> 31)) - (angle >> 31);
				arrow.rot += (angle - arrow.rot) * 0.2;
				arrow.bitmapData = rotArr[arrow.rot];
				
				arrow.ax *= .96;
				arrow.ay *= .96;
				arrow.vx *= .92;
				arrow.vy *= .92;
				
				// 좌표 배치 좌표를 정수화해 둡니다
				arrow.x = arrow.x | 0;
				arrow.y = arrow.y | 0;
				
				( _posX > 465 ) ? arrow.x = 0 :
					( _posX < 0 ) ? arrow.x = 465 : 0;
				( _posY > 465 ) ? arrow.y = 0 :
					( _posY < 0 ) ? arrow.y = 465 : 0;
			}
		}
		
		private function resetFunc(e:Event = null):void{
			forceMap.perlinNoise(117, 117, 3, seed, false, true, 6, false, offset);
			
			offset[0].x += 1.5;
			offset[1].y += 1;
			seed = Math.floor( Math.random() * 0xFFFFFF );
		}
	}
}

import flash.display.*;

class Arrow extends Bitmap
{
	public var rot:int = 0;
	public var vx:Number = 0;
	public var vy:Number = 0;
	public var ax:Number = 0;
	public var ay:Number = 0;
	
	function Arrow( x:Number, y:Number) {
		this.x = x;
		this.y = y;
	}
}

위 코드는 아래 링크에서 실행해 볼 수 있다. 
http://wonderfl.net/c/c0Gi/read


아래 화면은 위 코드를 실행시에 CPU 사용율과 함께 스크린 캡쳐를 한 것이다.



1000개의 화살표를 렌더링하는데 40~50 FPS 정도의 속도를 유지하면서 CPU 사용율이 70~80 정도 되었다.(필자 PC 스펙이 너무 구형이라 그럴 수도... ㅡㅡ) 분명 속도 자체는 문제 없겠지만 CPU 사용율이 너무 커서 다른 업무에 방해가 될 수 있다. 결국 CPU 사용율을 줄이기 위해 stage.frameRate를 20~30으로 줄일 수 밖에 없다. 또는 성능에 따른 렌더링 주기 조정(http://diebuster.com/flash/170)을 통해 CPU 점유율을 줄일 수 있다. 



2.2 Molehill을 이용한 2D 렌더링 예제

기존방식으로 렌더링하는 것은 속도 개선 및 CPU 사용율 줄이기에 대한 노하우가 크게 필요하다는 사실을 알았다. 물론 Molehill을 쓴다고 이런 노하우는 필요하다. 그래서 같은 방법으로 노하우를 적용하되 Molehill을 함께 사용한다면 사용자의 경험을 더욱 극대화 시킬 수 있을 것이다.

좋다. 그럼 위 예제를 Molehill 버전으로 변경한 코드를 보자. html에 embed시에 wmode는 반드시 direct로 지정되어야 한다. Flash Builder에서 테스트 하시려면 http://blog.jidolstar.com/759 에서 그 방법을 알 수 있다.

이 코드는 아래 코드가 미리 있어야 하겠다.

com.adobe.utils.AGALMiniAssembler : http://goo.gl/ITcrn 
net.hires.debug.Stats : http://goo.gl/EgZ1s
minimalcomps : https://github.com/minimalcomps


//출처 : http://wonderfl.net/c/4VE6
package 
{
	/**
	 * FP11로의 테스트.5000 파티클.빠르지는 되지만 범용성 없음
	 */
	
	import flash.display.*;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DBlendFactor;
	import flash.display3D.Context3DCompareMode;
	import flash.display3D.Context3DProgramType;
	import flash.display3D.Context3DRenderMode;
	import flash.display3D.Context3DTextureFormat;
	import flash.display3D.Context3DVertexBufferFormat;
	import flash.display3D.IndexBuffer3D;
	import flash.display3D.textures.Texture;
	import flash.display3D.VertexBuffer3D;
	import flash.geom.*;
	import flash.events.*;
	import flash.text.TextField;
	import flash.utils.*;
	import flash.geom.*;
	import net.hires.debug.Stats;
	import com.bit101.components.ComboBox;
	
	[SWF(width="465", height="465", backgroundColor="0xFFFFFF")]
	public class MolehillTest extends Sprite {
		private const TEXTURE_WIDTH:int = 2048;
		private const NUM_PARTICLE:uint = 16380; // 파티클 최고수 
		private var ROT_STEPS:int = 0;
		
		private var num_limit:uint = 5000; // 렌더링 하는 수
		
		private var forceMap:BitmapData = new BitmapData( 233, 233, false, 0x000000 );
		private var randomSeed:uint = Math.floor( Math.random() * 0xFFFF );
		private var particleList:Vector.<Arrow> = new Vector.<Arrow>(NUM_PARTICLE, true);
		private var rect:Rectangle = new Rectangle( 0, 0, 465, 465 );
		private var seed:Number = Math.floor( Math.random() * 0xFFFF );
		private var offset:Array = [new Point(), new Point()];
		private var timer:Timer;
		private var world:Sprite = new Sprite();
		private var rotBmp: BitmapData;
		private var text : TextField;
		
		private var combobox : ComboBox;
		
		
		private var context : Context3D;
		private var program : ShaderProgram;
		private var iBuffer : IndexBuffer3D;
		private var vBuffer : VertexBuffer3D;
		private var uvBuffer : VertexBuffer3D;
		private var texture : Texture;
		private var ortho : Matrix3D = new Matrix3D();
		private var r_rot_steps : Vector.<Number> = Vector.<Number>([0,0,0,0]);
		
		private var vb : Vector.<Number> = new Vector.<Number>();
		private var uvb : Vector.<Number> = new Vector.<Number>();
		private var ib : Vector.<uint> = new Vector.<uint>();
		private const vunit : int = 4;
		private const uvunit : int = 2;
		
		private var uirect : Sprite = new Sprite;
		
		public function MolehillTest() {
			
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.quality = StageQuality.BEST;
			stage.frameRate = 110;
			
			addChild(world);
			
			// 포스 맵의 초기화를 행합니다
			resetFunc();
			
			// 루프 처리
			//addEventListener( Event.ENTER_FRAME, loop );
			
			//시간차이로 포스(force)맵과 색변화의 상태를 변경할 것임
			var timer:Timer = new Timer(1000)
			timer.addEventListener(TimerEvent.TIMER, resetFunc);
			timer.start();
			
			//화살표를 생성
			var dummy:Sprite = new Sprite();
			dummy.graphics.beginFill(0xFFFFFF, 1);
			dummy.graphics.lineStyle(1, 0x0, 1);
			
			dummy.graphics.moveTo(2, 4);
			dummy.graphics.lineTo(8, 4);
			dummy.graphics.lineTo(8, 0);
			dummy.graphics.lineTo(20, 7);
			dummy.graphics.lineTo(8, 14);
			dummy.graphics.lineTo(8, 10);
			dummy.graphics.lineTo(2, 10);
			dummy.graphics.lineTo(2, 4);
			
			var bmpw : int = TEXTURE_WIDTH;
			ROT_STEPS = bmpw / 16; 
			var matrix:Matrix;
			rotBmp = new BitmapData(bmpw, 16, true, 0x0);
			var i:int = ROT_STEPS;
			while (i--)
			{
				matrix = new Matrix();
				matrix.translate( -11, -7);
				matrix.rotate( ( 360 / ROT_STEPS * i )* Math.PI / 180);
				matrix.scale(0.75, 0.75); // 크기를 줄였어요.
				matrix.translate( 8+i*16, 8);
				rotBmp.draw(dummy, matrix);
			}
			
			// 파티클을 생성합니다
			for (i = 0; i < NUM_PARTICLE; i++) {
				var px:Number = Math.random() * 465;
				var py:Number = Math.random() * 465;
				particleList[i] = new Arrow(px, py);
				//world.addChild(particleList[i]);
			}
			
			// ui
			uirect.graphics.clear();
			uirect.graphics.beginFill(0x000000, 0.8);
			uirect.graphics.drawRoundRect(0, 0, 200, 100, 16, 16);
			uirect.graphics.endFill();
			
			combobox = new ComboBox(uirect, 80, 8, "5000", new Array(500, 1000, 5000, 10000, 16380));
			combobox.selectedIndex = 2;
			num_limit = 5000;
			
			addChild(uirect);
			
			// 디버그용의 스탓트를 표시하고 있습니다
			addChild(new Stats);
			
			//
			stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, createContext3D);
			stage.stage3Ds[0].requestContext3D();
			stage.stage3Ds[0].viewPort = new Rectangle(0, 0, rect.width, rect.height);
			
		}
		
		private function createContext3D(e:Event):void 
		{
			context = (e.target as Stage3D).context3D;
			context.configureBackBuffer(465, 465, 0, false);
			context.setRenderToBackBuffer();
			context.setBlendFactors(Context3DBlendFactor.SOURCE_ALPHA, Context3DBlendFactor.ONE_MINUS_SOURCE_ALPHA);
			context.enableErrorChecking = true;
			
			text = new TextField();
			text.textColor = 0xffffff;
			text.text = context.driverInfo;
			text.width = 465;
			text.y = 450;
			addChild(text);
			
			program = new ShaderProgram(context, new VertexShader(), new FragmentShader());
			ortho = MatrixUtil.ortho(rect.width, rect.height, false);        
			r_rot_steps[0] = 1/ROT_STEPS;
			
			for (var i : int = 0; i < NUM_PARTICLE; i++) {
				// 시험 삼아 정적인 다각형 정보와 매프레임 갱신하는 위치 정보를 다른 vertexBuffer로 해 보았지만, 속도적으로는 변화 없음
				vb.push( -8, -8,  0, 0);
				vb.push(  8, -8,  0 ,0);
				vb.push(  8,  8,  0 ,0);
				vb.push( -8,  8,  0, 0);
				
				uvb.push( 0,          0);
				uvb.push( 1/ROT_STEPS,0);
				uvb.push( 1/ROT_STEPS,1);
				uvb.push( 0,          1);
				
				
				ib.push( i*4+0, i*4+1, i*4+2, i*4+0, i*4+2, i*4+3 );
			}
			vBuffer = context.createVertexBuffer(vb.length / vunit, vunit);
			vBuffer.uploadFromVector(vb, 0, vb.length / vunit);
			
			uvBuffer = context.createVertexBuffer(uvb.length / uvunit, uvunit);
			uvBuffer.uploadFromVector(uvb, 0, uvb.length / uvunit);
			
			iBuffer = context.createIndexBuffer(ib.length);
			iBuffer.uploadFromVector(ib,0,ib.length);
			
			try {
				texture = context.createTexture(TEXTURE_WIDTH, 16, Context3DTextureFormat.BGRA, false);
				texture.uploadFromBitmapData(rotBmp);
				context.setTextureAt( 1, texture );
			} catch (e:Error) {
				text.text = e.message;
			}
			
			addEventListener(Event.ENTER_FRAME, loop);
		}
		
		private function loop( e:Event ):void {
			
			context.clear(0.4, 0.4, 0.5, 1); //이 정도치에 clear가 없으면 texture가 사라진다
			
			num_limit = parseInt(combobox.items[combobox.selectedIndex]);
			
			var len:uint = num_limit < particleList.length ? num_limit : particleList.length ;
			var col:Number;
			var index : int = 0;
			for (var i:uint = 0; i < len; i++) {
				var arrow:Arrow = particleList[i];
				
				var oldX:Number = arrow.x;
				var oldY:Number = arrow.y;
				
				col = forceMap.getPixel( arrow.x >> 1, arrow.y >> 1);
				arrow.ax += ( (col      & 0xff) - 0x80 ) * .0005;
				arrow.ay += ( (col >> 8 & 0xff) - 0x80 ) * .0005;
				arrow.vx += arrow.ax;
				arrow.vy += arrow.ay;
				arrow.x += arrow.vx;
				arrow.y += arrow.vy;
				
				var _posX:Number = arrow.x;
				var _posY:Number = arrow.y;
				var rot:Number = - Math.atan2((_posX - oldX), (_posY - oldY)) * 180 / Math.PI + 90;
				var angle:int = rot / 360 * ROT_STEPS | 0;
				// Math.abs의 고속화군요
				angle = (angle ^ (angle >> 31)) - (angle >> 31);
				//arrow.rot += (angle - arrow.rot) * 0.2;
				//arrow.bitmapData = rotBmp;
				
				arrow.ax *= .96;
				arrow.ay *= .96;
				arrow.vx *= .92;
				arrow.vy *= .92;
				
				// 배치 좌표를 정수화해 둡니다
				//arrow.x = arrow.x | 0;
				//arrow.y = arrow.y | 0;
				
				( _posX > 465 ) ? arrow.x = 0 :
					( _posX < 0 ) ? arrow.x = 465 : 0;
				( _posY > 465 ) ? arrow.y = 0 :
					( _posY < 0 ) ? arrow.y = 465 : 0;
				
				vb[index++] = (_posX - 465.0/2)-8;
				vb[index++] = (_posY - 465.0/2)-8;
				vb[index++] = angle >> 0;
				index++;
				
				vb[index++] = (_posX - 465.0/2)+8;
				vb[index++] = (_posY - 465.0/2)-8;
				vb[index++] = angle >> 0;
				index++;
				
				vb[index++] = (_posX - 465.0/2)+8;
				vb[index++] = (_posY - 465.0/2)+8;
				vb[index++] = angle >> 0;
				index++;
				
				vb[index++] = (_posX - 465.0/2)-8;
				vb[index++] = (_posY - 465.0/2)+8;
				vb[index++] = angle >> 0;
				index++;
			}
			vBuffer.uploadFromVector(vb, 0, num_limit*4); 
			
			context.setProgram(program.program);
			
			context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0, ortho, true);
			context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 4, r_rot_steps);
			
			context.setVertexBufferAt(0, vBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
			context.setVertexBufferAt(1, vBuffer, 2, Context3DVertexBufferFormat.FLOAT_2);
			context.setVertexBufferAt(2, uvBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
			
			context.drawTriangles(iBuffer, 0, 2*num_limit);
			context.present();
		}
		
		private function resetFunc(e:Event = null):void{
			forceMap.perlinNoise(117, 117, 3, seed, false, true, 6, false, offset);
			
			offset[0].x += 1.5;
			offset[1].y += 1;
			seed = Math.floor( Math.random() * 0xFFFFFF );
		}
	}
}

import com.adobe.utils.AGALMiniAssembler;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Program3D;
import flash.geom.Matrix3D;

import flash.display.*;

class Arrow// extends Bitmap
{
	public var rot:int = 0;
	public var vx:Number = 0;
	public var vy:Number = 0;
	public var ax:Number = 0;
	public var ay:Number = 0;
	public var x:Number = 0;
	public var y:Number = 0;
	
	function Arrow( x:Number, y:Number) {
		this.x = x;
		this.y = y;
	}
}

class ShaderProgram
{
	public var program : Program3D = null;
	
	public function ShaderProgram(context : Context3D, vsh : AGALMiniAssembler, fsh : AGALMiniAssembler)
	{
		program = context.createProgram();
		program.upload(vsh.agalcode, fsh.agalcode);
	}
}

class VertexShader  extends AGALMiniAssembler
{
	//
	// 
	//  vBuffer0(x,y)     --> attribute(0) : va0.xy
	//  vBuffer1(rot,rsv) --> attribute(1) : va1.x, va1.y
	//  uvBuffer2(u,v)    --> attribute(2) : va2.xy
	//
	// 
	//  projmatrix(transposed)   --> | vc0.x  vc1.x  vc2.x  vc3.x |
	//                               | vc0.y  vc1.y  vc2.y  vc3.y |
	//                               | vc0.z  vc1.z  vc2.z  vc3.z |
	//                               | vc0.w  vc1.w  vc2.w  vc3.w |
	//
	//  texture coord step       --> vc4.x   (1/rotation steps)
	//
	// 
	//  position                 --> op.xyzw
	//
	// 
	//  texture coord            --> v0.uv
	//
	//  m44 op, va0, vc0             position = (x,y) * projmatrix
	//  mov v0, va2                  uv = (u,v)
	//  mul vt0.x, va1.x, vc4.x      
	//  add v0.x, va2.x, vt0.x       u = u + (rot*texture_coord_step)
	//
	private var src : String =
		"m44 op, va0, vc0 \n" + // m33라도 좋을지도
		"mov v0, va2 \n" +
		"mul vt0.x, va1.x, vc4.x \n" +
		"add v0.x, va2.x, vt0.x \n" +
		"";    
	
	public function VertexShader()
	{
		assemble(Context3DProgramType.VERTEX, src);
	}
}

class FragmentShader  extends AGALMiniAssembler
{
	private var src : String =
		"mov ft0, v0\n" +
		"tex ft1, ft0.xy, fs1 <2d,repeat,nearest>\n" + 
		"mov oc, ft1\n";
	
	public function FragmentShader()
	{
		assemble(Context3DProgramType.FRAGMENT, src);
	}
}
class MatrixUtil
{
	public static function ortho(w : int, h : int, rev : Boolean) : Matrix3D
	{
		return new Matrix3D(Vector.<Number>([2/w, 0, 0, 0,  0, rev?-2/h:2/h, 0, 0,  0, 0, 1, 0,  0, 0, 0, 1]));
	}
	
}


위 코드는 아래 링크를 통해 실행해 볼 수 있다.
http://escargot.la.coocan.jp/molehill_fast/index.html


아래 화면은 화살표를 5000개로 맞춰놓고 렌더링한 캡쳐화면이다. 기존방식보다 4000개 이상 처리함에도 불구하고CPU 점유율과는 비교가 안될 정도로 떨어졌고 FPS도 50~60사이이다. 


아래 화면은 16380개로 올린 결과 화면이다. CPU 점유율은 24%로 전보다 다소 올라갔으나 FPS는 변함이 거의 없다. CPU 점유율이 올라간것은 as3 코드 loop 부분이 더 복잡해서일 뿐이다. 


두가지 결과만 보더라도 Molehill을 통한 GPU 가속은 꽤나 유용함을 금방 알 수 있다. 
 
아래 링크의 예제를 통해 같은 방법으로 비교해보는 것도 괜찮을 것 같다.

기존방법 Clear Water: http://wonderfl.net/c/9R8a
Molehill이용 Clear Water  : http://wonderfl.net/c/enj6
관련 기술 설명 : http://goo.gl/eySSG


3. Molehill 기반 2D framework 소개 

Molehill을 이용해 2D를 렌더링하는 것이 얼마나 이득이 될 수 있는가 알아보았다. 이러한 이득은 곧바로 필요성으로 이어져 관련 framework 개발로 이어질 수 있다. 찾아보니 실제로 그런 프로젝트가 있었다.

소개하고자 하는 M2D라는 오픈소스 프로젝트는 Molehill을 이용해 2D을 표현하도록 하도록 하는데 목적이 있다. Molehill의 저수준의 언어 접근성을 고수준으로 만들어주어 개발이 용이하게 만든것이 특징이다. 이는 iOS기반 GPU가속 2D라이브러리인 Cocos2D와 같은 필요성에서 탄생된 프로젝트이다.



아직 진행중인 프로젝트이기 때문에 관련된 문서도 없고 기능도 제약이 있다. 

ND2D라는 라이브러리도 있다. 


ND3D를 만든 개발자가 Molehill 버전의 2D 엔진인 ND2D를 만든것이다.
위 사진은 아래 링크에서 실행해 볼 수 있다.
http://www.nulldesign.de/2011/03/10/nd2d-molehill-2d-engine/ 

소스는 아래 링크에서 다운받을 수 있겠다.
https://github.com/nulldesign/nd2d

M2D보다는 ND2D가 더 좋아보인다. ^^


4. 정리하며 

지금까지 내용을 통해 Flash Player 차세대 렌더링 엔진 Molehill을 이용해 2D 표현시 어떤 장점이 있을까 객관적인 자료를 찾아보고 분석해보았다. Molehill을 이용해 GPU 가속을 할 수 있다는 것 자체는 큰 장점이긴 하나 그만큼 연구해야할 내용은 더 많아진 것은 사실이다. 앞으로 Flash Player가 모바일에서 활약하는 날이 올때 그 빛은 엄청 발할 것이라 판단한다. 그러므로 우리 개발자들은 미리 준비할 필요가 있겠다.

Flash Player 11 Incubator를 통해 차세대 3D 엔진인 Molehill을 미리 경험할 수 있다는 것은 큰 혜택이다. 새롭게 연구해야하는 과정은 참 어렵다. 필자도 이런 어려운 과정을 겪고 있으며 혼자 이런 연구를 하는게 무척이나 힘들다. 뭔가 이러한 일을 함께 하는 사람들이 많았으면 하는 바램이다.


5. 관련글


 글쓴이 : 지돌스타(http://blog.jidolstar.com/763)


올해들어 Adobe Flash/AIR에 관련된 기술이 모바일의 흐름에 따라 급변하고 있습니다. 바쁘게 일하고 있는 사람으로써 이런 신기술을 흡수하기가 너무 어려울 정도입니다.

최근 새로운 CS 5.5버전이 발표되었고 Flash Builder 4.5가 함께 소개되었습니다. Flash Builder 4.5부터는 안드로이드 뿐만 아니라 블랙베리, iOS기반 어플도 개발할 수 있게 되었습니다. 현재 브라질에서 열리고 있는 Flash Camp에서 Flash Runtime의 미래라는 주제로 멀티스레드지원, 빠른 GC, 새로운 숫자형, Stage3D, StageVideo, Threaded video pipeline등의 차세대 Flash에 추가될 내용들이 소개되어지고 있고요. Adobe가 Flash의 GPU가속에 대한 지원을 아끼지 않으면서 3D렌더링에 대한 다양한 API가 만들어져 이미 Flash Player 11 Incubator 버전이 개발자들 사이에서 실험되고 있습니다. 모두 모바일에 초점이 맞추어 제한된 화면, 제한된 밧데리, 전혀 다른 사용자 경험에 따라 변해가고 있다는 생각입니다. 굉장히 전략적이고 빠른 대응을 하고 있습니다. 결국 시장의 급격한 변화에 Flash 기술이 따라가고 있으며 어찌보면 Cross Device, Cross Platform분야에서 만큼은 매우 선도적입니다.

Flash 기술이 급변함에 따라 예전처럼 쉽게 접근할 수 있던 Flash가 이제 더 이상 아닌 것처럼 느껴집니다. 더욱 전문성이 더해지기 시작했고 Flash의 원래 장점이였던 개발의 저변화를 통한 다양한 컨텐츠 생산이 약간 없어지는 상황이 발생하지 않을까라는 조심스런 추측도 합니다. 하지만 한편으로는 Flash IDE는 여전히 디자이너 접근을 용이하게 해주기 때문에 별 영향이 없을 것 같다는 생각도 합니다. 그러나 분명한 것은 모바일 디바이스의 대중화에 따른 사용자 경험이 바뀌고 이에 따라 기존 웹중심의 컨텐츠는 모바일 중심으로 변화하고 있다는 것에 대해 발빠르게 대응해야한다는 점은 인정해야할 사실이고 또한 준비해야합니다.

새로운 트랜드 대응에 도움을 주기 위해 관련된 정보를 링크해둡니다. 참고하시고 이를 통해 국내에서도 관련된 다양한 정보가 쏟아져 나오길 기대해 봅니다.


아래는 관련 동영상입니다.

글쓴이 : 지돌스타(http://blog.jidolstar.com)

어도비는 2011년 2월 말에 Flash Player Incubator를 배포했다. 이것은 Flash Player 11이 정식 배포되기 전 개발자들이 테스트할 수 있도록 Adobe에서 실험용 버전으로 배포한 것이다. 다음 링크는 Flash Player Incubator 공식 페이지이다.

Adobe AIR and Adobe Flash Player Incubator : http://goo.gl/aFqZH

이 글은 Flash Player Incubator에 대한 간략한 소개와 함께 Flash Builder 개발환경을 만들어 테스트하는 방법을 다룬다.(처음 해보는 사람을 위해서 자세하게 쓰려고 노력했다.)

1. Flash Player Incubator 에 대해

이번에 개발용으로 배포된 Flash Player Incubator는 다음 두 가지 feature가 추가되었다.

1.1 "Molehill" 3D API
GPU가속을 위한 low-level 3D API를 지원한다.  기존 Flash Player 10.2에서 지원하지 못했던 z-buffering, stencil color buffer, fragmentvertex shader, 큐브 텍스처 등을 기본으로 지원한다. 이 API를 사용하면 윈도우에서는 DirectX 9, 리눅스와 MacOS에서는 OpenGL 1.3, 그리고 모바일에서는 OpenGL ES 2.0 기반에서 렌더링이 될 수 있도록 한다. 만약 여기에 상관되어 있지 않다면 기존처럼 CPU 렌더링한다. 기존 Flash Player 10.1 에서는 3D API가 있긴 하지만 z-buffering을 지원하지 않으면서도 수백 개의 폴리곤을 CPU 렌더링하는데 30fps가 나왔던 반면, Molehill에서는 z-buffering이 적용된 수십만 개의 폴리곤을 HD급으로 렌더링하는데 60fps가 나온다. 단, 웹브라우져에서 이를 실행하는 경우, GPU가속을 하기 위해서는 wmode가 direct로 설정되어야 한다. 다음 페이지는 Flash Incubator의 Molehill 3D API에 대한 Adobe 공식 페이지이다.

3D APIs for Adobe Flash Player and Adobe AIR : http://goo.gl/yLdvx

3D APIs는 매우 low-level API이기 때문에 직접 다루면 개발 생산성과 효율성에 문제가 있을 수 있으므로 Alternative3D, Away3d, CopperCube, Flare3D, Minko, Sophie3D, Yogurt3D와 같은 ActionScript 3D 프레임워크들로 좀더 쉽게 개발할 수 있는 환경이 조성될 것이다. 이들 중에 조사한바 다음 프레임워크는 Molehill 3D APIs를 지원하고 있다.

1.2 Cubic Bezier Curves
flash.display.Graphic에 cubicCurveTo 메서드가 추가되었다. 이 메서드는 커스텀 ActionScript 코드를 사용하지 않고 쉽게 Cubic Bezier Curve를 그릴 수 있게 해준다. 어떤 것인지 궁금하면 다음 동영상으로 보자.

http://www.vimeo.com/10187896
http://goo.gl/yooER

이 글은 위 두 가지 feature중 Flash Player Incubator 환경에서 "Molehill" 3D APIs를 테스트할 수 있는 개발환경을 구성하는 방법을 소개한다. 특별히 Flash Builder Burrito를 기반으로 설명할 것이다. 아쉽지만 Flash CS5 IDE 사용방법을 몰라서 이에 대한 설명은 하지 않겠다. 대신 Flash CS5에서 테스트 환경 구성은 다음 글을 통해 공부할 수 있다.

http://blog.naver.com/q3korea/120125249427


2. Flash Player Incubator 버전 설치하기 

Flash Player Incubator는 현재 MS Windows, MacOSX, Linux용으로 배포하고 있다. 
http://labs.adobe.com/downloads/flashplatformruntimes_incubator.html

설치를 할 때 문서 아래에 Uninstaller를 먼저 실행하고 설치하기 바란다. 이 버전은 다 개발용이기 때문에 Debugging 기능이 내장되어 있다. 설치를 하지 않으면 아래 예제들을 실행할 수 없다.

참고로 Google Chrome을 사용하면 구동되는 Flash Player를 선택할 수 있다. 기존 Flash Player를 지우지 않고 전환해서 테스트 해볼 수 있기 때문에 유용하다. 다음 글을 참고한다.

Google Chrome 에서 Flash Player 10과 11(Molehill)을 전환하여 사용하는 방법 : http://ufx.kr/blog/142 


3. Molehill 3D 경험하기

Molehill 3D API의 결과물을 한번에 볼 수 있는 동영상을 경험해보길 바란다. 
http://blog.theflashblog.com/?p=2638

다음 링크를 통해 Molehill 3D APIs 를 이용한 다양한 Flash 어플들을 실행해 볼 수 있다. 단, Flash Player Incubator 버전이 여러분의 브라우저에 설치 되어야만 제대로 볼 수 있다.
 

http://molehill.zombietycoon.com/


http://alternativaplatform.com/en/demos/maxracer/


http://alternativaplatform.com/ru/demos/metro2033online/


http://www.lidev.com.ar/demos/fractals/tree/broomstick/



http://www.mcfunkypants.com/2011/molehill-terrain-demo/



http://infiniteturtles.co.uk/projects/away3d/broomstick/ShallowWaterDemo.html


http://www.swfgeek.net/2011/02/28/cubewall-using-away3d-4-0broomstick-jiglibflash-on-molehill/



http://not-so-stupid.com/clients/not-so-stupid/away4/duck/




http://aerys.in/minko-quake-3



http://infiniteturtles.co.uk/projects/away3d/broomstick/LoaderOBJTest.html




http://infiniteturtles.co.uk/projects/away3d/broomstick/EnvMapTest.html




http://infiniteturtles.co.uk/projects/away3d/broomstick/AnimBlendTest.html




http://infiniteturtles.co.uk/projects/away3d/broomstick/EnvMapDiffuseTest.html



http://acemobe.com/dungeon/demo.php



http://www.ambiera.com/coppercube/demo.php?demo=backyard



http://iflash3d.com/performance/how-fast-is-molehill/



http://ryanspeets.com/uncategorized/adobe-releases-molehill/



http://www.nulldesign.de/wp-content/uploads/2011/nd2d_spritesheets/Main.html



http://www.ringo.nl/projects/jiglibflash/Away3DGridSystem.html
http://www.ringo.nl/projects/jiglibflash/Away3DTriangleMesh.html
http://www.ringo.nl/projects/jiglibflash/Away3DStackingTest.html
http://www.ringo.nl/projects/jiglibflash/Away3DTerrainTest.html
http://www.ringo.nl/projects/jiglibflash/Away3DCarDrive.html

더 많은 데모 : http://blog.theflashblog.com/?p=2607


4. Flash Player Incubator용 API 문서 보기

Flash Player Incubator에 적용된 API를 학습하기 위한 문서이다. 다운로드 받아 보면 좋겠다.
Download the documentation for Flash Player 11,0,0,58 

API 문서를 보기 전에 아래 글을 선행적으로 본다면 이해하는데 도움이 될 것이다.
Digging more into the Molehill APIs
MoleHill Getting Started


5. Flash Builder Burrito에 Flash Player Incubator 개발환경 만들기

Flash Builder Burrito는 beta 버전으로 Flex Hero 및 모바일 개발을 할 수 있는 환경을 제공한다. Flash Builder Burrito에 함께 포함되어 있는 Flex SDK는 Flash Player 10.1 기반으로만 개발할 수 있기 때문에 Flash Player Incubator 환경에서 개발할 수 있는 환경을 따로 구축할 필요가 있다. 다음 과정을 통해 개발 환경을 구축 할 수 있다.

5.1. 다운로드
개발 환경을 구성하기 전에 다음 링크를 통해 해당 자료를 다운로드 받는다.

- Flash Player 11,0,0,58 Incubator : http://goo.gl/yXySu
- Flash Builder Burrito(로그인 필요) : http://goo.gl/iM7g
- playerglobal.swc : http://goo.gl/NnEyx
- Flex SDK 4.5.0.19786 : http://goo.gl/2lAIb

5.2. 설치

설치하는 과정은 아래 순서대로 따라 하면 되겠다. 복잡하지 않으니 천천히 하도록 하자.

첫 번째로 Flash Player 11,0,0,58 Incubator를 설치한다. 이 글대로 진행했다면 이미 설치가 되었을 것이다. 설치가 정상적으로 이루어졌다면 해당 브라우저에서 Flash Player가 구동이 될 때 화면 아래 Flash Player 11,0,0,58 문구가 고정되어 새겨져 있을 것이다.

두 번째로 Flash Builder Burrito를 설치한다. Flash Builder Burrito는 일종의 Flash관련 어플을 개발하는 Adobe공식 통합개발도구(IDE)이다. Flash Develop, FDT등 다양한 툴이 있긴 하지만 여기서는 Flash Builder Burrito만 다룬다. 개인적으로는 Eclipse plug-in 버전을 다운받아 설치할 것을 권장 하지만 Flash Builder 에 제작 환경에 경험이 없다면 그냥 All-in-one 버전으로 설치한다.

세 번째로 Flex SDK 4.5.0.19786를 압축을 풀어 {Flash Builder Burrito 설치 경로}/sdks/에 복사해 넣는다. 윈도우라면 /Program Files/Adobe/Adobe Flash Builder Burrito/sdks/flex_sdk_4.5.0.19786 이 될 것이다. 이 SDK는 Flash Player 10.2에 대응하도록 되어 있다. 

네 번째로 다운받은 flashplayer_inc_playerglobal_022711.swc를 {Flash Builder Burrito 설치 경로}/sdks/frameworks/libs/player에 11.0 폴더를 만들고 복사한다. 이름을 playerglobal.swc로 수정한다. playerglobal.swc 는 Flash Player 11.0 이상의 API를 이용해 개발하고 컴파일할 수 있도록 하기 위해 필요하다. 

다섯 번째로 Flash Builder Burrito를 실행한다. 중간에 워크스페이스 경로를 설정하는 부분이 있는데 원하는 경로로 설정하면 되겠다. 이 경로상에 여러분의 Flash, AIR 프로젝트 들이 생성될 것이다.


5.3. 설정

Flash Builder를 이용해 몇 가지 설정을 통해 개발환경을 만들어보자.

첫 번째로 메뉴에서 Window > Preference로 들어간다. 창이 뜨면 왼쪽에 Flash Builder를 펼치고 그 안에 Installed Flex SDKs를 선택한다. 아래 화면과 같이 나올 것이다. 
 


여기에서 아까 설치했던 Flex SDKs를 추가한다. 좌측에 Add 버튼을 누르고 {Adobe Flash Builder Burrito 설치경로}/sdks/flex_sdk_4.5.0.19786 를 선택한다. 이때 Name은 Flex 4.5(FP11)로 정하자. 그리고 추가된 SDK를 위 그림처럼 Default SDK로 체크한 뒤 OK를 누른다.

두 번째로 ActionScript 3.0 프로젝트를 생성하고 몇 가지 설정을 하겠다. 메뉴에서 File > New > ActionScript Project 를 선택한다. 그럼 아래와 같은 창이 뜬다. Project name에 아무 이름이나 넣는다. 우리는 FP11Test로 했다. 참고로 Flex SDK version이 이전에 선택한 SDK가 나옴을 확인할 수 있다. 필요하다면 여기서 설치된 SDK를 선택할 수 있음을 의미한다. 우리는 기본 SDK를 사용할 것이므로 그대로 두고 Finish 버튼을 누른다. 



세 번째로 Flash builder의 Package Explorer 창에 FP11Test 프로젝트가 만들어졌을 것이다. 

프로젝트는 src와 html-template, bin-debug 폴더가 있다. src는 여러분이 만들 actionscript 3.0 기반 코드이며 여기서 기본적으로 만들어진 FP11Test.as는 FP11Test 클래스이며 flash.display.Sprite 기반으로 만들어졌다. 일종의 Main 클래스이다. html-template는 배포를 위해 사용하는 것으로 컴파일된 swf를 웹브라우져상에 배포하는데 있어서 필요한 html, javascript 코드가 담겨 있다. 개발자는 필요하다면 이 코드를 수정하면 컴파일 시 반영된다. bin-debug는 html-template를 기반으로 컴파일 된 swf와 함께 컴파일 된 결과물이다. 이는 실제배포 소스는 아니며 디버깅용도로 사용된다. flash builder상에서 이 어플을 실행하면 FP11Test.html이 웹브라우저상에 실행되며 그 안에 FP11Test.swf가 포함되어 실행된다. 

Flex 4.5(FP11) SDK를 사용하고 있음을 보여주고 있다. 이전에 Flex 4.5(FP11) SDK에 playerglobal.swc를 복사해뒀던 것을 기억할 것이다. 하지만 여기서 보여지고 있는 playerglobal.swc는 Flash Player 10.2 버전의 API를 담은 SWC이다. 우리는 아까 복사해둔 11.0 버전을 지원하는 playerglobal.swc가 선택이 되도록 해야 한다. 


위 그림상에서 보는 데로 프로젝트(FP11Test)를 선택한 상태에서 메뉴의 Project > Properties를 선택하자. 아래 그림과 같은 창이 나올 것이다. 오른쪽 메뉴에서 ActionScript Compiler를 선택한 뒤 Adobe Flash Player options에 Use a specific version을 11.0.0으로 바꾼다. 또한 Compiler Options에 -swf-version=13를 넣는다. HTML wrapper는 그대로 둬도 되지만 Check target player version과 Enable integration with browser navigation은 의미가 없으므로 체크를 하지 않도록 한다. 그리고 OK 버튼을 누르면 되겠다. 



마지막으로 Flash Player 11환경에서 GPU 가속을 시키려면 wmode가 direct로 설정되어 있어야만 한다. 프로젝트상에 html-template내 index.template.html을 연다. 참고로 이때 더블 클릭하면 웹브라우저가 실행되어 버린다. 더블 클릭하지 말고 마우스 오른쪽 버튼을 눌러 Open With > Text Editor로 열면 html 소스코드를 볼 수 있다. (더블클릭때마다 웹브라우저를 열지 않는 방법이 있다. 메뉴 > Window > Preference > General > Editors > File Associations를 참고하자.) index.template.html 내에 스크립트 상에 var params = {}; 부분이 있다. 그 아래 params.wmode = "direct";를 추가하자. 
 

5.3. 실행 
이제 실행해볼 수 있게 되었다. Ctrl+F11(Run) 또는 F11(Debug)를 눌러 실행해보자. 아래 화면처럼 브라우저 창에 Adobe Flash Player 11 (11,0,0,58d) (Incubator build)가 뜨면서 실행되었으면 성공이다. 만약 실행이 안되거나 컴파일 에러가 난다면 위 과정을 다시 살펴보길 바란다.



5.4. 간단한 코드 짜보기 

이제 Molehill 3D API를 직접 적용해보자. 여기서는 소스 코드를 분석해서 설명하기 보다 그저 실행해보는데 목적이 있음을 알아두자.

아래 링크로 가면 Molehill 3D API에 대한 소개와 간단한 테스트 코드가 있다. 

MoleHill Getting Started : http://labs.jam3.ca/2011/03/molehill-getting-started/ 

이 소스는 AGAL 어셈블러인 AGALMiniAssembler 소스가 필요하다. 
AGALMiniAssembler.as : http://goo.gl/ITcrn


아래 링크로부터 이 두 개 소스를 받자.


이것을 압축을 풀어 프로젝트 src에 복사하자. 그리고 Ctrl+F11이나 F11로 실행하면 다음과 같은 화면을 볼 수 있다. 



다른 소스도 테스트 해보자.
먼저 프로젝트 내에 src/(Defaul package)를 선택한 다음 오른쪽 마우스 버튼을 눌러 New > ActionScript Class를 선택한다.

두 번째로 창이 뜨면 Name에 Cube를 넣고 Finish를 한다.

세 번째로 아래 링크에서 샘플 소스를 복사한 뒤 아까 만든 Cube.as를 선택해 이전 코드를 삭제하고 붙여넣자.
http://goo.gl/ITcrn

네 번째로 아래 그림처럼 Cube.as를 선택하고 마우스 오른쪽 버튼을 눌러 Set as Default Application을 선택한다. 이렇게 하면 이 프로젝트의 기본 Main 실행 클래스가 Cube.as가 된다. 이 상태에서 Ctrl+F11이나 F11를 눌러 실행해보자. 


실행 시 Bad input size라는 Error가 발생한다면 IE내에서 실행하는 Flash Player의 버그이다(참고 : http://blog.jidolstar.com/656). 이 때는 아래 코드로 대체해보자.


성공적으로 실행하면 다음과 같은 화면을 볼 수 있을 것이다. 


이 소스에 대한 설명은 http://ltslashgt.com/2011/02/28/molehill-spinning-cube/ 를 참고한다.


6. 정리하며
지금까지 Flash Player Incubator 환경에서 Molehill 3D를 테스트 해볼 수 있는 개발환경을 구축하고 테스트하는 방법을 알아보았다. 하지만 이 글은 Molehill 3D API에 대한 자세한 설명을 배제했다. 이 글 다음에는 Molehill 3D API에 대한 내용을 정리할 계획을 가지고 있다. 

Molehill 3D API를 이용한 마지막 2개의 테스트 소스를 보면 알겠지만 굉장히 접근하기 형태의 Native API이기 때문에 코딩으로 직접 3D를 표현하는 것은 질 좋은 3D Flash 어플을 만드는데 한계가 있다. 그렇기 때문에 Away3D나 Alternativa3D와 같은 프레임워크를 도입해야 하는 이유가 여기에 있는 것이다. 이 부분에 대해서도 이후에 글을 적어보려고 한다. 

앞선 테스트 어플들에 3D가 아닌 2D화면도 봤을 것이다. Molehill이 무조건 3D에서만 GPU를 이용하는 것은 아니다는 것을 보여준다. 기존에 많은 2D Flash 컨텐츠도 Molehill을 적극 활용하면 생각지도 못했던 양질의 퍼포먼스를 기대할 수 있다는 것을 보여주는 셈이다. 일종에 아이폰의 OpenGL ES기반으로 2D를 표현하기 위한 Cocos2d가 있듯이 Flash에서도 이러한 형태로 표현할 수 있음을 알 수 있다. 아래 링크의 동영상을 보면 그 이유를 알 수 있을 것이다.
http://clockmaker.jp/blog/2011/03/molehill_video/ 

Flash Player에 3D 기능을 추가됨에 따라 Unity3D에 Flash Player에서도 동작할 수 있도록 해주는 기능도 포함되었다. 이것은 Unity3D 개발자나 Flash 개발자 양쪽에 꽤 흥미로운 사실이다. 

 
아직 Flash Player 11이 정식오픈 되려면 시간이 필요할 것이다. 버그 수정을 거치면서 안정화를 시켜야 하기 때문이다. 

Flash 3D가 표현된다는 것은 무조건 좋은 일만은 아니다. Flash는 웹브라우저 및 크로스 플랫폼에서 운용되기 때문에 접속할 때마다 새로 자원을 로드 해야 한다. 이는 자원을 로컬에 저장해두는데 제약이 있기 때문인데 결과적으로 접속할때마다 필요한 자원을 로드함에 있어서 2D자원보다 3D자원이 훨씬 크고 관리하기 어렵다. 이는 위에 이미 소개한 Flash 3D 예제를 보면서 느꼈을 것이다. 멋진 3D 화면을 보기 위해 자원을 로드하는데 꽤 오랫동안 기다려야 한다. 물론 AIR로 개발한다면 상관없겠지만 웹기반에서 소셜게임을 만든다면 이야기가 다르다. 이 말은 자원관리가 그만큼 어려워지고 전문적으로 해야함을 의미한다.

그럼에도 불구하고 Flash가 3D를 표현하는데 GPU를 지원한다는 사실만으로도 많은 장점이 있기에 3D를 준비해야 차기 Flash 시장의 미래를 선도할 수 있을 것이다. 미리 준비할 필요가 있다.
 

7. 관련사이트 
Adobe AIR and Adobe Flash Player Incubator : http://goo.gl/pvwzd
Flash Player 11,0,0,58 Incubator Release Notes : http://goo.gl/FlH7C
Flash Player 11,0,0,58 Incubator 다운로드 : http://goo.gl/yXySu
Digging more into the Molehill APIs : http://goo.gl/d2WYu
Away3d 4.0 Alpha : http://goo.gl/bZBav
Alternativa 3D  : http://goo.gl/jqfE
Flare3D 2.0 Pre-release : http://goo.gl/1vgCA 
Flash CS5 환경에서 테스트 : http://blog.naver.com/q3korea/120125249427
Molehill Getting Start : http://blog.naver.com/q3korea/120126463667 
Molehill spinning cube : http://ltslashgt.com/2011/02/28/molehill-spinning-cube/
Unity, Flash & 3D on the web : http://goo.gl/OAY1q
 
글쓴이 : 지돌스타(http://blog.jidolstar.com/759
지난해 2010년 11월 30일 Flash Player 10.2 Beta가 처음 배포되면서 가장 눈에 띈 것은 바로 StageVideo가 아닌가 싶다. 이전 버전 Flash Player 10.1은 H.264 코덱 영상의 하드웨어 가속 기능을 강화하여 동영상 재생시 CPU 점유율을 감소시켰다는데 의미가 있었다. 10.2에서는 비디오 랜더링 파이프라인을 더욱 확장하고 색상 보정 기능과 이미지 스케일링등의 각종 기능을 추가했다. 즉, GPU가속 기능을 더욱 확대했다는 것을 의미하며 이로써 1080P 해상도의 HD 동영상을 보여주는데 CPU 점유율 0%에 가까운 수준이 되었다고 한다. 이것은 새로운 비디오 렌더링 방식인 StageVideo를 도입한데서 비롯된다. 이 문서는 StageVideo 에 대해서 이해하는 것을 목적으로 한다. (현재 시점에서 Flash Player 10.2이 공식 배포중이다.)


StageVideo 구조에 대해 
Flash Player 10.2 부터 지원하는 StageVideo는 어떻게 동작하는 것일까? 어떻게 해서 CPU 점유율을 줄이고 GPU 가속을 받을 수 있을까? 이런 부분에 대한 궁금증이 생길것이다. 

아래 화면은 전통적으로 사용된 기존 Flash Player에서 Video 시각객체(DisplayObject) 렌더링하는 방식을 묘사하고 있다. 


기존에 Flash Player에서 Video를 보여주는 위해 시각객체의 부모격인 flash.display.Stage위에 추가해야만 했다. 이 방식의 문제점은 동영상 렌더링을 위한 Video객체가 다른 시각객체와 연결되어 있어 CPU 점유율이 높아질 수 밖에 없는 구조라는 점이다. GPU를 적극활용하기에는 물리적으로 불리한 방식이다. 

반면에 다음 그림은 비디오를 렌더링하기 위해 Flash Player 10.2부터 지원하는 StageVideo를 사용했을때를 묘사한다.


전통적인 방식과 달리 Flash Player 10.2부터는 비디오를 렌더링하기 위해 flash.display.Stage의 도움을 받지 않는다. flash.display.Stage 뒤에 StageVideo가 물리적으로 분리가 되어 있어 다른 시각객체들과 연관성 없이 동작이 가능해졌다. 이렇게 됨으로써 flash.display.Stage위에 시각객체들이 그래픽 가속을 받지 않더라도 StageVideo만은 GPU가속이 가능하게 된 것이다. 


StageVideo 사용여부에 따른 CPU 점유율 

운영체제 및 그래픽카드별로 StageVideo를 사용여부에 따른 CPU 점유율에 대한 비교 표가 다음 링크에 공유되어 있다. 

Stage Video with the Brightcove Player : http://goo.gl/ZALsa


CPU 점유율이 분명 개선이 되었다는 것을 확인할 수 있다. 

다음 동영상은 지난 2010 Adobe MAX 행사에서 StageVideo 사용여부에 따른 퍼포먼스를 보여주고 있다.



결국 StageVideo를 이용하면 다른 시각객체들과 무관하게 되어 GPU를 이용해 렌더링함으로써 CPU점유율과 메모리 사용량이 많이 줄어든다는 것을 알 수 있다.


Flash Player 10.2 환경에서 StageVideo를 느껴보자.

Adobe에서 제공하는 Big Buck Bunny라는 제목의 HD 동영상을 통해 여러분은 직접 StageVideo 환경을 경험해볼 수 있다. 아래 링크로 방문해보길 바란다.




StageVideo Running : true가 되어 있는지 확인하고 플레이 해보길 바란다. false라면 Flash Player 10.2가 설치가 되었는지 확인해보고 10.1 이하라면 다음 링크에서 10.2 버전을 다운로드 받아 설치하면 되겠다. 

Adobe Flash Player 10.2 다운로드 : http://get.adobe.com/kr/flashplayer


StageVideo의 제약사항 
StageVideo는 다른 시각객체(DisplayObject)와 별도의 구조를 가진다. 이렇게 됨으로써 비디오 객체가 기존 시각객체가 가지는 특징 및 속성을 활용하는데 제약이 따른다. 가령 다음과 같은 제약사항이 있다.

- StageVideo는 회전할 수 없다. 단지 90 회전만 가능하다.
- StageVideo는 ColorTransform 또는 3D transform을 적용할 수 없다.
- StageVideo 객체는 alpha채널, blendmode, filter, mask, scale9Grid등을 적용할 수 없다.
- StageVideo에 렌더링 되는 영상은 BitmapData 객체로 복사할 수 없다.
- StageVideo에 렌더링 되는 영상은 bitmap 캐쉬 할 수 없다.
- 영상은 SWF 파일에 Embed 될 수 없다. 반드시 NetStream 객체를 이용해서 운영되어야만 한다.
- wmode가 transparent나 opaque인 경우는 GPU 가속에 제한된다. wmode를 direct로 지정해야한다. 
- 기본 하드웨어에 따라 몇몇 색상이 지원되지 않을 수 있다. 이러한 경우 Flash Player의 임의의 color space을 사용한다.

위와 같은 제약사항은 사실 거의 제약이라고 보지 않아도 된다. 왜냐하면 Youtube 영상을 보면서 회전하거나 filtering 하는 경우는 드물기 때문이다. 제약사항은 있으나 GPU 가속이 된다는 것만으로도 큰 효과를 기대할 수 있겠다. 



StageVideo API 사용하기
이 문서를 보는 사람중에 개발자도 분명히 있을 것이다. 개발자는 Flash Builder Burrito와 Flex SDK  4.5.0.18623 이상의 환경만 갖춰진다면 StageVidoe를 테스트해볼 수 있다. 

Flash Builder Burrito 다운받기 : http://labs.adobe.com/technologies/flashbuilder_burrito/

완벽한 개발환경을 갖추기 위해서는 여러분의 브라우져에 Flash Player 10.2 디버그 버전을 설치하는 것이 좋겠다. 다음 링크에서 윈도우, Mac, 리눅스 환경에서 각 브라우져별 Flash Player 10.2 디버그 버전을 받아 설치할 수 있겠다. 

다음 문서를 통해 여러 시나리오로 StageVideo API를 테스트 해볼 수 있다.

조금 더 구체적으로 개발환경을 구성하는 방법과 함께 StageVideo API를 이용한 개발방법을 경험하시려면 다음 동영상을 보기 바란다.

StageVideo 사용법 : http://gotoandlearn.com/play.php?id=134

추가사항 
오창훈 님께서 저보다 먼저 글을 써주셨네요. ^^ 소스코드도 있으니 참고하세요.


정리하며 

지금까지 Flash Player 10.2에서 지원하는 StageVideo에 대해서 다뤄봤다. 

이미 Flash Player를 이용한 동영상 서비스는 보편화 된 상태이다. 이제 HD급 영상에 대한 렌더링도 GPU가속이 됨으로써 많은 관련 업체들이 적극적으로 StageVideo를 도입 할 것으로 판단한다. 

Flash Player 10.2 부터는 StageVideo 개념외에 IE9에서 GPU 가속지원, 네이티브 커스텀 마우스 커서 지원, 멀티모니터 풀스크린 지원, Sub-pixel 텍스트 렌더링 지원을 하게 되었다. 이런 부분도 함께 보면 업무 추진에 도움이 되지 않을까 생각한다. 자세한 내용은 다음 링크를 통해 확인해 볼 수 있겠다. 

Flash Player 개발자 센터 : http://www.adobe.com/devnet/flashplayer.html
Flash Player 10.2 feature : http://www.adobe.com/products/flashplayer/


StageVideo와 관련된 내용들

Adobe Flash Player 10.2 다운로드 : http://get.adobe.com/kr/flashplayer
(영문)Adobe 개발자 센터에서 소개하는 Stage Video : http://goo.gl/5bmBV
(영문)Flash Player 10.2 Beta: Stage Video : http://labs.adobe.com/technologies/flashplayer10/stagevideo.html
(영문)Getting started with stage video : http://www.adobe.com/devnet/flashplayer/articles/stage_video.html
(동영상)MAX Sneaks : Flash Player Video Performance Improvements : http://www.youtube.com/watch?v=geK7geL3I40
(동영상)StageVideo 사용법 : http://gotoandlearn.com/play.php?id=134
(영문)Introducing SimpleStageVideo : http://www.bytearray.org/?p=2571
(한글)StageVideo에 대해 : http://hazbola.tistory.com/222 
(영문)Delivering video and content for the Flash Platform on TV : http://www.adobe.com/devnet/devices/articles/video_content_tv.html
(한글)어도비, 동영상 가속 기능 강화된 플래시 플레이어 10.2 베타 발표 http://www.kbench.com/hardware/?no=93384&sc=1
Flash Player 개발자 센터 : http://www.adobe.com/devnet/flashplayer.html
Flash Player 10.2 feature : http://www.adobe.com/products/flashplayer/
[StageVideo 샘플 소스 공유]플래시 플레이어 10.2 정식 Release : http://lovedev.tistory.com/619


글쓴이 : 지돌스타(http://blog.jidolstar.com/743


Flash Player 10.2 beta가 2010년 12월 초에 배포가 되었다. 아무튼 강력한 GPU가속을 이용해 비디오 렌더링을 최적화 시킨 것이 가장 큰 변화라고 볼 수 있겠다. GPU를 이용하다보니 CPU 사용율이 급격히 줄어든다. 아래 동영상을 통해 Flash Player 10.2 beta의 GPU를 이용한 동영상 렌더링 효과를 눈으로 확인할 수 있다.


현재 Flash Player 10.2 beta는 정식 버전이 아니므로 자동으로 배포되어지지 않는다. 그러므로 다음 링크를 통해 다운로드 받을 수 있다. 개발자라면 debug 버전을 받을 것을 추천한다.


이번 배포의 변화는 다음과 같다.
1. Stage Video 하드웨어 가속
2. IE9에서 하드웨어 가속 지원
3. 네이티브 커스텀 마우스 커서 지원
4. 멀티모니터에서 풀스크린모드 지원 

이미 꽤 지난 내용이라 검색해보면 한글로된 설명글들도 있다.


Flash 분야에 손놓고 지낸지 오래라... 좀 파악하고 있는 중이다. ㅎㅎ

글쓴이 : 지돌스타(http://blog.jidolstar.com) 

지난 Adobe MAX 2010에서 가장 이슈가 되었던 것중에 하나가 GPU 가속을 상시 지원해줄 수 있는 Molehill이라는 Flash Player 3D API 가 아닌가 싶다. Molehill은 Flash Player 3D APIs의 코드네임이다.

지금까지 Flash Player가 일부 GPU 가속을 지원해줬기 때문에 테스트 정도로만 가능했지만, 미래에 GPU를 상시 지원하게 되는 Molehill 3D API가 차세대 Flash Player에 장착하게 되면 파급효과가 클 것으로 생각된다. 

CPU에 의존해 왔던 3D 기존 프레임워크인 Away3D나 Alternativa3D등은 Molehill로 변환되어 배포될 것이고 많은 Flash 컨텐츠 제작사, 소셜게임제작사들이 새로운 Flash Player 3D API를 이용한 다양한 어플들을 내놓을 것이다. 더불어 이들 어플들은 고스란히 모바일에도 접목되게 될 것으로 예상이되어 파급효과가 클 것으로 전망이 된다.

지속적으로 Molehill에 대해서 관심을 가지고 지켜볼 필요가 있겠다.



위에 두 영상화면을 보고 Flash Player 에서 동작하는 모습이다라면 누가 믿겠는가? ㅎㅎ

읽을만한 글
Adobe Labs - 3D APIs for Adobe Flash Player and Adobe AIR
Adobe MAX 2010에서 소개된 차세대 GPU 가속 Flash API - Molehill
Molehill Flash Player 3D APIs 소개
Flash Player 3D APIs 간단한 소개글 - 잼있음
[동영상][at MAX 2010] GPU Acceleration on Adobe AIR "Molehill" - 우야꼬 군이 직접 미국에 MAX 행사에가서 찍은 영상입니다.
[동영상][at MAX 2010] Alternativa 3D in Adobe MAX 2010 - 우야꼬 군이 직접 미국에서 Molehill을 체험했군요.
[동영상] Adobe MAX 2010 - Alternativa 3D 시연 - 땡굴이 님께서 Alternativa의 시연모습을 동영상으로 담았습니다.
Molehill Programming Tutorial
ActionScript의 언어 순위는 몇 위일까?

글쓴이 : 지돌스타(http://blog.jidolstar.com/733)

- TV, 모바일 및 PC등 다양한 스크린에서 구동되는 어도비 에어 2.5 출시
- 어도비에서 운영하는 새로운 애플리케이션 스토어, 어도비 인마켓 (Adobe InMarket) 공개

대한민국, 서울 — 2010년 10월 28일 — 한국어도비시스템즈(www.adobe.com/kr, 대표이사 지준영)는 미국 로스앤젤레스에서 10월 24일부터 27일까지 열린, 전세계 개발자와 디자이너들을 위한 컨퍼런스 어도비 맥스(Adobe MAX)에서 TV, 태블릿PC, 스마트폰 및 데스크톱을 아우르는 다양한 스크린에서 웹 브라우저 없이 인터넷 상의 플래시 컨텐츠를 구현하는 애플리케이션 런타임인 어도비 에어 2.5(Adobe® AIR® 2.5)을 발표했다. 어도비 플래시 플랫폼(Adobe Flash® Platform)의 중요 구성요소인 어도비 에어는 개발자들이 기존의 코드를 활용하여 다양한 디바이스와 플랫폼에 적합한 독립형 애플리케이션을 제작하고 전달할 수 있도록 한다.
 
현재 어도비 에어는 윈도우(Windows®), 맥킨토시(Macintosh), 리눅스(Linux®) 운영체제가 탑재된 블랙베리(BlackBerry®) 태블릿 OS, 안드로이드(Android™), iOS, 데스크톱을 기반으로 한 스마트폰과 태블릿PC를 지원한다. 또한, 스마트 TV에 어도비 에어 2.5를 최초로 탑재하는 TV 제조 업체는 삼성전자가 될 것이며, 2010년 후반이나 2011년 초반에 출시되는 에이서(Acer), HTC, 모토로라(Motorola), 림(RIM), 삼성(Samsung) 및 타기업의 태블릿과 스마트폰을 포함한 다양한 디바이스에 어도비 에어 2.5 가 탑재되어 시장에 선보이게 될 예정이다. 어도비 에어를 기반으로 개발자들은 어도비 플래시 프로페셔널 CS5(Adobe® Flash® Professional CS5), 어도비 플래시 빌더(Adobe® Flash® Builder™), 플렉스 (Adobe® Flex™)를 포함한 친숙한 개발 툴들을 활용하여 풍부하고 각 디바이스 환경에 맞는 독립형 애플리케이션을 만들 수 있다.  현재, 많은 애플리케이션이 안드로이드 마켓(Android Market), 인텔 앱업센터(Intel AppUp center), 애플 앱스토어(Apple’s App Store)에 등록되어 있다.
 
어도비 에어 2.5 공개에 이어, 어도비는 개발자들이 온라인 상에서의 에이서, 인텔 및 타 기업의 다양한 디바이스 타입을 넘나들며 그들의 애플리케이션을 사고 팔 수 있는 자체 애플리케이션 스토어인 어도비 인마켓(Adobe InMarket, http://www.adobe.com/devnet/inmarket.html)를 공개하였다. 사용자들은 어도비 인마켓의 스토어프론트에서 직접 애플리케이션을 다운로드 받을 수 있다. 
 
어도비 크리에이티브 및 인터랙티브 솔루션 사업부의 데이비드 와드화니(David Wadhwani) 수석 부사장은  “ 어도비 에어 2.5의 발표로 3백만 명 이상의 플래시 개발자들이 다양한 애플리케이션 스토어 및 디바이스를 넘나들며 쉽게 게임 및 애플리케이션을 개발하고 운영할 수 있게 되었다.”라고 말하며, “이는 풍부하고 혁신적인 애플리케이션을 제공하고자 하는 개발자들과, 개별 디바이스 및 플랫폼을 구축할 때 발생되었던 비용을 절감하고자 하는 이들에게 큰 도움이 될 것으로 기대된다.”라고 말했다.
 
에어 2.5는 가속계, 카메라, 비디오, 마이크, 멀티 터치 및 동작감지를 포함한 다양한 새로운 기능들을 통해 풍부한 애플리케이션 사용자경험의 기반을 제공한다. 위치 정보 기능은 개발자들이 위치 기반의 애플리케이션 서비스를 제공할 수 있도록 한다. 또한, 에어 2.5는 HTML5와 플래시(확장자 .SWF) 컨텐츠를 통합함으로써 애플리케이션 내에 네이티브 브라우저 컨트롤(native browser control)을 보여줄 수 있으며, SQLite 을 지원하여 에어 애플리케이션 내에 데이터베이스를 쉽게 저장할 수 있다. 또한, 브로드컴社(Broadcom Corporation), 인텔社, 엔비디아社, ST마이크로일렉트로닉스社, 트리던트社 (Trident), 텍사스 인스트루먼츠社(Texas Instruments), 퀼컴社(Qualcomm) 등을 포함한 주요 반도체 기업 들의 제품에서 어도비 에어를 위한 하드웨어 가속화를 지원한다.
 
어도비 플래시 플레이어 10.1 (Adobe® Flash® Player 10.1)
안드로이드 마켓에서 5만 여 명 이상이 5개 만점에서 별 4.5개의 평가로 이미 무료 인기 애플리케이션 중 하나가 된 플래시 플레이어 10.1은 모바일 디바이스 상에서 브라우저를 통한 풍부한 플래시 컨텐츠를 구동시키는 런타임이다.  현재, 어도비 런타임은 12 종류의 안드로이드 디바이스에서 구동되고 있으며, 앞으로 더 많은 안드로이드 디바이스에 구동 될 예정이다. 또한, 공식적으로 안드로이드 마켓에서 플래시 플레이어 10.1이 2백 만 번 이상이 다운로드 되었다고 발표된 바 있다.
모바일 용 런타임은 안드로이드 마켓에서 디바이스 제조업체 따라 배포되며, 이미 설치한 운영자와 운영시스템에 의해 업그레이드 된다. 플래시 플레이어 10.1은 현재 안드로이드와 구글 TV에서 이용가능하며, 앞으로 블랙베리 플랫폼, HP 웹 OS 2.0, 윈도우(Windows®)폰 차기 버전, 리모(LiMo), 미고(MeeGo) 및 심비안 OS 에서도 지원될 계획이다. 플래시 플레이어 10.1이 지원되는 디바이스는 어도비 웹페이지(http://www.adobe.com/flashplatform/supported_devices/smartphones.html)에서 확인 할 수 있다.
 
플래시 플랫폼 개발 툴
어도비는 멀티스크린 상에서의 개발 과정을 보다 간소화 시켜주는 개발자 툴 베타버전을 발표했다. 어도비 에어 2.5 소프트웨어 개발 키트(SDK)를 포함한 새로운 플래시 플랫폼 툴의 출시로, 개발자들은 디자인과 개발 생산성을 극대화시키면서 스마트폰, 태블릿 및 TV 용 모바일과 멀티스크린 애플리케이션을 구축할 수 있다. 플렉스 프레임워크의 오픈소스 업데이트는 개발자들에게 웹, 데스크톱, 그리고 현재 모바일 애플리케이션을 위한 광범위한 프레임워크를 제공한다. 개발자들은 웹과 데스크톱의 플랫폼상에서와 같이, 손쉽게 고품질의 모바일 플렉스 애플리케이션을 구축할 수 있다. 더 자세한 사항은 어도비 웹페이지(http://www.adobe.com/go/flexsdk_preview/)에서 확인할 수 있다.
 
어도비 플래시 빌더 베타버전은 개발자들의 개발 비용을 절감시키며, 익숙한 개발언어와 구성요소, 툴을 활용하여 멀티스크린을 위한 애플리케이션을 구축할 수 있도록 한다. 특히, 모바일 디바이스로의 확장과 디바이스상에서의 디버깅, 빠른 개발을 위한 코딩 툴들의 매우 놀랍고 새로운 기능들이 플렉스 등에 추가 되었다.
 
이용 방법
윈도우, 맥킨토시, 리눅스가 탑재된 안드로이드 및 데스크톱 OS 용 어도비 에어 2.5 와 어도비 에어 2.5 SDK는 현재 이용 가능하다 .어도비 에어를 위한 블랙베리 태블릿 OS SDK는 블랙베리 태블릿 OS용 애플리케이션을 제작하기 위해 어도비 에어 2.5 SDK와 함께 작동하는 것으로 림(RIM)에서 이용 가능하며 이것은 블랙베리 플레이북에 미리 탑재될 예정이다.


------------------------------------------------------------------------------
회사일이 너무 바뻐서 Adobe MAX 2010 행사에는 관심을 가지기가 힘들었네요.

작년 맥스 행사에서 Open Screen Project 일환으로 다양한 모바일 기기로 Flash 기술이 도입되는 시점이였다면 이제 본격적인 진입시점에 도달한 것 같습니다. 실제로 국내에도 스마트폰이 엄청나게 보급되어가고 있으니깐요. 이번 AIR 2.5도 이런 차원에서 모든 것이 진행된 것을 판단합니다. ACC분들의 생생한 Max 중계를 다음 링크에서 확인할 수 있습니다.

http://twitter.com/#!/search?q=%23atMAX2010
http://www.action-scripter.com/blog/search/Adobe%20Max%202010
http://twitter.com/#!/FlashLovesMe
http://me2day.net/lovedev
http://koko8829.tistory.com/tag/Max%202010

그외 소식
Adobe MAX 2010
MAX Online
어도비, 모바일로 진화
11월 13일, 모바일+플래시 개발자를 위한 즐거운 수다
12월 7일, FITC Seoul 2010
삼성 스마트TV에 어도비 AIR 탑재된다
Introducing the Molehill 3D APIs
타임라인으로HTML5컨텐츠 작성을 가능하게 한다---Adobe MAX 2010기조 강연
Adobe 앱 Air 2.5, 스마트폰, 태블릿, TV 모두 같은 앱을 사용한다?!
어도비 AIR 2.5, RIM 플레이북 앱 개발로 확산 시동 
Adobe AIR features
3D APIs for Adobe Flash Player and Adobe AIR
Adobe Flash Builder "Burrito"
Flash Player features

Mac에서도 Flash Player가 H.264 비디오 디코딩 하드웨어 가속을 지원한다. 공개된 Flash Player는 코드네임이 "Gala"로 명칭되며 현재 Flash Player 다운로드 페이지에서 받을 수 있도록 되어 있다. 정식버전은 아니다.

현재 공개된 Flash Player에서는 Mac OS X 10.6.3 이상의 OS에 NVIDA GeForce 9400M, GeForce 320M, GeForce GT 330M등의 GPU 환경을 지원한다. 

Mac에서 H.264 비디오 코덱은 이미 Flash Player에서 지원하고 있었으나 하드웨어 가속은 아니였다. 그렇게 됨에 따라 많은 CPU 자원을 소비할 수 밖에 없었다. 이미 Flash Player 10.1 베타가 출시되면서 윈도우 PC나 x86기반 넷북에 설치된 Flash Player을 H.264 하드웨어 가속을 지원했다. 이제 "Gala"로 Mac 사용자도 Flash Player에서 H.264 비디오 디코딩시 하드웨어 가속을 된 것이다. 

하드웨어 가속을 지원한다는 것은 CPU를 통해 비디오를 디코딩하지 않고 GPU로 하기 때문에 훨씬 더 쾌적한 H.264 비디오를 감상할 수 있다는 것을 의미한다. 

이는 Open Screen Project의 일환으로 가능한 것이라 판단한다. GPU 가속을 하기 위해 그래픽 카드 제작회사인 Nvida와 Adobe가 이 프로젝트를 통해 Flash Player에 대한 하드웨어 가속을 지원받을 수 있게 된 것이다.
이는 Open Screen Project와는 전혀 무관한 일이였군요. 지금껏 Apple이 자신의 OS API를 열어주지 않아서였습니다. 결국 Adobe는 완전 피해자가 된 셈이네요. 역시 Apple이 플랫폼을 개방안한것을 Adobe에 덤탱이 씌운거라는...

앞으로 Open Screen Project를 통해 더욱 다양한 기기에서 이런 협력이 많이 일어날 것으로 보이며 Flash Player는 더욱 Cross Device 세계로 나갈 것으로 기대한다.

Flash Player "Gala" Preview Release : http://labs.adobe.com/technologies/flashplayer10/gala/
Adobe Labs - Flash Player 10.1 : http://labs.adobe.com/technologies/flashplayer10/

 
글쓴이 : 지돌스타(http://blog.jidolstar.com/683

Flash는 다양한 보안모델을 가진다. 보안모델에 따라 동작하지 않는 경우에는 Flash Player는 여지없이 Security Error를 발생시킨다. 이러한 보안모델이 있으면 개발할 때는 난해하지만 사용자 입장 및 서버 관리자 입장에서 보안문제를 적절히 처리할 수 있기 때문에 안심하고 Flash 어플리케이션을 사용할 수 있는 것이다.

Flash Player 보안에 관련된 것은 다음 글을 보면 자세히 나온다.

Flash Player 보안


각설하고...
SWF파일과 그것을 감싸는 HTML이 동일한 도메인에 위치하는 경우에는 <object>및 <embed> 태그에 allowScriptAccess 매개변수값을 sameDomain이나 always를 지정하는 것만으로 SWF에 ExternalInterface.addCallback() 함수로 자신내부의 메소드를 호출할 수 있게끔 되어 있는 경우 보안상 아무 문제없이 HTML에서 SWF의 메소드를 호출할 수 있다. 다음글을 참고해 보자.

아웃바운드 URL 액세스 제어

하지만 SWF파일과 HTML이 동일한 도메인에 위치하지 않은 경우에는 Flash Player 보안이 더욱 강화된다. allowScriptAccess 매개변수를 기본적으로 allowScriptAccess="always"로 지정해야 하는 것 외에 다른 보안 설정이 필요하다. 그것은 SWF에 Security.allowDomain()  메소드가 가능하게 한다.

SWF가 domain1.com에 있고 HTML이 domain2.com에 있다고 할 때 HTML에서 SWF내에서 ExternalInterface.addCallback()으로 외부접근을 허락한 메소드를 접근하려면 SWF에  Security.allowDomain("domain2.com");을 지정해 주어야 한다. 이 말은 이 SWF는 domain2.com에 있는 HTML에서 접근하는 것을 허락한다는 것을 의미한다.

어떤 도메인에 있던지 SWF 내부의 메소드 접근을 항상 허용하려면 Security.allowDomain("*") 로 지정하면 된다. 하지만 이것은 보안상 좋지 않는 방법이다.

서로 다른 도메인에 있는 SWF와 HTML에 대해서 이런 보안이 있는 이유는 명료하다. 내가 배포한 SWF에 정의된 함수를 HTML에서 접근할 수 있도록 ExternalInterface.addCallback()을 정의했는데, 다른 사람이 다른 도메인에서 이것을 악용할 소지가 있을 수 있기 때문이다.

일반서비스인 domain.com과 파일서버인 file.domain.com을 보자. 두개다 domain.com을 사용하지만 domain.com은 file.domain.com의 슈퍼도메인이다.  이는 Flash Player 6 이전에는 같은 것으로 인식했으나 Flash Player 7이상으로 되면서 다른 도메인으로 인식하게 되었다. 이렇게 된 것은 보안상 문제로 보안정책의 변경이 필요했기 때문이다. file.domain.com에 어떤 사용자가 악성 스크립트를 심은 swf를 업로드 했다고 가정하자. 이때 domain.com과 file.domain.com을 동일하게 인식해버리면 이 swf는 domain.com에 마음대로 접근이 가능해진다. 그래서 flash player는 file.domain.com과 domain.com을 다르게 인식하는 것이다. 이것은 crossdomain정책과 같다.

더 자세한 내용은 다음 글을 참고한다.

Security.allowDomain()에 대해

아쉬운 것은 Security.allowDomain("*.domain.com") 식의 지정이 안된다는 것이다.  crossdomain.xml 설정시에는 와일드카드(*)를 *.domain.com 형태로 사용할 수 있지만 Security.allowDomain()에서 안되는 것은 이외다.

개인적으로 개발환경과 테스트환경, 배포환경이 모두 다르기 때문에 와일드카드 지원이 있으면 좀 편할텐데 하는 아쉬움이 남는다.

글쓴이 : 지돌스타(http://blog.jidolstar.com/675 )





Flash Player 10.1을 설치하려고 기존 Flash Player를 전부 uninstaller로 삭제한다음 Flash Player 10.1을 다운로드 받아 설치하려는데 다음과 같은 에러를 발생시키며 설치할 수 없었습니다.

설치하려고 하는 Adobe Flash Player 버전은 최신 버전이 아닙니다.

Windows 7 환경에서 인터넷 익스플로러(IE8)에 Active-x debug(개발자용) 버전을 설치가 되지 않아 하루 종일 이것까지고 씨름했습죠. 

  1. Adobe 이와 관련된 기술노트가 있어서 따라해 봤지만 안되었습니다.(관리자 권한으로 실행해도 마찬가지였습니다.)
  2. 또한 무식하게 Windows까지 새로 깔았지만 안되더군요.

그래서 마지막으로 관련 레지스트리를 삭제했습니다. 됩니다 ㅡㅡ;;;

  1. 시작 > 실행 > regedit 입력
  2. HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\FlashPlayer\SafeVersions 를 찾아 전부삭제

흑.... 어제부터 이것때문에 완전 생쑈를 했습니다. 시간 아까워.....

글쓴이 : 지돌스타( http://blog.jidolstar.com/668 )


Flash 애플리케이션을 제작할때 항상 고민되는 것은 메모리와 속도일 것이다. 이 문서는 이러한 고민을 했던 분들을 위해 본인의 경험을 반영하여 작성한 것이다. 주의할 것은 이 문서에서 다루는 Object Pool은 메모리, 속도 개선을 위한 하나의 방법일 뿐이지 전부는 아니다라는 것이다. Object Pool이 어떻게 당신의 애플리케이션의 속도와 메모리를 개선시켜줄 것인가 전달하는 것이 문서의 목표이다.

목차

  1. 객체 관리에 대한 질문!
  2. new 연산자는 비싸다!
  3. Object Pool이란?
  4. Object Pool을 도입할 때 고려사항
  5. Object Pool을 사용해보자.
  6. Object Pool과 new 연산자 사용 비교
  7. 메모리 사용의 폭이 급격한 애플리케이션은 좋지 못하다.
  8. 재사용할 수 있는 클래스 제작
  9. 정리하며
  10. 참고글



1. 객체 관리에 대한 질문!
제작된 애플리케이션에 필요한 최소한의 메모리에 대해서 생각해 본적이 있는가? 하나의 애플리케이션에 들어가는 최소 자원(resource)은 얼마나 될까? 그 자원은 얼마나 자주 사용하고 버리는 것일까?

슈팅 게임을 보면 동일한 적군전투기가 많이 나온다. 그 중에 적군전투기1이 있다고 하자. 적군전투기1이 한 화면에 5개가 나왔다. 아군전투기에 의해 죽든 화면에서 사라지든 어쨌든지 언젠간 화면에서 사라지고 쓸모없게 된다. 좀 있다가 또 적군전투기1이 3개가 나온다. 또 반복해서 사라진다. 당신이 이 슈팅 게임을 만든다면 적군전투기1 관리를 어떻게 할 것인가? 즉, 화면에 나타날때 new로 생성하고 사라지면 delete로 메모리에게 해지요청할 것인가? 아니면 어느 특정 영역에 화면에 나타날 전투기1을 미리 5개에서 10개 생성해놓고 필요할 때마다 재사용할 것인가?

2. new 연산자는 비싸다!
new는 클래스를 통해 객체를 생성하는 연산자이다. 이는 비교적 비용이 비싼편이다. 비용이 비싸다는 말을 구체적으로 설명하자면 new를 통해 객체를 생성하여 메모리에 올리고 다 사용했다고 판단될때 delete이나 null등을 이용해 객체참조를 제거하여 가비지 컬렉터에 맡기게 되며 결과적으로 가비지 컬렉터는 이 객체를 어느 특정시점에 제거하는 일련의 객체 생성과 삭제까지 동작이 꽤 복잡하여 메모리, CPU연산등의 자원소비가 크다라는 것을 의미한다. 특히나 클래스의 크기가 크고 복잡하다면 그 비용은 더욱 갑절로 들게 된다. new 연산 사용은 이처럼 비싼 비용을 지불해야 하기 때문에 할 수 있다면 최소한으로 사용하도록 하는 것이 속도와 메모리 관리에 도움을 준다.

앞서 설명한 슈팅 게임을 보자면 적군전투기1은 수시로 보였다가 안보였다가 한다. 이 경우 new, delete를 반복한다면 경우에 따라서 엄청난(?) 비싼 비용을 지불하게 된다.

다른 예를 들어보겠다. 본인은 얼마전에 스타플(http://starpl.com)이라는 사이트에서 제공하는 타임라인 애플리케이션을 Flash로 개발했다. 타임라인은 사용자의 기록, 앨범등을 시간순으로 보여주게 되며 좌우측으로 이동해서 내 인생의 기록을 보는듯한 느낌을 주도록 만들었다. 이때 화면에 보여지는 사용자의 기록들이 수시로 보여졌다가 사라진다. 이때 사용된 기록을 보여주는 시각객체(DisplayObject)를 new와 delete를 반복해서 생성 및 삭제한다면 너무 비싼 비용을 들이는 것과 같다.

스타플의 타임라인

참고글 : 스타플 타임라인 업그레이드 및 앨범 기능 추가 소식

앞의 2가지 예에서 언급했듯이 자주 보여지고 사라지는 객체를 필요할 때마다 new연산자를 사용하는 것보다는 어느 특정 영역에 미리 생성해놓고 재사용을 반복하는 구조를 도입한다면 메모리와 CPU연산에 있어서 큰 비용절감을 기대할 수 있게 된다.

3. Object Pool이란?
Object Pool(객체 풀)은 객체를 미리 만들어놓고 담아놓는 메모리 영역이다. 개발자는 이 Object Pool에 미리 만들어진 객체를 사용하고 다 사용한 뒤에는 다시 반환시킴으로서 재사용(또는 대여)을 하도록 한다. Object Pool을 사용하면 처음 객체를 생성할때와 더 필요한 객체가 있는 경우를 제외하고 new 연산을 최소화 할 수 있다.

4. Object Pool을 도입할 때 고려사항
Object Pool은 미리 객체를 생성하고 지속적으로 재사용하기 위해 사용한다. 이때 미리 객체를 생성한다는 것은 초반 애플리케이션 동작 퍼포먼스에 영향을 미칠 수 있다.

Object Pool을 사용했을때 다음과 같은 장점을 얻을 수 있다.

1. new 연산자를 자주 사용해야하는 경우에 도입하면 애플리케이션 속도 향상을 기대할 수 있다.
2. 가비지 컬렉터에 의존하지 않는 메모리 관리를 꾀할 수 있다.

하지만 일반적으로 10개가 필요한데 미리 100개를 만들어 항상 10% 미만 정도의 재사용률을 보인다면 그것은 메모리 낭비이다. 그러므로 다음과 같은 조건에서 Object Pool을 사용하고 관리하는 것이 좋겠다.

1. 비교적 큰 용량의 객체를 자주 사용되거나 반환해야하는 경우에 사용한다.
2. 미리 생성할 객체를 적당하게 정하도록 한다.

반대로 위 경우가 아니라면 쓸데없이 Object Pool을 사용하지 말자.


5. Object Pool을 사용해보자.

폴리고널 lab에서 간단한 Object Pool을 공개했다. 아래 링크에서 다운로드 받을 수 있다.

Download: ObjectPool_v1.1.zip

사용 방법은 매우 간단하다. ObjectPool 클래스는 아래 코드처럼 특정 클래스를 할당(allocate)하면 된다.

var isDynamic:Boolean = true;

var size:int = 100;

var pool:ObjectPool = new ObjectPool(isDynamic);

pool.allocate(MyClass, size);


isDynamic 플래그는 Object Pool내의 객체가 비어있는가 체크하기 위해 사용한다. 즉, true이면 Pool은 자동적으로 정해진 크기(size)를 넘어서더라도 Pool의 크기를 확장하여 새로운 객체를 줄 수 있으나 false이면 정해진 크기만큼 객체를 이미 준 경우에는 Pool이 비게 되므로 Error를 발생시킨다. 

크기(size)를 100으로 지정했기 때문에 미리 Object Pool에 100개의 MyClass의 객체를 생성해 두도록 한다.

이제부터 MyClass는 아래와 같은 방식으로 사용하면 되겠다.

myObjectArray[i] = new MyClass();

// 코드 대신 아래를 사용한다.

myObjectArray[i] = pool.instance;


다 사용한 MyClass객체는 Object Pool에 반환해줘야 한다. 이때 가비지 컬렉터의 기능을 이용하는게 아니라 재사용(recycle)을 위해서 다음과 같이 코딩하면 되겠다.

pool.instance = myObjectArray[i];

사용방법은 이게 전부다.

원한다면 자신의 애플리케이션에 맞게 이 공개된 ObjectPool을 개선시킬 수 있다. 가령, 100개의 Pool을 만들어놓지만 처음부터 100개를 생성해놓지는 않겠고 필요할 때마다 생성해주는 구조인 게으른(lazy) 생성을 기대할 수 있을 것이다. 또는 DisplayObject의 경우라면 사용한다는 것을 DisplayObject.parent 속성으로 판단할 수 있다. 위 처럼 pool.instance = '다 사용한 객체'와 같은 형태로 반환하는 것보다 자신의 부모가 존재하지 않는다면 재사용할 객체로 판단하도록 만들면 일종의 자동 Object Pool을 만들 수 있다. 자동 Object Pool은 다음 링크를 참고하면 좋겠다.

자동 풀링(auto pooling)을 구현해보자.



6. Object Pool과 new 연산자 사용 비교

Object Pool을 사용해야하는 타당성은 퍼포먼스 실험을 통해 쉽게 알 수 있다.  이러한 점에서 폴리고널 랩에서 제공하는 실험은 매우 유용한 자료이다.

실험 방법은 아래와 같다. (폴리고널 랩에서는 이 실험을 Window Vista, Flash Player 9.0.124에서 진행했다.) 그리고 Pool크기는 100으로 지정했다.

첫번째로 아래 코드처럼 k수 만큼 Object Pool로 부터 객체를 get만 한다.

for (var i:int = 0; i < k; i++) instances[i] = p.instance;


두번째로 아래 코드처럼 k수 만큼 Object Pool로부터 객체를 get/set 한다.

for (i = 0; i < k; i++) instances[i] = p.instance;

for (i = 0; i < k; i++) p.instance = instances[i];


세번째로 아래 코드처럼 k수 만큼 Object Pool대신 new 연산자를 사용한다.

for (i = 0; i < k; i++) instances[i] = new MyClass();



결과는 다음과 같다.


네이티브 Object 클래스의 경우 Object Pool을 사용하는 것이 new 연산자를 사용한 것보다 5배 정도 빨랐다.


Object 보다 더 크고 복잡한 flash.geom.Point의 경우는 약간더 빠른 결과를 보인다.


 flash.display.Sprite 객체를 가지고 하면 무려 80배나 속도 개선이 되었다. 이는 복잡하고 큰 클래스에 Object Pool을 도입하면 효과적일 수 있다고 판단할 수 있다.

이 실험을 통해 적절한 방법으로 Object Pool을 사용하는 것은 애플리케이션의 퍼포먼스 증가에 지대한 영향을 줄 수 있다는 것을 깨달을 수 있다.


7. 메모리 사용의 폭이 급격한 애플리케이션은 좋지 못하다.
본인은 어떤 애플리케이션(Flash가 아니더라도)이든지 그 애플리케이션에 필요한 최소한의 메모리는 항상 존재한다고 생각한다. 무조건 메모리 사용을 줄여보겠다고 new, delete를 반복하는 것은 잘못된 것이다. new, delete를 반복하면 오히려 CPU 및 메모리 사용의 반복을 부축이며 애플리케이션의 전체적인 퍼포먼스를 저하시키는 경우가 발생할 수 있다. 실제로 new,delete를 반복하는 구조로 개발한 애플리케이션을 Flash Builder의 프로파일링 기능을 통해 메모리 사용을 살펴보면 큰폭으로 메모리 사용/해지가 일어난다는 것을 확인할 수 있다. 그러므로 몇몇 사람들이 Object Pool과 같은 개념과 같이 퍼포먼스 향상에 도움이 되는 개념을 전혀 사용하지 않고 Flash는 느리고 가비지 컬렉터 동작은 비정상적이다라고 말하는 것은 섣부른 판단이다라고 생각한다. 얼마든지 메모리를 효율적으로 사용하고 속도 개선을 할 수 있음에도 불구하고 잘못된 개발 방식때문에 전체적인 퍼포먼스가 나빠지는 것은 결국 개발자의 잘못인 것이다. 이는 Flash든 어떤 언어든 동일한 생각으로 접근해야 한다.

Flash Builder의 프로파일링 기능을 이용해 Object Pool과 new 연산자간의 메모리 변화를 확인할 수 있는 간단한 실험을 해보겠다. (프로파일링 기능을 사용하는 방법은 주제에서 벗어나므로 제외하겠다.)

먼저 Shape객체를 확장해서 크기와 색이 렌덤하게 그려지는 클래스를 만든다.

//화면에 출력할 Shape

class RandomShape extends Shape {

        static private var colorPool:Array = [0xff0000,0x00ffff,0x0000ff,0x00ff00,0x0f0f0f,0xf0f0f0,0xffff00,0xf00cf0,0x00fcaa,0xff0c9a];

        public function RandomShape():void {

        }

        public function draw():void {

               var radius:Number = Math.random() * 40;

               var color:uint = colorPool[ Math.floor(Math.random()*9) ];

               graphics.clear();

               graphics.beginFill(color,1.0);

               graphics.drawCircle( 0, 0, radius );

               graphics.endFill();

        }

}


위 클래스를 가지고 자동 Pool을 구현한 클래스를 만든다.(참고 : http://www.diebuster.com/?p=1000)

//Shape 자동 객체 Pool

class RandomShapeAutoPool {

        private var _pool:Vector.<RandomShape>;

        public function RandomShapeAutoPool() {

               //적당히 수로 초기화한다.

               _pool=new Vector.<RandomShape>();

        }

 

        public function getShape():RandomShape {

               var key:*, result:RandomShape;

               //먼저 기존의 pool에서 찾아본다.

               for (key in _pool) {

                       //만약 해당 객체가 null이라면 new 통해 생성한다.

                       if (_pool[key] === null) {

                              _pool[key]=new RandomShape;

                              result=_pool[key];

                              break;

                       //null 아니라면 parent 조사하여 사용가능한지 판단한다.

                       } else if (_pool[key].parent === null) {

                              result=_pool[key];

                              break;

                       }

               }

               //기존의 pool안에서 쓸만한 찾지 못했다면

               if (result === null) {

                       result=new RandomShape;

                       _pool[_pool.length]=result;

               }

               //인스턴스를 반환한다.

               return result;

        }

}


이제 테스트할 수 있는 호스트코드를 제작해보겠다.

package {

        import flash.display.*;

        import flash.events.*;

        import flash.text.*;

        import flash.utils.*;

 

        [SWF(backgroundColor="#ffffff", frameRate="60", width="400", height="400")]

        public class ObjectPoolTest extends Sprite {

               private var pool:RandomShapeAutoPool=new RandomShapeAutoPool;

               private var poolFlag:Boolean = false;

               private var textPoolFlag:TextField;

               private var shapeCanvas:Sprite;

 

               public function ObjectPoolTest() {

                       addEventListener(Event.ADDED_TO_STAGE, ADDED_TO_STAGE);

               }

 

               private function ADDED_TO_STAGE($e:Event):void {

                       removeEventListener(Event.ADDED_TO_STAGE, ADDED_TO_STAGE);

                       stage.scaleMode=StageScaleMode.NO_SCALE;

                       stage.align=StageAlign.TOP_LEFT;

                       //rf)http://blog.jidolstar.com/656

                       if (stage.stageWidth === 0 && stage.stageHeight === 0) {

                              stage.addEventListener(Event.ENTER_FRAME, function($e:Event):void {

                                             if (stage.stageWidth > 0 || stage.stageHeight > 0) {

                                                     stage.removeEventListener($e.type, arguments.callee);

                                                     init();

                                             }

                                      });

                       } else {

                              init();

                       }

               }

 

               private function init():void {

                       //shape 부모객체

                       shapeCanvas = new Sprite;

                       addChild( shapeCanvas );

                       //PoolFlag 상태표시

                       textPoolFlag = new TextField();

                       textPoolFlag.text = "poolFlag=" + poolFlag;

                       addChild(textPoolFlag);

                       //마우스 클릭 영역

                       graphics.beginFill(0x000000,0);

                       graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);

                       graphics.endFill();

                       addEventListener(MouseEvent.CLICK, MOUSE_CLICK);

                       //반복동작     

                       addEventListener(Event.ENTER_FRAME, ENTER_FRAME);

               }

 

               private function MOUSE_CLICK($e:MouseEvent):void {

                       //마우스 클릭때마다 poolFlag 상태를 전환

                       poolFlag = !poolFlag;

                       textPoolFlag.text = "poolFlag=" + poolFlag;

               }

              

               private function ENTER_FRAME($e:Event):void {

                       var shape:RandomShape, i:int, numChildren:int;

                       //poolFlag 따라서 new연산자 또는 Object Pool에서 객체 참조

                       shape = poolFlag ? pool.getShape() : new RandomShape;

                       shape.draw();

                       shape.x = Math.random() * stage.stageWidth;

                       shape.y = 0;

                       shapeCanvas.addChild( shape );

                       //계속 아래로 떨어뜨림. 화면에서 벗어나면 removeChild시킴

                       numChildren = shapeCanvas.numChildren;

                       for( i=0; i<numChildren;i++) {

                              shape = shapeCanvas.getChildAt(i) as RandomShape;

                              shape.y += 5;

                              if( shape.y > stage.stageHeight ) {

                                      shapeCanvas.removeChild( shape );

                                      i--;

                                      numChildren--;

                              }

                       }

               }

        }

}


동작은 매우 단순하다. poolFlag가 true이면 제작한 자동 Object Pool을 사용하겠다는 것이고 false이면 new 연산자를 사용해 RandomShape객체를 생성하겠다는 것이다. poolFlag 전환은 마우스 클릭으로 할 수 있다. 그리고 비가 내리는 것처럼 Shape 객체는 위에서 부터 아래로 떨어지며 맨 아래에 닿으면 removeChild 시킨다.

테스트 화면


실행 코드와 결과물은 http://wonderfl.net/code/805dc65d1f7800b7bee5dc3cd72ca21c0a87c2d6 에서도 볼 수 있다.

이제 Flash Builder의 프로파일링 기능을 이용해 메모리 변화 및 객체 생성빈도를 살펴보자.

먼저 new 연산자를 사용했을때 메모리 변화를 보자.

new 연산자로 객체생성시 Memory Usage


new 연산자를 사용해 객체를 생성하고 필요없을때 removeChild를 하게 되면 가비지 컬렉션 처리가 되기 때문에 일정한 시점에 메모리가 해지되는 것을 반복하는 것을 확인할 수 있다.

new 연산자로 객체생성시 Live Object


위 표는 축적된 객체수(Cumulative Instances), 현재 객체수(Instances), 축적된 메모리(Cumulative Memory), 현재 메모리(Memory)를 나타낸다. 변화 무쌍하며 실제로 보여지지 않는 객체도 가비지 컬렉션 처리가 일어날때까지 메모리에 남아 있다. 분명 비효율적으로 보인다.

반대로 Object Pool을 이용했을때 메모리 변화이다.

Object Pool로 객체관리시 Memory Usage

new 연산자를 사용했을때와 비교가 안될 정도로 고요한 느낌이 든다. 거의 일직선의 메모리 사용율을 보인다.

Object Pool로 객체관리시 Live Object


축적되는 객체도 81개를 넘지 않는다. 그만큼 객체 생성과 삭제에 민감하지 않게 되고 가비지 컬렉터 도움을 받지 않고 객체관리가 되는 것을 확인할 수 있다.


8. 재사용할 수 있는 클래스 제작

Object Pool을 사용시 한가지 고려할 사항은 재사용할 수 있는 클래스를 만들어야 한다는 점이다. 왜냐하면 Object Pool은 단순히 재사용을 위한 공간만 제공하는 것이지 재사용을 하기 위한 어떤 기능을 클래스에게 줄 수 없기 때문이다. 그래서 재사용이 가능한 클래스를 설계하는 것은 하나의 기술적 이슈가 될 수 있다. 

재사용할 수 있는 클래스를 어떻게 만드는지 간단한 예를 들어보겠다.

final public class MyData {

        public var type:String;

        public var id:int;

        public var name:String;

}


위 클래스는 데이터를 담는 클래스이다. id, name은 실제 사용하는 데이타 값들이고 이 데이타의 종류는 type으로 구분한다. 이 데이타를 사용하는 인터페이스를 제작해보겠다.

public interface IMyClass {

        function init($data:MyData):void;

        function clear():void;

        function get data():MyData;

}


이 인터페이스는 앞으로 만들 MyClass01, MyClass02... 등을 구현하기 위한 것이다. 초기화 하기 위해 init()함수가 있고 인자로 위에서 제작한 MyData 객체를 받는다. 또한 사용할 필요가 없을때 내부 청소를 위해 clear()함수를 추가했다. 게다가 가지고 있는 data를 참고하기 위해 get data()도 만들었다. 이제 이 인터페이스를 구현한 클래스는 아래처럼 만든다.

final internal class MyClass01 extends Sprite implements IMyClass {

        private var _data:MyData;

        public function MyClass01() {

        }

        public function init($data:Mydata):void {

               _data = $data;

               //구현

        }

        public function clear():void {

               _data = null;

        }

        public function get data():MyData {

               return _data;

        }

}

 

final internal class MyClass02 extends Sprite implements IMyClass {

        private var _data:MyData;

        public function MyClass02() {

        }

        public function init($data:Mydata):void {

               _data = $data;

               //구현

        }

        public function clear():void {

               _data = null;

        }

        public function get data():MyData {

               return _data;

        }

}

 

final internal class MyClass03 extends Sprite implements IMyClass {

        private var _data:MyData;

        public function MyClass03() {

        }

        public function init($data:Mydata):void {

               _data = $data;

               //구현

        }

        public function clear():void {

               _data = null;

        }

        public function get data():MyData {

               return _data;

        }

}



코드가 길어보이지만 3개 클래스 모두 IMyClass를 구현했고 Sprite를 확장했다. 단지 클래스 이름만 다르며 실제 구현부는 알아서 구현하면 된다.

개발자는 MyClass01, MyClass02, MyClass03은 매우 자주 new 연산자로부터 생성되는 클래스로 판단했고 그래서 Object Pool을 도입하겠다고 결정했다고 하자. 그럼 다음과 같이 시도해 볼 수 있다.

import de.polygonal.core.ObjectPool;

import flash.display.DisplayObject;

 

public class MyPool {

        private static var poolList:Object;

       

        static public function init():void {

               poolList = {

                       'type01':new ObjectPool(true),

                       'type02':new ObjectPool(true),

                       'type03':new ObjectPool(true),

               };

               poolList.type01.allocate(20, MyClass01);

               poolList.type02.allocate(10, MyClass02);

               poolList.type03.allocate(100, MyClass03);

        }

       

        static public function getObject($data:MyData):IMyClass {

               if( $data === null ) {

                       throw new Error('인자값은 null이면 안됩니다.');

               }

               try {

                       var object:IMyClass = poolList[$data.type].object;

                       object.init($data);

               } catch {

                       throw new Error('데이타의 type값이 잘못된 값입니다.');

               }

               return object;

        }

       

        static public function returnObject($object:IMyClass):void {

               if( $object === null ) {

                       throw new Error('인자값은 null이면 안됩니다.');

               }

               $object.clear();

               if( DisplayObject($object).parent ) {

                       DisplayObject($object).parent.removeChild( DisplayObject($object) );

               }

               poolList[$object.data.type].object = $object;

        }

}



위에서 제작된 MyPool은 static클래스이며 ObjectPool을 이용해 IMyClass 인터페이스를 구현한 클래스를 init()함수에서 적당하게 할당하는 것을 확인할 수 있다. 또한 getObject()를 통해 인자값 data를 참고하여 참조할 Object Pool을 찾아 IMyClass를 구현한 각각의 클래스의 객체를 받아올 수 있으며 returnObject를 통해 다 사용한 객체를 반환한다.

실제로 실무에서 이런 형태로 개발했고 이는 매우 유용했다. MyPool 클래스를 더 개선해서 더 많은 수 Object Pool을 감당할 수 있도록 확장할 수 있다면 더욱 유용해질 것이라 생각한다.


9. 정리하며

Object Pool 개념은 Flash에만 국한되는 유용한 개념이 아니다. 이런 개념들에 대한 노하우를 계속 쌓아간다면 당신의 애플리케이션은 더욱 좋은 작품으로 탈바꿈할 수 있을 것이다.

Flash Player가 느리고 메모리 관리가 안된다고 생각하지는 말자. Flash Player 태생자체가 그런것을 어찌하겠는가? 제작한 애플리케이션이 느리다면 그것은 결국 개발자가 잘못한 것임을 항상 인지하자. 중요한 것은 여전히 Flash Player는 유용하고 많이 사용되고 있으며 지금도 나날이 발전하여 Cross OS, Cross Browser를 넘어 Cross Device 세계로 뻗어가고 있다는 점이다.


10. 참고글
글쓴이 : 지돌스타(http://blog.jidolstar.com/666)
지난 2월 2일 AIR 2.0 beta 2가 배포된데 이어 오늘(한국날짜기준 2010.02.24) Adobe Flash Player 10.1 beta 3가 배포되었습니다. Adobe Labs에 가면 상세한 정보를 보실 수 있습니다. 


릴리즈 노트의 Fixed Issues에 별표(*) 표시된 것이 이번 배포의 수정사항들입니다. 보면 기존에 있었던 Fix된 버그와 개선사항을 확인할 수 있습니다.

주의사항은 이것은 말그대로 beta라는 점입니다. beta는 정식버전이 아니기 때문에 Flash Player 10.1 API를 이용해서 개발하셔도 실제로 서비스하는 것은 안된다는 것을 의미합니다. 테스트 용도로만 설치하셔서 사용하시기 바랍니다.

글쓴이 : 지돌스타(http:/blog.jidolstar.com

애플이 아이패드를 발표하면서 Flash Player 지원을 공식적으로 거부했습니다.
그 이후로 엄청난 논란이 있는 가운데...
Adobe CTO 케빈 린치는 다음 처럼 의견을 제시했습니다.

Adobe 케빈 린치의 '컨텐츠 및 애플리케이션에 대한 오픈 액세스

아무튼 이런 상황에서 아래와 같은 기사도 올라왔네요.
한번 읽어보시고 각자의 의견을 들어보는 것도 좋을 것 같아요. ^^

---------------------------------------------------------------------

[원문]
http://online.wsj.com/article/SB20001424052748703546004575055184080144688.html


[월 스트리트 저널(Wall Street Journal)]


애플(Apple)의 마이크로소프트(Microsoft)화?


2010.02.09 / 홀먼 W. 제킨스 주니어(Holman W. Jenkins, Jr.)


애플은 증오적 라이벌 관계로 인해 제로섬 전략에 집착하는 회사로 전락할 위험에 놓여있습니다.

현재를 언급하는 것이 아니라 애플의 시가총액이 상상할 수 없는 규모에 달하여 마이크로소프트의 시가총액을 뛰어넘는 해의 이야기가 될 수 있습니다. 당연히 축하 인사가 따르겠지만 위로의 말도 함께 따를 것입니다. 제품 개발에만 전념하는 회사의 경우 전략에 집착하는 회사가 될 위험의 소지가 있기 때문입니다. 그리고 여기서 “전략”이란 증오적 라이벌 관계로 인한 제로섬 전략을 의미합니다.

안타깝게도 현재 우리는 신뢰를 찾기 힘든 타락한 세상에 살고 있습니다.

아이패드(iPad)의 예를 들어보겠습니다. 아이패드는 세상에 공개되자마자 “구세주 태블릿”이라는 별명을 얻었습니다. 아이패드는 상상하지 못할 만큼 탁월한 제품이 아닌 단지 애플이 넷북 경쟁에 뛰어들기 위해 출시한 제품으로, 아이팟 터치(iPod Touch)를 확대해 놓은 버전에 불과합니다. 아이패드는 최상의 웹 브라우징 시스템으로 부각될 수 없을 수도 있습니다. 왜냐하면 애플이 웹 상에서 비디오를 전달하는 데 75% 가량 사용되고 있는 플래시(Flash) 지원을 거부했기 때문입니다. 그러나 아이패드(iPad)(‘지불’이라는 영어 PAID의 철자 순서를 바꾸어 만든 말)는 애플의 온라인 서비스를 통해 판매되고 있는 e북, 음악 및 비디오를 사용하기에는 적합한 디바이스로 보입니다. 단도직입적으로 말하자면 아이패드는 마치 아이튠즈(iTunes) 스토어를 후원하기 위해 최적화된 디바이스로 보입니다.


그렇다면 왜 애플은 플래시를 제외시키기로 결정했는지 궁금하지 않을 수 없습니다. 애플과 애플의 후원업체들은 플래시가 짜증나는 웹 광고를 만드는데 사용되는 제품이라는 미학적이고 철학적인 이유를 내세우고 있습니다.


애플이 플래시를 거부하는 이유는 바로 여기에 있습니다. 플래시를 사용하면 아이폰(iPhone) 및 아이패드 사용자는 아이튠즈를 통하지 않고 비디오 및 기타 엔터테인먼트를 사용할 수 있을 것이고 애플 앱 스토어(Apple App Store)에서만 현재 구입할 수 있는 다양한 기능을 무료로 얻을 수 있게 됩니다.


네트 중립성 옹호자들이나 독점 금지법 집행자들이 스티브 잡스(Steve Jobs)를 연행해가는 오류를 범하지 않도록, 한 가지 덧붙이자면 애플은 플래시를 거부할 수 있는 적법한 권리를 가지고 있습니다. 그러나 한 가지 짚고 넘어가야 할 것은 애플은 엄청난 양의 웹 컨텐츠와 사용자를 분리시키려는 전략적 선택을 내세우고 있다는 점입니다. 플래시가 버그를 부른다는 주장 등에 대해 플래시 옹호자의 시점에서 잠시 벗어나 설명해 보겠습니다. 플래시는 다른 비디오 플레이어와의 시장 경쟁에서 우위를 점하고 있으며 10억 명에 달하는 PC 사용자가 정기적인 업데이트를 다운로드하고 있다는 사실은 엄청난 성공이라고 해도 과언이 아닐 것입니다. Hulu.com에서 TV 프로그램을 시청하거나 MLB.com에서 야구 경기를 보거나 Facebook을 통해 친구와 커뮤니케이션할 때에도 플래시가 필요합니다.


현재로선 플래시를 소유하고 있는 어도비는 최소한 플래시 프로그래머가 애플의 앱 스토어를 통해 자신이 개발한 컨텐츠나 애플리케이션을 제공할 수 있도록 몇 가지 툴을 출시하고 있다고 말하고 있습니다. 이것도 애플의 축복이 있어야 가능할 것입니다. 그러나 애플은 미래의 웹 표준은 독점적인 플래시를 대체하게 될 것이라고 주장하고 있습니다. 이것은 지켜봐야 할 일입니다. 플래시는 현재 전세계 95%의 PC에 설치되어 있어 하루 아침에 웹 표준이 바뀔 가능성은 극히 희박합니다. 또한 파이어폭스(Firefox) 같은 브라우저 제작업체 모두가 애플이 말한 새로운 표준과 생각을 함께 하고 있는 것도 아닙니다.


더 크게 우려되는 바는 여기에 있습니다. 애플이 이러한 무모한 목표로 인해 자사의 모바일 디바이스 사용자층을 확대하여 단지 더 많은 사용자가 아이튠즈만 이용하도록 사용자를 가두는 “네트워크 효과”의 매혹적인 유혹에 무릎을 꿇을 수 있다는 점입니다. 애플은 최근까지 제휴 관계를 유지했던 구글(Google)과 전면전에 돌입했습니다.


지난달 말  애플 직원과의 미팅에서 스티브 잡스가  “지금까지 애플은 검색 시장에서 구글과의  경쟁을 피하기 위해 노력했지만 ‘아이폰  타도’ 를 위해 자사의 모바일 디바이스르  출시했다.” 면서 “사악해지지 말자(Don't be evil) " 라는 구글의 모토를 폄하한 발언이 일파 만파 퍼졌습니다.


구글폰으로 인해 아이폰이 없어지지는 않을 것입니다. 시장은 수많은 모바일 디바이스를 수용할 수 있는 여건을 충분히 갖추고 있습니다. 그러나 실제 위협이 되는 것은 수천만 명의 소비자를 앱 스토어인 아이튠즈만 이용할 것을 주입시킬 수 있는 애플의 능력입니다. 구글이 아이패드가 공개되기 며칠 전 자사의 슬레이트 모양의 디바이스 모델을 발표한 것은 의미 있는 행보였습니다. 구글의 모바일 디바이스는 플래시를 지원하고 있습니다. 애플 사용자가 사용할 수 없는 비디오 및 기타 웹 기능을 사용자가 구매하거나 사용할 수 있도록 했습니다.


애플이 아이폰에서 구글을 대체하기 위해 마이크로소프트의 검색 엔진인 빙(Bing)과 거래를 고려하고 있다는 소문이 돌고 있습니다. 또한 애플이 광고 사업에도 뛰어들어 구글의 서비스와 경쟁하기 위해 클라우드 서비스를 확대할 것이라는 소문도 들리고 있습니다. 어디서 많이 들어본 스토리 아닌가요?


네트워크 효과는 권력과 부를 가져오는 방법이 될 수는 있지만 마이크로소프트의 사례에서 볼 수 있듯이 너무 많은 성과는 특권의 지위를 유지하기 위한 방어적이고 망상적 시도로 인해 물거품이 될 수 있습니다. 회사의 최고 심미가이자 완벽주의자가 더 이상 정상적인 의사 결정을 내리지 못하게 되면 과연 애플은 어떤 회사가 될 것인지 많은 전문가들은 의문을 가지고 바라보고 있습니다. 애플이 점점 더 많은 사용자들에게 아이튠즈 앱 스토어만 사용할 수 있는 질이 나쁜 디바이스를 출시하는 회사로 전락되지 않을까 우려되는 바입니다.
 




원래 이런 문제가 발생하면 안되는건데... 현재 구글 크롬에서 Flash Player를 설치해도 설치되지 않은 것처럼 보여주는 버그가 있습니다. 제 컴퓨터만 그렇겠지 했는데... 회사 동료도 이런 문제가 있더군요. 허허허....

회사 동료로부터 좋은 정보를 얻게 되어 이 문제를 해결하는 방법을 소개합니다. ^^

http://blog.still.pe.kr/550

Window 7에서 하실때 권한 문제같은거 발생할 수 있는데요.
C:\Documents and Settings\[사용자 이름]\Local Settings\Application Data\Google\Chrome\Application
까지만 들어가셔서 거기에 Plugins를 폴더를 만드시면 될 것 같습니다. ^^

Flash Platform 개발자 분들에게 반가운 소식이 있습니다. AIR 2.0 Beta와 Flash Player 10.1 Prelease 버전이 공개되었습니다. 이제 Adobe Labs(http://labs.adobe.com/)에서 직접 다운로드 받을 수 있습니다.


 

Adobe AIR 2.0 beta

AIR 2.0은 다음과 같은 새로운 feature들이 추가되었습니다.(영어 압박? 그럼 : http://blog.chanik.com/entry/AIR-20-Beta-릴리즈 )

  • Support for the detection of mass storage devices.
  • Advanced networking capabilities like secure sockets, UDP support, and the ability to listen on sockets.
  • Support for native code integration.
  • The ability to open a file with its default application.
  • Multi-touch and gesture support.
  • New APIs for access to raw microphone data.
  • Webkit update with HTML5/CSS3 support.
  • Global error handling.
  • Improved cross-platform printing
  • Improved security and support for enterprise and government standards.

AIR 2.0에 대해서 자세한 설명 다음 글들을 참고하세요. 



AIR 2.0으로 개발테스트 하시려면 다음과 같이 합니다. 윈도우, Flash Builder 4 beta 2 환경을 가정하고 설명드립니다.

더 쉽게 환경을 구축하고 테스트 해보시겠다면 다음 링크를 참고하세요.
http://blog.jidolstar.com/619 

 

  1. 만약 Flash Builder를 설치 안했다면 다음 링크를 통해 받으세요.
  2. SDK와 Runtime을 다운로드 받습니다.
  3. 다운받은 Runtime을 실행해 설치합니다.
  4. SDK는 압축을 풀고 그안에 있는 내용을 Flash builder가 설치된 sdks/4.0.0과 sdks/3.4.1 폴더에 각각 덮어씌웁니다. 제 경우는 C:\Program Files\Adobe\Adobe Flash Builder Plug-in Beta 2\sdks\4.0.0
  5. Flash Builder를 실행합니다.
    Windows>Preferences에 들어가 Flash Builder > Installed Flex SDKs를 확인해보세요.
  6. Learn to Use Adobe AIR 2 Beta에 들어가 관련 내용을 학습합니다.
  7. Adobe AIR 2 Sample Applications에 들어가 Sample을 받아보고 실제 Flash Builder에서 작업해봅시다. (해당작업화면을 이미지 캡쳐하고 이런거 너무 힘들어서요. 그냥 말로 주절주절 써봅니다.)
    저는 일단 수많은 예제들중에 Microphone 예제의 소스를 다운로드 받았습니다.
    Flash Builder에서 Flex Project를 생성합니다. 물론 Application Type은 Desktop으로 설정해야겠죠? 예제를 다운받아 사용하므로 프로젝트 이름은 예제 소스 압축을 풀어보면 메인소스의 이름을 선택해주면 됩니다. 저의 경우 MicrophoneExamples군요. 프로젝트를 생성했으면 그 다음으로 Flash Builder에서 방금 생성한 프로젝트를 선택한 상태에서 마우스 오른쪽 버튼을 눌러 Import로 들어갑니다. 창이 뜨면 General > Archive File을 선택하고 다음 버튼을 누릅니다. Browse...버튼을 눌러 다운받은 소스압축파일을 선택합니다. 그리고 Finish하세요. Overwrite할거냐 물으면 Yes To All 을 선택하시면 됩니다. 초반에 sdk 에러가 뜰겁니다. 원본 소스의 sdk 설정이 달라서 그러는데요. 이것을 해결하기 위해 프로젝트명을 선택한후 마우스오른쪽 버튼을 눌러 Properties로 들어가 Flex Compiler를 선택한 다음 Use a specific SDK를 Flex 3.4로 선택해주시면 됩니다. 4.0이 아닌 이유는 예제 소스가 mx:WindowedApplication으로 만든 것으로보아 Flex 3.4 기반으로 만들어졌기 때문입니다. 다른 예제가 s:WindowedApplication으로 만들어져 있다면 Flex 4.0을 선택하세요. 다 끝났습니다. 이제 실행해보세요.


    앗... 제 데톱에 마이크가 없군요... ㅡㅡ; 아무튼 이렇게 하면 됩니다. Sample에는 Flex뿐 아니라 Ajax, Flash용도 있으니 잘 활용하시면 학습하는데 도움이 될겁니다.

 

Flash Player 10.1 Prelease

Flash Player 10.1의 가장 큰 특징은 바로 모바일 지원입니다. 제 블로그에서 앞서 설명했지만 Flash Player 10.1은 오픈소스프로젝트를 통해 탄생된 결과물입니다. 데스크탑 뿐아니라 다양한 기기에서도 Adobe Flash Platform 기술이 적용될 수 있도록 Flash Player 10.1을 만든겁니다. 이는 모바일과 같이 저급(?) 하드웨어 기반에서 항상 이슈가 되어 왔던 메모리, 전력소비, 속도, 하드웨어가속등의 문제를 해결한 Flash Player를 만들었다는 것을 의미합니다. 이외에도 차세대 모바일에 걸맞는 몇가지 기능(멀티터치등)을 구현할 수 있는 API도 추가되었죠. 또한 H.264 비디오도 지원해줍니다.

Flash Player 10.1에 대해서 더욱 자세히 알고 싶다면 Flash Player 10.1 Beta Release Notes를 참고하시면 될 것 같습니다.

Flash Player 10.1 기반의 프로그램을 개발하고 싶다면 Flash Player 10.1 플러그인을 자신의 컴퓨터에 먼저 설치한뒤 Player Global SWC를 다운받아 개발하면 됩니다. 일련의 절차를 간단하게 설명드립니다.

참고로 Flash Player 10.1은 정식 배포버전이 아닙니다. 테스트 목적으로 하시고 실제 배포는 하지 마세요.

Flash Player 10.1 플러그인을 http://labs.adobe.com/downloads/flashplayer10.html 에서 다운로드 받습니다. 기존에 설치된 Flash Player는 삭제를 하시고 설치하세요. 윈도우의 경우 파이어폭스와 모질라 계열이라면 Download plug-in for Windows (EXE, 2.2 MB)를 받고 IE라면 Download active-x for Windows (EXE, 2.2 MB)를 다운로드 받으세요. 아쉽게도 개발자를 위한 디버그 버전은 아직 없는 것 같습니다.

Flash Player 10.1 기반 개발을 위해 해당 API로 개발할 수 있도록 지원해주는 SWC를 다운로드를 같은 페이지에서 받을 수 있습니다. 다운받아 압축을 풀면 playerglobal.swc가 있습니다. 이것을 자신의 프로젝트에 포함하여 개발하면 됩니다. 함께 포함된 readme.txt파일을 보면 사용하는 방법이 잘 나와 있는데 여기서도 간단히 설명해 드리죠. (단, Flash Builder 4 beta 2 기준입니다.)

  1. 만약 Flash Builder를 설치 안했다면 다음 링크를 통해 받으세요.
  2. 새로운 애플리케이션 프로젝트를 만듭니다.
  3. playerglobal.swc를 playerglobal10.1.swf로 이름을 바꾸고 만들어진 프로젝트의 libs폴더에 복사합니다. libs폴더에 복사하면 자동으로 Referenced Libraries로 설정됩니다. (여기서 이름을 바꾼 이유는 다음 내용을 설정할 때 playerglobal.swc의 Link Type을 수정못하도록 Flash Builder가 만들어져 있기 때문입니다.)
  4. 프로젝트명을 선택후 마우스 오른쪽 버튼을 눌러 properties를 선택한 뒤 Flex Builder Path를 선택합니다. 그런 다음 Library path 탭을 선택한뒤 libs 폴더를 열어 Link Type을 External로 바꿉니다. 그런 다음 Flex 4.0 를 열어 기존 playerglobal.swc는 삭제합니다. Link type이 External이라는 것은 컴파일시 사용한 클래스를 빼놓는다는 뜻입니다. 어짜피 playerglobal.swc에 정의된 클래스는 이미 Flash player 10.1에서 지원해주기 때문에 굳이 swf안에 포함할 필요가 없기 때문이지요.
  5. Flash Player 10.1을 요구하는 HTML이 되도록 만들어주기 위해 Properties 창에서 Flex Compiler를 선택합니다. Adobe Flash Player options에서 Use a specific version을 10.1.0으로 바꾸거나 Additional compiler arguments에 -target-player=10.1.0 을 추가합니다.

이로써 Flash Player 10.1 에서 돌아가는 Flash 애플리케이션을 만들때 환경 구축을 모두 완료했습니다.

아래처럼 Flash Player 10.1 API인 TouchEvent, TransformGestureEvent 등을 사용할 수 있게 되었습니다.



아래 링크를 통해 Flash Player 10.1에 대한 다양한 정보를 얻을 수 있습니다.


앞으로 정식버전이 배포되고 Flash CS5도 나오게 되면 아이폰 및 다양한 기기에서 동작하는 재미있는 애플리케이션들을 만들 수 있게 될 것입니다. 

Flash Platform 개발자들이여.. 향후 10년 밥벌이 벌었습니다. ㅋㅋㅋ


글쓴이 : 지돌스타(http://blog.jidolstar.com/617)
 

이번 Adobe MAX 2009에서 Flash Player 10.1을 공개했습니다. 이번 키노트를 통해 더욱 최적화되고 강력해진 Flash player에 대해 설명을 들을 수 있었는데요, 주목할 점은 다양한 모바일등의 다양한 플렛폼 지원과 최적화 부분이겠네요.

MAX현장에서 직접 찍은 사진입니다. ^^
위 화면에서 Flash Player 10.1의 추가 및 향상된 기능을 보실 수 있습니다. 스마트 폰을 지원하며 멀티터치 기능이 가능해집니다. 또한 메모리, 전력, 하드웨어 가속에 대해서 최적화 했으며 Http 비디오 스트리밍등을 지원하게 됩니다.

각종 스마트폰에 지원이 되는 만큼 애플리케이션의 저전력 구동은 핵심이 될겁니다.  일반 비디오는 3.4시간, 활동적인 에니메이션이 들어간 애플리케이션인 경우 6.5시간, 저전력 모드에서는 14.5시간 볼 수 있다고 언급하고 있습니다.

Flash Player 10.1과 기존 Flash Player 10의 메모리 사용양을 나타냅니다. 같은 자원을 쓰고서도 거의 1/2~2/3가량 용량이 줄어들었습니다. Flash Player 10.1이 모바일에 지원되기 위한 최적화의 노력의 성과겠네요.

Adobe는 이번 키노트를 통해 Flash Player가 더이상 데스크탑이 아닌 모바일에서도 같은 동작을 한다는 것을 강조하고 있습니다. 지금까지 Flash Lite로만 모바일 기기 애플리케이션을 만들었지만 Flash Player 10.1부터는 일반 Flash로도 충분히 모바일에서 돌아가는 플래시 컨텐츠를 생산할 수 있게 되었습니다. 이렇게 Flash Player가 다양한 모바일에 지원된데에는 오픈 스크린 프로젝트(Open Screen Project)의 추진과 관련 있습니다. 흥미로운 점은 이 프로젝트에 구글이 동참했다는 점입니다. 오픈 스크린 프로젝트는 더이상 PC, 모바일만을 뜻하지 않으며 다양한 플렛폼에서 다양한 경험을 제공하는 것을 목표로 합니다. 이 오픈 스크린 프로젝트는 구글, 삼성, LG를 비롯해 노키아, NVIDIA등 수많은 회사가 참여하고 있으며, 앞으로 이들이 내높는 다양한 플랫폼에 Flash Player를 지원하게 되어 어디서든 Flash 컨텐츠를 접할 수 있게 됩니다. 하지만 아쉽게도 아이폰의 제작 회사인 Apple은 이 프로젝트에 포함되지 않았군요.


하지만 가만히 있을 Adobe가 아니죠.


위 그림 하나로 다들 쓰러졌다는....
그러니깐 Flash IDE에서 Flash컨텐츠를 개발해서 그대로 iPhone용으로 익스포트 시켜주는 기능이 CS5부터 추가된다고 합니다. 멀티터치 기능도 추가되겠다. 결국 이 기능도 iPhone을 겨냥한듯합니다. ㅎㅎ

Flash Player 10.1 에 대한 다양한 글이 이미 인터넷에 퍼졌습니다.

Flash Player 10.0 에 대해서는 아래 Adobe MAX 키노트 동영상을 참고하세요.

음... Flash Player 10.1 은 내년 초에 나온다고 하네요. ^^

글쓴이 : 지돌스타(http://blog.jidolstar.com/594)



스타플(http://starpl.com)에서 제공하는 위젯중에 아래와 같은 “내별정보위젯”이 있다.

 


 

마우스를 올리면 내 별에 방문하거나 별받기를 할 수 있다.

 

스타플의 방문페이지와 별받기페이지에 접속시키기 위해 ExternalInterface.call()과 navigateToURL()을 아래와 같이 사용했다.

 

 

새창띄워 방문하기

ExternalInterface.call("window.open", 경로, "_blank", ""); 

 

방문하기

var request:URLRequest = new URLRequest( 경로 );
flash.net.navigateToURL( request, "_parent");

 

하지만 이러한 것들도 flash 컨텐츠를 웹페이지에 추가할때 쓰는 <object>태그와 <embed> 태그의 allowScriptAccess 속성과 allowNetworking 속성을 어떻게 지정하느냐에 따라 사용가능여부가 달라진다.

 

가령 이들 속성은 아래와 같은 방법으로 쓰여질 수 있다.

 

<object width="425" height="344">
<param name="allowScriptAccess" value="never" />
<param name="allowNetworking" value="internal" />
<param name="movie" value="swf경로"></param>
<param name="allowFullScreen" value="true"></param>
<embed src="swf경로"
    invokeURLs="false"
    autostart="false"
    allowScriptAccess="never"
    allowNetworking="internal"
    type="application/x-shockwave-flash"
    allowfullscreen="true"
    width="425"
    height="344"></embed>
</object>

 

각 속성에 대해서 자세히 설명하자면 다음과 같다.

 

 

allowScriptAccess 속성

 

이 속성은 SWF의 ExternalInterface을 통해 Javascript와 통신가능여부를 결정지어주는 속성이다. 이 속성은 다음 3가지 값중 하나가 된다.

  • never : SWF에서 ExternalInterface를 이용해 Javascript통신을 할 수 없다.
  • always : SWF에서 ExternalInterface를 이용해 Javascript통신이 언제든지 가능하다.
  • sameDomain : 같은 도메인에 있는 SWF일때 Javascript 통신이 가능하다.(기본)

 

allowNetworking 속성 

 

이 속성은 SWF에서 네트워크 기능 API 사용을 제한하는 옵션이다. 다음과 같은 3가지 값중 하나를 가진다.

  • all : 모든 네트워크 API 허용(기본)
  • internal : 브라우저 네비게시션이나 브라우저 상호작용 API 사용 제한
  • none : 모든 네크워크 API 제한

internal인 경우 제한 API

  • navigateToURL()
  • fscommand()
  • ExternalInterface.call()

none인 경우 제한 API (internal 포함)

  • sendToURL()
  • FileReference.download()
  • FileReference.upload()
  • Loader.load()
  • LocalConnection.connect()
  • LocalConnection.send()
  • NetConnection.connect()
  • NetStream.play()
  • Security.loadPolicyFile()
  • SharedObject.getLocal()
  • SharedObject.getRemote()
  • Socket.connect()
  • Sound.load()
  • URLLoader.load()
  • URLStream.load()
  • XMLSocket.connect()

 

이제 네이버에서 스타플 위젯을 통해 스타플에 방문할 수 없는 이유를 보자.

 

<EMBED
    invokeURLs="false"
    autostart="false"
    allowScriptAccess="never"
    allowNetworking="internal"
    src="경로"
    width="54"
    height="96"
    type="application/x-shockwave-flash"
    allowfullscreen="true">
</EMBED>

 

몇몇 분들이 이런 제한정책때문에 네이버 블로그에 있기를 꺼려하시는 분들이 계시다. 물론 보안상 어떻게 할 수 없다고는 할 수 있지만…


참고글

□ 개요

   o Adobe Flash Player에서 입력 검증 오류, 버퍼오버플로, 클릭재킹 등의 다수 취약점이
      발견되어 보안 업데이트가 발표됨[1]
   o 낮은 버전의 Adobe Flash Player 사용으로 악성코드 감염 등의 사고가 발생할 수 있음으로
      사용자의 주의 및 최신버전 설치가 권고됨


□ 해당프로그램

   o Adobe Flash Player 10.0.12.36 이하 버전이 설치된 Linux 제외 모든 운영체제
   o Adobe Flash Player 10.0.12.36 이하 버전 - 내부 네트워크 배포용
   o Adobe Flash Player 10.0.15.3 이하 버전이 설치된 Linux 운영체제
   o Adobe AIR 1.5 버전
   o Adobe Flash CS4 Professional에서 사용되는 Adobe Flash Player 10.0.22.87 이전버전
   o Adobe Flash CS3 Professional에서 사용되는 Adobe Flash Player / Debug Player 9.0.159.0
      이전버전
   o Adobe Flex 3에서 사용되는 Adobe Flash Debug Player 10.0.22.87 이전버전

 

□ 설명

   o Adobe Flash Player 취약점에 대한 보안 업데이트(총 5건)가 아래와 같이 발표됨
     ① Adobe Flash Player가 개체를 삭제하는 과정에서 개체에 할당된 메모리를 적절히 해제하지
         않아 발생하는 원격코드 실행 가능한 버퍼오버플로 취약점[2](CVE-2009-0520)
     ② Adobe Flash Player가 부적절하게 입력 검증하는 과정에서 발생하는 서비스 거부 취약점[3]
        (CVE-2009-0519)
     ③ Adobe Flash Player의 설정 관리자로 인한 클릭재킹 취약점[4](CVE-2009-0114)
     ④ Windows 운영체제에서 마우스 포인터를 출력할 때 발생하는 클릭재킹 취약점[5]
        (CVE-2009-0522)
     ⑤ Linux 운영체제에서 권한 상승으로 연계될 수 있는 정보 노출 취약점[6](CVE-2009-0521)
   o 상기 취약점을 이용하여 공격자는 SWF 파일을 조작하여 피해자의 PC에 악성 스크립트를
      실행시키거나 악성코드 감염 등과 같은 악성행위를 할 수 있음

 

□ 해결방안

   o 다음 표와 같은 버전의 Adobe 제품 사용자는 취약하지 않은 버전으로 업데이트 할 것을 권고함
     ※ 일부 Adobe 제품은 구글 툴바 추가 설치가 기본으로 설정되어 있으니 설치 전 확인 필요

 

   o Adobe Flash 컨텐츠를 사용하는 웹서버 관리자는 아래와 같이 웹페이지를 수정하여
      이용자들이 최신버전 Adobe Flash Player를 설치하도록 ActiveX 버전 수정 필요

< object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#
version=10,0,22,87" width="921" height="109" >

   o 향후에도 유사 취약점 노출로 인한 피해예방을 위해 아래와 같이 안전한 브라우징 습관을
     준수해야 함
      - 신뢰되지 않은 웹사이트의 플래시 파일 다운로드 주의
      - 의심되는 이메일에 포함된 플래시 파일 링크를 방문하지 않음
      - 개인방화벽과 백신제품 사용 등

 

□ 용어 정리

   o 클릭재킹 : 사용자가 웹 페이지를 클릭 할 때 자신도 모르게 의도하지 않은 기능을 실행
      하여 공격자가 컴퓨터에 대한 제어권 혹은 중요 정보를 획득하는 취약점[12]
   o Adobe Flash CS3/CS4 Professional : Adobe Flash 애니메이션 제작을 위한 도구[13]
   o Adobe AIR(Adobe Integrated Runtime) : 이미 입증된 웹 기술을 브라우저 외부 데스크톱
      에서 실행될 수 있도록 도와주는 프로그램 제작 도구[14]
   o Adobe Flex : Adobe Flash Player 또는 Adobe AIR에서 사용할 인터넷 어플리케이션
      개발 도구[15]

 

□ 기타 문의사항

   o 한국정보보호진흥원 인터넷침해사고대응지원센터 : 국번없이 118

 

□ 참고사이트

   [1] http://www.adobe.com/support/security/bulletins/apsb09-01.html
   [2] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0520
   [3] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0519
   [4] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0114
   [5] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0522
   [6] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0521
   [7] http://www.adobe.com/go/getflash
   [8] http://www.adobe.com/products/players/fpsh_distribution1.html
   [9] http://get.adobe.com/kr/air/
   [10] http://www.adobe.com/support/flashplayer/downloads.html#fp10
   [11] http://www.adobe.com/support/flashplayer/downloads.html#fp9
   [12] http://en.wikipedia.org/wiki/Clickjacking
   [13] http://www.adobe.com/kr/products/flash/
   [14] http://www.adobe.com/products/air/
   [15] http://www.adobeflex.co.kr/aboutflex/flex.html

 

출처 : http://www.krcert.net/secureNoticeView.do?seq=-1&num=316

우야꼬의 “Flash CS4로 만드는 Adobe AIR 1.5″ 책 저자인 우야꼬 님이 Stratus에 대한 번역을 해주셨네요.

번역글 : http://wooyaggo.tistory.com/search/stratus

 

 

Stratus는 Flash Player간 RTMFP(Real-Time Media Flow Protocal)을 이용해 Peer-to-Peer 통신을 가능하게 해주는 신기술입니다. 최소한의 서버 통신을 이용해 Flash Player간에 직접적 통신이 가능하도록 하여 서버부하를 줄여줄 수 있다는데 큰 매력을 느끼게 합니다. TCP가 아닌 UDP 기반으로 통신하기 때문에 훨씬 속도가 빠르겠군요.

 

이제 Flash Player 간 인터넷전화, 메신저, 화상채팅등이 구현이 되겠군요.
지속적으로 관심을 가지고 지켜봐야할 기술임에 틀림없겠습니다.

+ Recent posts