PageRenderTime 33ms CodeModel.GetById 19ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/src/away3d/core/render/Filter3DRenderer.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 174 lines | 138 code | 33 blank | 3 comment | 15 complexity | 003c650d5d157591df3e915546b7c5f8 MD5 | raw file
  1/**
  2 */
  3package away3d.core.render
  4{
  5	import away3d.cameras.*;
  6	import away3d.core.managers.*;
  7	import away3d.events.Stage3DEvent;
  8	import away3d.filters.*;
  9	import away3d.filters.tasks.*;
 10	
 11	import flash.display3D.*;
 12	import flash.display3D.textures.*;
 13	import flash.events.*;
 14	
 15	public class Filter3DRenderer
 16	{
 17		private var _filters:Array;
 18		private var _tasks:Vector.<Filter3DTaskBase>;
 19		private var _filterTasksInvalid:Boolean;
 20		private var _mainInputTexture:Texture;
 21		
 22		private var _requireDepthRender:Boolean;
 23		
 24		private var _rttManager:RTTBufferManager;
 25		private var _stage3DProxy:Stage3DProxy;
 26		private var _filterSizesInvalid:Boolean = true;
 27		
 28		public function Filter3DRenderer(stage3DProxy:Stage3DProxy)
 29		{
 30			_stage3DProxy = stage3DProxy;
 31			_stage3DProxy.addEventListener(Stage3DEvent.CONTEXT3D_RECREATED, onContext3DRecreated);
 32			_rttManager = RTTBufferManager.getInstance(stage3DProxy);
 33			_rttManager.addEventListener(Event.RESIZE, onRTTResize);
 34		}
 35
 36		private function onContext3DRecreated(event:Stage3DEvent):void {
 37			_filterSizesInvalid = true;
 38		}
 39		
 40		private function onRTTResize(event:Event):void
 41		{
 42			_filterSizesInvalid = true;
 43		}
 44		
 45		public function get requireDepthRender():Boolean
 46		{
 47			return _requireDepthRender;
 48		}
 49		
 50		public function getMainInputTexture(stage3DProxy:Stage3DProxy):Texture
 51		{
 52			if (_filterTasksInvalid)
 53				updateFilterTasks(stage3DProxy);
 54			return _mainInputTexture;
 55		}
 56		
 57		public function get filters():Array
 58		{
 59			return _filters;
 60		}
 61		
 62		public function set filters(value:Array):void
 63		{
 64			_filters = value;
 65			_filterTasksInvalid = true;
 66			
 67			_requireDepthRender = false;
 68			if (!_filters)
 69				return;
 70			
 71			for (var i:int = 0; i < _filters.length; ++i)
 72				_requireDepthRender ||= Boolean(_filters[i].requireDepthRender);
 73			
 74			_filterSizesInvalid = true;
 75		}
 76		
 77		private function updateFilterTasks(stage3DProxy:Stage3DProxy):void
 78		{
 79			var len:uint;
 80			
 81			if (_filterSizesInvalid)
 82				updateFilterSizes();
 83			
 84			if (!_filters) {
 85				_tasks = null;
 86				return;
 87			}
 88			
 89			_tasks = new Vector.<Filter3DTaskBase>();
 90			
 91			len = _filters.length - 1;
 92			
 93			var filter:Filter3DBase;
 94			
 95			for (var i:uint = 0; i <= len; ++i) {
 96				// make sure all internal tasks are linked together
 97				filter = _filters[i];
 98				filter.setRenderTargets(i == len? null : Filter3DBase(_filters[i + 1]).getMainInputTexture(stage3DProxy), stage3DProxy);
 99				_tasks = _tasks.concat(filter.tasks);
100			}
101			
102			_mainInputTexture = _filters[0].getMainInputTexture(stage3DProxy);
103		}
104		
105		public function render(stage3DProxy:Stage3DProxy, camera3D:Camera3D, depthTexture:Texture):void
106		{
107			var len:int;
108			var i:int;
109			var task:Filter3DTaskBase;
110			var context:Context3D = stage3DProxy.context3D;
111			var indexBuffer:IndexBuffer3D = _rttManager.indexBuffer;
112			var vertexBuffer:VertexBuffer3D = _rttManager.renderToTextureVertexBuffer;
113			
114			if (!_filters)
115				return;
116			if (_filterSizesInvalid)
117				updateFilterSizes();
118			if (_filterTasksInvalid)
119				updateFilterTasks(stage3DProxy);
120			
121			len = _filters.length;
122			for (i = 0; i < len; ++i)
123				_filters[i].update(stage3DProxy, camera3D);
124			
125			len = _tasks.length;
126			
127			if (len > 1) {
128				context.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
129				context.setVertexBufferAt(1, vertexBuffer, 2, Context3DVertexBufferFormat.FLOAT_2);
130			}
131			
132			for (i = 0; i < len; ++i) {
133				task = _tasks[i];
134				stage3DProxy.setRenderTarget(task.target);
135				
136				if (!task.target) {
137					stage3DProxy.scissorRect = null;
138					vertexBuffer = _rttManager.renderToScreenVertexBuffer;
139					context.setVertexBufferAt(0, vertexBuffer, 0, Context3DVertexBufferFormat.FLOAT_2);
140					context.setVertexBufferAt(1, vertexBuffer, 2, Context3DVertexBufferFormat.FLOAT_2);
141				}
142				context.setTextureAt(0, task.getMainInputTexture(stage3DProxy));
143				context.setProgram(task.getProgram3D(stage3DProxy));
144				context.clear(0.0, 0.0, 0.0, 0.0);
145				task.activate(stage3DProxy, camera3D, depthTexture);
146				context.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO);
147				context.drawTriangles(indexBuffer, 0, 2);
148				task.deactivate(stage3DProxy);
149			}
150			
151			context.setTextureAt(0, null);
152			context.setVertexBufferAt(0, null);
153			context.setVertexBufferAt(1, null);
154		}
155		
156		private function updateFilterSizes():void
157		{
158			for (var i:int = 0; i < _filters.length; ++i) {
159				_filters[i].textureWidth = _rttManager.textureWidth;
160				_filters[i].textureHeight = _rttManager.textureHeight;
161			}
162			
163			_filterSizesInvalid = false;
164		}
165		
166		public function dispose():void
167		{
168			_rttManager.removeEventListener(Event.RESIZE, onRTTResize);
169			_rttManager = null;
170			_stage3DProxy.removeEventListener(Stage3DEvent.CONTEXT3D_RECREATED, onContext3DRecreated);
171			_stage3DProxy = null;
172		}
173	}
174}