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 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 
 27 //CONSTANTS:
 28 
 29 /**
 30  * Horizontal center and vertical center.
 31  * @constant
 32  * @type Number
 33  */
 34 cc.ALIGN_CENTER = 0x33;
 35 
 36 /**
 37  * Horizontal center and vertical top.
 38  * @constant
 39  * @type Number
 40  */
 41 cc.ALIGN_TOP = 0x13;
 42 
 43 /**
 44  * Horizontal right and vertical top.
 45  * @constant
 46  * @type Number
 47  */
 48 cc.ALIGN_TOP_RIGHT = 0x12;
 49 
 50 /**
 51  * Horizontal right and vertical center.
 52  * @constant
 53  * @type Number
 54  */
 55 cc.ALIGN_RIGHT = 0x32;
 56 
 57 /**
 58  * Horizontal right and vertical bottom.
 59  * @constant
 60  * @type Number
 61  */
 62 cc.ALIGN_BOTTOM_RIGHT = 0x22;
 63 
 64 /**
 65  * Horizontal center and vertical bottom.
 66  * @constant
 67  * @type Number
 68  */
 69 cc.ALIGN_BOTTOM = 0x23;
 70 
 71 /**
 72  * Horizontal left and vertical bottom.
 73  * @constant
 74  * @type Number
 75  */
 76 cc.ALIGN_BOTTOM_LEFT = 0x21;
 77 
 78 /**
 79  * Horizontal left and vertical center.
 80  * @constant
 81  * @type Number
 82  */
 83 cc.ALIGN_LEFT = 0x31;
 84 
 85 /**
 86  * Horizontal left and vertical top.
 87  * @constant
 88  * @type Number
 89  */
 90 cc.ALIGN_TOP_LEFT = 0x11;
 91 //----------------------Possible texture pixel formats----------------------------
 92 
 93 
 94 // By default PVR images are treated as if they don't have the alpha channel premultiplied
 95 cc.PVRHaveAlphaPremultiplied_ = false;
 96 
 97 //cc.Texture2DWebGL move to TextureWebGL.js
 98 
 99 if (cc._renderType === cc._RENDER_TYPE_CANVAS) {
100 
101     /**
102      * <p>
103      * This class allows to easily create OpenGL or Canvas 2D textures from images, text or raw data.                                    <br/>
104      * The created cc.Texture2D object will always have power-of-two dimensions.                                                <br/>
105      * Depending on how you create the cc.Texture2D object, the actual image area of the texture might be smaller than the texture dimensions <br/>
106      *  i.e. "contentSize" != (pixelsWide, pixelsHigh) and (maxS, maxT) != (1.0, 1.0).                                           <br/>
107      * Be aware that the content of the generated textures will be upside-down! </p>
108      * @name cc.Texture2D
109      * @class
110      * @extends cc.Class
111      *
112      * @property {WebGLTexture}     name            - <@readonly> WebGLTexture Object
113      * @property {Number}           pixelFormat     - <@readonly> Pixel format of the texture
114      * @property {Number}           pixelsWidth     - <@readonly> Width in pixels
115      * @property {Number}           pixelsHeight    - <@readonly> Height in pixels
116      * @property {Number}           width           - Content width in points
117      * @property {Number}           height          - Content height in points
118      * @property {cc.GLProgram}     shaderProgram   - The shader program used by drawAtPoint and drawInRect
119      * @property {Number}           maxS            - Texture max S
120      * @property {Number}           maxT            - Texture max T
121      */
122     cc.Texture2D = cc.Class.extend(/** @lends cc.Texture2D# */{
123         _contentSize: null,
124         _textureLoaded: false,
125         _htmlElementObj: null,
126         url: null,
127         _pattern: null,
128 
129         ctor: function () {
130             this._contentSize = cc.size(0, 0);
131             this._textureLoaded = false;
132             this._htmlElementObj = null;
133             this._pattern = "";
134         },
135 
136         /**
137          * get width in pixels
138          * @return {Number}
139          */
140         getPixelsWide: function () {
141             return this._contentSize.width;
142         },
143 
144         /**
145          * get height of in pixels
146          * @return {Number}
147          */
148         getPixelsHigh: function () {
149             return this._contentSize.height;
150         },
151 
152         /**
153          * get content size
154          * @returns {cc.Size}
155          */
156         getContentSize: function () {
157             var locScaleFactor = cc.contentScaleFactor();
158             return cc.size(this._contentSize.width / locScaleFactor, this._contentSize.height / locScaleFactor);
159         },
160 
161         _getWidth: function () {
162             return this._contentSize.width / cc.contentScaleFactor();
163         },
164         _getHeight: function () {
165             return this._contentSize.height / cc.contentScaleFactor();
166         },
167 
168         /**
169          * get content size in pixels
170          * @returns {cc.Size}
171          */
172         getContentSizeInPixels: function () {
173             return this._contentSize;
174         },
175 
176         /**
177          * init with HTML element
178          * @param {HTMLImageElement|HTMLCanvasElement} element
179          */
180         initWithElement: function (element) {
181             if (!element)
182                 return;
183             this._htmlElementObj = element;
184             this._contentSize.width = element.width;
185             this._contentSize.height = element.height;
186             this._textureLoaded = true;
187         },
188 
189         /**
190          * HTMLElement Object getter
191          * @return {HTMLImageElement|HTMLCanvasElement}
192          */
193         getHtmlElementObj: function () {
194             return this._htmlElementObj;
195         },
196 
197         /**
198          * check whether texture is loaded
199          * @returns {boolean}
200          */
201         isLoaded: function () {
202             return this._textureLoaded;
203         },
204 
205         /**
206          * handle loaded texture
207          */
208         handleLoadedTexture: function () {
209             var self = this;
210             if (self._textureLoaded) return;
211             if (!self._htmlElementObj) {
212                 var img = cc.loader.getRes(self.url);
213                 if (!img) return;
214                 self.initWithElement(img);
215             }
216 
217             var locElement = self._htmlElementObj;
218             self._contentSize.width = locElement.width;
219             self._contentSize.height = locElement.height;
220 
221             //dispatch load event to listener.
222             self.dispatchEvent("load");
223         },
224 
225         /**
226          * description of cc.Texture2D
227          * @returns {string}
228          */
229         description: function () {
230             return "<cc.Texture2D | width = " + this._contentSize.width + " height " + this._contentSize.height + ">";
231         },
232 
233         initWithData: function (data, pixelFormat, pixelsWide, pixelsHigh, contentSize) {
234             //support only in WebGl rendering mode
235             return false;
236         },
237 
238         initWithImage: function (uiImage) {
239             //support only in WebGl rendering mode
240             return false;
241         },
242 
243         initWithString: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) {
244             //support only in WebGl rendering mode
245             return false;
246         },
247 
248         releaseTexture: function () {
249             cc.loader.release(this.url);
250         },
251 
252         getName: function () {
253             //support only in WebGl rendering mode
254             return null;
255         },
256 
257         getMaxS: function () {
258             //support only in WebGl rendering mode
259             return 1;
260         },
261 
262         setMaxS: function (maxS) {
263             //support only in WebGl rendering mode
264         },
265 
266         getMaxT: function () {
267             return 1;
268         },
269 
270         setMaxT: function (maxT) {
271             //support only in WebGl rendering mode
272         },
273 
274         getPixelFormat: function () {
275             //support only in WebGl rendering mode
276             return null;
277         },
278 
279         getShaderProgram: function () {
280             //support only in WebGl rendering mode
281             return null;
282         },
283 
284         setShaderProgram: function (shaderProgram) {
285             //support only in WebGl rendering mode
286         },
287 
288         hasPremultipliedAlpha: function () {
289             //support only in WebGl rendering mode
290             return false;
291         },
292 
293         hasMipmaps: function () {
294             //support only in WebGl rendering mode
295             return false;
296         },
297 
298         releaseData: function (data) {
299             //support only in WebGl rendering mode
300             data = null;
301         },
302 
303         keepData: function (data, length) {
304             //support only in WebGl rendering mode
305             return data;
306         },
307 
308         drawAtPoint: function (point) {
309             //support only in WebGl rendering mode
310         },
311 
312         drawInRect: function (rect) {
313             //support only in WebGl rendering mode
314         },
315 
316         /**
317          * init with ETC file
318          * @warning does not support on HTML5
319          */
320         initWithETCFile: function (file) {
321             cc.log(cc._LogInfos.Texture2D_initWithETCFile);
322             return false;
323         },
324 
325         /**
326          * init with PVR file
327          * @warning does not support on HTML5
328          */
329         initWithPVRFile: function (file) {
330             cc.log(cc._LogInfos.Texture2D_initWithPVRFile);
331             return false;
332         },
333 
334         /**
335          * init with PVRTC data
336          * @warning does not support on HTML5
337          */
338         initWithPVRTCData: function (data, level, bpp, hasAlpha, length, pixelFormat) {
339             cc.log(cc._LogInfos.Texture2D_initWithPVRTCData);
340             return false;
341         },
342 
343         setTexParameters: function (texParams, magFilter, wrapS, wrapT) {
344             if(magFilter !== undefined)
345                 texParams = {minFilter: texParams, magFilter: magFilter, wrapS: wrapS, wrapT: wrapT};
346 
347             if(texParams.wrapS === cc.REPEAT && texParams.wrapT === cc.REPEAT){
348                 this._pattern = "repeat";
349                 return;
350             }
351 
352             if(texParams.wrapS === cc.REPEAT ){
353                 this._pattern = "repeat-x";
354                 return;
355             }
356 
357             if(texParams.wrapT === cc.REPEAT){
358                 this._pattern = "repeat-y";
359                 return;
360             }
361 
362             this._pattern = "";
363         },
364 
365         setAntiAliasTexParameters: function () {
366             //support only in WebGl rendering mode
367         },
368 
369         setAliasTexParameters: function () {
370             //support only in WebGl rendering mode
371         },
372 
373         generateMipmap: function () {
374             //support only in WebGl rendering mode
375         },
376 
377         stringForFormat: function () {
378             //support only in WebGl rendering mode
379             return "";
380         },
381 
382         bitsPerPixelForFormat: function (format) {
383             //support only in WebGl rendering mode
384             return -1;
385         },
386 
387         /**
388          * add listener for loaded event
389          * @param {Function} callback
390          * @param {cc.Node} target
391          * @deprecated since 3.1, please use addEventListener instead
392          */
393         addLoadedEventListener: function (callback, target) {
394             this.addEventListener("load", callback, target);
395         },
396 
397         /**
398          * remove listener from listeners by target
399          * @param {cc.Node} target
400          */
401         removeLoadedEventListener: function (target) {
402             this.removeEventListener("load", target);
403         },
404 
405         //hack for gray effect
406         _grayElementObj: null,
407         _backupElement: null,
408         _isGray: false,
409         _switchToGray: function(toGray){
410             if(!this._textureLoaded || this._isGray === toGray)
411                 return;
412             this._isGray = toGray;
413             if(this._isGray){
414                 this._backupElement = this._htmlElementObj;
415                 if(!this._grayElementObj)
416                      this._grayElementObj = cc.Texture2D._generateGrayTexture(this._htmlElementObj);
417                 this._htmlElementObj = this._grayElementObj;
418             } else {
419                 if(this._backupElement !== null)
420                     this._htmlElementObj = this._backupElement;
421             }
422         }
423     });
424 
425     cc.Texture2D._generateGrayTexture = function(texture, rect, renderCanvas){
426         if (texture === null)
427             return null;
428         renderCanvas = renderCanvas || cc.newElement("canvas");
429         rect = rect || cc.rect(0, 0, texture.width, texture.height);
430         renderCanvas.width = rect.width;
431         renderCanvas.height = rect.height;
432 
433         var context = renderCanvas.getContext("2d");
434         context.drawImage(texture, rect.x, rect.y, rect.width, rect.height, 0, 0, rect.width, rect.height);
435         var imgData = context.getImageData(0, 0, rect.width, rect.height);
436         var data = imgData.data;
437         for (var i = 0, len = data.length; i < len; i += 4) {
438             data[i] = data[i + 1] = data[i + 2] = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2];
439         }
440         context.putImageData(imgData, 0, 0);
441         return renderCanvas;
442     };
443 
444 } else {
445     cc.assert(cc.isFunction(cc._tmp.WebGLTexture2D), cc._LogInfos.MissingFile, "TexturesWebGL.js");
446     cc._tmp.WebGLTexture2D();
447     delete cc._tmp.WebGLTexture2D;
448 }
449 
450 cc.EventHelper.prototype.apply(cc.Texture2D.prototype);
451 
452 cc.assert(cc.isFunction(cc._tmp.PrototypeTexture2D), cc._LogInfos.MissingFile, "TexturesPropertyDefine.js");
453 cc._tmp.PrototypeTexture2D();
454 delete cc._tmp.PrototypeTexture2D;