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_MAX: 8,
 88 
 89     _programs: {},
 90 
 91     _init: function () {
 92         this.loadDefaultShaders();
 93         return true;
 94     },
 95 
 96     _loadDefaultShader: function (program, type) {
 97         switch (type) {
 98             case this.TYPE_POSITION_TEXTURECOLOR:
 99                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_FRAG);
100 
101                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
102                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
103                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
104                 break;
105             case this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST:
106                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_COLOR_VERT, cc.SHADER_POSITION_TEXTURE_COLOR_ALPHATEST_FRAG);
107 
108                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
109                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
110                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
111                 break;
112             case this.TYPE_POSITION_COLOR:
113                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_COLOR_VERT, cc.SHADER_POSITION_COLOR_FRAG);
114 
115                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
116                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
117                 break;
118             case this.TYPE_POSITION_TEXTURE:
119                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_VERT, cc.SHADER_POSITION_TEXTURE_FRAG);
120 
121                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
122                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
123                 break;
124             case this.TYPE_POSITION_TEXTURE_UCOLOR:
125                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_UCOLOR_VERT, cc.SHADER_POSITION_TEXTURE_UCOLOR_FRAG);
126 
127                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
128                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
129                 break;
130             case this.TYPE_POSITION_TEXTURE_A8COLOR:
131                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_TEXTURE_A8COLOR_VERT, cc.SHADER_POSITION_TEXTURE_A8COLOR_FRAG);
132 
133                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
134                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
135                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
136                 break;
137             case this.TYPE_POSITION_UCOLOR:
138                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_UCOLOR_VERT, cc.SHADER_POSITION_UCOLOR_FRAG);
139                 program.addAttribute("aVertex", cc.VERTEX_ATTRIB_POSITION);
140                 break;
141             case this.TYPE_POSITION_LENGTH_TEXTURECOLOR:
142                 program.initWithVertexShaderByteArray(cc.SHADER_POSITION_COLOR_LENGTH_TEXTURE_VERT, cc.SHADER_POSITION_COLOR_LENGTH_TEXTURE_FRAG);
143 
144                 program.addAttribute(cc.ATTRIBUTE_NAME_POSITION, cc.VERTEX_ATTRIB_POSITION);
145                 program.addAttribute(cc.ATTRIBUTE_NAME_TEX_COORD, cc.VERTEX_ATTRIB_TEX_COORDS);
146                 program.addAttribute(cc.ATTRIBUTE_NAME_COLOR, cc.VERTEX_ATTRIB_COLOR);
147                 break;
148             default:
149                 cc.log("cocos2d: cc.shaderCache._loadDefaultShader, error shader type");
150                 return;
151         }
152 
153         program.link();
154         program.updateUniforms();
155 
156         //cc.checkGLErrorDebug();
157     },
158 
159     /**
160      * loads the default shaders
161      */
162     loadDefaultShaders: function () {
163         // Position Texture Color shader
164         var program = new cc.GLProgram();
165         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR);
166         this._programs[cc.SHADER_POSITION_TEXTURECOLOR] = program;
167         this._programs["ShaderPositionTextureColor"] = program;
168 
169         // Position Texture Color alpha test
170         program = new cc.GLProgram();
171         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST);
172         this._programs[cc.SHADER_POSITION_TEXTURECOLORALPHATEST] = program;
173         this._programs["ShaderPositionTextureColorAlphaTest"] = program;
174 
175         //
176         // Position, Color shader
177         //
178         program = new cc.GLProgram();
179         this._loadDefaultShader(program, this.TYPE_POSITION_COLOR);
180         this._programs[cc.SHADER_POSITION_COLOR] = program;
181         this._programs["ShaderPositionColor"] = program;
182 
183         //
184         // Position Texture shader
185         //
186         program = new cc.GLProgram();
187         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE);
188         this._programs[cc.SHADER_POSITION_TEXTURE] = program;
189         this._programs["ShaderPositionTexture"] = program;
190 
191         //
192         // Position, Texture attribs, 1 Color as uniform shader
193         //
194         program = new cc.GLProgram();
195         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_UCOLOR);
196         this._programs[cc.SHADER_POSITION_TEXTURE_UCOLOR] = program;
197         this._programs["ShaderPositionTextureUColor"] = program;
198 
199         //
200         // Position Texture A8 Color shader
201         //
202         program = new cc.GLProgram();
203         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_A8COLOR);
204         this._programs[cc.SHADER_POSITION_TEXTUREA8COLOR] = program;
205         this._programs["ShaderPositionTextureA8Color"] = program;
206 
207         //
208         // Position and 1 color passed as a uniform (to similate glColor4ub )
209         //
210         program = new cc.GLProgram();
211         this._loadDefaultShader(program, this.TYPE_POSITION_UCOLOR);
212         this._programs[cc.SHADER_POSITION_UCOLOR] = program;
213         this._programs["ShaderPositionUColor"] = program;
214 
215         //
216         // Position, Legth(TexCoords, Color (used by Draw Node basically )
217         //
218         program = new cc.GLProgram();
219         this._loadDefaultShader(program, this.TYPE_POSITION_LENGTH_TEXTURECOLOR);
220         this._programs[cc.SHADER_POSITION_LENGTHTEXTURECOLOR] = program;
221         this._programs["ShaderPositionLengthTextureColor"] = program;
222     },
223 
224     /**
225      * reload the default shaders
226      */
227     reloadDefaultShaders: function () {
228         // reset all programs and reload them
229 
230         // Position Texture Color shader
231         var program = this.programForKey(cc.SHADER_POSITION_TEXTURECOLOR);
232         program.reset();
233         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR);
234 
235         // Position Texture Color alpha test
236         program = this.programForKey(cc.SHADER_POSITION_TEXTURECOLORALPHATEST);
237         program.reset();
238         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURECOLOR_ALPHATEST);
239 
240         //
241         // Position, Color shader
242         //
243         program = this.programForKey(cc.SHADER_POSITION_COLOR);
244         program.reset();
245         this._loadDefaultShader(program, this.TYPE_POSITION_COLOR);
246 
247         //
248         // Position Texture shader
249         //
250         program = this.programForKey(cc.SHADER_POSITION_TEXTURE);
251         program.reset();
252         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE);
253 
254         //
255         // Position, Texture attribs, 1 Color as uniform shader
256         //
257         program = this.programForKey(cc.SHADER_POSITION_TEXTURE_UCOLOR);
258         program.reset();
259         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_UCOLOR);
260 
261         //
262         // Position Texture A8 Color shader
263         //
264         program = this.programForKey(cc.SHADER_POSITION_TEXTUREA8COLOR);
265         program.reset();
266         this._loadDefaultShader(program, this.TYPE_POSITION_TEXTURE_A8COLOR);
267 
268         //
269         // Position and 1 color passed as a uniform (to similate glColor4ub )
270         //
271         program = this.programForKey(cc.SHADER_POSITION_UCOLOR);
272         program.reset();
273         this._loadDefaultShader(program, this.TYPE_POSITION_UCOLOR);
274     },
275 
276     /**
277      * returns a GL program for a given key
278      * @param {String} key
279      */
280     programForKey: function (key) {
281         return this._programs[key];
282     },
283 
284     /**
285      * returns a GL program for a shader name
286      * @param {String} shaderName
287      * @return {cc.GLProgram}
288      */
289     getProgram: function (shaderName) {
290         return this._programs[shaderName];
291     },
292 
293     /**
294      * adds a CCGLProgram to the cache for a given name
295      * @param {cc.GLProgram} program
296      * @param {String} key
297      */
298     addProgram: function (program, key) {
299         this._programs[key] = program;
300     }
301 };