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