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