1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2009 Jason Booth 4 Copyright (c) 2008-2010 Ricardo Quesada 5 Copyright (c) 2011 Zynga Inc. 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 _ctorForCanvas: function () { 121 cc.Node.prototype.ctor.call(this); 122 this._clearColor = cc.color(255, 255, 255, 255); 123 this._clearColorStr = "rgba(255,255,255,1)"; 124 125 this._cacheCanvas = document.createElement('canvas'); 126 this._cacheContext = this._cacheCanvas.getContext('2d'); 127 this.anchorX = 0; 128 this.anchorY = 0; 129 }, 130 131 _ctorForWebGL: function () { 132 cc.Node.prototype.ctor.call(this); 133 this._clearColor = cc.color(0, 0, 0, 0); 134 }, 135 136 cleanup:null, 137 138 _cleanupForCanvas:function () { 139 cc.Node.prototype.onExit.call(this); 140 this._cacheContext = null; 141 this._cacheCanvas = null; 142 }, 143 144 _cleanupForWebGL: function () { 145 cc.Node.prototype.onExit.call(this); 146 147 //this.sprite = null; 148 this._textureCopy = null; 149 150 var gl = cc._renderContext; 151 gl.deleteFramebuffer(this._fBO); 152 if (this._depthRenderBuffer) 153 gl.deleteRenderbuffer(this._depthRenderBuffer); 154 this._uITextureImage = null; 155 //if (this._texture) 156 // this._texture.releaseTexture(); 157 }, 158 159 /** 160 * The sprite 161 * @return {cc.Sprite} 162 */ 163 getSprite:function () { 164 return this.sprite; 165 }, 166 167 /** 168 * @param {cc.Sprite} sprite 169 */ 170 setSprite:function (sprite) { 171 this.sprite = sprite; 172 }, 173 174 /** 175 * @function 176 * @param {Number} width 177 * @param {Number} height 178 * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} format 179 * @param {Number} depthStencilFormat 180 * @return {Boolean} 181 */ 182 initWithWidthAndHeight: null, 183 184 _initWithWidthAndHeightForCanvas: function (width, height, format, depthStencilFormat) { 185 var locCacheCanvas = this._cacheCanvas, locScaleFactor = cc.CONTENT_SCALE_FACTOR(); 186 locCacheCanvas.width = 0 | (width * locScaleFactor); 187 locCacheCanvas.height = 0 | (height * locScaleFactor); 188 this._cacheContext.translate(0, locCacheCanvas.height); 189 var texture = new cc.Texture2D(); 190 texture.initWithElement(locCacheCanvas); 191 texture.handleLoadedTexture(); 192 this.sprite = cc.Sprite.create(texture); 193 return true; 194 }, 195 196 _initWithWidthAndHeightForWebGL: function (width, height, format, depthStencilFormat) { 197 if(format == cc.Texture2D.PIXEL_FORMAT_A8) 198 cc.log( "cc.RenderTexture._initWithWidthAndHeightForWebGL() : only RGB and RGBA formats are valid for a render texture;"); 199 200 var gl = cc._renderContext, locScaleFactor = cc.CONTENT_SCALE_FACTOR(); 201 202 width = 0 | (width * locScaleFactor); 203 height = 0 | (height * locScaleFactor); 204 205 this._oldFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING); 206 207 // textures must be power of two squared 208 var powW , powH; 209 210 if (cc.configuration.supportsNPOT()) { 211 powW = width; 212 powH = height; 213 } else { 214 powW = cc.NextPOT(width); 215 powH = cc.NextPOT(height); 216 } 217 218 //void *data = malloc(powW * powH * 4); 219 var dataLen = powW * powH * 4; 220 var data = new Uint8Array(dataLen); 221 //memset(data, 0, (int)(powW * powH * 4)); 222 for (var i = 0; i < powW * powH * 4; i++) 223 data[i] = 0; 224 225 this._pixelFormat = format; 226 227 this._texture = new cc.Texture2D(); 228 if (!this._texture) 229 return false; 230 231 var locTexture = this._texture; 232 locTexture.initWithData(data, this._pixelFormat, powW, powH, cc.size(width, height)); 233 //free( data ); 234 235 var oldRBO = gl.getParameter(gl.RENDERBUFFER_BINDING); 236 237 if (cc.configuration.checkForGLExtension("GL_QCOM")) { 238 this._textureCopy = new cc.Texture2D(); 239 if (!this._textureCopy) { 240 return false; 241 } 242 this._textureCopy.initWithData(data, this._pixelFormat, powW, powH, cc.size(width, height)); 243 } 244 245 // generate FBO 246 this._fBO = gl.createFramebuffer(); 247 gl.bindFramebuffer(gl.FRAMEBUFFER, this._fBO); 248 249 // associate texture with FBO 250 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, locTexture._webTextureObj, 0); 251 252 if (depthStencilFormat != 0) { 253 //create and attach depth buffer 254 this._depthRenderBuffer = gl.createRenderbuffer(); 255 gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthRenderBuffer); 256 gl.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, powW, powH); 257 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthRenderBuffer); 258 259 // if depth format is the one with stencil part, bind same render buffer as stencil attachment 260 //if (depthStencilFormat == gl.DEPTH24_STENCIL8) 261 // gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthRenderBuffer); 262 } 263 264 // check if it worked (probably worth doing :) ) 265 if(gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) 266 cc.log("Could not attach texture to the framebuffer"); 267 268 locTexture.setAliasTexParameters(); 269 270 this.sprite = cc.Sprite.create(locTexture); 271 var locSprite = this.sprite; 272 locSprite.scaleY = -1; 273 locSprite.setBlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); 274 275 gl.bindRenderbuffer(gl.RENDERBUFFER, oldRBO); 276 gl.bindFramebuffer(gl.FRAMEBUFFER, this._oldFBO); 277 278 // Disabled by default. 279 this.autoDraw = false; 280 281 // add sprite for backward compatibility 282 this.addChild(locSprite); 283 return true; 284 }, 285 286 /** 287 * starts grabbing 288 * @function 289 */ 290 begin: null, 291 292 _beginForCanvas: function () { 293 cc._renderContext = this._cacheContext; 294 cc.view._setScaleXYForRenderTexture(); 295 296 /*// Save the current matrix 297 cc.kmGLMatrixMode(cc.KM_GL_PROJECTION); 298 cc.kmGLPushMatrix(); 299 cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); 300 cc.kmGLPushMatrix();*/ 301 }, 302 303 _beginForWebGL: function () { 304 // Save the current matrix 305 cc.kmGLMatrixMode(cc.KM_GL_PROJECTION); 306 cc.kmGLPushMatrix(); 307 cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); 308 cc.kmGLPushMatrix(); 309 310 var director = cc.director; 311 director.setProjection(director.getProjection()); 312 313 var texSize = this._texture.getContentSizeInPixels(); 314 315 // Calculate the adjustment ratios based on the old and new projections 316 var size = cc.director.getWinSizeInPixels(); 317 var widthRatio = size.width / texSize.width; 318 var heightRatio = size.height / texSize.height; 319 320 var gl = cc._renderContext; 321 322 // Adjust the orthographic projection and viewport 323 gl.viewport(0, 0, texSize.width, texSize.height); 324 325 var orthoMatrix = new cc.kmMat4(); 326 cc.kmMat4OrthographicProjection(orthoMatrix, -1.0 / widthRatio, 1.0 / widthRatio, 327 -1.0 / heightRatio, 1.0 / heightRatio, -1, 1); 328 cc.kmGLMultMatrix(orthoMatrix); 329 330 this._oldFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING); 331 gl.bindFramebuffer(gl.FRAMEBUFFER, this._fBO);//Will direct drawing to the frame buffer created above 332 333 /* Certain Qualcomm Andreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture. 334 * 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. 335 * Create a temporary texture to overcome this. At the end of CCRenderTexture::begin(), switch the attached texture to the second one, call glClear, 336 * 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. 337 */ 338 if (cc.configuration.checkForGLExtension("GL_QCOM")) { 339 // -- bind a temporary texture so we can clear the render buffer without losing our texture 340 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._textureCopy._webTextureObj, 0); 341 //cc.CHECK_GL_ERROR_DEBUG(); 342 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 343 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this._texture._webTextureObj, 0); 344 } 345 }, 346 347 /** 348 * starts rendering to the texture while clearing the texture first.<br/> 349 * This is more efficient then calling -clear first and then -begin 350 * @param {Number} r red 0-1 351 * @param {Number} g green 0-1 352 * @param {Number} b blue 0-1 353 * @param {Number} a alpha 0-1 0 is transparent 354 * @param {Number} [depthValue=] 355 * @param {Number} [stencilValue=] 356 */ 357 beginWithClear:function (r, g, b, a, depthValue, stencilValue) { 358 var gl = cc._renderContext; 359 depthValue = depthValue || gl.COLOR_BUFFER_BIT; 360 stencilValue = stencilValue || (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 361 362 this._beginWithClear(r, g, b, a, depthValue, stencilValue, (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)); 363 }, 364 365 _beginWithClear: null, 366 367 _beginWithClearForCanvas: function (r, g, b, a, depthValue, stencilValue, flags) { 368 this.begin(); 369 370 r = r || 0; 371 g = g || 0; 372 b = b || 0; 373 a = isNaN(a) ? 1 : a; 374 375 //var context = cc._renderContext; 376 var context = this._cacheContext; 377 var locCanvas = this._cacheCanvas; 378 context.save(); 379 context.fillStyle = "rgba(" + (0 | r) + "," + (0 | g) + "," + (0 | b) + "," + a / 255 + ")"; 380 context.clearRect(0, 0, locCanvas.width, -locCanvas.height); 381 context.fillRect(0, 0, locCanvas.width, -locCanvas.height); 382 context.restore(); 383 }, 384 385 _beginWithClearForWebGL: function (r, g, b, a, depthValue, stencilValue, flags) { 386 this.begin(); 387 388 var gl = cc._renderContext; 389 390 // save clear color 391 var clearColor = [0.0, 0.0, 0.0, 0.0]; 392 var depthClearValue = 0.0; 393 var stencilClearValue = 0; 394 395 if (flags & gl.COLOR_BUFFER_BIT) { 396 clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE); 397 gl.clearColor(r, g, b, a); 398 } 399 400 if (flags & gl.DEPTH_BUFFER_BIT) { 401 depthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE); 402 gl.clearDepth(depthValue); 403 } 404 405 if (flags & gl.STENCIL_BUFFER_BIT) { 406 stencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE); 407 gl.clearStencil(stencilValue); 408 } 409 410 gl.clear(flags); 411 412 // restore 413 if (flags & gl.COLOR_BUFFER_BIT) 414 gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); 415 416 if (flags & gl.DEPTH_BUFFER_BIT) 417 gl.clearDepth(depthClearValue); 418 419 if (flags & gl.STENCIL_BUFFER_BIT) 420 gl.clearStencil(stencilClearValue); 421 }, 422 423 /** 424 * ends grabbing 425 * @function 426 */ 427 end: null, 428 429 _endForCanvas: function () { 430 cc._renderContext = cc._mainRenderContextBackup; 431 cc.view._resetScale(); 432 433 //TODO 434 /*//restore viewport 435 director.setViewport(); 436 cc.kmGLMatrixMode(cc.KM_GL_PROJECTION); 437 cc.kmGLPopMatrix(); 438 cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); 439 cc.kmGLPopMatrix();*/ 440 }, 441 442 _endForWebGL: function () { 443 var gl = cc._renderContext; 444 var director = cc.director; 445 gl.bindFramebuffer(gl.FRAMEBUFFER, this._oldFBO); 446 447 //restore viewport 448 director.setViewport(); 449 cc.kmGLMatrixMode(cc.KM_GL_PROJECTION); 450 cc.kmGLPopMatrix(); 451 cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW); 452 cc.kmGLPopMatrix(); 453 454 /* var size = director.getWinSizeInPixels(); 455 456 // restore viewport 457 gl.viewport(0, 0, size.width * cc.CONTENT_SCALE_FACTOR(), size.height * cc.CONTENT_SCALE_FACTOR()); 458 459 // special viewport for 3d projection + retina display 460 if (director.getProjection() == cc.DIRECTOR_PROJECTION_3D && cc.CONTENT_SCALE_FACTOR() != 1) { 461 gl.viewport((-size.width / 2), (-size.height / 2), (size.width * cc.CONTENT_SCALE_FACTOR()), (size.height * cc.CONTENT_SCALE_FACTOR())); 462 } 463 464 director.setProjection(director.getProjection());*/ 465 }, 466 467 /** 468 * clears the texture with a color 469 * @param {Number|cc.Rect} r red 0-1 470 * @param {Number} g green 0-1 471 * @param {Number} b blue 0-1 472 * @param {Number} a alpha 0-1 473 */ 474 clear:function (r, g, b, a) { 475 this.beginWithClear(r, g, b, a); 476 this.end(); 477 }, 478 479 clearRect:null, 480 481 _clearRectForCanvas:function(x, y, width, height){ 482 this._cacheContext.clearRect(x, y, width, -height); 483 }, 484 485 _clearRectForWebGL:function(x, y, width, height){ 486 //TODO need to implement 487 }, 488 489 /** 490 * clears the texture with a specified depth value 491 * @function 492 * @param {Number} depthValue 493 */ 494 clearDepth:null, 495 496 _clearDepthForCanvas:function (depthValue) { 497 cc.log("clearDepth isn't supported on Cocos2d-Html5"); 498 }, 499 500 _clearDepthForWebGL:function (depthValue) { 501 this.begin(); 502 503 var gl = cc._renderContext; 504 //! save old depth value 505 var depthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE); 506 507 gl.clearDepth(depthValue); 508 gl.clear(gl.DEPTH_BUFFER_BIT); 509 510 // restore clear color 511 gl.clearDepth(depthClearValue); 512 this.end(); 513 }, 514 515 /** 516 * clears the texture with a specified stencil value 517 * @function 518 * @param {Number} stencilValue 519 */ 520 clearStencil:null, 521 522 _clearStencilForCanvas:function (stencilValue) { 523 cc.log("clearDepth isn't supported on Cocos2d-Html5"); 524 }, 525 526 _clearStencilForWebGL:function (stencilValue) { 527 var gl = cc._renderContext; 528 // save old stencil value 529 var stencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE); 530 531 gl.clearStencil(stencilValue); 532 gl.clear(gl.STENCIL_BUFFER_BIT); 533 534 // restore clear color 535 gl.clearStencil(stencilClearValue); 536 }, 537 538 visit:null, 539 540 _visitForCanvas:function (ctx) { 541 // override visit. 542 // Don't call visit on its children 543 if (!this._visible) 544 return; 545 546 ctx = ctx || cc._renderContext; 547 ctx.save(); 548 549 this.draw(ctx); // update children of RenderTexture before 550 this.transform(ctx); 551 this.sprite.visit(); // draw the RenderTexture 552 553 ctx.restore(); 554 555 this.arrivalOrder = 0; 556 }, 557 558 _visitForWebGL:function (ctx) { 559 // override visit. 560 // Don't call visit on its children 561 if (!this._visible) 562 return; 563 564 cc.kmGLPushMatrix(); 565 566 var locGrid = this.grid; 567 if (locGrid && locGrid.isActive()) { 568 locGrid.beforeDraw(); 569 this.transformAncestors(); 570 } 571 572 this.transform(ctx); 573 this.sprite.visit(); 574 this.draw(ctx); 575 576 if (locGrid && locGrid.isActive()) 577 locGrid.afterDraw(this); 578 579 cc.kmGLPopMatrix(); 580 581 this.arrivalOrder = 0; 582 }, 583 584 draw:null, 585 586 _drawForCanvas: function (ctx) { 587 ctx = ctx || cc._renderContext; 588 if (this.autoDraw) { 589 this.begin(); 590 591 if (this.clearFlags) { 592 var locCanvas = this._cacheCanvas; 593 ctx.save(); 594 ctx.fillStyle = this._clearColorStr; 595 ctx.clearRect(0, 0, locCanvas.width, -locCanvas.height); 596 ctx.fillRect(0, 0, locCanvas.width, -locCanvas.height); 597 ctx.restore(); 598 } 599 600 //! make sure all children are drawn 601 this.sortAllChildren(); 602 var locChildren = this._children; 603 var childrenLen = locChildren.length; 604 var selfSprite = this.sprite; 605 for (var i = 0; i < childrenLen; i++) { 606 var getChild = locChildren[i]; 607 if (getChild != selfSprite) 608 getChild.visit(); 609 } 610 611 this.end(); 612 } 613 }, 614 615 _drawForWebGL: function (ctx) { 616 var gl = cc._renderContext; 617 if (this.autoDraw) { 618 this.begin(); 619 620 var locClearFlags = this.clearFlags; 621 if (locClearFlags) { 622 var oldClearColor = [0.0, 0.0, 0.0, 0.0]; 623 var oldDepthClearValue = 0.0; 624 var oldStencilClearValue = 0; 625 626 // backup and set 627 if (locClearFlags & gl.COLOR_BUFFER_BIT) { 628 oldClearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE); 629 gl.clearColor(this._clearColor.r/255, this._clearColor.g/255, this._clearColor.b/255, this._clearColor.a/255); 630 } 631 632 if (locClearFlags & gl.DEPTH_BUFFER_BIT) { 633 oldDepthClearValue = gl.getParameter(gl.DEPTH_CLEAR_VALUE); 634 gl.clearDepth(this.clearDepthVal); 635 } 636 637 if (locClearFlags & gl.STENCIL_BUFFER_BIT) { 638 oldStencilClearValue = gl.getParameter(gl.STENCIL_CLEAR_VALUE); 639 gl.clearStencil(this.clearStencilVal); 640 } 641 642 // clear 643 gl.clear(locClearFlags); 644 645 // restore 646 if (locClearFlags & gl.COLOR_BUFFER_BIT) 647 gl.clearColor(oldClearColor[0], oldClearColor[1], oldClearColor[2], oldClearColor[3]); 648 649 if (locClearFlags & gl.DEPTH_BUFFER_BIT) 650 gl.clearDepth(oldDepthClearValue); 651 652 if (locClearFlags & gl.STENCIL_BUFFER_BIT) 653 gl.clearStencil(oldStencilClearValue); 654 } 655 656 //! make sure all children are drawn 657 this.sortAllChildren(); 658 var locChildren = this._children; 659 for (var i = 0; i < locChildren.length; i++) { 660 var getChild = locChildren[i]; 661 if (getChild != this.sprite) 662 getChild.visit(); 663 } 664 665 this.end(); 666 } 667 }, 668 669 /** 670 * creates a new CCImage from with the texture's data. Caller is responsible for releasing it by calling delete. 671 * @return {*} 672 */ 673 newCCImage:function(flipImage){ 674 cc.log("saveToFile isn't supported on cocos2d-html5"); 675 return null; 676 }, 677 678 _memcpy:function (destArr, destIndex, srcArr, srcIndex, size) { 679 for (var i = 0; i < size; i++) { 680 destArr[destIndex + i] = srcArr[srcIndex + i]; 681 } 682 }, 683 684 /** 685 * saves the texture into a file using JPEG format. The file will be saved in the Documents folder. 686 * Returns YES if the operation is successful. 687 * (doesn't support in HTML5) 688 * @param {Number} filePath 689 * @param {Number} format 690 */ 691 saveToFile:function (filePath, format) { 692 cc.log("saveToFile isn't supported on Cocos2d-Html5"); 693 }, 694 695 /** 696 * Listen "come to background" message, and save render texture. It only has effect on Android. 697 * @param {cc.Class} obj 698 */ 699 listenToBackground:function (obj) { 700 cc.log("listenToBackground isn't supported on Cocos2d-Html5"); 701 }, 702 703 /** 704 * Listen "come to foreground" message and restore the frame buffer object. It only has effect on Android. 705 * @param {cc.Class} obj 706 */ 707 listenToForeground:function (obj) { 708 cc.log("listenToForeground isn't supported on Cocos2d-Html5"); 709 }, 710 711 /** 712 * Valid flags: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT. They can be OR'ed. Valid when "autoDraw is YES. 713 * @return {Number} 714 */ 715 getClearFlags:function () { 716 return this.clearFlags; 717 }, 718 719 setClearFlags:function (clearFlags) { 720 this.clearFlags = clearFlags; 721 }, 722 723 /** 724 * Clear color value. Valid only when "autoDraw" is true. 725 * @function 726 * @return {cc.Color} 727 */ 728 getClearColor:function () { 729 return this._clearColor; 730 }, 731 732 /** 733 * Set the clear color value. Valid only when "autoDraw" is true. 734 * @function 735 * @param {cc.Color} clearColor The clear color 736 */ 737 setClearColor:null, 738 739 _setClearColorForCanvas:function (clearColor) { 740 var locClearColor = this._clearColor; 741 locClearColor.r = clearColor.r; 742 locClearColor.g = clearColor.g; 743 locClearColor.b = clearColor.b; 744 locClearColor.a = clearColor.a; 745 746 this._clearColorStr = "rgba(" + (0 | clearColor.r) + "," + (0 | clearColor.g) + "," + (0 | clearColor.b) + "," + clearColor.a / 255 + ")"; 747 }, 748 749 _setClearColorForWebGL:function (clearColor) { 750 var locClearColor = this._clearColor; 751 locClearColor.r = clearColor.r; 752 locClearColor.g = clearColor.g; 753 locClearColor.b = clearColor.b; 754 locClearColor.a = clearColor.a; 755 }, 756 757 /** 758 * Value for clearDepth. Valid only when autoDraw is true. 759 * @return {Number} 760 */ 761 getClearDepth:function () { 762 return this.clearDepthVal; 763 }, 764 765 setClearDepth:function (clearDepth) { 766 this.clearDepthVal = clearDepth; 767 }, 768 769 /** 770 * Value for clear Stencil. Valid only when autoDraw is true 771 * @return {Number} 772 */ 773 getClearStencil:function () { 774 return this.clearStencilVal; 775 }, 776 777 setClearStencil:function (clearStencil) { 778 this.clearStencilVal = clearStencil; 779 }, 780 781 /** 782 * When enabled, it will render its children into the texture automatically. Disabled by default for compatiblity reasons. <br/> 783 * Will be enabled in the future. 784 * @return {Boolean} 785 */ 786 isAutoDraw:function () { 787 return this.autoDraw; 788 }, 789 790 setAutoDraw:function (autoDraw) { 791 this.autoDraw = autoDraw; 792 } 793 }); 794 795 window._p = cc.RenderTexture.prototype; 796 797 if(cc._renderType == cc._RENDER_TYPE_WEBGL){ 798 _p.ctor = _p._ctorForWebGL; 799 _p.cleanup = _p._cleanupForWebGL; 800 _p.initWithWidthAndHeight = _p._initWithWidthAndHeightForWebGL; 801 _p.begin = _p._beginForWebGL; 802 _p._beginWithClear = _p._beginWithClearForWebGL; 803 _p.end = _p._endForWebGL; 804 _p.clearRect = _p._clearRectForWebGL; 805 _p.clearDepth = _p._clearDepthForWebGL; 806 _p.clearStencil = _p._clearStencilForWebGL; 807 _p.visit = _p._visitForWebGL; 808 _p.draw = _p._drawForWebGL; 809 _p.setClearColor = _p._setClearColorForWebGL; 810 } else { 811 _p.ctor = _p._ctorForCanvas; 812 _p.cleanup = _p._cleanupForCanvas; 813 _p.initWithWidthAndHeight = _p._initWithWidthAndHeightForCanvas; 814 _p.begin = _p._beginForCanvas; 815 _p._beginWithClear = _p._beginWithClearForCanvas; 816 _p.end = _p._endForCanvas; 817 _p.clearRect = _p._clearRectForCanvas; 818 _p.clearDepth = _p._clearDepthForCanvas; 819 _p.clearStencil = _p._clearStencilForCanvas; 820 _p.visit = _p._visitForCanvas; 821 _p.draw = _p._drawForCanvas; 822 _p.setClearColor = _p._setClearColorForCanvas; 823 } 824 825 // Extended 826 /** @expose */ 827 _p.clearColorVal; 828 cc.defineGetterSetter(_p, "clearColorVal", _p.getClearColor, _p.setClearColor); 829 830 delete window._p; 831 832 /** 833 * creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid 834 * @param {Number} width 835 * @param {Number} height 836 * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} format 837 * @param {Number} depthStencilFormat 838 * @return {cc.RenderTexture} 839 * @example 840 * // Example 841 * var rt = cc.RenderTexture.create() 842 */ 843 cc.RenderTexture.create = function (width, height, format, depthStencilFormat) { 844 format = format || cc.Texture2D.PIXEL_FORMAT_RGBA8888; 845 depthStencilFormat = depthStencilFormat || 0; 846 847 var ret = new cc.RenderTexture(); 848 if (ret && ret.initWithWidthAndHeight(width, height, format, depthStencilFormat)) 849 return ret; 850 return null; 851 }; 852