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