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 // ------------------- vertex attrib flags ----------------------------- 28 /** 29 * @constant 30 * @type {Number} 31 */ 32 cc.VERTEX_ATTRIB_FLAG_NONE = 0; 33 /** 34 * @constant 35 * @type {Number} 36 */ 37 cc.VERTEX_ATTRIB_FLAG_POSITION = 1 << 0; 38 /** 39 * @constant 40 * @type {Number} 41 */ 42 cc.VERTEX_ATTRIB_FLAG_COLOR = 1 << 1; 43 /** 44 * @constant 45 * @type {Number} 46 */ 47 cc.VERTEX_ATTRIB_FLAG_TEXCOORDS = 1 << 2; 48 /** 49 * @constant 50 * @type {Number} 51 */ 52 cc.VERTEX_ATTRIB_FLAG_POSCOLORTEX = ( cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR | cc.VERTEX_ATTRIB_FLAG_TEXCOORDS ); 53 54 /** 55 * GL server side states 56 * @constant 57 * @type {Number} 58 */ 59 cc.GL_ALL = 0; 60 61 cc._currentProjectionMatrix = -1; 62 cc._vertexAttribPosition = false; 63 cc._vertexAttribColor = false; 64 cc._vertexAttribTexCoords = false; 65 66 if (cc.ENABLE_GL_STATE_CACHE) { 67 cc.MAX_ACTIVETEXTURE = 16; 68 69 cc._currentShaderProgram = -1; 70 cc._currentBoundTexture = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1]; 71 cc._blendingSource = -1; 72 cc._blendingDest = -1; 73 cc._GLServerState = 0; 74 if(cc.TEXTURE_ATLAS_USE_VAO) 75 cc._uVAO = 0; 76 } 77 78 // GL State Cache functions 79 80 /** 81 * Invalidates the GL state cache.<br/> 82 * If CC_ENABLE_GL_STATE_CACHE it will reset the GL state cache. 83 */ 84 cc.glInvalidateStateCache = function () { 85 cc.kmGLFreeAll(); 86 cc._currentProjectionMatrix = -1; 87 cc._vertexAttribPosition = false; 88 cc._vertexAttribColor = false; 89 cc._vertexAttribTexCoords = false; 90 if (cc.ENABLE_GL_STATE_CACHE) { 91 cc._currentShaderProgram = -1; 92 for (var i = 0; i < cc.MAX_ACTIVETEXTURE; i++) { 93 cc._currentBoundTexture[i] = -1; 94 } 95 cc._blendingSource = -1; 96 cc._blendingDest = -1; 97 cc._GLServerState = 0; 98 } 99 }; 100 101 /** 102 * Uses the GL program in case program is different than the current one.<br/> 103 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glUseProgram() directly. 104 * @param {WebGLProgram} program 105 */ 106 cc.glUseProgram = function (program) { 107 if (program !== cc._currentShaderProgram) { 108 cc._currentShaderProgram = program; 109 cc.renderContext.useProgram(program); 110 } 111 }; 112 113 if(!cc.ENABLE_GL_STATE_CACHE){ 114 cc.glUseProgram = function (program) { 115 cc.renderContext.useProgram(program); 116 } 117 } 118 119 /** 120 * Deletes the GL program. If it is the one that is being used, it invalidates it.<br/> 121 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glDeleteProgram() directly. 122 * @param {WebGLProgram} program 123 */ 124 cc.glDeleteProgram = function (program) { 125 if (cc.ENABLE_GL_STATE_CACHE) { 126 if (program === cc._currentShaderProgram) 127 cc._currentShaderProgram = -1; 128 } 129 gl.deleteProgram(program); 130 }; 131 132 /** 133 * Uses a blending function in case it not already used.<br/> 134 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will the glBlendFunc() directly. 135 * @param {Number} sfactor 136 * @param {Number} dfactor 137 */ 138 cc.glBlendFunc = function (sfactor, dfactor) { 139 if ((sfactor !== cc._blendingSource) || (dfactor !== cc._blendingDest)) { 140 cc._blendingSource = sfactor; 141 cc._blendingDest = dfactor; 142 cc.setBlending(sfactor, dfactor); 143 } 144 }; 145 146 cc.setBlending = function (sfactor, dfactor) { 147 var ctx = cc.renderContext; 148 if ((sfactor === ctx.ONE) && (dfactor === ctx.ZERO)) { 149 ctx.disable(ctx.BLEND); 150 } else { 151 ctx.enable(ctx.BLEND); 152 cc.renderContext.blendFunc(sfactor,dfactor); 153 //TODO need fix for WebGL 154 //ctx.blendFuncSeparate(ctx.SRC_ALPHA, dfactor, sfactor, dfactor); 155 } 156 }; 157 158 cc.glBlendFuncForParticle = function(sfactor, dfactor) { 159 if ((sfactor !== cc._blendingSource) || (dfactor !== cc._blendingDest)) { 160 cc._blendingSource = sfactor; 161 cc._blendingDest = dfactor; 162 var ctx = cc.renderContext; 163 if ((sfactor === ctx.ONE) && (dfactor === ctx.ZERO)) { 164 ctx.disable(ctx.BLEND); 165 } else { 166 ctx.enable(ctx.BLEND); 167 //TODO need fix for WebGL 168 ctx.blendFuncSeparate(ctx.SRC_ALPHA, dfactor, sfactor, dfactor); 169 } 170 } 171 }; 172 173 if(!cc.ENABLE_GL_STATE_CACHE){ 174 cc.glBlendFunc = cc.setBlending; 175 }; 176 177 /** 178 * Resets the blending mode back to the cached state in case you used glBlendFuncSeparate() or glBlendEquation().<br/> 179 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will just set the default blending mode using GL_FUNC_ADD. 180 */ 181 cc.glBlendResetToCache = function () { 182 var ctx = cc.renderContext; 183 ctx.blendEquation(ctx.FUNC_ADD); 184 if (cc.ENABLE_GL_STATE_CACHE) 185 cc.setBlending(cc._blendingSource, cc._blendingDest); 186 else 187 cc.setBlending(ctx.BLEND_SRC, ctx.BLEND_DST); 188 }; 189 190 /** 191 * sets the projection matrix as dirty 192 */ 193 cc.setProjectionMatrixDirty = function () { 194 cc._currentProjectionMatrix = -1; 195 }; 196 197 /** 198 * <p> 199 * Will enable the vertex attribs that are passed as flags. <br/> 200 * Possible flags: <br/> 201 * cc.VERTEX_ATTRIB_FLAG_POSITION <br/> 202 * cc.VERTEX_ATTRIB_FLAG_COLOR <br/> 203 * cc.VERTEX_ATTRIB_FLAG_TEXCOORDS <br/> 204 * <br/> 205 * These flags can be ORed. The flags that are not present, will be disabled. 206 * </p> 207 * @param {cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR | cc.VERTEX_ATTRIB_FLAG_TEXCOORDS} flags 208 */ 209 cc.glEnableVertexAttribs = function (flags) { 210 /* Position */ 211 var ctx = cc.renderContext; 212 var enablePosition = ( flags & cc.VERTEX_ATTRIB_FLAG_POSITION ); 213 if (enablePosition !== cc._vertexAttribPosition) { 214 if (enablePosition) 215 ctx.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); 216 else 217 ctx.disableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION); 218 cc._vertexAttribPosition = enablePosition; 219 } 220 221 /* Color */ 222 var enableColor = (flags & cc.VERTEX_ATTRIB_FLAG_COLOR); 223 if (enableColor !== cc._vertexAttribColor) { 224 if (enableColor) 225 ctx.enableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); 226 else 227 ctx.disableVertexAttribArray(cc.VERTEX_ATTRIB_COLOR); 228 cc._vertexAttribColor = enableColor; 229 } 230 231 /* Tex Coords */ 232 var enableTexCoords = (flags & cc.VERTEX_ATTRIB_FLAG_TEXCOORDS); 233 if (enableTexCoords !== cc._vertexAttribTexCoords) { 234 if (enableTexCoords) 235 ctx.enableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS); 236 else 237 ctx.disableVertexAttribArray(cc.VERTEX_ATTRIB_TEX_COORDS); 238 cc._vertexAttribTexCoords = enableTexCoords; 239 } 240 }; 241 242 /** 243 * If the texture is not already bound, it binds it.<br/> 244 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindTexture() directly. 245 * @param {cc.Texture2D} textureId 246 */ 247 cc.glBindTexture2D = function (textureId) { 248 cc.glBindTexture2DN(0, textureId); 249 }; 250 251 /** 252 * If the texture is not already bound to a given unit, it binds it.<br/> 253 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindTexture() directly. 254 * @param {Number} textureUnit 255 * @param {cc.Texture2D} textureId 256 */ 257 cc.glBindTexture2DN = function (textureUnit, textureId) { 258 if (cc._currentBoundTexture[textureUnit] == textureId) 259 return; 260 cc._currentBoundTexture[textureUnit] = textureId; 261 262 var ctx = cc.renderContext; 263 ctx.activeTexture(ctx.TEXTURE0 + textureUnit); 264 if(textureId) 265 ctx.bindTexture(ctx.TEXTURE_2D, textureId._webTextureObj); 266 else 267 ctx.bindTexture(ctx.TEXTURE_2D, null); 268 }; 269 if (!cc.ENABLE_GL_STATE_CACHE){ 270 cc.glBindTexture2DN = function (textureUnit, textureId) { 271 var ctx = cc.renderContext; 272 ctx.activeTexture(ctx.TEXTURE0 + textureUnit); 273 if(textureId) 274 ctx.bindTexture(ctx.TEXTURE_2D, textureId._webTextureObj); 275 else 276 ctx.bindTexture(ctx.TEXTURE_2D, null); 277 }; 278 } 279 280 /** 281 * It will delete a given texture. If the texture was bound, it will invalidate the cached. <br/> 282 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glDeleteTextures() directly. 283 * @param {WebGLTexture} textureId 284 */ 285 cc.glDeleteTexture = function (textureId) { 286 cc.glDeleteTextureN(0, textureId); 287 }; 288 289 /** 290 * It will delete a given texture. If the texture was bound, it will invalidate the cached for the given texture unit.<br/> 291 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glDeleteTextures() directly. 292 * @param {Number} textureUnit 293 * @param {WebGLTexture} textureId 294 */ 295 cc.glDeleteTextureN = function (textureUnit, textureId) { 296 if (cc.ENABLE_GL_STATE_CACHE) { 297 if (textureId == cc._currentBoundTexture[ textureUnit ]) 298 cc._currentBoundTexture[ textureUnit ] = -1; 299 } 300 cc.renderContext.deleteTexture(textureId); 301 }; 302 303 /** 304 * If the vertex array is not already bound, it binds it.<br/> 305 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glBindVertexArray() directly. 306 * @param vaoId 307 */ 308 cc.glBindVAO = function (vaoId) { 309 if (!cc.TEXTURE_ATLAS_USE_VAO) 310 return; 311 312 if (cc.ENABLE_GL_STATE_CACHE) { 313 if (cc._uVAO != vaoId) { 314 cc._uVAO = vaoId; 315 //TODO need fixed 316 //glBindVertexArray(vaoId); 317 } 318 } else { 319 //glBindVertexArray(vaoId); 320 } 321 }; 322 323 /** 324 * It will enable / disable the server side GL states.<br/> 325 * If CC_ENABLE_GL_STATE_CACHE is disabled, it will call glEnable() directly. 326 * @param {Number} flags 327 */ 328 cc.glEnable = function (flags) { 329 if (cc.ENABLE_GL_STATE_CACHE) { 330 /*var enabled; 331 332 */ 333 /* GL_BLEND */ 334 /* 335 if ((enabled = (flags & cc.GL_BLEND)) != (cc._GLServerState & cc.GL_BLEND)) { 336 if (enabled) { 337 cc.renderContext.enable(cc.renderContext.BLEND); 338 cc._GLServerState |= cc.GL_BLEND; 339 } else { 340 cc.renderContext.disable(cc.renderContext.BLEND); 341 cc._GLServerState &= ~cc.GL_BLEND; 342 } 343 }*/ 344 } else { 345 /*if ((flags & cc.GL_BLEND)) 346 cc.renderContext.enable(cc.renderContext.BLEND); 347 else 348 cc.renderContext.disable(cc.renderContext.BLEND);*/ 349 } 350 }; 351 352