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