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