babylon.renderTargetTexture.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. var __extends = (this && this.__extends) || function (d, b) {
  2. for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
  3. function __() { this.constructor = d; }
  4. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  5. };
  6. var BABYLON;
  7. (function (BABYLON) {
  8. var RenderTargetTexture = (function (_super) {
  9. __extends(RenderTargetTexture, _super);
  10. function RenderTargetTexture(name, size, scene, generateMipMaps, doNotChangeAspectRatio, type, isCube) {
  11. if (doNotChangeAspectRatio === void 0) { doNotChangeAspectRatio = true; }
  12. if (type === void 0) { type = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
  13. if (isCube === void 0) { isCube = false; }
  14. _super.call(this, null, scene, !generateMipMaps);
  15. this.isCube = isCube;
  16. /**
  17. * Use this list to define the list of mesh you want to render.
  18. */
  19. this.renderList = new Array();
  20. this.renderParticles = true;
  21. this.renderSprites = false;
  22. this.coordinatesMode = BABYLON.Texture.PROJECTION_MODE;
  23. // Events
  24. /**
  25. * An event triggered when the texture is unbind.
  26. * @type {BABYLON.Observable}
  27. */
  28. this.onAfterUnbindObservable = new BABYLON.Observable();
  29. /**
  30. * An event triggered before rendering the texture
  31. * @type {BABYLON.Observable}
  32. */
  33. this.onBeforeRenderObservable = new BABYLON.Observable();
  34. /**
  35. * An event triggered after rendering the texture
  36. * @type {BABYLON.Observable}
  37. */
  38. this.onAfterRenderObservable = new BABYLON.Observable();
  39. /**
  40. * An event triggered after the texture clear
  41. * @type {BABYLON.Observable}
  42. */
  43. this.onClearObservable = new BABYLON.Observable();
  44. this._currentRefreshId = -1;
  45. this._refreshRate = 1;
  46. this.name = name;
  47. this.isRenderTarget = true;
  48. this._size = size;
  49. this._generateMipMaps = generateMipMaps;
  50. this._doNotChangeAspectRatio = doNotChangeAspectRatio;
  51. if (isCube) {
  52. this._texture = scene.getEngine().createRenderTargetCubeTexture(size, { generateMipMaps: generateMipMaps });
  53. this.coordinatesMode = BABYLON.Texture.INVCUBIC_MODE;
  54. this._textureMatrix = BABYLON.Matrix.Identity();
  55. }
  56. else {
  57. this._texture = scene.getEngine().createRenderTargetTexture(size, { generateMipMaps: generateMipMaps, type: type });
  58. }
  59. // Rendering groups
  60. this._renderingManager = new BABYLON.RenderingManager(scene);
  61. }
  62. Object.defineProperty(RenderTargetTexture, "REFRESHRATE_RENDER_ONCE", {
  63. get: function () {
  64. return RenderTargetTexture._REFRESHRATE_RENDER_ONCE;
  65. },
  66. enumerable: true,
  67. configurable: true
  68. });
  69. Object.defineProperty(RenderTargetTexture, "REFRESHRATE_RENDER_ONEVERYFRAME", {
  70. get: function () {
  71. return RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYFRAME;
  72. },
  73. enumerable: true,
  74. configurable: true
  75. });
  76. Object.defineProperty(RenderTargetTexture, "REFRESHRATE_RENDER_ONEVERYTWOFRAMES", {
  77. get: function () {
  78. return RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYTWOFRAMES;
  79. },
  80. enumerable: true,
  81. configurable: true
  82. });
  83. Object.defineProperty(RenderTargetTexture.prototype, "onAfterUnbind", {
  84. set: function (callback) {
  85. if (this._onAfterUnbindObserver) {
  86. this.onAfterUnbindObservable.remove(this._onAfterUnbindObserver);
  87. }
  88. this._onAfterUnbindObserver = this.onAfterUnbindObservable.add(callback);
  89. },
  90. enumerable: true,
  91. configurable: true
  92. });
  93. Object.defineProperty(RenderTargetTexture.prototype, "onBeforeRender", {
  94. set: function (callback) {
  95. if (this._onBeforeRenderObserver) {
  96. this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
  97. }
  98. this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);
  99. },
  100. enumerable: true,
  101. configurable: true
  102. });
  103. Object.defineProperty(RenderTargetTexture.prototype, "onAfterRender", {
  104. set: function (callback) {
  105. if (this._onAfterRenderObserver) {
  106. this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
  107. }
  108. this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
  109. },
  110. enumerable: true,
  111. configurable: true
  112. });
  113. Object.defineProperty(RenderTargetTexture.prototype, "onClear", {
  114. set: function (callback) {
  115. if (this._onClearObserver) {
  116. this.onClearObservable.remove(this._onClearObserver);
  117. }
  118. this._onClearObserver = this.onClearObservable.add(callback);
  119. },
  120. enumerable: true,
  121. configurable: true
  122. });
  123. RenderTargetTexture.prototype.resetRefreshCounter = function () {
  124. this._currentRefreshId = -1;
  125. };
  126. Object.defineProperty(RenderTargetTexture.prototype, "refreshRate", {
  127. get: function () {
  128. return this._refreshRate;
  129. },
  130. // Use 0 to render just once, 1 to render on every frame, 2 to render every two frames and so on...
  131. set: function (value) {
  132. this._refreshRate = value;
  133. this.resetRefreshCounter();
  134. },
  135. enumerable: true,
  136. configurable: true
  137. });
  138. RenderTargetTexture.prototype._shouldRender = function () {
  139. if (this._currentRefreshId === -1) {
  140. this._currentRefreshId = 1;
  141. return true;
  142. }
  143. if (this.refreshRate === this._currentRefreshId) {
  144. this._currentRefreshId = 1;
  145. return true;
  146. }
  147. this._currentRefreshId++;
  148. return false;
  149. };
  150. RenderTargetTexture.prototype.isReady = function () {
  151. if (!this.getScene().renderTargetsEnabled) {
  152. return false;
  153. }
  154. return _super.prototype.isReady.call(this);
  155. };
  156. RenderTargetTexture.prototype.getRenderSize = function () {
  157. return this._size;
  158. };
  159. Object.defineProperty(RenderTargetTexture.prototype, "canRescale", {
  160. get: function () {
  161. return true;
  162. },
  163. enumerable: true,
  164. configurable: true
  165. });
  166. RenderTargetTexture.prototype.scale = function (ratio) {
  167. var newSize = this._size * ratio;
  168. this.resize(newSize, this._generateMipMaps);
  169. };
  170. RenderTargetTexture.prototype.getReflectionTextureMatrix = function () {
  171. if (this.isCube) {
  172. return this._textureMatrix;
  173. }
  174. return _super.prototype.getReflectionTextureMatrix.call(this);
  175. };
  176. RenderTargetTexture.prototype.resize = function (size, generateMipMaps) {
  177. this.releaseInternalTexture();
  178. if (this.isCube) {
  179. this._texture = this.getScene().getEngine().createRenderTargetCubeTexture(size);
  180. }
  181. else {
  182. this._texture = this.getScene().getEngine().createRenderTargetTexture(size, generateMipMaps);
  183. }
  184. };
  185. RenderTargetTexture.prototype.render = function (useCameraPostProcess, dumpForDebug) {
  186. var scene = this.getScene();
  187. if (this.activeCamera && this.activeCamera !== scene.activeCamera) {
  188. scene.setTransformMatrix(this.activeCamera.getViewMatrix(), this.activeCamera.getProjectionMatrix(true));
  189. }
  190. if (this._waitingRenderList) {
  191. this.renderList = [];
  192. for (var index = 0; index < this._waitingRenderList.length; index++) {
  193. var id = this._waitingRenderList[index];
  194. this.renderList.push(scene.getMeshByID(id));
  195. }
  196. delete this._waitingRenderList;
  197. }
  198. // Is predicate defined?
  199. if (this.renderListPredicate) {
  200. this.renderList.splice(0); // Clear previous renderList
  201. var sceneMeshes = this.getScene().meshes;
  202. for (var index = 0; index < sceneMeshes.length; index++) {
  203. var mesh = sceneMeshes[index];
  204. if (this.renderListPredicate(mesh)) {
  205. this.renderList.push(mesh);
  206. }
  207. }
  208. }
  209. if (this.renderList && this.renderList.length === 0) {
  210. return;
  211. }
  212. // Prepare renderingManager
  213. this._renderingManager.reset();
  214. var currentRenderList = this.renderList ? this.renderList : scene.getActiveMeshes().data;
  215. var sceneRenderId = scene.getRenderId();
  216. for (var meshIndex = 0; meshIndex < currentRenderList.length; meshIndex++) {
  217. var mesh = currentRenderList[meshIndex];
  218. if (mesh) {
  219. if (!mesh.isReady()) {
  220. // Reset _currentRefreshId
  221. this.resetRefreshCounter();
  222. continue;
  223. }
  224. mesh._preActivateForIntermediateRendering(sceneRenderId);
  225. if (mesh.isEnabled() && mesh.isVisible && mesh.subMeshes && ((mesh.layerMask & scene.activeCamera.layerMask) !== 0)) {
  226. mesh._activate(sceneRenderId);
  227. for (var subIndex = 0; subIndex < mesh.subMeshes.length; subIndex++) {
  228. var subMesh = mesh.subMeshes[subIndex];
  229. scene._activeIndices += subMesh.indexCount;
  230. this._renderingManager.dispatch(subMesh);
  231. }
  232. }
  233. }
  234. }
  235. if (this.isCube) {
  236. for (var face = 0; face < 6; face++) {
  237. this.renderToTarget(face, currentRenderList, useCameraPostProcess, dumpForDebug);
  238. scene.incrementRenderId();
  239. scene.resetCachedMaterial();
  240. }
  241. }
  242. else {
  243. this.renderToTarget(0, currentRenderList, useCameraPostProcess, dumpForDebug);
  244. }
  245. this.onAfterUnbindObservable.notifyObservers(this);
  246. if (this.activeCamera && this.activeCamera !== scene.activeCamera) {
  247. scene.setTransformMatrix(scene.activeCamera.getViewMatrix(), scene.activeCamera.getProjectionMatrix(true));
  248. }
  249. scene.resetCachedMaterial();
  250. };
  251. RenderTargetTexture.prototype.renderToTarget = function (faceIndex, currentRenderList, useCameraPostProcess, dumpForDebug) {
  252. var scene = this.getScene();
  253. var engine = scene.getEngine();
  254. // Bind
  255. if (!useCameraPostProcess || !scene.postProcessManager._prepareFrame(this._texture)) {
  256. if (this.isCube) {
  257. engine.bindFramebuffer(this._texture, faceIndex);
  258. }
  259. else {
  260. engine.bindFramebuffer(this._texture);
  261. }
  262. }
  263. this.onBeforeRenderObservable.notifyObservers(faceIndex);
  264. // Clear
  265. if (this.onClearObservable.hasObservers()) {
  266. this.onClearObservable.notifyObservers(engine);
  267. }
  268. else {
  269. engine.clear(scene.clearColor, true, true);
  270. }
  271. if (!this._doNotChangeAspectRatio) {
  272. scene.updateTransformMatrix(true);
  273. }
  274. // Render
  275. this._renderingManager.render(this.customRenderFunction, currentRenderList, this.renderParticles, this.renderSprites);
  276. if (useCameraPostProcess) {
  277. scene.postProcessManager._finalizeFrame(false, this._texture, faceIndex);
  278. }
  279. if (!this._doNotChangeAspectRatio) {
  280. scene.updateTransformMatrix(true);
  281. }
  282. this.onAfterRenderObservable.notifyObservers(faceIndex);
  283. // Dump ?
  284. if (dumpForDebug) {
  285. BABYLON.Tools.DumpFramebuffer(this._size, this._size, engine);
  286. }
  287. // Unbind
  288. if (!this.isCube || faceIndex === 5) {
  289. if (this.isCube) {
  290. if (faceIndex === 5) {
  291. engine.generateMipMapsForCubemap(this._texture);
  292. }
  293. }
  294. engine.unBindFramebuffer(this._texture, this.isCube);
  295. }
  296. };
  297. RenderTargetTexture.prototype.clone = function () {
  298. var textureSize = this.getSize();
  299. var newTexture = new RenderTargetTexture(this.name, textureSize.width, this.getScene(), this._generateMipMaps);
  300. // Base texture
  301. newTexture.hasAlpha = this.hasAlpha;
  302. newTexture.level = this.level;
  303. // RenderTarget Texture
  304. newTexture.coordinatesMode = this.coordinatesMode;
  305. newTexture.renderList = this.renderList.slice(0);
  306. return newTexture;
  307. };
  308. RenderTargetTexture.prototype.serialize = function () {
  309. if (!this.name) {
  310. return null;
  311. }
  312. var serializationObject = _super.prototype.serialize.call(this);
  313. serializationObject.renderTargetSize = this.getRenderSize();
  314. serializationObject.renderList = [];
  315. for (var index = 0; index < this.renderList.length; index++) {
  316. serializationObject.renderList.push(this.renderList[index].id);
  317. }
  318. return serializationObject;
  319. };
  320. RenderTargetTexture._REFRESHRATE_RENDER_ONCE = 0;
  321. RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYFRAME = 1;
  322. RenderTargetTexture._REFRESHRATE_RENDER_ONEVERYTWOFRAMES = 2;
  323. return RenderTargetTexture;
  324. })(BABYLON.Texture);
  325. BABYLON.RenderTargetTexture = RenderTargetTexture;
  326. })(BABYLON || (BABYLON = {}));