/src/away3d/core/render/DefaultRenderer.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 249 lines · 188 code · 38 blank · 23 comment · 24 complexity · fa263cf76976451878c8232c10845c60 MD5 · raw file

  1. package 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.managers.Stage3DProxy;
  8. import away3d.core.math.Matrix3DUtils;
  9. import away3d.core.math.Matrix3DUtils;
  10. import away3d.core.traverse.EntityCollector;
  11. import away3d.lights.DirectionalLight;
  12. import away3d.lights.LightBase;
  13. import away3d.lights.PointLight;
  14. import away3d.lights.shadowmaps.ShadowMapperBase;
  15. import away3d.materials.MaterialBase;
  16. import flash.display3D.Context3DBlendFactor;
  17. import flash.display3D.Context3DCompareMode;
  18. import flash.display3D.textures.TextureBase;
  19. import flash.geom.Matrix3D;
  20. import flash.geom.Rectangle;
  21. import flash.geom.Vector3D;
  22. use namespace arcane;
  23. /**
  24. * The DefaultRenderer class provides the default rendering method. It renders the scene graph objects using the
  25. * materials assigned to them.
  26. */
  27. public class DefaultRenderer extends RendererBase
  28. {
  29. private static var RTT_PASSES:int = 1;
  30. private static var SCREEN_PASSES:int = 2;
  31. private static var ALL_PASSES:int = 3;
  32. private var _activeMaterial:MaterialBase;
  33. private var _distanceRenderer:DepthRenderer;
  34. private var _depthRenderer:DepthRenderer;
  35. private var _skyboxProjection:Matrix3D = new Matrix3D();
  36. private var _tempSkyboxMatrix:Matrix3D = new Matrix3D();
  37. private var _skyboxTempVector:Vector3D = new Vector3D();
  38. /**
  39. * Creates a new DefaultRenderer object.
  40. * @param antiAlias The amount of anti-aliasing to use.
  41. * @param renderMode The render mode to use.
  42. */
  43. public function DefaultRenderer()
  44. {
  45. super();
  46. _depthRenderer = new DepthRenderer();
  47. _distanceRenderer = new DepthRenderer(false, true);
  48. }
  49. arcane override function set stage3DProxy(value:Stage3DProxy):void
  50. {
  51. super.stage3DProxy = value;
  52. _distanceRenderer.stage3DProxy = _depthRenderer.stage3DProxy = value;
  53. }
  54. protected override function executeRender(entityCollector:EntityCollector, target:TextureBase = null, scissorRect:Rectangle = null, surfaceSelector:int = 0):void
  55. {
  56. updateLights(entityCollector);
  57. // otherwise RTT will interfere with other RTTs
  58. if (target) {
  59. drawRenderables(entityCollector.opaqueRenderableHead, entityCollector, RTT_PASSES);
  60. drawRenderables(entityCollector.blendedRenderableHead, entityCollector, RTT_PASSES);
  61. }
  62. super.executeRender(entityCollector, target, scissorRect, surfaceSelector);
  63. }
  64. private function updateLights(entityCollector:EntityCollector):void
  65. {
  66. var dirLights:Vector.<DirectionalLight> = entityCollector.directionalLights;
  67. var pointLights:Vector.<PointLight> = entityCollector.pointLights;
  68. var len:uint, i:uint;
  69. var light:LightBase;
  70. var shadowMapper:ShadowMapperBase;
  71. len = dirLights.length;
  72. for (i = 0; i < len; ++i) {
  73. light = dirLights[i];
  74. shadowMapper = light.shadowMapper;
  75. if (light.castsShadows && (shadowMapper.autoUpdateShadows || shadowMapper._shadowsInvalid))
  76. shadowMapper.renderDepthMap(_stage3DProxy, entityCollector, _depthRenderer);
  77. }
  78. len = pointLights.length;
  79. for (i = 0; i < len; ++i) {
  80. light = pointLights[i];
  81. shadowMapper = light.shadowMapper;
  82. if (light.castsShadows && (shadowMapper.autoUpdateShadows || shadowMapper._shadowsInvalid))
  83. shadowMapper.renderDepthMap(_stage3DProxy, entityCollector, _distanceRenderer);
  84. }
  85. }
  86. /**
  87. * @inheritDoc
  88. */
  89. override protected function draw(entityCollector:EntityCollector, target:TextureBase):void
  90. {
  91. _context.setBlendFactors(Context3DBlendFactor.ONE, Context3DBlendFactor.ZERO);
  92. if (entityCollector.skyBox) {
  93. if (_activeMaterial)
  94. _activeMaterial.deactivate(_stage3DProxy);
  95. _activeMaterial = null;
  96. _context.setDepthTest(false, Context3DCompareMode.ALWAYS);
  97. drawSkyBox(entityCollector);
  98. }
  99. _context.setDepthTest(true, Context3DCompareMode.LESS_EQUAL);
  100. var which:int = target? SCREEN_PASSES : ALL_PASSES;
  101. drawRenderables(entityCollector.opaqueRenderableHead, entityCollector, which);
  102. drawRenderables(entityCollector.blendedRenderableHead, entityCollector, which);
  103. _context.setDepthTest(false, Context3DCompareMode.LESS_EQUAL);
  104. if (_activeMaterial)
  105. _activeMaterial.deactivate(_stage3DProxy);
  106. _activeMaterial = null;
  107. }
  108. /**
  109. * Draw the skybox if present.
  110. * @param entityCollector The EntityCollector containing all potentially visible information.
  111. */
  112. private function drawSkyBox(entityCollector:EntityCollector):void
  113. {
  114. var skyBox:IRenderable = entityCollector.skyBox;
  115. var material:MaterialBase = skyBox.material;
  116. var camera:Camera3D = entityCollector.camera;
  117. updateSkyBoxProjection(camera);
  118. material.activatePass(0, _stage3DProxy, camera);
  119. material.renderPass(0, skyBox, _stage3DProxy, entityCollector, _skyboxProjection);
  120. material.deactivatePass(0, _stage3DProxy);
  121. }
  122. private function updateSkyBoxProjection(camera:Camera3D):void
  123. {
  124. _skyboxProjection.copyFrom(_rttViewProjectionMatrix);
  125. _skyboxProjection.copyRowTo(2, _skyboxTempVector);
  126. var camPos:Vector3D = camera.scenePosition;
  127. var cx:Number = _skyboxTempVector.x;
  128. var cy:Number = _skyboxTempVector.y;
  129. var cz:Number = _skyboxTempVector.z;
  130. var length:Number = Math.sqrt(cx*cx + cy*cy + cz*cz);
  131. _skyboxTempVector.x = 0;
  132. _skyboxTempVector.y = 0;
  133. _skyboxTempVector.z = 0;
  134. _skyboxTempVector.w = 1;
  135. _tempSkyboxMatrix.copyFrom(camera.sceneTransform);
  136. _tempSkyboxMatrix.copyColumnFrom(3,_skyboxTempVector);
  137. _skyboxTempVector.x = 0;
  138. _skyboxTempVector.y = 0;
  139. _skyboxTempVector.z = 1;
  140. _skyboxTempVector.w = 0;
  141. Matrix3DUtils.transformVector(_tempSkyboxMatrix,_skyboxTempVector, _skyboxTempVector);
  142. _skyboxTempVector.normalize();
  143. var angle:Number = Math.acos(_skyboxTempVector.x*(cx/length) + _skyboxTempVector.y*(cy/length) + _skyboxTempVector.z*(cz/length));
  144. if(Math.abs(angle)>0.000001) {
  145. return;
  146. }
  147. var cw:Number = -(cx*camPos.x + cy*camPos.y + cz*camPos.z + length);
  148. var signX:Number = cx >= 0? 1 : -1;
  149. var signY:Number = cy >= 0? 1 : -1;
  150. var p:Vector3D = _skyboxTempVector;
  151. p.x = signX;
  152. p.y = signY;
  153. p.z = 1;
  154. p.w = 1;
  155. _tempSkyboxMatrix.copyFrom(_skyboxProjection);
  156. _tempSkyboxMatrix.invert();
  157. var q:Vector3D = Matrix3DUtils.transformVector(_tempSkyboxMatrix,p,Matrix3DUtils.CALCULATION_VECTOR3D);
  158. _skyboxProjection.copyRowTo(3, p);
  159. var a:Number = (q.x*p.x + q.y*p.y + q.z*p.z + q.w*p.w)/(cx*q.x + cy*q.y + cz*q.z + cw*q.w);
  160. _skyboxTempVector.x = cx*a;
  161. _skyboxTempVector.y = cy*a;
  162. _skyboxTempVector.z = cz*a;
  163. _skyboxTempVector.w = cw*a;
  164. //copy changed near far
  165. _skyboxProjection.copyRowFrom(2, _skyboxTempVector);
  166. }
  167. /**
  168. * Draw a list of renderables.
  169. * @param renderables The renderables to draw.
  170. * @param entityCollector The EntityCollector containing all potentially visible information.
  171. */
  172. private function drawRenderables(item:RenderableListItem, entityCollector:EntityCollector, which:int):void
  173. {
  174. var numPasses:uint;
  175. var j:uint;
  176. var camera:Camera3D = entityCollector.camera;
  177. var item2:RenderableListItem;
  178. while (item) {
  179. _activeMaterial = item.renderable.material;
  180. _activeMaterial.updateMaterial(_context);
  181. numPasses = _activeMaterial.numPasses;
  182. j = 0;
  183. do {
  184. item2 = item;
  185. var rttMask:int = _activeMaterial.passRendersToTexture(j)? 1 : 2;
  186. if ((rttMask & which) != 0) {
  187. _activeMaterial.activatePass(j, _stage3DProxy, camera);
  188. do {
  189. _activeMaterial.renderPass(j, item2.renderable, _stage3DProxy, entityCollector, _rttViewProjectionMatrix);
  190. item2 = item2.next;
  191. } while (item2 && item2.renderable.material == _activeMaterial);
  192. _activeMaterial.deactivatePass(j, _stage3DProxy);
  193. } else {
  194. do
  195. item2 = item2.next;
  196. while (item2 && item2.renderable.material == _activeMaterial);
  197. }
  198. } while (++j < numPasses);
  199. item = item2;
  200. }
  201. }
  202. arcane override function dispose():void
  203. {
  204. super.dispose();
  205. _depthRenderer.dispose();
  206. _distanceRenderer.dispose();
  207. _depthRenderer = null;
  208. _distanceRenderer = null;
  209. }
  210. }
  211. }