CCGrid.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  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. Copyright (c) 2009 On-Core
  6. http://www.cocos2d-x.org
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. ****************************************************************************/
  23. /**
  24. * Base class for cc.Grid
  25. * @class
  26. * @extends cc.Class
  27. */
  28. cc.GridBase = cc.Class.extend(/** @lends cc.GridBase# */{
  29. _active:false,
  30. _reuseGrid:0,
  31. _gridSize:null,
  32. _texture:null,
  33. _step:null,
  34. _grabber:null,
  35. _isTextureFlipped:false,
  36. _shaderProgram:null,
  37. _directorProjection:0,
  38. _dirty:false,
  39. /**
  40. * create one cc.GridBase Object
  41. * Constructor of cc.GridBase
  42. * @param {cc.Size} gridSize
  43. * @param {cc.Texture2D} [texture=]
  44. * @param {Boolean} [flipped=]
  45. */
  46. ctor:function (gridSize, texture, flipped) {
  47. cc._checkWebGLRenderMode();
  48. this._active=false;
  49. this._reuseGrid=0;
  50. this._gridSize=null;
  51. this._texture=null;
  52. this._step = cc.p(0, 0);
  53. this._grabber=null;
  54. this._isTextureFlipped=false;
  55. this._shaderProgram=null;
  56. this._directorProjection=0;
  57. this._dirty=false;
  58. if(gridSize !== undefined)
  59. this.initWithSize(gridSize, texture, flipped);
  60. },
  61. /**
  62. * whether or not the grid is active
  63. * @return {Boolean}
  64. */
  65. isActive:function () {
  66. return this._active;
  67. },
  68. /**
  69. * whether or not the grid is active
  70. * @param {Number} active
  71. */
  72. setActive:function (active) {
  73. this._active = active;
  74. if (!active) {
  75. var director = cc.director;
  76. var proj = director.getProjection();
  77. director.setProjection(proj);
  78. }
  79. },
  80. /**
  81. * get number of times that the grid will be reused
  82. * @return {Number}
  83. */
  84. getReuseGrid:function () {
  85. return this._reuseGrid;
  86. },
  87. /**
  88. * set number of times that the grid will be reused
  89. * @param reuseGrid
  90. */
  91. setReuseGrid:function (reuseGrid) {
  92. this._reuseGrid = reuseGrid;
  93. },
  94. /**
  95. * get size of the grid
  96. * @return {cc.Size}
  97. */
  98. getGridSize:function () {
  99. return cc.size(this._gridSize.width, this._gridSize.height);
  100. },
  101. /**
  102. * set size of the grid
  103. * @param {cc.Size} gridSize
  104. */
  105. setGridSize:function (gridSize) {
  106. this._gridSize.width = parseInt(gridSize.width);
  107. this._gridSize.height = parseInt(gridSize.height);
  108. },
  109. /**
  110. * get pixels between the grids
  111. * @return {cc.Point}
  112. */
  113. getStep:function () {
  114. return cc.p(this._step.x, this._step.y);
  115. },
  116. /**
  117. * set pixels between the grids
  118. * @param {cc.Point} step
  119. */
  120. setStep:function (step) {
  121. this._step.x = step.x;
  122. this._step.y = step.y;
  123. },
  124. /**
  125. * get wheter or not the texture is flipped
  126. * @return {Boolean}
  127. */
  128. isTextureFlipped:function () {
  129. return this._isTextureFlipped;
  130. },
  131. /**
  132. * set wheter or not the texture is flipped
  133. * @param {Boolean} flipped
  134. */
  135. setTextureFlipped:function (flipped) {
  136. if (this._isTextureFlipped != flipped) {
  137. this._isTextureFlipped = flipped;
  138. this.calculateVertexPoints();
  139. }
  140. },
  141. /**
  142. *
  143. * @param {cc.Size} gridSize
  144. * @param {cc.Texture2D} [texture=]
  145. * @param {Boolean} [flipped=false]
  146. * @returns {boolean}
  147. */
  148. initWithSize:function (gridSize, texture, flipped) {
  149. if (!texture) {
  150. var director = cc.director;
  151. var winSize = director.getWinSizeInPixels();
  152. var POTWide = cc.NextPOT(winSize.width);
  153. var POTHigh = cc.NextPOT(winSize.height);
  154. var data = new Uint8Array(POTWide * POTHigh * 4);
  155. if (!data) {
  156. cc.log("cocos2d: CCGrid: not enough memory.");
  157. return false;
  158. }
  159. texture = new cc.Texture2D();
  160. // we only use rgba8888
  161. texture.initWithData(data, cc.Texture2D.PIXEL_FORMAT_RGBA8888, POTWide, POTHigh, winSize);
  162. if (!texture) {
  163. cc.log("cocos2d: CCGrid: error creating texture");
  164. return false;
  165. }
  166. }
  167. flipped = flipped || false;
  168. this._active = false;
  169. this._reuseGrid = 0;
  170. this._gridSize = gridSize;
  171. this._texture = texture;
  172. this._isTextureFlipped = flipped;
  173. this._step.x = this._texture.width / gridSize.width;
  174. this._step.y = this._texture.height / gridSize.height;
  175. this._grabber = new cc.Grabber();
  176. if (!this._grabber)
  177. return false;
  178. this._grabber.grab(this._texture);
  179. this._shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
  180. this.calculateVertexPoints();
  181. return true;
  182. },
  183. beforeDraw:function () {
  184. // save projection
  185. this._directorProjection = cc.director.getProjection();
  186. // 2d projection
  187. // [director setProjection:kCCDirectorProjection2D];
  188. this.set2DProjection();
  189. this._grabber.beforeRender(this._texture);
  190. },
  191. afterDraw:function (target) {
  192. this._grabber.afterRender(this._texture);
  193. // restore projection
  194. cc.director.setProjection(this._directorProjection);
  195. if (target.getCamera().isDirty()) {
  196. var offset = target.getAnchorPointInPoints();
  197. //
  198. // XXX: Camera should be applied in the AnchorPoint
  199. //
  200. cc.kmGLTranslatef(offset.x, offset.y, 0);
  201. target.getCamera().locate();
  202. cc.kmGLTranslatef(-offset.x, -offset.y, 0);
  203. }
  204. cc.glBindTexture2D(this._texture);
  205. // restore projection for default FBO .fixed bug #543 #544
  206. //TODO: CCDirector::sharedDirector().setProjection(CCDirector::sharedDirector().getProjection());
  207. //TODO: CCDirector::sharedDirector().applyOrientation();
  208. this.blit();
  209. },
  210. blit:function () {
  211. cc.log("cc.GridBase.blit(): Shall be overridden in subclass.");
  212. },
  213. reuse:function () {
  214. cc.log("cc.GridBase.reuse(): Shall be overridden in subclass.");
  215. },
  216. calculateVertexPoints:function () {
  217. cc.log("cc.GridBase.calculateVertexPoints(): Shall be overridden in subclass.");
  218. },
  219. set2DProjection:function () {
  220. var winSize = cc.director.getWinSizeInPixels();
  221. var gl = cc._renderContext;
  222. gl.viewport(0, 0, winSize.width , winSize.height);
  223. cc.kmGLMatrixMode(cc.KM_GL_PROJECTION);
  224. cc.kmGLLoadIdentity();
  225. var orthoMatrix = new cc.kmMat4();
  226. cc.kmMat4OrthographicProjection(orthoMatrix, 0, winSize.width, 0, winSize.height, -1, 1);
  227. cc.kmGLMultMatrix(orthoMatrix);
  228. cc.kmGLMatrixMode(cc.KM_GL_MODELVIEW);
  229. cc.kmGLLoadIdentity();
  230. cc.setProjectionMatrixDirty()
  231. }
  232. });
  233. /**
  234. * create one cc.GridBase Object
  235. * @deprecated
  236. * @param {cc.Size} gridSize
  237. * @param {cc.Texture2D} [texture=]
  238. * @param {Boolean} [flipped=]
  239. * @return {cc.GridBase}
  240. */
  241. cc.GridBase.create = function (gridSize, texture, flipped) {
  242. return new cc.GridBase(gridSize, texture, flipped);
  243. };
  244. /**
  245. * cc.Grid3D is a 3D grid implementation. Each vertex has 3 dimensions: x,y,z
  246. * @class
  247. * @extends cc.GridBase
  248. */
  249. cc.Grid3D = cc.GridBase.extend(/** @lends cc.Grid3D# */{
  250. _texCoordinates:null,
  251. _vertices:null,
  252. _originalVertices:null,
  253. _indices:null,
  254. _texCoordinateBuffer:null,
  255. _verticesBuffer:null,
  256. _indicesBuffer:null,
  257. /**
  258. * create one Grid3D object
  259. * Constructor of cc.Grid3D
  260. * @param {cc.Size} gridSize
  261. * @param {cc.Texture2D} [texture=]
  262. * @param {Boolean} [flipped=]
  263. */
  264. ctor:function (gridSize, texture, flipped) {
  265. cc.GridBase.prototype.ctor.call(this);
  266. this._texCoordinates=null;
  267. this._vertices=null;
  268. this._originalVertices=null;
  269. this._indices=null;
  270. this._texCoordinateBuffer=null;
  271. this._verticesBuffer=null;
  272. this._indicesBuffer=null;
  273. if(gridSize !== undefined)
  274. this.initWithSize(gridSize, texture, flipped);
  275. },
  276. /**
  277. * returns the vertex at a given position
  278. * @param {cc.Point} pos
  279. * @return {cc.Vertex3F}
  280. */
  281. vertex:function (pos) {
  282. if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
  283. cc.log("cc.Grid3D.vertex() : Numbers must be integers");
  284. var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
  285. var locVertices = this._vertices;
  286. return new cc.Vertex3F(locVertices[index], locVertices[index + 1], locVertices[index + 2]);
  287. },
  288. /**
  289. * returns the original (non-transformed) vertex at a given position
  290. * @param {cc.Point} pos
  291. * @return {cc.Vertex3F}
  292. */
  293. originalVertex:function (pos) {
  294. if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
  295. cc.log("cc.Grid3D.originalVertex() : Numbers must be integers");
  296. var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
  297. var locOriginalVertices = this._originalVertices;
  298. return new cc.Vertex3F(locOriginalVertices[index], locOriginalVertices[index + 1], locOriginalVertices[index + 2]);
  299. },
  300. /**
  301. * sets a new vertex at a given position
  302. * @param {cc.Point} pos
  303. * @param {cc.Vertex3F} vertex
  304. */
  305. setVertex:function (pos, vertex) {
  306. if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
  307. cc.log("cc.Grid3D.setVertex() : Numbers must be integers");
  308. var index = 0 | ((pos.x * (this._gridSize.height + 1) + pos.y) * 3);
  309. var vertArray = this._vertices;
  310. vertArray[index] = vertex.x;
  311. vertArray[index + 1] = vertex.y;
  312. vertArray[index + 2] = vertex.z;
  313. this._dirty = true;
  314. },
  315. blit:function () {
  316. var n = this._gridSize.width * this._gridSize.height;
  317. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS);
  318. this._shaderProgram.use();
  319. this._shaderProgram.setUniformsForBuiltins();
  320. var gl = cc._renderContext, locDirty = this._dirty;
  321. //
  322. // Attributes
  323. //
  324. // position
  325. gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
  326. if (locDirty)
  327. gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
  328. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, 0);
  329. // texCoords
  330. gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
  331. if (locDirty)
  332. gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
  333. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, 0);
  334. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
  335. if (locDirty)
  336. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
  337. gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0);
  338. if (locDirty)
  339. this._dirty = false;
  340. cc.incrementGLDraws(1);
  341. },
  342. reuse:function () {
  343. if (this._reuseGrid > 0) {
  344. var locOriginalVertices = this._originalVertices, locVertices = this._vertices;
  345. for (var i = 0, len = this._vertices.length; i < len; i++)
  346. locOriginalVertices[i] = locVertices[i];
  347. --this._reuseGrid;
  348. }
  349. },
  350. calculateVertexPoints:function () {
  351. var gl = cc._renderContext;
  352. var width = this._texture.pixelsWidth;
  353. var height = this._texture.pixelsHeight;
  354. var imageH = this._texture.getContentSizeInPixels().height;
  355. var locGridSize = this._gridSize;
  356. var numOfPoints = (locGridSize.width + 1) * (locGridSize.height + 1);
  357. this._vertices = new Float32Array(numOfPoints * 3);
  358. this._texCoordinates = new Float32Array(numOfPoints * 2);
  359. this._indices = new Uint16Array(locGridSize.width * locGridSize.height * 6);
  360. if(this._verticesBuffer)
  361. gl.deleteBuffer(this._verticesBuffer);
  362. this._verticesBuffer = gl.createBuffer();
  363. if(this._texCoordinateBuffer)
  364. gl.deleteBuffer(this._texCoordinateBuffer);
  365. this._texCoordinateBuffer = gl.createBuffer();
  366. if(this._indicesBuffer)
  367. gl.deleteBuffer(this._indicesBuffer);
  368. this._indicesBuffer = gl.createBuffer();
  369. var x, y, i, locIndices = this._indices, locTexCoordinates = this._texCoordinates;
  370. var locIsTextureFlipped = this._isTextureFlipped, locVertices = this._vertices;
  371. for (x = 0; x < locGridSize.width; ++x) {
  372. for (y = 0; y < locGridSize.height; ++y) {
  373. var idx = (y * locGridSize.width) + x;
  374. var x1 = x * this._step.x;
  375. var x2 = x1 + this._step.x;
  376. var y1 = y * this._step.y;
  377. var y2 = y1 + this._step.y;
  378. var a = (x * (locGridSize.height + 1) + y);
  379. var b = ((x + 1) * (locGridSize.height + 1) + y);
  380. var c = ((x + 1) * (locGridSize.height + 1) + (y + 1));
  381. var d = (x * (locGridSize.height + 1) + (y + 1));
  382. locIndices[idx * 6] = a;
  383. locIndices[idx * 6 + 1] = b;
  384. locIndices[idx * 6 + 2] = d;
  385. locIndices[idx * 6 + 3] = b;
  386. locIndices[idx * 6 + 4] = c;
  387. locIndices[idx * 6 + 5] = d;
  388. var l1 = [a * 3, b * 3, c * 3, d * 3];
  389. var e = {x:x1, y:y1, z:0}; //new cc.Vertex3F(x1, y1, 0);
  390. var f = {x:x2, y:y1, z:0}; //new cc.Vertex3F(x2, y1, 0);
  391. var g = {x:x2, y:y2, z:0}; // new cc.Vertex3F(x2, y2, 0);
  392. var h = {x:x1, y:y2, z:0}; //new cc.Vertex3F(x1, y2, 0);
  393. var l2 = [e, f, g, h];
  394. var tex1 = [a * 2, b * 2, c * 2, d * 2];
  395. var tex2 = [cc.p(x1, y1), cc.p(x2, y1), cc.p(x2, y2), cc.p(x1, y2)];
  396. for (i = 0; i < 4; ++i) {
  397. locVertices[l1[i]] = l2[i].x;
  398. locVertices[l1[i] + 1] = l2[i].y;
  399. locVertices[l1[i] + 2] = l2[i].z;
  400. locTexCoordinates[tex1[i]] = tex2[i].x / width;
  401. if (locIsTextureFlipped)
  402. locTexCoordinates[tex1[i] + 1] = (imageH - tex2[i].y) / height;
  403. else
  404. locTexCoordinates[tex1[i] + 1] = tex2[i].y / height;
  405. }
  406. }
  407. }
  408. this._originalVertices = new Float32Array(this._vertices);
  409. gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
  410. gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
  411. gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
  412. gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
  413. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
  414. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
  415. this._dirty = true;
  416. }
  417. });
  418. /**
  419. * create one Grid3D object
  420. * @deprecated
  421. * @param {cc.Size} gridSize
  422. * @param {cc.Texture2D} [texture=]
  423. * @param {Boolean} [flipped=]
  424. * @return {cc.Grid3D}
  425. */
  426. cc.Grid3D.create = function (gridSize, texture, flipped) {
  427. return new cc.Grid3D(gridSize, texture, flipped);
  428. };
  429. /**
  430. * cc.TiledGrid3D is a 3D grid implementation. It differs from Grid3D in that <br/>
  431. * the tiles can be separated from the grid.
  432. * @class
  433. * @extends cc.GridBase
  434. */
  435. cc.TiledGrid3D = cc.GridBase.extend(/** @lends cc.TiledGrid3D# */{
  436. _texCoordinates:null,
  437. _vertices:null,
  438. _originalVertices:null,
  439. _indices:null,
  440. _texCoordinateBuffer:null,
  441. _verticesBuffer:null,
  442. _indicesBuffer:null,
  443. /**
  444. * create one TiledGrid3D object
  445. * Constructor of cc.TiledGrid3D
  446. * @param {cc.Size} gridSize
  447. * @param {cc.Texture2D} [texture=]
  448. * @param {Boolean} [flipped=]
  449. */
  450. ctor:function (gridSize, texture, flipped) {
  451. cc.GridBase.prototype.ctor.call(this);
  452. this._texCoordinates=null;
  453. this._vertices=null;
  454. this._originalVertices=null;
  455. this._indices=null;
  456. this._texCoordinateBuffer=null;
  457. this._verticesBuffer=null;
  458. this._indicesBuffer=null;
  459. if(gridSize !== undefined)
  460. this.initWithSize(gridSize, texture, flipped);
  461. },
  462. /**
  463. * returns the tile at the given position
  464. * @param {cc.Point} pos
  465. * @return {cc.Quad3}
  466. */
  467. tile:function (pos) {
  468. if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
  469. cc.log("cc.TiledGrid3D.tile() : Numbers must be integers");
  470. var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3;
  471. var locVertices = this._vertices;
  472. return new cc.Quad3(new cc.Vertex3F(locVertices[idx], locVertices[idx + 1], locVertices[idx + 2]),
  473. new cc.Vertex3F(locVertices[idx + 3], locVertices[idx + 4], locVertices[idx + 5]),
  474. new cc.Vertex3F(locVertices[idx + 6 ], locVertices[idx + 7], locVertices[idx + 8]),
  475. new cc.Vertex3F(locVertices[idx + 9], locVertices[idx + 10], locVertices[idx + 11]));
  476. },
  477. /**
  478. * returns the original tile (untransformed) at the given position
  479. * @param {cc.Point} pos
  480. * @return {cc.Quad3}
  481. */
  482. originalTile:function (pos) {
  483. if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
  484. cc.log("cc.TiledGrid3D.originalTile() : Numbers must be integers");
  485. var idx = (this._gridSize.height * pos.x + pos.y) * 4 * 3;
  486. var locOriginalVertices = this._originalVertices;
  487. return new cc.Quad3(new cc.Vertex3F(locOriginalVertices[idx], locOriginalVertices[idx + 1], locOriginalVertices[idx + 2]),
  488. new cc.Vertex3F(locOriginalVertices[idx + 3], locOriginalVertices[idx + 4], locOriginalVertices[idx + 5]),
  489. new cc.Vertex3F(locOriginalVertices[idx + 6 ], locOriginalVertices[idx + 7], locOriginalVertices[idx + 8]),
  490. new cc.Vertex3F(locOriginalVertices[idx + 9], locOriginalVertices[idx + 10], locOriginalVertices[idx + 11]));
  491. },
  492. /**
  493. * sets a new tile
  494. * @param {cc.Point} pos
  495. * @param {cc.Quad3} coords
  496. */
  497. setTile:function (pos, coords) {
  498. if(pos.x !== (0| pos.x) || pos.y !== (0| pos.y))
  499. cc.log("cc.TiledGrid3D.setTile() : Numbers must be integers");
  500. var idx = (this._gridSize.height * pos.x + pos.y) * 12;
  501. var locVertices = this._vertices;
  502. locVertices[idx] = coords.bl.x;
  503. locVertices[idx + 1] = coords.bl.y;
  504. locVertices[idx + 2] = coords.bl.z;
  505. locVertices[idx + 3] = coords.br.x;
  506. locVertices[idx + 4] = coords.br.y;
  507. locVertices[idx + 5] = coords.br.z;
  508. locVertices[idx + 6] = coords.tl.x;
  509. locVertices[idx + 7] = coords.tl.y;
  510. locVertices[idx + 8] = coords.tl.z;
  511. locVertices[idx + 9] = coords.tr.x;
  512. locVertices[idx + 10] = coords.tr.y;
  513. locVertices[idx + 11] = coords.tr.z;
  514. this._dirty = true;
  515. },
  516. blit:function () {
  517. var n = this._gridSize.width * this._gridSize.height;
  518. this._shaderProgram.use();
  519. this._shaderProgram.setUniformsForBuiltins();
  520. //
  521. // Attributes
  522. //
  523. var gl = cc._renderContext, locDirty = this._dirty;
  524. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS);
  525. // position
  526. gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
  527. if (locDirty)
  528. gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
  529. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 0, this._vertices);
  530. // texCoords
  531. gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
  532. if (locDirty)
  533. gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
  534. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, this._texCoordinates);
  535. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
  536. if (locDirty)
  537. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.STATIC_DRAW);
  538. gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, 0);
  539. if (locDirty)
  540. this._dirty = false;
  541. cc.incrementGLDraws(1);
  542. },
  543. reuse:function () {
  544. if (this._reuseGrid > 0) {
  545. var locVertices = this._vertices, locOriginalVertices = this._originalVertices;
  546. for (var i = 0; i < locVertices.length; i++)
  547. locOriginalVertices[i] = locVertices[i];
  548. --this._reuseGrid;
  549. }
  550. },
  551. calculateVertexPoints:function () {
  552. var width = this._texture.pixelsWidth;
  553. var height = this._texture.pixelsHeight;
  554. var imageH = this._texture.getContentSizeInPixels().height;
  555. var locGridSize = this._gridSize;
  556. var numQuads = locGridSize.width * locGridSize.height;
  557. this._vertices = new Float32Array(numQuads * 12);
  558. this._texCoordinates = new Float32Array(numQuads * 8);
  559. this._indices = new Uint16Array(numQuads * 6);
  560. var gl = cc._renderContext;
  561. if(this._verticesBuffer)
  562. gl.deleteBuffer(this._verticesBuffer);
  563. this._verticesBuffer = gl.createBuffer();
  564. if(this._texCoordinateBuffer)
  565. gl.deleteBuffer(this._texCoordinateBuffer);
  566. this._texCoordinateBuffer = gl.createBuffer();
  567. if(this._indicesBuffer)
  568. gl.deleteBuffer(this._indicesBuffer);
  569. this._indicesBuffer = gl.createBuffer();
  570. var x, y, i = 0;
  571. var locStep = this._step, locVertices = this._vertices, locTexCoords = this._texCoordinates, locIsTextureFlipped = this._isTextureFlipped;
  572. for (x = 0; x < locGridSize.width; x++) {
  573. for (y = 0; y < locGridSize.height; y++) {
  574. var x1 = x * locStep.x;
  575. var x2 = x1 + locStep.x;
  576. var y1 = y * locStep.y;
  577. var y2 = y1 + locStep.y;
  578. locVertices[i * 12] = x1;
  579. locVertices[i * 12 + 1] = y1;
  580. locVertices[i * 12 + 2] = 0;
  581. locVertices[i * 12 + 3] = x2;
  582. locVertices[i * 12 + 4] = y1;
  583. locVertices[i * 12 + 5] = 0;
  584. locVertices[i * 12 + 6] = x1;
  585. locVertices[i * 12 + 7] = y2;
  586. locVertices[i * 12 + 8] = 0;
  587. locVertices[i * 12 + 9] = x2;
  588. locVertices[i * 12 + 10] = y2;
  589. locVertices[i * 12 + 11] = 0;
  590. var newY1 = y1;
  591. var newY2 = y2;
  592. if (locIsTextureFlipped) {
  593. newY1 = imageH - y1;
  594. newY2 = imageH - y2;
  595. }
  596. locTexCoords[i * 8] = x1 / width;
  597. locTexCoords[i * 8 + 1] = newY1 / height;
  598. locTexCoords[i * 8 + 2] = x2 / width;
  599. locTexCoords[i * 8 + 3] = newY1 / height;
  600. locTexCoords[i * 8 + 4] = x1 / width;
  601. locTexCoords[i * 8 + 5] = newY2 / height;
  602. locTexCoords[i * 8 + 6] = x2 / width;
  603. locTexCoords[i * 8 + 7] = newY2 / height;
  604. i++;
  605. }
  606. }
  607. var locIndices = this._indices;
  608. for (x = 0; x < numQuads; x++) {
  609. locIndices[x * 6 + 0] = (x * 4 + 0);
  610. locIndices[x * 6 + 1] = (x * 4 + 1);
  611. locIndices[x * 6 + 2] = (x * 4 + 2);
  612. locIndices[x * 6 + 3] = (x * 4 + 1);
  613. locIndices[x * 6 + 4] = (x * 4 + 2);
  614. locIndices[x * 6 + 5] = (x * 4 + 3);
  615. }
  616. this._originalVertices = new Float32Array(this._vertices);
  617. gl.bindBuffer(gl.ARRAY_BUFFER, this._verticesBuffer);
  618. gl.bufferData(gl.ARRAY_BUFFER, this._vertices, gl.DYNAMIC_DRAW);
  619. gl.bindBuffer(gl.ARRAY_BUFFER, this._texCoordinateBuffer);
  620. gl.bufferData(gl.ARRAY_BUFFER, this._texCoordinates, gl.DYNAMIC_DRAW);
  621. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indicesBuffer);
  622. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this._indices, gl.DYNAMIC_DRAW);
  623. this._dirty = true;
  624. }
  625. });
  626. /**
  627. * create one TiledGrid3D object
  628. * @deprecated since v3.0, plese use new cc.TiledGrid3D(gridSize, texture, flipped) instead
  629. * @param {cc.Size} gridSize
  630. * @param {cc.Texture2D} [texture=]
  631. * @param {Boolean} [flipped=]
  632. * @return {cc.TiledGrid3D}
  633. */
  634. cc.TiledGrid3D.create = function (gridSize, texture, flipped) {
  635. return new cc.TiledGrid3D(gridSize, texture, flipped);
  636. };