PageRenderTime 184ms CodeModel.GetById 80ms app.highlight 13ms RepoModel.GetById 87ms app.codeStats 1ms

/src/away3d/core/render/DepthRenderer.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 184 lines | 133 code | 30 blank | 21 comment | 23 complexity | 4139a926a29af74a1df0f92957efa3c8 MD5 | raw file
  1package away3d.core.render
  2{
  3	import away3d.arcane;
  4	import away3d.cameras.Camera3D;
  5	import away3d.core.base.IRenderable;
  6	import away3d.core.data.RenderableListItem;
  7	import away3d.core.math.Plane3D;
  8	import away3d.core.traverse.EntityCollector;
  9	import away3d.entities.Entity;
 10	import away3d.materials.MaterialBase;
 11	
 12	import flash.display3D.Context3DBlendFactor;
 13	import flash.display3D.Context3DCompareMode;
 14	import flash.display3D.textures.TextureBase;
 15	import flash.geom.Rectangle;
 16	
 17	use namespace arcane;
 18	
 19	/**
 20	 * The DepthRenderer class renders 32-bit depth information encoded as RGBA
 21	 */
 22	public class DepthRenderer extends RendererBase
 23	{
 24		private var _activeMaterial:MaterialBase;
 25		private var _renderBlended:Boolean;
 26		private var _distanceBased:Boolean;
 27		private var _disableColor:Boolean;
 28		
 29		/**
 30		 * Creates a new DepthRenderer object.
 31		 * @param renderBlended Indicates whether semi-transparent objects should be rendered.
 32		 * @param distanceBased Indicates whether the written depth value is distance-based or projected depth-based
 33		 */
 34		public function DepthRenderer(renderBlended:Boolean = false, distanceBased:Boolean = false)
 35		{
 36			super();
 37			_renderBlended = renderBlended;
 38			_distanceBased = distanceBased;
 39			_backgroundR = 1;
 40			_backgroundG = 1;
 41			_backgroundB = 1;
 42		}
 43		
 44		public function get disableColor():Boolean
 45		{
 46			return _disableColor;
 47		}
 48		
 49		public function set disableColor(value:Boolean):void
 50		{
 51			_disableColor = value;
 52		}
 53		
 54		arcane override function set backgroundR(value:Number):void
 55		{
 56		}
 57		
 58		arcane override function set backgroundG(value:Number):void
 59		{
 60		}
 61		
 62		arcane override function set backgroundB(value:Number):void
 63		{
 64		}
 65		
 66		arcane function renderCascades(entityCollector:EntityCollector, target:TextureBase, numCascades:uint, scissorRects:Vector.<Rectangle>, cameras:Vector.<Camera3D>):void
 67		{
 68			_renderTarget = target;
 69			_renderTargetSurface = 0;
 70			_renderableSorter.sort(entityCollector);
 71			_stage3DProxy.setRenderTarget(target, true, 0);
 72			_context.clear(1, 1, 1, 1, 1, 0);
 73			_context.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO);
 74			_context.setDepthTest(true, Context3DCompareMode.LESS);
 75			
 76			var head:RenderableListItem = entityCollector.opaqueRenderableHead;
 77			var first:Boolean = true;
 78			for (var i:int = numCascades - 1; i >= 0; --i) {
 79				_stage3DProxy.scissorRect = scissorRects[i];
 80				drawCascadeRenderables(head, cameras[i], first? null : cameras[i].frustumPlanes);
 81				first = false;
 82			}
 83			
 84			if (_activeMaterial)
 85				_activeMaterial.deactivateForDepth(_stage3DProxy);
 86			
 87			_activeMaterial = null;
 88			
 89			//line required for correct rendering when using away3d with starling. DO NOT REMOVE UNLESS STARLING INTEGRATION IS RETESTED!
 90			_context.setDepthTest(false, Context3DCompareMode.LESS_EQUAL);
 91			
 92			_stage3DProxy.scissorRect = null;
 93		}
 94		
 95		private function drawCascadeRenderables(item:RenderableListItem, camera:Camera3D, cullPlanes:Vector.<Plane3D>):void
 96		{
 97			var material:MaterialBase;
 98			
 99			while (item) {
100				if (item.cascaded) {
101					item = item.next;
102					continue;
103				}
104				
105				var renderable:IRenderable = item.renderable;
106				var entity:Entity = renderable.sourceEntity;
107				
108				// if completely in front, it will fall in a different cascade
109				// do not use near and far planes
110				if (!cullPlanes || entity.worldBounds.isInFrustum(cullPlanes, 4)) {
111					material = renderable.material;
112					if (_activeMaterial != material) {
113						if (_activeMaterial)
114							_activeMaterial.deactivateForDepth(_stage3DProxy);
115						_activeMaterial = material;
116						_activeMaterial.activateForDepth(_stage3DProxy, camera, false);
117					}
118					
119					_activeMaterial.renderDepth(renderable, _stage3DProxy, camera, camera.viewProjection);
120				} else
121					item.cascaded = true;
122				
123				item = item.next;
124			}
125		}
126		
127		/**
128		 * @inheritDoc
129		 */
130		override protected function draw(entityCollector:EntityCollector, target:TextureBase):void
131		{
132			_context.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO);
133			_context.setDepthTest(true, Context3DCompareMode.LESS);
134			drawRenderables(entityCollector.opaqueRenderableHead, entityCollector);
135			
136			if (_disableColor)
137				_context.setColorMask(false, false, false, false);
138			
139			if (_renderBlended)
140				drawRenderables(entityCollector.blendedRenderableHead, entityCollector);
141			
142			if (_activeMaterial)
143				_activeMaterial.deactivateForDepth(_stage3DProxy);
144			
145			if (_disableColor)
146				_context.setColorMask(true, true, true, true);
147			
148			_activeMaterial = null;
149		}
150		
151		/**
152		 * Draw a list of renderables.
153		 * @param renderables The renderables to draw.
154		 * @param entityCollector The EntityCollector containing all potentially visible information.
155		 */
156		private function drawRenderables(item:RenderableListItem, entityCollector:EntityCollector):void
157		{
158			var camera:Camera3D = entityCollector.camera;
159			var item2:RenderableListItem;
160			
161			while (item) {
162				_activeMaterial = item.renderable.material;
163				
164				// otherwise this would result in depth rendered anyway because fragment shader kil is ignored
165				if (_disableColor && _activeMaterial.hasDepthAlphaThreshold()) {
166					item2 = item;
167					// fast forward
168					do
169						item2 = item2.next;
170					while (item2 && item2.renderable.material == _activeMaterial);
171				} else {
172					_activeMaterial.activateForDepth(_stage3DProxy, camera, _distanceBased);
173					item2 = item;
174					do {
175						_activeMaterial.renderDepth(item2.renderable, _stage3DProxy, camera, _rttViewProjectionMatrix);
176						item2 = item2.next;
177					} while (item2 && item2.renderable.material == _activeMaterial);
178					_activeMaterial.deactivateForDepth(_stage3DProxy);
179				}
180				item = item2;
181			}
182		}
183	}
184}