CCRenderTexture.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. /****************************************************************************
  2. Copyright (c) 2008-2010 Ricardo Quesada
  3. Copyright (c) 2011-2012 cocos2d-x.org
  4. Copyright (c) 2013-2014 Chukong Technologies Inc.
  5. Copyright (c) 2009 Jason Booth
  6. http://www.cocos2d-x.org
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. ****************************************************************************/
  23. /**
  24. * enum for jpg
  25. * @constant
  26. * @type Number
  27. */
  28. cc.IMAGE_FORMAT_JPEG = 0;
  29. /**
  30. * enum for png
  31. * @constant
  32. * @type Number
  33. */
  34. cc.IMAGE_FORMAT_PNG = 1;
  35. /**
  36. * enum for raw
  37. * @constant
  38. * @type Number
  39. */
  40. cc.IMAGE_FORMAT_RAWDATA = 9;
  41. /**
  42. * @param {Number} x
  43. * @return {Number}
  44. * Constructor
  45. */
  46. cc.NextPOT = function (x) {
  47. x = x - 1;
  48. x = x | (x >> 1);
  49. x = x | (x >> 2);
  50. x = x | (x >> 4);
  51. x = x | (x >> 8);
  52. x = x | (x >> 16);
  53. return x + 1;
  54. };
  55. /**
  56. * cc.RenderTexture is a generic rendering target. To render things into it,<br/>
  57. * simply construct a render target, call begin on it, call visit on any cocos<br/>
  58. * scenes or objects to render them, and call end. For convenience, render texture<br/>
  59. * adds a sprite as it's display child with the results, so you can simply add<br/>
  60. * the render texture to your scene and treat it like any other CocosNode.<br/>
  61. * There are also functions for saving the render texture to disk in PNG or JPG format.
  62. * @class
  63. * @extends cc.Node
  64. *
  65. * @property {cc.Sprite} sprite - The sprite.
  66. * @property {cc.Sprite} clearFlags - Code for "auto" update.
  67. * @property {Number} clearDepthVal - Clear depth value.
  68. * @property {Boolean} autoDraw - Indicate auto draw mode activate or not.
  69. * @property {Number} clearStencilVal - Clear stencil value.
  70. * @property {cc.Color} clearColorVal - Clear color value, valid only when "autoDraw" is true.
  71. */
  72. cc.RenderTexture = cc.Node.extend(/** @lends cc.RenderTexture# */{
  73. sprite:null,
  74. //
  75. // <p>Code for "auto" update<br/>
  76. // Valid flags: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT.<br/>
  77. // They can be OR'ed. Valid when "autoDraw is YES.</p>
  78. // @public
  79. //
  80. clearFlags:0,
  81. clearDepthVal:0,
  82. autoDraw:false,
  83. //
  84. // the off-screen canvas for rendering and storing the texture
  85. // @type HTMLCanvasElement
  86. //
  87. _cacheCanvas:null,
  88. /**
  89. * stores a reference to the canvas context object
  90. * @type CanvasRenderingContext2D
  91. */
  92. _cacheContext:null,
  93. _fBO:0,
  94. _depthRenderBuffer:0,
  95. _oldFBO:0,
  96. _texture:null,
  97. _textureCopy:null,
  98. _uITextureImage:null,
  99. _pixelFormat:cc.Texture2D.PIXEL_FORMAT_RGBA8888,
  100. _clearColor:null,
  101. clearStencilVal:0,
  102. _clearColorStr:null,
  103. _className:"RenderTexture",
  104. /**
  105. * creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid
  106. * Constructor of cc.RenderTexture for Canvas
  107. * @param {Number} width
  108. * @param {Number} height
  109. * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} format
  110. * @param {Number} depthStencilFormat
  111. * @example
  112. * // Example
  113. * var rt = new cc.RenderTexture(width, height, format, depthStencilFormat)
  114. * @function
  115. */
  116. ctor: null,
  117. _ctorForCanvas: function (width, height, format, depthStencilFormat) {
  118. cc.Node.prototype.ctor.call(this);
  119. this._cascadeColorEnabled = true;
  120. this._cascadeOpacityEnabled = true;
  121. this._clearColor = cc.color(255, 255, 255, 255);
  122. this._clearColorStr = "rgba(255,255,255,1)";
  123. this._cacheCanvas = cc.newElement('canvas');
  124. this._cacheContext = this._cacheCanvas.getContext('2d');
  125. this.anchorX = 0;
  126. this.anchorY = 0;
  127. if(width !== undefined && height !== undefined){
  128. format = format || cc.Texture2D.PIXEL_FORMAT_RGBA8888;
  129. depthStencilFormat = depthStencilFormat || 0;
  130. this.initWithWidthAndHeight(width, height, format, depthStencilFormat);
  131. }
  132. },
  133. _ctorForWebGL: function (width, height, format, depthStencilFormat) {
  134. cc.Node.prototype.ctor.call(this);
  135. this._cascadeColorEnabled = true;
  136. this._cascadeOpacityEnabled = true;
  137. this._clearColor = cc.color(0, 0, 0, 0);
  138. if(width !== undefined && height !== undefined){
  139. format = format || cc.Texture2D.PIXEL_FORMAT_RGBA8888;
  140. depthStencilFormat = depthStencilFormat || 0;
  141. this.initWithWidthAndHeight(width, height, format, depthStencilFormat);
  142. }
  143. },
  144. /**
  145. * Clear RenderTexture.
  146. * @function
  147. */
  148. cleanup:null,
  149. _cleanupForCanvas:function () {
  150. cc.Node.prototype.onExit.call(this);
  151. this._cacheContext = null;
  152. this._cacheCanvas = null;
  153. },
  154. _cleanupForWebGL: function () {
  155. cc.Node.prototype.onExit.call(this);
  156. //this.sprite = null;
  157. this._textureCopy = null;
  158. var gl = cc._renderContext;
  159. gl.deleteFramebuffer(this._fBO);
  160. if (this._depthRenderBuffer)
  161. gl.deleteRenderbuffer(this._depthRenderBuffer);
  162. this._uITextureImage = null;
  163. //if (this._texture)
  164. // this._texture.releaseTexture();
  165. },
  166. /**
  167. * Gets the sprite
  168. * @return {cc.Sprite}
  169. */
  170. getSprite:function () {
  171. return this.sprite;
  172. },
  173. /**
  174. * Set the sprite
  175. * @param {cc.Sprite} sprite
  176. */
  177. setSprite:function (sprite) {
  178. this.sprite = sprite;
  179. },
  180. /**
  181. * Initializes the instance of cc.RenderTexture
  182. * @function
  183. * @param {Number} width
  184. * @param {Number} height
  185. * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} [format]
  186. * @param {Number} [depthStencilFormat]
  187. * @return {Boolean}
  188. */
  189. initWithWidthAndHeight: null,
  190. _initWithWidthAndHeightForCanvas: function (width, height, format, depthStencilFormat) {
  191. var locCacheCanvas = this._cacheCanvas, locScaleFactor = cc.contentScaleFactor();
  192. locCacheCanvas.width = 0 | (width * locScaleFactor);
  193. locCacheCanvas.height = 0 | (height * locScaleFactor);
  194. this._cacheContext.translate(0, locCacheCanvas.height);
  195. var texture = new cc.Texture2D();
  196. texture.initWithElement(locCacheCanvas);
  197. texture.handleLoadedTexture();
  198. var locSprite = this.sprite = cc.Sprite.create(texture);
  199. locSprite.setBlendFunc(cc.ONE, cc.ONE_MINUS_SRC_ALPHA);
  200. // Disabled by default.
  201. this.autoDraw = false;
  202. // add sprite for backward compatibility
  203. this.addChild(locSprite);
  204. return true;
  205. },
  206. _initWithWidthAndHeightForWebGL: function (width, height, format, depthStencilFormat) {
  207. if(format == cc.Texture2D.PIXEL_FORMAT_A8)
  208. cc.log( "cc.RenderTexture._initWithWidthAndHeightForWebGL() : only RGB and RGBA formats are valid for a render texture;");
  209. var gl = cc._renderContext, locScaleFactor = cc.contentScaleFactor();
  210. width = 0 | (width * locScaleFactor);
  211. height = 0 | (height * locScaleFactor);
  212. this._oldFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING);
  213. // textures must be power of two squared
  214. var powW , powH;
  215. if (cc.configuration.supportsNPOT()) {
  216. powW = width;
  217. powH = height;
  218. } else {
  219. powW = cc.NextPOT(width);
  220. powH = cc.NextPOT(height);
  221. }
  222. //void *data = malloc(powW * powH * 4);
  223. var dataLen = powW * powH * 4;
  224. var data = new Uint8Array(dataLen);
  225. //memset(data, 0, (int)(powW * powH * 4));
  226. for (var i = 0; i < powW * powH * 4; i++)
  227. data[i] = 0;
  228. this._pixelFormat = format;
  229. this._texture = new cc.Texture2D();
  230. if (!this._texture)
  231. return false;
  232. var locTexture = this._texture;
  233. locTexture.initWithData(data, this._pixelFormat, powW, powH, cc.size(width, height));
  234. //free( data );
  235. var oldRBO = gl.getParameter(gl.RENDERBUFFER_BINDING);
  236. if (cc.configuration.checkForGLExtension("GL_QCOM")) {
  237. this._textureCopy = new cc.Texture2D();
  238. if (!this._textureCopy) {
  239. return false;
  240. }
  241. this._textureCopy.initWithData(data, this._pixelFormat, powW, powH, cc.size(width, height));
  242. }
  243. // generate FBO
  244. this._fBO = gl.createFramebuffer();
  245. gl.bindFramebuffer(gl.FRAMEBUFFER, this._fBO);
  246. // associate texture with FBO
  247. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, locTexture._webTextureObj, 0);
  248. if (depthStencilFormat != 0) {
  249. //create and attach depth buffer
  250. this._depthRenderBuffer = gl.createRenderbuffer();
  251. gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthRenderBuffer);
  252. gl.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, powW, powH);
  253. if(depthStencilFormat == gl.DEPTH_STENCIL)
  254. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthRenderBuffer);
  255. else if(depthStencilFormat == gl.STENCIL_INDEX || depthStencilFormat == gl.STENCIL_INDEX8)
  256. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, this._depthRenderBuffer);
  257. else if(depthStencilFormat == gl.DEPTH_COMPONENT16)
  258. gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthRenderBuffer);
  259. }
  260. // check if it worked (probably worth doing :) )
  261. if(gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE)
  262. cc.log("Could not attach texture to the framebuffer");
  263. locTexture.setAliasTexParameters();
  264. this.sprite = cc.Sprite.create(locTexture);
  265. var locSprite = this.sprite;
  266. locSprite.scaleY = -1;
  267. locSprite.setBlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  268. gl.bindRenderbuffer(gl.RENDERBUFFER, oldRBO);
  269. gl.bindFramebuffer(gl.FRAMEBUFFER, this._oldFBO);
  270. // Disabled by default.
  271. this.autoDraw = false;
  272. // add sprite for backward compatibility
  273. this.addChild(locSprite);
  274. return true;
  275. },
  276. /**
  277. * starts grabbing
  278. * @function
  279. */
  280. begin: null,
  281. _beginForCanvas: function () {
  282. cc._renderContext = this._cacheContext;
  283. cc.view._setScaleXYForRenderTexture();
  284. /*// Save the current matrix
  285. cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
  286. cc.kmGLPushMatrix();
  287. cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
  288. cc.kmGLPushMatrix();*/
  289. },
  290. _beginForWebGL: function () {
  291. // Save the current matrix
  292. cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
  293. cc.kmGLPushMatrix();
  294. cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
  295. cc.kmGLPushMatrix();
  296. var director = cc.director;
  297. director.setProjection(director.getProjection());
  298. var texSize = this._texture.getContentSizeInPixels();
  299. // Calculate the adjustment ratios based on the old and new projections
  300. var size = cc.director.getWinSizeInPixels();
  301. var widthRatio = size.width / texSize.width;
  302. var heightRatio = size.height / texSize.height;
  303. var gl = cc._renderContext;
  304. // Adjust the orthographic projection and viewport
  305. gl.viewport(0, 0, texSize.width, texSize.height);
  306. var orthoMatrix = new cc.kmMat4();
  307. cc.kmMat4OrthographicProjection(orthoMatrix, -1.0 / widthRatio, 1.0 / widthRatio,
  308. -1.0 / heightRatio, 1.0 / heightRatio, -1, 1);
  309. cc.kmGLMultMatrix(orthoMatrix);
  310. this._oldFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING);
  311. gl.bindFramebuffer(gl.FRAMEBUFFER, this._fBO);//Will direct drawing to the frame buffer created above
  312. /* Certain Qualcomm Andreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture.
  313. * The solution is to clear the frame buffer before rendering to the texture. However, calling glClear has the unintended result of clearing the current texture.
  314. * Create a temporary texture to overcome this. At the end of CCRenderTexture::begin(), switch the attached texture to the second one, call glClear,
  315. * and then switch back to the original texture. This solution is unnecessary for other devices as they don't have the same issue with switching frame buffers.
  316. */
  317. if (cc.configuration.checkForGLExtension("GL_QCOM")) {
  318. // -- bind a temporary texture so we can clear the render buffer without losing our texture
  319. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._textureCopy._webTextureObj, 0);
  320. //cc.checkGLErrorDebug();
  321. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  322. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._texture._webTextureObj, 0);
  323. }
  324. },
  325. /**
  326. * starts rendering to the texture while clearing the texture first.<br/>
  327. * This is more efficient then calling -clear first and then -begin
  328. * @param {Number} r red 0-255
  329. * @param {Number} g green 0-255
  330. * @param {Number} b blue 0-255
  331. * @param {Number} a alpha 0-255 0 is transparent
  332. * @param {Number} [depthValue=]
  333. * @param {Number} [stencilValue=]
  334. */
  335. beginWithClear:function (r, g, b, a, depthValue, stencilValue) {
  336. var gl = cc._renderContext;
  337. depthValue = depthValue || gl.COLOR_BUFFER_BIT;
  338. stencilValue = stencilValue || (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  339. this._beginWithClear(r , g , b , a , depthValue, stencilValue, (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
  340. },
  341. _beginWithClear: null,
  342. _beginWithClearForCanvas: function (r, g, b, a, depthValue, stencilValue, flags) {
  343. this.begin();
  344. r = r || 0;
  345. g = g || 0;
  346. b = b || 0;
  347. a = isNaN(a) ? 1 : a;
  348. //var context = cc._renderContext;
  349. var context = this._cacheContext;
  350. var locCanvas = this._cacheCanvas;
  351. context.save();
  352. context.fillStyle = "rgba(" + (0 | r) + "," + (0 | g) + "," + (0 | b) + "," + a / 255 + ")";
  353. context.clearRect(0, 0, locCanvas.width, -locCanvas.height);
  354. context.fillRect(0, 0, locCanvas.width, -locCanvas.height);
  355. context.restore();
  356. },
  357. _beginWithClearForWebGL: function (r, g, b, a, depthValue, stencilValue, flags) {
  358. r = r / 255;
  359. g = g / 255;
  360. b = b / 255;
  361. a = a / 255;
  362. this.begin();
  363. var gl = cc._renderContext;
  364. // save clear color
  365. var clearColor = [0.0, 0.0, 0.0, 0.0];
  366. var depthClearValue = 0.0;
  367. var stencilClearValue = 0;
  368. if (flags & gl.COLOR_BUFFER_BIT) {
  369. clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
  370. gl.clearColor(r, g, b, a);
  371. }
  372. if (flags & gl.DEPTH_BUFFER_BIT) {
  373. depthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE);
  374. gl.clearDepth(depthValue);
  375. }
  376. if (flags & gl.STENCIL_BUFFER_BIT) {
  377. stencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE);
  378. gl.clearStencil(stencilValue);
  379. }
  380. gl.clear(flags);
  381. // restore
  382. if (flags & gl.COLOR_BUFFER_BIT)
  383. gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
  384. if (flags & gl.DEPTH_BUFFER_BIT)
  385. gl.clearDepth(depthClearValue);
  386. if (flags & gl.STENCIL_BUFFER_BIT)
  387. gl.clearStencil(stencilClearValue);
  388. },
  389. /**
  390. * ends grabbing
  391. * @function
  392. */
  393. end: null,
  394. _endForCanvas: function () {
  395. cc._renderContext = cc._mainRenderContextBackup;
  396. cc.view._resetScale();
  397. //TODO
  398. /*//restore viewport
  399. director.setViewport();
  400. cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
  401. cc.kmGLPopMatrix();
  402. cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
  403. cc.kmGLPopMatrix();*/
  404. },
  405. _endForWebGL: function () {
  406. var gl = cc._renderContext;
  407. var director = cc.director;
  408. gl.bindFramebuffer(gl.FRAMEBUFFER, this._oldFBO);
  409. //restore viewport
  410. director.setViewport();
  411. cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
  412. cc.kmGLPopMatrix();
  413. cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
  414. cc.kmGLPopMatrix();
  415. /* var size = director.getWinSizeInPixels();
  416. // restore viewport
  417. gl.viewport(0, 0, size.width * cc.contentScaleFactor(), size.height * cc.contentScaleFactor());
  418. // special viewport for 3d projection + retina display
  419. if (director.getProjection() == cc.Director.PROJECTION_3D && cc.contentScaleFactor() != 1) {
  420. gl.viewport((-size.width / 2), (-size.height / 2), (size.width * cc.contentScaleFactor()), (size.height * cc.contentScaleFactor()));
  421. }
  422. director.setProjection(director.getProjection());*/
  423. },
  424. /**
  425. * clears the texture with a color
  426. * @param {Number|cc.Rect} r red 0-1
  427. * @param {Number} g green 0-1
  428. * @param {Number} b blue 0-1
  429. * @param {Number} a alpha 0-1
  430. */
  431. clear:function (r, g, b, a) {
  432. this.beginWithClear(r, g, b, a);
  433. this.end();
  434. },
  435. /**
  436. * clears the texture with rect.
  437. * @function
  438. * @param {number} x
  439. * @param {number} y
  440. * @param {number} width
  441. * @param {number} height
  442. */
  443. clearRect:null,
  444. _clearRectForCanvas:function(x, y, width, height){
  445. this._cacheContext.clearRect(x, y, width, -height);
  446. },
  447. _clearRectForWebGL:function(x, y, width, height){
  448. //TODO need to implement
  449. },
  450. /**
  451. * clears the texture with a specified depth value
  452. * @function
  453. * @param {Number} depthValue
  454. */
  455. clearDepth:null,
  456. _clearDepthForCanvas:function (depthValue) {
  457. cc.log("clearDepth isn't supported on Cocos2d-Html5");
  458. },
  459. _clearDepthForWebGL:function (depthValue) {
  460. this.begin();
  461. var gl = cc._renderContext;
  462. //! save old depth value
  463. var depthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE);
  464. gl.clearDepth(depthValue);
  465. gl.clear(gl.DEPTH_BUFFER_BIT);
  466. // restore clear color
  467. gl.clearDepth(depthClearValue);
  468. this.end();
  469. },
  470. /**
  471. * clears the texture with a specified stencil value
  472. * @function
  473. * @param {Number} stencilValue
  474. */
  475. clearStencil:null,
  476. _clearStencilForCanvas:function (stencilValue) {
  477. cc.log("clearDepth isn't supported on Cocos2d-Html5");
  478. },
  479. _clearStencilForWebGL:function (stencilValue) {
  480. var gl = cc._renderContext;
  481. // save old stencil value
  482. var stencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE);
  483. gl.clearStencil(stencilValue);
  484. gl.clear(gl.STENCIL_BUFFER_BIT);
  485. // restore clear color
  486. gl.clearStencil(stencilClearValue);
  487. },
  488. /**
  489. * Recursive method that visit its children and draw them
  490. * @function
  491. * @param {CanvasRenderingContext2D|WebGLRenderingContext} ctx
  492. */
  493. visit:null,
  494. _visitForCanvas:function (ctx) {
  495. // override visit.
  496. // Don't call visit on its children
  497. if (!this._visible)
  498. return;
  499. ctx = ctx || cc._renderContext;
  500. ctx.save();
  501. this.draw(ctx); // update children of RenderTexture before
  502. this.transform(ctx);
  503. this.sprite.visit(); // draw the RenderTexture
  504. ctx.restore();
  505. this.arrivalOrder = 0;
  506. },
  507. _visitForWebGL:function (ctx) {
  508. // override visit.
  509. // Don't call visit on its children
  510. if (!this._visible)
  511. return;
  512. cc.kmGLPushMatrix();
  513. var locGrid = this.grid;
  514. if (locGrid && locGrid.isActive()) {
  515. locGrid.beforeDraw();
  516. this.transformAncestors();
  517. }
  518. this.transform(ctx);
  519. this.sprite.visit();
  520. this.draw(ctx);
  521. if (locGrid && locGrid.isActive())
  522. locGrid.afterDraw(this);
  523. cc.kmGLPopMatrix();
  524. this.arrivalOrder = 0;
  525. },
  526. /**
  527. * Render function using the canvas 2d context or WebGL context, internal usage only, please do not call this function
  528. * @function
  529. * @param {CanvasRenderingContext2D | WebGLRenderingContext} ctx The render context
  530. */
  531. draw:null,
  532. _drawForCanvas: function (ctx) {
  533. ctx = ctx || cc._renderContext;
  534. if (this.autoDraw) {
  535. this.begin();
  536. if (this.clearFlags) {
  537. var locCanvas = this._cacheCanvas;
  538. ctx.save();
  539. ctx.fillStyle = this._clearColorStr;
  540. ctx.clearRect(0, 0, locCanvas.width, -locCanvas.height);
  541. ctx.fillRect(0, 0, locCanvas.width, -locCanvas.height);
  542. ctx.restore();
  543. }
  544. //! make sure all children are drawn
  545. this.sortAllChildren();
  546. var locChildren = this._children;
  547. var childrenLen = locChildren.length;
  548. var selfSprite = this.sprite;
  549. for (var i = 0; i < childrenLen; i++) {
  550. var getChild = locChildren[i];
  551. if (getChild != selfSprite)
  552. getChild.visit();
  553. }
  554. this.end();
  555. }
  556. },
  557. _drawForWebGL: function (ctx) {
  558. var gl = cc._renderContext;
  559. if (this.autoDraw) {
  560. this.begin();
  561. var locClearFlags = this.clearFlags;
  562. if (locClearFlags) {
  563. var oldClearColor = [0.0, 0.0, 0.0, 0.0];
  564. var oldDepthClearValue = 0.0;
  565. var oldStencilClearValue = 0;
  566. // backup and set
  567. if (locClearFlags & gl.COLOR_BUFFER_BIT) {
  568. oldClearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
  569. gl.clearColor(this._clearColor.r/255, this._clearColor.g/255, this._clearColor.b/255, this._clearColor.a/255);
  570. }
  571. if (locClearFlags & gl.DEPTH_BUFFER_BIT) {
  572. oldDepthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE);
  573. gl.clearDepth(this.clearDepthVal);
  574. }
  575. if (locClearFlags & gl.STENCIL_BUFFER_BIT) {
  576. oldStencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE);
  577. gl.clearStencil(this.clearStencilVal);
  578. }
  579. // clear
  580. gl.clear(locClearFlags);
  581. // restore
  582. if (locClearFlags & gl.COLOR_BUFFER_BIT)
  583. gl.clearColor(oldClearColor[0], oldClearColor[1], oldClearColor[2], oldClearColor[3]);
  584. if (locClearFlags & gl.DEPTH_BUFFER_BIT)
  585. gl.clearDepth(oldDepthClearValue);
  586. if (locClearFlags & gl.STENCIL_BUFFER_BIT)
  587. gl.clearStencil(oldStencilClearValue);
  588. }
  589. //! make sure all children are drawn
  590. this.sortAllChildren();
  591. var locChildren = this._children;
  592. for (var i = 0; i < locChildren.length; i++) {
  593. var getChild = locChildren[i];
  594. if (getChild != this.sprite)
  595. getChild.visit();
  596. }
  597. this.end();
  598. }
  599. },
  600. /**
  601. * creates a new CCImage from with the texture's data. Caller is responsible for releasing it by calling delete.
  602. * @return {*}
  603. */
  604. newCCImage:function(flipImage){
  605. cc.log("saveToFile isn't supported on cocos2d-html5");
  606. return null;
  607. },
  608. _memcpy:function (destArr, destIndex, srcArr, srcIndex, size) {
  609. for (var i = 0; i < size; i++) {
  610. destArr[destIndex + i] = srcArr[srcIndex + i];
  611. }
  612. },
  613. /**
  614. * saves the texture into a file using JPEG format. The file will be saved in the Documents folder.
  615. * Returns YES if the operation is successful.
  616. * (doesn't support in HTML5)
  617. * @param {Number} filePath
  618. * @param {Number} format
  619. */
  620. saveToFile:function (filePath, format) {
  621. cc.log("saveToFile isn't supported on Cocos2d-Html5");
  622. },
  623. /**
  624. * Listen "come to background" message, and save render texture. It only has effect on Android.
  625. * @param {cc.Class} obj
  626. */
  627. listenToBackground:function (obj) {
  628. cc.log("listenToBackground isn't supported on Cocos2d-Html5");
  629. },
  630. /**
  631. * Listen "come to foreground" message and restore the frame buffer object. It only has effect on Android.
  632. * @param {cc.Class} obj
  633. */
  634. listenToForeground:function (obj) {
  635. cc.log("listenToForeground isn't supported on Cocos2d-Html5");
  636. },
  637. /**
  638. * Valid flags: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT. They can be OR'ed. Valid when "autoDraw is YES.
  639. * @return {Number}
  640. */
  641. getClearFlags:function () {
  642. return this.clearFlags;
  643. },
  644. /**
  645. * Set the clearFlags
  646. * @param {Number} clearFlags
  647. */
  648. setClearFlags:function (clearFlags) {
  649. this.clearFlags = clearFlags;
  650. },
  651. /**
  652. * Clear color value. Valid only when "autoDraw" is true.
  653. * @function
  654. * @return {cc.Color}
  655. */
  656. getClearColor:function () {
  657. return this._clearColor;
  658. },
  659. /**
  660. * Set the clear color value. Valid only when "autoDraw" is true.
  661. * @function
  662. * @param {cc.Color} clearColor The clear color
  663. */
  664. setClearColor:null,
  665. _setClearColorForCanvas:function (clearColor) {
  666. var locClearColor = this._clearColor;
  667. locClearColor.r = clearColor.r;
  668. locClearColor.g = clearColor.g;
  669. locClearColor.b = clearColor.b;
  670. locClearColor.a = clearColor.a;
  671. this._clearColorStr = "rgba(" + (0 | clearColor.r) + "," + (0 | clearColor.g) + "," + (0 | clearColor.b) + "," + clearColor.a / 255 + ")";
  672. },
  673. _setClearColorForWebGL:function (clearColor) {
  674. var locClearColor = this._clearColor;
  675. locClearColor.r = clearColor.r;
  676. locClearColor.g = clearColor.g;
  677. locClearColor.b = clearColor.b;
  678. locClearColor.a = clearColor.a;
  679. },
  680. /**
  681. * Value for clearDepth. Valid only when autoDraw is true.
  682. * @return {Number}
  683. */
  684. getClearDepth:function () {
  685. return this.clearDepthVal;
  686. },
  687. /**
  688. * Set value for clearDepth. Valid only when autoDraw is true.
  689. * @param {Number} clearDepth
  690. */
  691. setClearDepth:function (clearDepth) {
  692. this.clearDepthVal = clearDepth;
  693. },
  694. /**
  695. * Value for clear Stencil. Valid only when autoDraw is true
  696. * @return {Number}
  697. */
  698. getClearStencil:function () {
  699. return this.clearStencilVal;
  700. },
  701. /**
  702. * Set value for clear Stencil. Valid only when autoDraw is true
  703. * @return {Number}
  704. */
  705. setClearStencil:function (clearStencil) {
  706. this.clearStencilVal = clearStencil;
  707. },
  708. /**
  709. * When enabled, it will render its children into the texture automatically. Disabled by default for compatiblity reasons. <br/>
  710. * Will be enabled in the future.
  711. * @return {Boolean}
  712. */
  713. isAutoDraw:function () {
  714. return this.autoDraw;
  715. },
  716. /**
  717. * When enabled, it will render its children into the texture automatically. Disabled by default for compatiblity reasons. <br/>
  718. * Will be enabled in the future.
  719. * @return {Boolean}
  720. */
  721. setAutoDraw:function (autoDraw) {
  722. this.autoDraw = autoDraw;
  723. }
  724. });
  725. var _p = cc.RenderTexture.prototype;
  726. if(cc._renderType == cc._RENDER_TYPE_WEBGL){
  727. _p.ctor = _p._ctorForWebGL;
  728. _p.cleanup = _p._cleanupForWebGL;
  729. _p.initWithWidthAndHeight = _p._initWithWidthAndHeightForWebGL;
  730. _p.begin = _p._beginForWebGL;
  731. _p._beginWithClear = _p._beginWithClearForWebGL;
  732. _p.end = _p._endForWebGL;
  733. _p.clearRect = _p._clearRectForWebGL;
  734. _p.clearDepth = _p._clearDepthForWebGL;
  735. _p.clearStencil = _p._clearStencilForWebGL;
  736. _p.visit = _p._visitForWebGL;
  737. _p.draw = _p._drawForWebGL;
  738. _p.setClearColor = _p._setClearColorForWebGL;
  739. } else {
  740. _p.ctor = _p._ctorForCanvas;
  741. _p.cleanup = _p._cleanupForCanvas;
  742. _p.initWithWidthAndHeight = _p._initWithWidthAndHeightForCanvas;
  743. _p.begin = _p._beginForCanvas;
  744. _p._beginWithClear = _p._beginWithClearForCanvas;
  745. _p.end = _p._endForCanvas;
  746. _p.clearRect = _p._clearRectForCanvas;
  747. _p.clearDepth = _p._clearDepthForCanvas;
  748. _p.clearStencil = _p._clearStencilForCanvas;
  749. _p.visit = _p._visitForCanvas;
  750. _p.draw = _p._drawForCanvas;
  751. _p.setClearColor = _p._setClearColorForCanvas;
  752. }
  753. // Extended
  754. /** @expose */
  755. _p.clearColorVal;
  756. cc.defineGetterSetter(_p, "clearColorVal", _p.getClearColor, _p.setClearColor);
  757. /**
  758. * creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid
  759. * @deprecated since v3.0 please use new cc.RenderTexture() instead.
  760. * @param {Number} width
  761. * @param {Number} height
  762. * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} format
  763. * @param {Number} depthStencilFormat
  764. * @return {cc.RenderTexture}
  765. * @example
  766. * // Example
  767. * var rt = cc.RenderTexture.create()
  768. */
  769. cc.RenderTexture.create = function (width, height, format, depthStencilFormat) {
  770. return new cc.RenderTexture(width, height, format, depthStencilFormat);
  771. };