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 var cc = cc = cc || {}; 28 29 /** Base class for other 30 */ 31 cc.GridBase = cc.Class.extend({ 32 _active:null, 33 _reuseGrid:null, 34 _gridSize:null, 35 _texture:null, 36 _step:cc.p(0, 0), 37 _grabber:null, 38 _isTextureFlipped:null, 39 /** wheter or not the grid is active */ 40 isActive:function () { 41 return this._active; 42 }, 43 setActive:function (active) { 44 this._active = active; 45 if (!active) { 46 var director = cc.Director.getInstance(); 47 var proj = director.getProjection(); 48 director.setProjection(proj); 49 } 50 }, 51 52 /** number of times that the grid will be reused */ 53 getReuseGrid:function () { 54 return this._reuseGrid; 55 }, 56 setReuseGrid:function (reuseGrid) { 57 this._reuseGrid = reuseGrid; 58 }, 59 60 /** size of the grid */ 61 getGridSize:function () { 62 return this._gridSize; 63 }, 64 setGridSize:function (gridSize) { 65 this._gridSize.x = parseInt(gridSize.x); 66 this._gridSize.y = parseInt(gridSize.y); 67 }, 68 69 /** pixels between the grids */ 70 getStep:function () { 71 return this._step; 72 }, 73 setStep:function (step) { 74 this._step = step; 75 }, 76 77 /** is texture flipped */ 78 isTextureFlipped:function () { 79 return this._isTextureFlipped; 80 }, 81 setIsTextureFlipped:function (flipped) { 82 if (this._isTextureFlipped != flipped) { 83 this._isTextureFlipped = flipped; 84 this.calculateVertexPoints(); 85 } 86 }, 87 88 initWithSize:function (gridSize, texture, flipped) { 89 var argnum = arguments.length; 90 if (argnum = 1) { 91 var director = cc.Director.getInstance(); 92 var s = director.getWinSizeInPixels(); 93 94 var POTWide = cc.NextPOT(s.width); 95 var POTHigh = cc.NextPOT(s.height); 96 97 // we only use rgba8888 98 var format = cc.TEXTURE_2D_PIXEL_FORMAT_RGBA8888; 99 100 var pTextureTemp = new cc.Texture2D(); 101 pTextureTemp.initWithData(format, POTWide, POTHigh, s); 102 if (!pTextureTemp) { 103 cc.log("cocos2d: CCGrid: error creating texture"); 104 return false; 105 } 106 texture = pTextureTemp; 107 108 flipped = false; 109 } 110 111 112 var ret = true; 113 114 this._active = false; 115 this._reuseGrid = 0; 116 this._gridSize = gridSize; 117 this._texture = texture; 118 this._isTextureFlipped = flipped; 119 120 var texSize = this._texture.getContentSizeInPixels(); 121 this._step.x = texSize.width / this._gridSize.x; 122 this._step.y = texSize.height / this._gridSize.y; 123 124 this._grabber = new cc.Grabber(); 125 if (this._grabber) { 126 this._grabber.grab(this._texture); 127 } 128 else { 129 ret = false; 130 } 131 132 133 this.calculateVertexPoints(); 134 135 return ret; 136 137 }, 138 139 beforeDraw:function () { 140 this.set2DProjection(); 141 this._grabber.beforeRender(this._texture); 142 }, 143 afterDraw:function (target) { 144 this._grabber.afterRender(this._texture); 145 146 this.set3DProjection(); 147 148 if (target.getCamera().getDirty()) { 149 var offset = target.getAnchorPointInPixels(); 150 151 // 152 // XXX: Camera should be applied in the AnchorPoint 153 // 154 //todo gl 155 //ccglTranslate(offset.x, offset.y, 0); 156 target.getCamera().locate(); 157 //ccglTranslate(-offset.x, -offset.y, 0); 158 } 159 //todo gl 160 //glBindTexture(GL_TEXTURE_2D, this._texture.getName()); 161 162 // restore projection for default FBO .fixed bug #543 #544 163 //cc.Director.getInstance().setProjection(cc.Director.getInstance().getProjection()); 164 //cc.Director.getInstance().applyOrientation(); 165 this.blit(); 166 }, 167 blit:function () { 168 cc.Assert(0, ""); 169 }, 170 reuse:function () { 171 cc.Assert(0, ""); 172 }, 173 calculateVertexPoints:function () { 174 cc.Assert(0, ""); 175 }, 176 set2DProjection:function () { 177 var winSize = cc.Director.getInstance().getWinSizeInPixels(); 178 179 //todo gl 180 /* glViewport(0, 0, (GLsizei)(size.width * CC_CONTENT_SCALE_FACTOR()), (GLsizei)(size.height * CC_CONTENT_SCALE_FACTOR()) ); 181 kmGLMatrixMode(KM_GL_PROJECTION); 182 kmGLLoadIdentity(); 183 184 kmMat4 orthoMatrix; 185 kmMat4OrthographicProjection(&orthoMatrix, 0, size.width * CC_CONTENT_SCALE_FACTOR(), 0, size.height * CC_CONTENT_SCALE_FACTOR(), -1, 1); 186 kmGLMultMatrix( &orthoMatrix ); 187 188 kmGLMatrixMode(KM_GL_MODELVIEW); 189 kmGLLoadIdentity(); 190 191 192 ccSetProjectionMatrixDirty();*/ 193 } 194 }); 195 cc.GridBase.create = function () { 196 return new cc.GridBase(); 197 }; 198 199 /** 200 cc.Grid3D is a 3D grid implementation. Each vertex has 3 dimensions: x,y,z 201 */ 202 cc.Grid3D = cc.GridBase.extend({ 203 _texCoordinates:null, 204 _vertices:null, 205 _originalVertices:null, 206 _indices:null, 207 /** returns the vertex at a given position */ 208 vertex:function (pos) { 209 var index = (pos.x * (this._gridSize.y + 1) + pos.y) * 3; 210 var vertArray = this._vertices; 211 212 var vert = new cc.Vertex3F(vertArray[index], vertArray[index + 1], vertArray[index + 2]); 213 214 return vert; 215 }, 216 /** returns the original (non-transformed) vertex at a given position */ 217 originalVertex:function (pos) { 218 var index = (pos.x * (this._gridSize.y + 1) + pos.y) * 3; 219 var vertArray = this._originalVertices; 220 221 var vert = new cc.Vertex3F(vertArray[index], vertArray[index + 1], vertArray[index + 2]); 222 223 return vert; 224 }, 225 /** sets a new vertex at a given position */ 226 setVertex:function (pos, vertex) { 227 var index = (pos.x * (this._gridSize.y + 1) + pos.y) * 3; 228 var vertArray = this._vertices; 229 vertArray[index] = vertex.x; 230 vertArray[index + 1] = vertex.y; 231 vertArray[index + 2] = vertex.z; 232 }, 233 234 blit:function () { 235 var n = this._gridSize.x * this._gridSize.y; 236 237 // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY 238 // Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY 239 // Unneeded states: GL_COLOR_ARRAY 240 //todo gl 241 /*glDisableClientState(GL_COLOR_ARRAY); 242 243 glVertexPointer(3, GL_FLOAT, 0, this._vertices); 244 glTexCoordPointer(2, GL_FLOAT, 0, this._texCoordinates); 245 glDrawElements(GL_TRIANGLES, n*6, GL_UNSIGNED_SHORT, this._indices); 246 247 // restore default GL state 248 glEnableClientState(GL_COLOR_ARRAY);*/ 249 }, 250 reuse:function () { 251 if (this._reuseGrid > 0) { 252 --this._reuseGrid; 253 } 254 }, 255 calculateVertexPoints:function () { 256 var width = this._texture.getPixelsWide(); 257 var height = this._texture.getPixelsHigh(); 258 var imageH = this._texture.getContentSizeInPixels().height; 259 260 var numQuads = this._gridSize.x * this._gridSize.y; 261 262 this._vertices = []; 263 this._originalVertices = []; 264 this._texCoordinates = []; 265 this._indices = []; 266 267 var vertArray = this._vertices; 268 var texArray = this._texCoordinates; 269 var idxArray = this._indices; 270 271 var x, y; 272 273 for (x = 0; x < this._gridSize.x; x++) { 274 for (y = 0; y < this._gridSize.y; y++) { 275 var x1 = x * this._step.x; 276 var x2 = x1 + this._step.x; 277 var y1 = y * this._step.y; 278 var y2 = y1 + this._step.y; 279 280 vertArray[x * y] = x1; 281 vertArray[x * y + 1] = y1; 282 vertArray[x * y + 2] = 0; 283 vertArray[x * y + 3] = x2; 284 vertArray[x * y + 4] = y1; 285 vertArray[x * y + 5] = 0; 286 vertArray[x * y + 6] = x1; 287 vertArray[x * y + 7] = y2; 288 vertArray[x * y + 8] = 0; 289 vertArray[x * y + 9] = x2; 290 vertArray[x * y + 10] = y2; 291 vertArray[x * y + 11] = 0; 292 293 var newY1 = y1; 294 var newY2 = y2; 295 296 if (this._isTextureFlipped) { 297 newY1 = imageH - y1; 298 newY2 = imageH - y2; 299 } 300 301 texArray[x * y + 12] = x1 / width; 302 texArray[x * y + 13] = newY1 / height; 303 texArray[x * y + 14] = x2 / width; 304 texArray[x * y + 15] = newY1 / height; 305 texArray[x * y + 16] = x1 / width; 306 texArray[x * y + 17] = newY2 / height; 307 texArray[x * y + 18] = x2 / width; 308 texArray[x * y + 19] = newY2 / height; 309 } 310 } 311 312 for (x = 0; x < numQuads; x++) { 313 idxArray[x * 6 + 0] = x * 4 + 0; 314 idxArray[x * 6 + 1] = x * 4 + 1; 315 idxArray[x * 6 + 2] = x * 4 + 2; 316 317 idxArray[x * 6 + 3] = x * 4 + 1; 318 idxArray[x * 6 + 4] = x * 4 + 2; 319 idxArray[x * 6 + 5] = x * 4 + 3; 320 } 321 322 } 323 }); 324 325 cc.Grid3D.create = function (gridSize, texture, flipped) { 326 327 }; 328 329 /** 330 cc.TiledGrid3D is a 3D grid implementation. It differs from Grid3D in that 331 the tiles can be separated from the grid. 332 */ 333 cc.TiledGrid3D = cc.GridBase.extend({ 334 _texCoordinates:null, 335 _vertices:null, 336 _originalVertices:null, 337 _indices:null, 338 /** returns the tile at the given position */ 339 tile:function (pos) { 340 var idx = (this._gridSize.y * pos.x + pos.y) * 4 * 3; 341 var vertArray = this._vertices; 342 var ret = new cc.Quad3(); 343 return ret; 344 }, 345 /** returns the original tile (untransformed) at the given position */ 346 originalTile:function (pos) { 347 var idx = (this._gridSize.y * pos.x + pos.y) * 4 * 3; 348 var vertArray = this._originalVertices; 349 350 var ret = new cc.Quad3(vertArray[idx], vertArray[idx + 1], vertArray[idx + 2], vertArray[idx + 3]); 351 352 return ret; 353 }, 354 /** sets a new tile */ 355 setTile:function (pos, coords) { 356 var idx = (this._gridSize.y * pos.x + pos.y) * 4 * 3; 357 var vertArray = this._vertices; 358 vertArray[idx] = coords; 359 }, 360 361 blit:function () { 362 var n = this._gridSize.x * this._gridSize.y; 363 364 // Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY 365 // Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY 366 // Unneeded states: GL_COLOR_ARRAY 367 //todo gl 368 /*glDisableClientState(GL_COLOR_ARRAY); 369 370 glVertexPointer(3, GL_FLOAT, 0, this._vertices); 371 glTexCoordPointer(2, GL_FLOAT, 0, this._texCoordinates); 372 glDrawElements(GL_TRIANGLES, (GLsizei)n*6, GL_UNSIGNED_SHORT, this._indices); 373 374 // restore default GL state 375 glEnableClientState(GL_COLOR_ARRAY);*/ 376 }, 377 reuse:function () { 378 if (this._reuseGrid > 0) { 379 var numQuads = this._gridSize.x * this._gridSize.y; 380 for (var i = 0, len = numQuads.length * 12; i < len; i++) { 381 this._originalVertices.push(this._vertices[i]) 382 } 383 //todo fix 384 //memcpy(this._originalVertices, this._vertices, numQuads * 12 * sizeof(GLfloat)); 385 --this._reuseGrid; 386 } 387 }, 388 calculateVertexPoints:function () { 389 var width = this._texture.getPixelsWide(); 390 var height = this._texture.getPixelsHigh(); 391 var imageH = this._texture.getContentSizeInPixels().height; 392 393 var numQuads = this._gridSize.x * this._gridSize.y; 394 395 this._vertices = []; 396 this._originalVertices = []; 397 this._texCoordinates = []; 398 this._indices = []; 399 400 var vertArray = this._vertices; 401 var texArray = this._texCoordinates; 402 var idxArray = this._indices; 403 404 var x, y; 405 406 for (x = 0; x < this._gridSize.x; x++) { 407 for (y = 0; y < this._gridSize.y; y++) { 408 var x1 = x * this._step.x; 409 var x2 = x1 + this._step.x; 410 var y1 = y * this._step.y; 411 var y2 = y1 + this._step.y; 412 413 vertArray[x * y] = x1; 414 vertArray[x * y + 1] = y1; 415 vertArray[x * y + 2] = 0; 416 vertArray[x * y + 3] = x2; 417 vertArray[x * y + 4] = y1; 418 vertArray[x * y + 5] = 0; 419 vertArray[x * y + 6] = x1; 420 vertArray[x * y + 7] = y2; 421 vertArray[x * y + 8] = 0; 422 vertArray[x * y + 9] = x2; 423 vertArray[x * y + 10] = y2; 424 vertArray[x * y + 11] = 0; 425 var newY1 = y1; 426 var newY2 = y2; 427 428 if (this._isTextureFlipped) { 429 newY1 = imageH - y1; 430 newY2 = imageH - y2; 431 } 432 433 texArray[x * y + 12] = x1 / width; 434 texArray[x * y + 13] = newY1 / height; 435 texArray[x * y + 14] = x2 / width; 436 texArray[x * y + 15] = newY1 / height; 437 texArray[x * y + 16] = x1 / width; 438 texArray[x * y + 17] = newY2 / height; 439 texArray[x * y + 18] = x2 / width; 440 texArray[x * y + 19] = newY2 / height; 441 } 442 } 443 444 for (x = 0; x < numQuads; x++) { 445 idxArray[x * 6 + 0] = x * 4 + 0; 446 idxArray[x * 6 + 1] = x * 4 + 1; 447 idxArray[x * 6 + 2] = x * 4 + 2; 448 449 idxArray[x * 6 + 3] = x * 4 + 1; 450 idxArray[x * 6 + 4] = x * 4 + 2; 451 idxArray[x * 6 + 5] = x * 4 + 3; 452 } 453 for (var i = 0, len = numQuads.length * 12; i < len; i++) { 454 this._originalVertices.push(this._vertices[i]) 455 } 456 //todo fix 457 //memcpy(this._originalVertices, this._vertices, numQuads * 12 * sizeof(GLfloat)); 458 } 459 }); 460 461 cc.TiledGrid3D.create = function (gridSize, texture, flipped) { 462 var ret = new cc.TiledGrid3D(); 463 ret.initWithSize(gridSize, texture, flipped) 464 return ret; 465 }; 466