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     _texture:null,
 94     _pixelFormat:cc.Texture2D.PIXEL_FORMAT_RGBA8888,
 95 
 96     clearStencilVal:0,
 97     _clearColor:null,
 98 
 99     _className:"RenderTexture",
100 
101     /**
102      * creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid
103      * Constructor of cc.RenderTexture for Canvas
104      * @param {Number} width
105      * @param {Number} height
106      * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} format
107      * @param {Number} depthStencilFormat
108      * @example
109      * // Example
110      * var rt = new cc.RenderTexture(width, height, format, depthStencilFormat)
111      * @function
112      */
113     ctor: function(width, height, format, depthStencilFormat){
114         cc.Node.prototype.ctor.call(this);
115         this._cascadeColorEnabled = true;
116         this._cascadeOpacityEnabled = true;
117         this._clearColor = new cc.Color(0,0,0,255);
118 
119         if(width !== undefined && height !== undefined) {
120             format = format || cc.Texture2D.PIXEL_FORMAT_RGBA8888;
121             depthStencilFormat = depthStencilFormat || 0;
122             this.initWithWidthAndHeight(width, height, format, depthStencilFormat);
123         }
124         this.setAnchorPoint(0,0);
125     },
126 
127     _createRenderCmd: function(){
128         if(cc._renderType === cc._RENDER_TYPE_CANVAS)
129             return new cc.RenderTexture.CanvasRenderCmd(this);
130         else
131             return new cc.RenderTexture.WebGLRenderCmd(this);
132     },
133 
134     /**
135      * Clear RenderTexture.
136      * @function
137      */
138     cleanup: function(){
139         cc.Node.prototype.onExit.call(this);
140         this._renderCmd.cleanup();
141     },
142 
143     /**
144      * Gets the sprite
145      * @return {cc.Sprite}
146      */
147     getSprite:function () {
148         return this.sprite;
149     },
150 
151     /**
152      * Set the sprite
153      * @param {cc.Sprite} sprite
154      */
155     setSprite:function (sprite) {
156         this.sprite = sprite;
157     },
158 
159     /**
160      * Used for grab part of screen to a texture.
161      * @param {cc.Point} rtBegin
162      * @param {cc.Rect} fullRect
163      * @param {cc.Rect} fullViewport
164      */
165     setVirtualViewport: function(rtBegin, fullRect, fullViewport){
166          this._renderCmd.setVirtualViewport(rtBegin, fullRect, fullViewport);
167     },
168 
169     /**
170      * Initializes the instance of cc.RenderTexture
171      * @function
172      * @param {Number} width
173      * @param {Number} height
174      * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} [format]
175      * @param {Number} [depthStencilFormat]
176      * @return {Boolean}
177      */
178     initWithWidthAndHeight: function(width, height, format, depthStencilFormat){
179         return this._renderCmd.initWithWidthAndHeight(width, height, format, depthStencilFormat);
180     },
181 
182     /**
183      * starts grabbing
184      * @function
185      */
186     begin: function(){
187         cc.renderer._turnToCacheMode(this.__instanceId);
188         this._renderCmd.begin();
189     },
190     /**
191      * starts rendering to the texture while clearing the texture first.<br/>
192      * This is more efficient then calling -clear first and then -begin
193      * @param {Number} r red 0-255
194      * @param {Number} g green 0-255
195      * @param {Number} b blue 0-255
196      * @param {Number} a alpha 0-255 0 is transparent
197      * @param {Number} [depthValue=]
198      * @param {Number} [stencilValue=]
199      */
200     beginWithClear:function (r, g, b, a, depthValue, stencilValue) {
201         //todo: only for WebGL?
202         var gl = cc._renderContext;
203         depthValue = depthValue || gl.COLOR_BUFFER_BIT;
204         stencilValue = stencilValue || (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
205 
206         this._beginWithClear(r , g , b , a , depthValue, stencilValue, (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
207     },
208 
209     _beginWithClear: function(r, g, b, a, depthValue, stencilValue, flags){
210         this.begin();
211         this._renderCmd._beginWithClear(r, g, b, a, depthValue, stencilValue, flags);
212     },
213 
214     /**
215      * ends grabbing
216      * @function
217      */
218     end: function(){
219         this._renderCmd.end();
220     },
221 
222     /**
223      * clears the texture with a color
224      * @param {Number|cc.Rect} r red 0-1
225      * @param {Number} g green 0-1
226      * @param {Number} b blue 0-1
227      * @param {Number} a alpha 0-1
228      */
229     clear:function (r, g, b, a) {
230         this.beginWithClear(r, g, b, a);
231         this.end();
232     },
233 
234     /**
235      * clears the texture with rect.
236      * @function
237      * @param {number} x
238      * @param {number} y
239      * @param {number} width
240      * @param {number} height
241      */
242     clearRect: function(x, y, width, height){
243         this._renderCmd.clearRect(x, y, width, height);
244     },
245 
246     /**
247      * clears the texture with a specified depth value
248      * @function
249      * @param {Number} depthValue
250      */
251     clearDepth: function(depthValue){
252         this._renderCmd.clearDepth(depthValue);
253     },
254 
255     /**
256      * clears the texture with a specified stencil value
257      * @function
258      * @param {Number} stencilValue
259      */
260     clearStencil: function(stencilValue) {
261         this._renderCmd.clearStencil(stencilValue);
262     },
263 
264     /**
265      * Valid flags: GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT. They can be OR'ed. Valid when "autoDraw is YES.
266      * @return {Number}
267      */
268     getClearFlags:function () {
269         return this.clearFlags;
270     },
271 
272     /**
273      * Set the clearFlags
274      * @param {Number} clearFlags
275      */
276     setClearFlags:function (clearFlags) {
277         this.clearFlags = clearFlags;
278     },
279 
280     /**
281      * Clear color value. Valid only when "autoDraw" is true.
282      * @function
283      * @return {cc.Color}
284      */
285     getClearColor:function () {
286         return this._clearColor;
287     },
288 
289 	/**
290 	 * Set the clear color value. Valid only when "autoDraw" is true.
291 	 * @function
292 	 * @param {cc.Color} clearColor The clear color
293 	 */
294     setClearColor: function(clearColor){
295         var locClearColor = this._clearColor;
296         locClearColor.r = clearColor.r;
297         locClearColor.g = clearColor.g;
298         locClearColor.b = clearColor.b;
299         locClearColor.a = clearColor.a;
300         this._renderCmd.updateClearColor(clearColor);
301     },
302 
303     /**
304      * Value for clearDepth. Valid only when autoDraw is true.
305      * @return {Number}
306      */
307     getClearDepth:function () {
308         return this.clearDepthVal;
309     },
310 
311     /**
312      * Set value for clearDepth. Valid only when autoDraw is true.
313      * @param {Number} clearDepth
314      */
315     setClearDepth:function (clearDepth) {
316         this.clearDepthVal = clearDepth;
317     },
318 
319     /**
320      * Value for clear Stencil. Valid only when autoDraw is true
321      * @return {Number}
322      */
323     getClearStencil:function () {
324         return this.clearStencilVal;
325     },
326 
327     /**
328      * Set value for clear Stencil. Valid only when autoDraw is true
329      * @return {Number}
330      */
331     setClearStencil:function (clearStencil) {
332         this.clearStencilVal = clearStencil;
333     },
334 
335     /**
336      * When enabled, it will render its children into the texture automatically. Disabled by default for compatiblity reasons. <br/>
337      * Will be enabled in the future.
338      * @return {Boolean}
339      */
340     isAutoDraw:function () {
341         return this.autoDraw;
342     },
343 
344     /**
345      * When enabled, it will render its children into the texture automatically. Disabled by default for compatiblity reasons. <br/>
346      * Will be enabled in the future.
347      * @return {Boolean}
348      */
349     setAutoDraw:function (autoDraw) {
350         this.autoDraw = autoDraw;
351     },
352 
353     //---- some stub functions for jsb
354     /**
355      * saves the texture into a file using JPEG format. The file will be saved in the Documents folder.
356      * Returns YES if the operation is successful.
357      * (doesn't support in HTML5)
358      * @param {Number} filePath
359      * @param {Number} format
360      */
361     saveToFile:function (filePath, format) {
362         cc.log("saveToFile isn't supported on Cocos2d-Html5");
363     },
364 
365     /**
366      * creates a new CCImage from with the texture's data. Caller is responsible for releasing it by calling delete.
367      * @return {*}
368      */
369     newCCImage:function(flipImage){
370         cc.log("saveToFile isn't supported on cocos2d-html5");
371         return null;
372     },
373 
374     /**
375      * Listen "come to background" message, and save render texture. It only has effect on Android.
376      * @param {cc.Class} obj
377      */
378     listenToBackground:function (obj) { },
379 
380     /**
381      * Listen "come to foreground" message and restore the frame buffer object. It only has effect on Android.
382      * @param {cc.Class} obj
383      */
384     listenToForeground:function (obj) { }
385 });
386 
387 var _p = cc.RenderTexture.prototype;
388 // Extended
389 /** @expose */
390 _p.clearColorVal;
391 cc.defineGetterSetter(_p, "clearColorVal", _p.getClearColor, _p.setClearColor);
392 
393 
394 /**
395  * creates a RenderTexture object with width and height in Points and a pixel format, only RGB and RGBA formats are valid
396  * @deprecated since v3.0 please use new cc.RenderTexture() instead.
397  * @param {Number} width
398  * @param {Number} height
399  * @param {cc.IMAGE_FORMAT_JPEG|cc.IMAGE_FORMAT_PNG|cc.IMAGE_FORMAT_RAWDATA} format
400  * @param {Number} depthStencilFormat
401  * @return {cc.RenderTexture}
402  */
403 cc.RenderTexture.create = function (width, height, format, depthStencilFormat) {
404     return new cc.RenderTexture(width, height, format, depthStencilFormat);
405 };
406