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