TexturesWebGL.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  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. http://www.cocos2d-x.org
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. THE SOFTWARE.
  21. ****************************************************************************/
  22. cc._tmp.WebGLTexture2D = function () {
  23. /**
  24. * <p>
  25. * This class allows to easily create OpenGL or Canvas 2D textures from images, text or raw data. <br/>
  26. * The created cc.Texture2D object will always have power-of-two dimensions. <br/>
  27. * Depending on how you create the cc.Texture2D object, the actual image area of the texture might be smaller than the texture dimensions <br/>
  28. * i.e. "contentSize" != (pixelsWide, pixelsHigh) and (maxS, maxT) != (1.0, 1.0). <br/>
  29. * Be aware that the content of the generated textures will be upside-down! </p>
  30. * @name cc.Texture2D
  31. * @class
  32. * @extends cc.Class
  33. *
  34. * @property {WebGLTexture} name - <@readonly> WebGLTexture Object
  35. * @property {Number} defaultPixelFormat - The default pixel format
  36. * @property {Number} pixelFormat - <@readonly> Pixel format of the texture
  37. * @property {Number} pixelsWidth - <@readonly> Width in pixels
  38. * @property {Number} pixelsHeight - <@readonly> Height in pixels
  39. * @property {Number} width - Content width in points
  40. * @property {Number} height - Content height in points
  41. * @property {cc.GLProgram} shaderProgram - The shader program used by drawAtPoint and drawInRect
  42. * @property {Number} maxS - Texture max S
  43. * @property {Number} maxT - Texture max T
  44. */
  45. //Original : Texture2DWebGL
  46. cc.Texture2D = cc.Class.extend(/** @lends cc.Texture2D# */{
  47. // By default PVR images are treated as if they don't have the alpha channel premultiplied
  48. _pVRHaveAlphaPremultiplied: true,
  49. _pixelFormat: null,
  50. _pixelsWide: 0,
  51. _pixelsHigh: 0,
  52. _name: "",
  53. _contentSize: null,
  54. maxS: 0,
  55. maxT: 0,
  56. _hasPremultipliedAlpha: false,
  57. _hasMipmaps: false,
  58. shaderProgram: null,
  59. _isLoaded: false,
  60. _htmlElementObj: null,
  61. _webTextureObj: null,
  62. url: null,
  63. _loadedEventListeners: null,
  64. /**
  65. * constructor of cc.Texture2D
  66. */
  67. ctor: function () {
  68. this._contentSize = cc.size(0, 0);
  69. this._pixelFormat = cc.Texture2D.defaultPixelFormat;
  70. },
  71. /**
  72. * release texture
  73. */
  74. releaseTexture: function () {
  75. if (this._webTextureObj)
  76. cc._renderContext.deleteTexture(this._webTextureObj);
  77. cc.loader.release(this.url);
  78. },
  79. /**
  80. * pixel format of the texture
  81. * @return {Number}
  82. */
  83. getPixelFormat: function () {
  84. return this._pixelFormat;
  85. },
  86. /**
  87. * width in pixels
  88. * @return {Number}
  89. */
  90. getPixelsWide: function () {
  91. return this._pixelsWide;
  92. },
  93. /**
  94. * height in pixels
  95. * @return {Number}
  96. */
  97. getPixelsHigh: function () {
  98. return this._pixelsHigh;
  99. },
  100. /**
  101. * get WebGLTexture Object
  102. * @return {WebGLTexture}
  103. */
  104. getName: function () {
  105. return this._webTextureObj;
  106. },
  107. /**
  108. * content size
  109. * @return {cc.Size}
  110. */
  111. getContentSize: function () {
  112. return cc.size(this._contentSize.width / cc.contentScaleFactor(), this._contentSize.height / cc.contentScaleFactor());
  113. },
  114. _getWidth: function () {
  115. return this._contentSize.width / cc.contentScaleFactor();
  116. },
  117. _getHeight: function () {
  118. return this._contentSize.height / cc.contentScaleFactor();
  119. },
  120. /**
  121. * get content size in pixels
  122. * @return {cc.Size}
  123. */
  124. getContentSizeInPixels: function () {
  125. return this._contentSize;
  126. },
  127. /**
  128. * texture max S
  129. * @return {Number}
  130. */
  131. getMaxS: function () {
  132. return this.maxS;
  133. },
  134. /**
  135. * set texture max S
  136. * @param {Number} maxS
  137. */
  138. setMaxS: function (maxS) {
  139. this.maxS = maxS;
  140. },
  141. /**
  142. * get texture max T
  143. * @return {Number}
  144. */
  145. getMaxT: function () {
  146. return this.maxT;
  147. },
  148. /**
  149. * set texture max T
  150. * @param {Number} maxT
  151. */
  152. setMaxT: function (maxT) {
  153. this.maxT = maxT;
  154. },
  155. /**
  156. * return shader program used by drawAtPoint and drawInRect
  157. * @return {cc.GLProgram}
  158. */
  159. getShaderProgram: function () {
  160. return this.shaderProgram;
  161. },
  162. /**
  163. * set shader program used by drawAtPoint and drawInRect
  164. * @param {cc.GLProgram} shaderProgram
  165. */
  166. setShaderProgram: function (shaderProgram) {
  167. this.shaderProgram = shaderProgram;
  168. },
  169. /**
  170. * whether or not the texture has their Alpha premultiplied
  171. * @return {Boolean}
  172. */
  173. hasPremultipliedAlpha: function () {
  174. return this._hasPremultipliedAlpha;
  175. },
  176. /**
  177. * whether or not use mipmap
  178. * @return {Boolean}
  179. */
  180. hasMipmaps: function () {
  181. return this._hasMipmaps;
  182. },
  183. /**
  184. * description
  185. * @return {string}
  186. */
  187. description: function () {
  188. var _t = this;
  189. return "<cc.Texture2D | Name = " + _t._name + " | Dimensions = " + _t._pixelsWide + " x " + _t._pixelsHigh
  190. + " | Coordinates = (" + _t.maxS + ", " + _t.maxT + ")>";
  191. },
  192. /**
  193. * These functions are needed to create mutable textures
  194. * @param {Array} data
  195. */
  196. releaseData: function (data) {
  197. data = null;
  198. },
  199. keepData: function (data, length) {
  200. //The texture data mustn't be saved becuase it isn't a mutable texture.
  201. return data;
  202. },
  203. /**
  204. * Intializes with a texture2d with data
  205. * @param {Array} data
  206. * @param {Number} pixelFormat
  207. * @param {Number} pixelsWide
  208. * @param {Number} pixelsHigh
  209. * @param {cc.Size} contentSize
  210. * @return {Boolean}
  211. */
  212. initWithData: function (data, pixelFormat, pixelsWide, pixelsHigh, contentSize) {
  213. var self = this, tex2d = cc.Texture2D;
  214. var gl = cc._renderContext;
  215. var format = gl.RGBA, type = gl.UNSIGNED_BYTE;
  216. var bitsPerPixel = cc.Texture2D._B[pixelFormat];
  217. var bytesPerRow = pixelsWide * bitsPerPixel / 8;
  218. if (bytesPerRow % 8 === 0) {
  219. gl.pixelStorei(gl.UNPACK_ALIGNMENT, 8);
  220. } else if (bytesPerRow % 4 === 0) {
  221. gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
  222. } else if (bytesPerRow % 2 === 0) {
  223. gl.pixelStorei(gl.UNPACK_ALIGNMENT, 2);
  224. } else {
  225. gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  226. }
  227. self._webTextureObj = gl.createTexture();
  228. cc.glBindTexture2D(self);
  229. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  230. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  231. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  232. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  233. // Specify OpenGL texture image
  234. switch (pixelFormat) {
  235. case tex2d.PIXEL_FORMAT_RGBA8888:
  236. format = gl.RGBA;
  237. break;
  238. case tex2d.PIXEL_FORMAT_RGB888:
  239. format = gl.RGB;
  240. break;
  241. case tex2d.PIXEL_FORMAT_RGBA4444:
  242. type = gl.UNSIGNED_SHORT_4_4_4_4;
  243. break;
  244. case tex2d.PIXEL_FORMAT_RGB5A1:
  245. type = gl.UNSIGNED_SHORT_5_5_5_1;
  246. break;
  247. case tex2d.PIXEL_FORMAT_RGB565:
  248. type = gl.UNSIGNED_SHORT_5_6_5;
  249. break;
  250. case tex2d.PIXEL_FORMAT_AI88:
  251. format = gl.LUMINANCE_ALPHA;
  252. break;
  253. case tex2d.PIXEL_FORMAT_A8:
  254. format = gl.ALPHA;
  255. break;
  256. case tex2d.PIXEL_FORMAT_I8:
  257. format = gl.LUMINANCE;
  258. break;
  259. default:
  260. cc.assert(0, cc._LogInfos.Texture2D_initWithData);
  261. }
  262. gl.texImage2D(gl.TEXTURE_2D, 0, format, pixelsWide, pixelsHigh, 0, format, type, data);
  263. self._contentSize.width = contentSize.width;
  264. self._contentSize.height = contentSize.height;
  265. self._pixelsWide = pixelsWide;
  266. self._pixelsHigh = pixelsHigh;
  267. self._pixelFormat = pixelFormat;
  268. self.maxS = contentSize.width / pixelsWide;
  269. self.maxT = contentSize.height / pixelsHigh;
  270. self._hasPremultipliedAlpha = false;
  271. self._hasMipmaps = false;
  272. self.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
  273. self._isLoaded = true;
  274. return true;
  275. },
  276. /**
  277. Drawing extensions to make it easy to draw basic quads using a CCTexture2D object.
  278. These functions require gl.TEXTURE_2D and both gl.VERTEX_ARRAY and gl.TEXTURE_COORD_ARRAY client states to be enabled.
  279. */
  280. /**
  281. * draws a texture at a given point
  282. * @param {cc.Point} point
  283. */
  284. drawAtPoint: function (point) {
  285. var self = this;
  286. var coordinates = [
  287. 0.0, self.maxT,
  288. self.maxS, self.maxT,
  289. 0.0, 0.0,
  290. self.maxS, 0.0 ];
  291. var width = self._pixelsWide * self.maxS,
  292. height = self._pixelsHigh * self.maxT;
  293. var vertices = [
  294. point.x, point.y, 0.0,
  295. width + point.x, point.y, 0.0,
  296. point.x, height + point.y, 0.0,
  297. width + point.x, height + point.y, 0.0 ];
  298. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS);
  299. self._shaderProgram.use();
  300. self._shaderProgram.setUniformsForBuiltins();
  301. cc.glBindTexture2D(self);
  302. var gl = cc._renderContext;
  303. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, 0, vertices);
  304. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, coordinates);
  305. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  306. },
  307. /**
  308. * draws a texture inside a rect
  309. * @param {cc.Rect} rect
  310. */
  311. drawInRect: function (rect) {
  312. var self = this;
  313. var coordinates = [
  314. 0.0, self.maxT,
  315. self.maxS, self.maxT,
  316. 0.0, 0.0,
  317. self.maxS, 0.0];
  318. var vertices = [ rect.x, rect.y, /*0.0,*/
  319. rect.x + rect.width, rect.y, /*0.0,*/
  320. rect.x, rect.y + rect.height, /*0.0,*/
  321. rect.x + rect.width, rect.y + rect.height /*0.0*/ ];
  322. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS);
  323. self._shaderProgram.use();
  324. self._shaderProgram.setUniformsForBuiltins();
  325. cc.glBindTexture2D(self);
  326. var gl = cc._renderContext;
  327. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, gl.FLOAT, false, 0, vertices);
  328. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 0, coordinates);
  329. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  330. },
  331. /**
  332. Extensions to make it easy to create a CCTexture2D object from an image file.
  333. Note that RGBA type textures will have their alpha premultiplied - use the blending mode (gl.ONE, gl.ONE_MINUS_SRC_ALPHA).
  334. */
  335. /**
  336. * Initializes a texture from a UIImage object
  337. * @param uiImage
  338. * @return {Boolean}
  339. */
  340. initWithImage: function (uiImage) {
  341. if (uiImage == null) {
  342. cc.log(cc._LogInfos.Texture2D_initWithImage);
  343. return false;
  344. }
  345. var imageWidth = uiImage.getWidth();
  346. var imageHeight = uiImage.getHeight();
  347. var maxTextureSize = cc.configuration.getMaxTextureSize();
  348. if (imageWidth > maxTextureSize || imageHeight > maxTextureSize) {
  349. cc.log(cc._LogInfos.Texture2D_initWithImage_2, imageWidth, imageHeight, maxTextureSize, maxTextureSize);
  350. return false;
  351. }
  352. this._isLoaded = true;
  353. // always load premultiplied images
  354. return this._initPremultipliedATextureWithImage(uiImage, imageWidth, imageHeight);
  355. },
  356. /**
  357. * init with HTML element
  358. * @param {HTMLImageElement|HTMLCanvasElement} element
  359. */
  360. initWithElement: function (element) {
  361. if (!element)
  362. return;
  363. this._webTextureObj = cc._renderContext.createTexture();
  364. this._htmlElementObj = element;
  365. },
  366. /**
  367. * HTMLElement Object getter
  368. * @return {HTMLElement}
  369. */
  370. getHtmlElementObj: function () {
  371. return this._htmlElementObj;
  372. },
  373. /**
  374. * whether texture is loaded
  375. * @return {Boolean}
  376. */
  377. isLoaded: function () {
  378. return this._isLoaded;
  379. },
  380. /**
  381. * handler of texture loaded event
  382. */
  383. handleLoadedTexture: function () {
  384. var self = this;
  385. // Not sure about this ! Some texture need to be updated even after loaded
  386. if (!cc._rendererInitialized) return;
  387. if (!self._htmlElementObj) {
  388. var img = cc.loader.getRes(self.url);
  389. if (!img) return;
  390. self.initWithElement(img);
  391. }
  392. if (!self._htmlElementObj.width || !self._htmlElementObj.height) {
  393. return;
  394. }
  395. self._isLoaded = true;
  396. //upload image to buffer
  397. var gl = cc._renderContext;
  398. cc.glBindTexture2D(self);
  399. gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
  400. // Specify OpenGL texture image
  401. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self._htmlElementObj);
  402. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  403. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  404. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  405. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  406. self.shaderProgram = cc.shaderCache.programForKey(cc.SHADER_POSITION_TEXTURE);
  407. cc.glBindTexture2D(null);
  408. var pixelsWide = self._htmlElementObj.width;
  409. var pixelsHigh = self._htmlElementObj.height;
  410. self._pixelsWide = self._contentSize.width = pixelsWide;
  411. self._pixelsHigh = self._contentSize.height = pixelsHigh;
  412. self._pixelFormat = cc.Texture2D.PIXEL_FORMAT_RGBA8888;
  413. self.maxS = 1;
  414. self.maxT = 1;
  415. self._hasPremultipliedAlpha = false;
  416. self._hasMipmaps = false;
  417. this._callLoadedEventCallbacks();
  418. },
  419. /**
  420. Extensions to make it easy to create a cc.Texture2D object from a string of text.
  421. Note that the generated textures are of type A8 - use the blending mode (gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA).
  422. */
  423. /**
  424. * Initializes a texture from a string with dimensions, alignment, font name and font size (note: initWithString does not support on HTML5)
  425. * @param {String} text
  426. * @param {String | cc.FontDefinition} fontName or fontDefinition
  427. * @param {Number} fontSize
  428. * @param {cc.Size} dimensions
  429. * @param {Number} hAlignment
  430. * @param {Number} vAlignment
  431. * @return {Boolean}
  432. */
  433. initWithString: function (text, fontName, fontSize, dimensions, hAlignment, vAlignment) {
  434. cc.log(cc._LogInfos.Texture2D_initWithString);
  435. return null;
  436. },
  437. /**
  438. * Initializes a texture from a ETC file (note: initWithETCFile does not support on HTML5)
  439. * @note Compatible to Cocos2d-x
  440. * @param {String} file
  441. * @return {Boolean}
  442. */
  443. initWithETCFile: function (file) {
  444. cc.log(cc._LogInfos.Texture2D_initWithETCFile_2);
  445. return false;
  446. },
  447. /**
  448. * Initializes a texture from a PVR file
  449. * @param {String} file
  450. * @return {Boolean}
  451. */
  452. initWithPVRFile: function (file) {
  453. cc.log(cc._LogInfos.Texture2D_initWithPVRFile_2);
  454. return false;
  455. },
  456. /**
  457. Extensions to make it easy to create a cc.Texture2D object from a PVRTC file
  458. Note that the generated textures don't have their alpha premultiplied - use the blending mode (gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA).
  459. */
  460. /**
  461. * Initializes a texture from a PVRTC buffer
  462. * @note compatible to cocos2d-iphone interface.
  463. * @param {Array} data
  464. * @param {Number} level
  465. * @param {Number} bpp
  466. * @param {Boolean} hasAlpha
  467. * @param {Number} length
  468. * @param {Number} pixelFormat
  469. * @return {Boolean}
  470. */
  471. initWithPVRTCData: function (data, level, bpp, hasAlpha, length, pixelFormat) {
  472. cc.log(cc._LogInfos.Texture2D_initWithPVRTCData_2);
  473. return false;
  474. },
  475. /**
  476. * sets the min filter, mag filter, wrap s and wrap t texture parameters. <br/>
  477. * If the texture size is NPOT (non power of 2), then in can only use gl.CLAMP_TO_EDGE in gl.TEXTURE_WRAP_{S,T}.
  478. * @param {Object|Number} texParams texParams object or minFilter
  479. * @param {Number} [magFilter]
  480. * @param {Number} [wrapS]
  481. * @param {Number} [wrapT]
  482. */
  483. setTexParameters: function (texParams, magFilter, wrapS, wrapT) {
  484. var _t = this;
  485. var gl = cc._renderContext;
  486. if(magFilter !== undefined)
  487. texParams = {minFilter: texParams, magFilter: magFilter, wrapS: wrapS, wrapT: wrapT};
  488. cc.assert((_t._pixelsWide == cc.NextPOT(_t._pixelsWide) && _t._pixelsHigh == cc.NextPOT(_t._pixelsHigh)) ||
  489. (texParams.wrapS == gl.CLAMP_TO_EDGE && texParams.wrapT == gl.CLAMP_TO_EDGE),
  490. "WebGLRenderingContext.CLAMP_TO_EDGE should be used in NPOT textures");
  491. cc.glBindTexture2D(_t);
  492. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texParams.minFilter);
  493. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texParams.magFilter);
  494. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, texParams.wrapS);
  495. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, texParams.wrapT);
  496. //TODO
  497. //VolatileTexture::setTexParameters(_t, texParams);
  498. },
  499. /**
  500. * sets antialias texture parameters: <br/>
  501. * - GL_TEXTURE_MIN_FILTER = GL_NEAREST <br/>
  502. * - GL_TEXTURE_MAG_FILTER = GL_NEAREST
  503. */
  504. setAntiAliasTexParameters: function () {
  505. var gl = cc._renderContext;
  506. cc.glBindTexture2D(this);
  507. if (!this._hasMipmaps)
  508. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  509. else
  510. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
  511. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  512. //TODO
  513. /*#if CC_ENABLE_CACHE_TEXTURE_DATA
  514. ccTexParams texParams = {m_bHasMipmaps?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR,GL_LINEAR,GL_NONE,GL_NONE};
  515. VolatileTexture::setTexParameters(this, &texParams);
  516. #endif*/
  517. },
  518. /**
  519. * sets alias texture parameters:
  520. * GL_TEXTURE_MIN_FILTER = GL_NEAREST
  521. * GL_TEXTURE_MAG_FILTER = GL_NEAREST
  522. */
  523. setAliasTexParameters: function () {
  524. var gl = cc._renderContext;
  525. cc.glBindTexture2D(this);
  526. if (!this._hasMipmaps)
  527. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  528. else
  529. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST);
  530. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  531. //TODO
  532. /*#if CC_ENABLE_CACHE_TEXTURE_DATA
  533. ccTexParams texParams = {m_bHasMipmaps?GL_NEAREST_MIPMAP_NEAREST:GL_NEAREST,GL_NEAREST,GL_NONE,GL_NONE};
  534. VolatileTexture::setTexParameters(this, &texParams);
  535. #endif*/
  536. },
  537. /**
  538. * Generates mipmap images for the texture.<br/>
  539. * It only works if the texture size is POT (power of 2).
  540. */
  541. generateMipmap: function () {
  542. var _t = this;
  543. cc.assert(_t._pixelsWide == cc.NextPOT(_t._pixelsWide) && _t._pixelsHigh == cc.NextPOT(_t._pixelsHigh), "Mimpap texture only works in POT textures");
  544. cc.glBindTexture2D(_t);
  545. cc._renderContext.generateMipmap(cc._renderContext.TEXTURE_2D);
  546. _t._hasMipmaps = true;
  547. },
  548. /**
  549. * returns the pixel format.
  550. * @return {String}
  551. */
  552. stringForFormat: function () {
  553. return cc.Texture2D._M[this._pixelFormat];
  554. },
  555. /**
  556. * returns the bits-per-pixel of the in-memory OpenGL texture
  557. * @return {Number}
  558. */
  559. bitsPerPixelForFormat: function (format) {//TODO I want to delete the format argument, use this._pixelFormat
  560. format = format || this._pixelFormat;
  561. var value = cc.Texture2D._B[format];
  562. if (value != null) return value;
  563. cc.log(cc._LogInfos.Texture2D_bitsPerPixelForFormat, format);
  564. return -1;
  565. },
  566. _initPremultipliedATextureWithImage: function (uiImage, width, height) {
  567. var tex2d = cc.Texture2D;
  568. var tempData = uiImage.getData();
  569. var inPixel32 = null;
  570. var inPixel8 = null;
  571. var outPixel16 = null;
  572. var hasAlpha = uiImage.hasAlpha();
  573. var imageSize = cc.size(uiImage.getWidth(), uiImage.getHeight());
  574. var pixelFormat = tex2d.defaultPixelFormat;
  575. var bpp = uiImage.getBitsPerComponent();
  576. var i;
  577. // compute pixel format
  578. if (!hasAlpha) {
  579. if (bpp >= 8) {
  580. pixelFormat = tex2d.PIXEL_FORMAT_RGB888;
  581. } else {
  582. cc.log(cc._LogInfos.Texture2D__initPremultipliedATextureWithImage);
  583. pixelFormat = tex2d.PIXEL_FORMAT_RGB565;
  584. }
  585. }
  586. // Repack the pixel data into the right format
  587. var length = width * height;
  588. if (pixelFormat == tex2d.PIXEL_FORMAT_RGB565) {
  589. if (hasAlpha) {
  590. // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGGBBBBB"
  591. tempData = new Uint16Array(width * height);
  592. inPixel32 = uiImage.getData();
  593. for (i = 0; i < length; ++i) {
  594. tempData[i] =
  595. ((((inPixel32[i] >> 0) & 0xFF) >> 3) << 11) | // R
  596. ((((inPixel32[i] >> 8) & 0xFF) >> 2) << 5) | // G
  597. ((((inPixel32[i] >> 16) & 0xFF) >> 3) << 0); // B
  598. }
  599. } else {
  600. // Convert "RRRRRRRRRGGGGGGGGBBBBBBBB" to "RRRRRGGGGGGBBBBB"
  601. tempData = new Uint16Array(width * height);
  602. inPixel8 = uiImage.getData();
  603. for (i = 0; i < length; ++i) {
  604. tempData[i] =
  605. (((inPixel8[i] & 0xFF) >> 3) << 11) | // R
  606. (((inPixel8[i] & 0xFF) >> 2) << 5) | // G
  607. (((inPixel8[i] & 0xFF) >> 3) << 0); // B
  608. }
  609. }
  610. } else if (pixelFormat == tex2d.PIXEL_FORMAT_RGBA4444) {
  611. // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRGGGGBBBBAAAA"
  612. tempData = new Uint16Array(width * height);
  613. inPixel32 = uiImage.getData();
  614. for (i = 0; i < length; ++i) {
  615. tempData[i] =
  616. ((((inPixel32[i] >> 0) & 0xFF) >> 4) << 12) | // R
  617. ((((inPixel32[i] >> 8) & 0xFF) >> 4) << 8) | // G
  618. ((((inPixel32[i] >> 16) & 0xFF) >> 4) << 4) | // B
  619. ((((inPixel32[i] >> 24) & 0xFF) >> 4) << 0); // A
  620. }
  621. } else if (pixelFormat == tex2d.PIXEL_FORMAT_RGB5A1) {
  622. // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRGGGGGBBBBBA"
  623. tempData = new Uint16Array(width * height);
  624. inPixel32 = uiImage.getData();
  625. for (i = 0; i < length; ++i) {
  626. tempData[i] =
  627. ((((inPixel32[i] >> 0) & 0xFF) >> 3) << 11) | // R
  628. ((((inPixel32[i] >> 8) & 0xFF) >> 3) << 6) | // G
  629. ((((inPixel32[i] >> 16) & 0xFF) >> 3) << 1) | // B
  630. ((((inPixel32[i] >> 24) & 0xFF) >> 7) << 0); // A
  631. }
  632. } else if (pixelFormat == tex2d.PIXEL_FORMAT_A8) {
  633. // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "AAAAAAAA"
  634. tempData = new Uint8Array(width * height);
  635. inPixel32 = uiImage.getData();
  636. for (i = 0; i < length; ++i) {
  637. tempData[i] = (inPixel32 >> 24) & 0xFF; // A
  638. }
  639. }
  640. if (hasAlpha && pixelFormat == tex2d.PIXEL_FORMAT_RGB888) {
  641. // Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRRRRGGGGGGGGBBBBBBBB"
  642. inPixel32 = uiImage.getData();
  643. tempData = new Uint8Array(width * height * 3);
  644. for (i = 0; i < length; ++i) {
  645. tempData[i * 3] = (inPixel32 >> 0) & 0xFF; // R
  646. tempData[i * 3 + 1] = (inPixel32 >> 8) & 0xFF; // G
  647. tempData[i * 3 + 2] = (inPixel32 >> 16) & 0xFF; // B
  648. }
  649. }
  650. this.initWithData(tempData, pixelFormat, width, height, imageSize);
  651. if (tempData != uiImage.getData())
  652. tempData = null;
  653. this._hasPremultipliedAlpha = uiImage.isPremultipliedAlpha();
  654. return true;
  655. },
  656. /**
  657. * add listener of loaded event
  658. * @param {Function} callback
  659. * @param {cc.Node} target
  660. */
  661. addLoadedEventListener: function (callback, target) {
  662. if (!this._loadedEventListeners)
  663. this._loadedEventListeners = [];
  664. this._loadedEventListeners.push({eventCallback: callback, eventTarget: target});
  665. },
  666. /**
  667. * return listener of loaded event
  668. * @param {cc.Node} target
  669. */
  670. removeLoadedEventListener: function (target) {
  671. if (!this._loadedEventListeners)
  672. return;
  673. var locListeners = this._loadedEventListeners;
  674. for (var i = 0; i < locListeners.length; i++) {
  675. var selCallback = locListeners[i];
  676. if (selCallback.eventTarget == target) {
  677. locListeners.splice(i, 1);
  678. }
  679. }
  680. },
  681. _callLoadedEventCallbacks: function () {
  682. if (!this._loadedEventListeners)
  683. return;
  684. var locListeners = this._loadedEventListeners;
  685. for (var i = 0, len = locListeners.length; i < len; i++) {
  686. var selCallback = locListeners[i];
  687. selCallback.eventCallback.call(selCallback.eventTarget, this);
  688. }
  689. locListeners.length = 0;
  690. }
  691. });
  692. };
  693. cc._tmp.WebGLTextureAtlas = function () {
  694. var _p = cc.TextureAtlas.prototype;
  695. _p._setupVBO = function () {
  696. var _t = this;
  697. var gl = cc._renderContext;
  698. //create WebGLBuffer
  699. _t._buffersVBO[0] = gl.createBuffer();
  700. _t._buffersVBO[1] = gl.createBuffer();
  701. _t._quadsWebBuffer = gl.createBuffer();
  702. _t._mapBuffers();
  703. };
  704. _p._mapBuffers = function () {
  705. var _t = this;
  706. var gl = cc._renderContext;
  707. gl.bindBuffer(gl.ARRAY_BUFFER, _t._quadsWebBuffer);
  708. gl.bufferData(gl.ARRAY_BUFFER, _t._quadsArrayBuffer, gl.DYNAMIC_DRAW);
  709. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _t._buffersVBO[1]);
  710. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, _t._indices, gl.STATIC_DRAW);
  711. //cc.checkGLErrorDebug();
  712. };
  713. /**
  714. * <p>Draws n quads from an index (offset). <br />
  715. * n + start can't be greater than the capacity of the atlas</p>
  716. * @param {Number} n
  717. * @param {Number} start
  718. */
  719. _p.drawNumberOfQuads = function (n, start) {
  720. var _t = this;
  721. start = start || 0;
  722. if (0 === n || !_t.texture || !_t.texture.isLoaded())
  723. return;
  724. var gl = cc._renderContext;
  725. cc.glBindTexture2D(_t.texture);
  726. //
  727. // Using VBO without VAO
  728. //
  729. //vertices
  730. //gl.bindBuffer(gl.ARRAY_BUFFER, _t._buffersVBO[0]);
  731. // XXX: update is done in draw... perhaps it should be done in a timer
  732. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX);
  733. gl.bindBuffer(gl.ARRAY_BUFFER, _t._quadsWebBuffer);
  734. if (_t.dirty)
  735. gl.bufferData(gl.ARRAY_BUFFER, _t._quadsArrayBuffer, gl.DYNAMIC_DRAW);
  736. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 3, gl.FLOAT, false, 24, 0); // vertices
  737. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_COLOR, 4, gl.UNSIGNED_BYTE, true, 24, 12); // colors
  738. gl.vertexAttribPointer(cc.VERTEX_ATTRIB_TEX_COORDS, 2, gl.FLOAT, false, 24, 16); // tex coords
  739. if (_t.dirty)
  740. _t.dirty = false;
  741. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, _t._buffersVBO[1]);
  742. if (cc.TEXTURE_ATLAS_USE_TRIANGLE_STRIP)
  743. gl.drawElements(gl.TRIANGLE_STRIP, n * 6, gl.UNSIGNED_SHORT, start * 6 * _t._indices.BYTES_PER_ELEMENT);
  744. else
  745. gl.drawElements(gl.TRIANGLES, n * 6, gl.UNSIGNED_SHORT, start * 6 * _t._indices.BYTES_PER_ELEMENT);
  746. cc.g_NumberOfDraws++;
  747. //cc.checkGLErrorDebug();
  748. };
  749. };
  750. cc._tmp.WebGLTextureCache = function () {
  751. var _p = cc.textureCache;
  752. _p.handleLoadedTexture = function (url) {
  753. var locTexs = this._textures;
  754. //remove judge(webgl)
  755. if (!cc._rendererInitialized) {
  756. locTexs = this._loadedTexturesBefore;
  757. }
  758. var tex = locTexs[url];
  759. if (!tex) {
  760. tex = locTexs[url] = new cc.Texture2D();
  761. tex.url = url;
  762. }
  763. tex.handleLoadedTexture();
  764. };
  765. /**
  766. * <p>Returns a Texture2D object given an file image <br />
  767. * If the file image was not previously loaded, it will create a new Texture2D <br />
  768. * object and it will return it. It will use the filename as a key.<br />
  769. * Otherwise it will return a reference of a previously loaded image. <br />
  770. * Supported image extensions: .png, .jpg, .gif</p>
  771. * @param {String} url
  772. * @param {Function} cb
  773. * @param {Object} target
  774. * @return {cc.Texture2D}
  775. * @example
  776. * //example
  777. * cc.textureCache.addImage("hello.png");
  778. */
  779. _p.addImage = function (url, cb, target) {
  780. cc.assert(url, cc._LogInfos.Texture2D_addImage_2);
  781. var locTexs = this._textures;
  782. //remove judge(webgl)
  783. if (!cc._rendererInitialized) {
  784. locTexs = this._loadedTexturesBefore;
  785. }
  786. var tex = locTexs[url] || locTexs[cc.loader._aliases[url]];
  787. if (tex) {
  788. cb && cb.call(target);
  789. return tex;
  790. }
  791. if (!cc.loader.getRes(url)) {
  792. if (cc.loader._checkIsImageURL(url)) {
  793. cc.loader.load(url, function (err) {
  794. cb && cb.call(target);
  795. });
  796. } else {
  797. cc.loader.cache[url] = cc.loader.loadImg(url, function (err, img) {
  798. if (err)
  799. return cb ? cb(err) : err;
  800. cc.textureCache.handleLoadedTexture(url);
  801. cb && cb(target, img);
  802. });
  803. }
  804. }
  805. tex = locTexs[url] = new cc.Texture2D();
  806. tex.url = url;
  807. return tex;
  808. };
  809. delete _p;
  810. }