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