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 /**
 28  * cc.shaderCache is a singleton object that stores manages GL shaders
 29  * @class
 30  * @name cc.shaderCache
 31  */
 32 cc.shaderCache = /** @lends cc.shaderCache# */{
 33 
 34     /**
 35      * @public
 36      * @constant
 37      * @type {Number}
 38      */
 39     TYPE_POSITION_TEXTURECOLOR: 0,
 40     /**
 41      * @public
 42      * @constant
 43      * @type {Number}
 44      */
 45     TYPE_POSITION_TEXTURECOLOR_ALPHATEST: 1,
 46     /**
 47      * @public
 48      * @constant
 49      * @type {Number}
 50      */
 51     TYPE_POSITION_COLOR: 2,
 52     /**
 53      * @public
 54      * @constant
 55      * @type {Number}
 56      */
 57     TYPE_POSITION_TEXTURE: 3,
 58     /**
 59      * @public
 60      * @constant
 61      * @type {Number}
 62      */
 63     TYPE_POSITION_TEXTURE_UCOLOR: 4,
 64     /**
 65      * @public
 66      * @constant
 67      * @type {Number}
 68      */
 69     TYPE_POSITION_TEXTURE_A8COLOR: 5,
 70     /**
 71      * @public
 72      * @constant
 73      * @type {Number}
 74      */
 75     TYPE_POSITION_UCOLOR: 6,
 76     /**
 77      * @public
 78      * @constant
 79      * @type {Number}
 80      */
 81     TYPE_POSITION_LENGTH_TEXTURECOLOR: 7,
 82     /**
 83      * @public
 84      * @constant
 85      * @type {Number}
 86      */
 87     TYPE_SPRITE_POSITION_TEXTURECOLOR: 8,
 88     /**
 89      * @public
 90      * @constant
 91      * @type {Number}
 92      */
 93     TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST: 9,
 94     /**
 95      * @public
 96      * @constant
 97      * @type {Number}
 98      */
 99     TYPE_SPRITE_POSITION_COLOR: 10,
100     /**
101      * @public
102      * @constant
103      * @type {Number}
104      */
105     TYPE_MAX: 10,
106 
107     _programs: {},
108 
109     _init: function () {
110         this.loadDefaultShaders();
111         return true;
112     },
113 
114     _loadDefaultShader: function (program, type) {
115         switch (type) {
116             case this.TYPE_POSITION_TEXTURECOLOR:
117                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_FRAG);
118                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
119                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
120                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
121                 break;
122             case this.TYPE_SPRITE_POSITION_TEXTURECOLOR:
123                 program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_FRAG);
124                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
125                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
126                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
127                 break;
128             case this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST:
129                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG);
130                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
131                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
132                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
133                 break;
134             case this.TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST:
135                 program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG);
136                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
137                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
138                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
139                 break;
140             case this.TYPE_POSITION_COLOR:
141                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_COLOR_VERT, cc.SHADER_POSITION_COLOR_FRAG);
142                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
143                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
144                 break;
145             case this.TYPE_SPRITE_POSITION_COLOR:
146                 program.initWithVertexShaderByteArray(cc.SHADER_SPRITE_POSITION_COLOR_VERT, cc.SHADER_POSITION_COLOR_FRAG);
147                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
148                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
149                 break;
150             case this.TYPE_POSITION_TEXTURE:
151                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_VERT, cc.SHADER_POSITION_TEXTURE_FRAG);
152                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
153                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
154                 break;
155             case this.TYPE_POSITION_TEXTURE_UCOLOR:
156                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_UCOLOR_VERT, cc.SHADER_POSITION_TEXTURE_UCOLOR_FRAG);
157                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
158                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
159                 break;
160             case this.TYPE_POSITION_TEXTURE_A8COLOR:
161                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_A8COLOR_VERT, cc.SHADER_POSITION_TEXTURE_A8COLOR_FRAG);
162                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
163                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
164                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
165                 break;
166             case this.TYPE_POSITION_UCOLOR:
167                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_UCOLOR_VERT, cc.SHADER_POSITION_UCOLOR_FRAG);
168                 program.addAttribute("aVertex", cc.VERTEX_ATTRIB_POSITION);
169                 break;
170             case this.TYPE_POSITION_LENGTH_TEXTURECOLOR:
171                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_COLOR_LENGTH_TEXTURE_VERT, cc.SHADER_POSITION_COLOR_LENGTH_TEXTURE_FRAG);
172                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
173                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
174                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
175                 break;
176             default:
177                 cc.log("cocos2d: cc.shaderCache._loadDefaultShader, error shader type");
178                 return;
179         }
180 
181         program.link();
182         program.updateUniforms();
183 
184         //cc.checkGLErrorDebug();
185     },
186 
187     /**
188      * loads the default shaders
189      */
190     loadDefaultShaders: function () {
191         // Position Texture Color shader
192         var program = new cc.GLProgram();
193         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR);
194         this._programs[cc.SHADER_POSITION_TEXTURECOLOR] = program;
195         this._programs["ShaderPositionTextureColor"] = program;
196 
197         // Position Texture Color shader with position precalculated
198         program = new cc.GLProgram();
199         this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_TEXTURECOLOR);
200         this._programs[cc.SHADER_SPRITE_POSITION_TEXTURECOLOR] = program;
201         this._programs["ShaderSpritePositionTextureColor"] = program;
202 
203         // Position Texture Color alpha test
204         program = new cc.GLProgram();
205         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST);
206         this._programs[cc.SHADER_POSITION_TEXTURECOLORALPHATEST] = program;
207         this._programs["ShaderPositionTextureColorAlphaTest"] = program;
208 
209         // Position Texture Color alpha with position precalculated
210         program = new cc.GLProgram();
211         this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST);
212         this._programs[cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST] = program;
213         this._programs["ShaderSpritePositionTextureColorAlphaTest"] = program;
214 
215         //
216         // Position, Color shader
217         //
218         program = new cc.GLProgram();
219         this._loadDefaultShader(program, this.TYPE_POSITION_COLOR);
220         this._programs[cc.SHADER_POSITION_COLOR] = program;
221         this._programs["ShaderPositionColor"] = program;
222 
223         //
224         // Position, Color shader with position precalculated
225         //
226         program = new cc.GLProgram();
227         this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_COLOR);
228         this._programs[cc.SHADER_SPRITE_POSITION_COLOR] = program;
229         this._programs["ShaderSpritePositionColor"] = program;
230 
231         //
232         // Position Texture shader
233         //
234         program = new cc.GLProgram();
235         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE);
236         this._programs[cc.SHADER_POSITION_TEXTURE] = program;
237         this._programs["ShaderPositionTexture"] = program;
238 
239         //
240         // Position, Texture attribs, 1 Color as uniform shader
241         //
242         program = new cc.GLProgram();
243         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_UCOLOR);
244         this._programs[cc.SHADER_POSITION_TEXTURE_UCOLOR] = program;
245         this._programs["ShaderPositionTextureUColor"] = program;
246 
247         //
248         // Position Texture A8 Color shader
249         //
250         program = new cc.GLProgram();
251         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_A8COLOR);
252         this._programs[cc.SHADER_POSITION_TEXTUREA8COLOR] = program;
253         this._programs["ShaderPositionTextureA8Color"] = program;
254 
255         //
256         // Position and 1 color passed as a uniform (to similate glColor4ub )
257         //
258         program = new cc.GLProgram();
259         this._loadDefaultShader(program, this.TYPE_POSITION_UCOLOR);
260         this._programs[cc.SHADER_POSITION_UCOLOR] = program;
261         this._programs["ShaderPositionUColor"] = program;
262 
263         //
264         // Position, Legth(TexCoords, Color (used by Draw Node basically )
265         //
266         program = new cc.GLProgram();
267         this._loadDefaultShader(program, this.TYPE_POSITION_LENGTH_TEXTURECOLOR);
268         this._programs[cc.SHADER_POSITION_LENGTHTEXTURECOLOR] = program;
269         this._programs["ShaderPositionLengthTextureColor"] = program;
270     },
271 
272     /**
273      * reload the default shaders
274      */
275     reloadDefaultShaders: function () {
276         // reset all programs and reload them
277 
278         // Position Texture Color shader
279         var program = this.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
280         program.reset();
281         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR);
282 
283         // Sprite Position Texture Color shader
284         program = this.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLOR);
285         program.reset();
286         this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_TEXTURECOLOR);
287 
288         // Position Texture Color alpha test
289         program = this.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
290         program.reset();
291         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST);
292 
293         // Sprite Position Texture Color alpha shader
294         program = this.programForKey(cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST);
295         program.reset();
296         this._loadDefaultShader(program, this.TYPE_SPRITE_POSITION_TEXTURECOLOR_ALPHATEST);
297 
298         //
299         // Position, Color shader
300         //
301         program = this.programForKey(cc.SHADER_POSITION_COLOR);
302         program.reset();
303         this._loadDefaultShader(program, this.TYPE_POSITION_COLOR);
304 
305         //
306         // Position Texture shader
307         //
308         program = this.programForKey(cc.SHADER_POSITION_TEXTURE);
309         program.reset();
310         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE);
311 
312         //
313         // Position, Texture attribs, 1 Color as uniform shader
314         //
315         program = this.programForKey(cc.SHADER_POSITION_TEXTURE_UCOLOR);
316         program.reset();
317         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_UCOLOR);
318 
319         //
320         // Position Texture A8 Color shader
321         //
322         program = this.programForKey(cc.SHADER_POSITION_TEXTUREA8COLOR);
323         program.reset();
324         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_A8COLOR);
325 
326         //
327         // Position and 1 color passed as a uniform (to similate glColor4ub )
328         //
329         program = this.programForKey(cc.SHADER_POSITION_UCOLOR);
330         program.reset();
331         this._loadDefaultShader(program, this.TYPE_POSITION_UCOLOR);
332     },
333 
334     /**
335      * returns a GL program for a given key
336      * @param {String} key
337      */
338     programForKey: function (key) {
339         return this._programs[key];
340     },
341 
342     /**
343      * returns a GL program for a shader name
344      * @param {String} shaderName
345      * @return {cc.GLProgram}
346      */
347     getProgram: function (shaderName) {
348         return this._programs[shaderName];
349     },
350 
351     /**
352      * adds a CCGLProgram to the cache for a given name
353      * @param {cc.GLProgram} program
354      * @param {String} key
355      */
356     addProgram: function (program, key) {
357         this._programs[key] = program;
358     }
359 };