PixelFormat.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. import PixelDatatype from '../Renderer/PixelDatatype.js';
  2. import freezeObject from './freezeObject.js';
  3. import WebGLConstants from './WebGLConstants.js';
  4. /**
  5. * The format of a pixel, i.e., the number of components it has and what they represent.
  6. *
  7. * @exports PixelFormat
  8. */
  9. var PixelFormat = {
  10. /**
  11. * A pixel format containing a depth value.
  12. *
  13. * @type {Number}
  14. * @constant
  15. */
  16. DEPTH_COMPONENT : WebGLConstants.DEPTH_COMPONENT,
  17. /**
  18. * A pixel format containing a depth and stencil value, most often used with {@link PixelDatatype.UNSIGNED_INT_24_8}.
  19. *
  20. * @type {Number}
  21. * @constant
  22. */
  23. DEPTH_STENCIL : WebGLConstants.DEPTH_STENCIL,
  24. /**
  25. * A pixel format containing an alpha channel.
  26. *
  27. * @type {Number}
  28. * @constant
  29. */
  30. ALPHA : WebGLConstants.ALPHA,
  31. /**
  32. * A pixel format containing red, green, and blue channels.
  33. *
  34. * @type {Number}
  35. * @constant
  36. */
  37. RGB : WebGLConstants.RGB,
  38. /**
  39. * A pixel format containing red, green, blue, and alpha channels.
  40. *
  41. * @type {Number}
  42. * @constant
  43. */
  44. RGBA : WebGLConstants.RGBA,
  45. /**
  46. * A pixel format containing a luminance (intensity) channel.
  47. *
  48. * @type {Number}
  49. * @constant
  50. */
  51. LUMINANCE : WebGLConstants.LUMINANCE,
  52. /**
  53. * A pixel format containing luminance (intensity) and alpha channels.
  54. *
  55. * @type {Number}
  56. * @constant
  57. */
  58. LUMINANCE_ALPHA : WebGLConstants.LUMINANCE_ALPHA,
  59. /**
  60. * A pixel format containing red, green, and blue channels that is DXT1 compressed.
  61. *
  62. * @type {Number}
  63. * @constant
  64. */
  65. RGB_DXT1 : WebGLConstants.COMPRESSED_RGB_S3TC_DXT1_EXT,
  66. /**
  67. * A pixel format containing red, green, blue, and alpha channels that is DXT1 compressed.
  68. *
  69. * @type {Number}
  70. * @constant
  71. */
  72. RGBA_DXT1 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT1_EXT,
  73. /**
  74. * A pixel format containing red, green, blue, and alpha channels that is DXT3 compressed.
  75. *
  76. * @type {Number}
  77. * @constant
  78. */
  79. RGBA_DXT3 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT3_EXT,
  80. /**
  81. * A pixel format containing red, green, blue, and alpha channels that is DXT5 compressed.
  82. *
  83. * @type {Number}
  84. * @constant
  85. */
  86. RGBA_DXT5 : WebGLConstants.COMPRESSED_RGBA_S3TC_DXT5_EXT,
  87. /**
  88. * A pixel format containing red, green, and blue channels that is PVR 4bpp compressed.
  89. *
  90. * @type {Number}
  91. * @constant
  92. */
  93. RGB_PVRTC_4BPPV1 : WebGLConstants.COMPRESSED_RGB_PVRTC_4BPPV1_IMG,
  94. /**
  95. * A pixel format containing red, green, and blue channels that is PVR 2bpp compressed.
  96. *
  97. * @type {Number}
  98. * @constant
  99. */
  100. RGB_PVRTC_2BPPV1 : WebGLConstants.COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
  101. /**
  102. * A pixel format containing red, green, blue, and alpha channels that is PVR 4bpp compressed.
  103. *
  104. * @type {Number}
  105. * @constant
  106. */
  107. RGBA_PVRTC_4BPPV1 : WebGLConstants.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,
  108. /**
  109. * A pixel format containing red, green, blue, and alpha channels that is PVR 2bpp compressed.
  110. *
  111. * @type {Number}
  112. * @constant
  113. */
  114. RGBA_PVRTC_2BPPV1 : WebGLConstants.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG,
  115. /**
  116. * A pixel format containing red, green, and blue channels that is ETC1 compressed.
  117. *
  118. * @type {Number}
  119. * @constant
  120. */
  121. RGB_ETC1 : WebGLConstants.COMPRESSED_RGB_ETC1_WEBGL,
  122. /**
  123. * @private
  124. */
  125. componentsLength : function(pixelFormat) {
  126. switch (pixelFormat) {
  127. case PixelFormat.RGB:
  128. return 3;
  129. case PixelFormat.RGBA:
  130. return 4;
  131. case PixelFormat.LUMINANCE_ALPHA:
  132. return 2;
  133. case PixelFormat.ALPHA:
  134. case PixelFormat.LUMINANCE:
  135. return 1;
  136. default:
  137. return 1;
  138. }
  139. },
  140. /**
  141. * @private
  142. */
  143. validate : function(pixelFormat) {
  144. return pixelFormat === PixelFormat.DEPTH_COMPONENT ||
  145. pixelFormat === PixelFormat.DEPTH_STENCIL ||
  146. pixelFormat === PixelFormat.ALPHA ||
  147. pixelFormat === PixelFormat.RGB ||
  148. pixelFormat === PixelFormat.RGBA ||
  149. pixelFormat === PixelFormat.LUMINANCE ||
  150. pixelFormat === PixelFormat.LUMINANCE_ALPHA ||
  151. pixelFormat === PixelFormat.RGB_DXT1 ||
  152. pixelFormat === PixelFormat.RGBA_DXT1 ||
  153. pixelFormat === PixelFormat.RGBA_DXT3 ||
  154. pixelFormat === PixelFormat.RGBA_DXT5 ||
  155. pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 ||
  156. pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 ||
  157. pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 ||
  158. pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1 ||
  159. pixelFormat === PixelFormat.RGB_ETC1;
  160. },
  161. /**
  162. * @private
  163. */
  164. isColorFormat : function(pixelFormat) {
  165. return pixelFormat === PixelFormat.ALPHA ||
  166. pixelFormat === PixelFormat.RGB ||
  167. pixelFormat === PixelFormat.RGBA ||
  168. pixelFormat === PixelFormat.LUMINANCE ||
  169. pixelFormat === PixelFormat.LUMINANCE_ALPHA;
  170. },
  171. /**
  172. * @private
  173. */
  174. isDepthFormat : function(pixelFormat) {
  175. return pixelFormat === PixelFormat.DEPTH_COMPONENT ||
  176. pixelFormat === PixelFormat.DEPTH_STENCIL;
  177. },
  178. /**
  179. * @private
  180. */
  181. isCompressedFormat : function(pixelFormat) {
  182. return pixelFormat === PixelFormat.RGB_DXT1 ||
  183. pixelFormat === PixelFormat.RGBA_DXT1 ||
  184. pixelFormat === PixelFormat.RGBA_DXT3 ||
  185. pixelFormat === PixelFormat.RGBA_DXT5 ||
  186. pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 ||
  187. pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 ||
  188. pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 ||
  189. pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1 ||
  190. pixelFormat === PixelFormat.RGB_ETC1;
  191. },
  192. /**
  193. * @private
  194. */
  195. isDXTFormat : function(pixelFormat) {
  196. return pixelFormat === PixelFormat.RGB_DXT1 ||
  197. pixelFormat === PixelFormat.RGBA_DXT1 ||
  198. pixelFormat === PixelFormat.RGBA_DXT3 ||
  199. pixelFormat === PixelFormat.RGBA_DXT5;
  200. },
  201. /**
  202. * @private
  203. */
  204. isPVRTCFormat : function(pixelFormat) {
  205. return pixelFormat === PixelFormat.RGB_PVRTC_4BPPV1 ||
  206. pixelFormat === PixelFormat.RGB_PVRTC_2BPPV1 ||
  207. pixelFormat === PixelFormat.RGBA_PVRTC_4BPPV1 ||
  208. pixelFormat === PixelFormat.RGBA_PVRTC_2BPPV1;
  209. },
  210. /**
  211. * @private
  212. */
  213. isETC1Format : function(pixelFormat) {
  214. return pixelFormat === PixelFormat.RGB_ETC1;
  215. },
  216. /**
  217. * @private
  218. */
  219. compressedTextureSizeInBytes : function(pixelFormat, width, height) {
  220. switch (pixelFormat) {
  221. case PixelFormat.RGB_DXT1:
  222. case PixelFormat.RGBA_DXT1:
  223. case PixelFormat.RGB_ETC1:
  224. return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 8;
  225. case PixelFormat.RGBA_DXT3:
  226. case PixelFormat.RGBA_DXT5:
  227. return Math.floor((width + 3) / 4) * Math.floor((height + 3) / 4) * 16;
  228. case PixelFormat.RGB_PVRTC_4BPPV1:
  229. case PixelFormat.RGBA_PVRTC_4BPPV1:
  230. return Math.floor((Math.max(width, 8) * Math.max(height, 8) * 4 + 7) / 8);
  231. case PixelFormat.RGB_PVRTC_2BPPV1:
  232. case PixelFormat.RGBA_PVRTC_2BPPV1:
  233. return Math.floor((Math.max(width, 16) * Math.max(height, 8) * 2 + 7) / 8);
  234. default:
  235. return 0;
  236. }
  237. },
  238. /**
  239. * @private
  240. */
  241. textureSizeInBytes : function(pixelFormat, pixelDatatype, width, height) {
  242. var componentsLength = PixelFormat.componentsLength(pixelFormat);
  243. if (PixelDatatype.isPacked(pixelDatatype)) {
  244. componentsLength = 1;
  245. }
  246. return componentsLength * PixelDatatype.sizeInBytes(pixelDatatype) * width * height;
  247. },
  248. /**
  249. * @private
  250. */
  251. alignmentInBytes : function(pixelFormat, pixelDatatype, width) {
  252. var mod = PixelFormat.textureSizeInBytes(pixelFormat, pixelDatatype, width, 1) % 4;
  253. return mod === 0 ? 4 : (mod === 2 ? 2 : 1);
  254. },
  255. /**
  256. * @private
  257. */
  258. createTypedArray : function(pixelFormat, pixelDatatype, width, height) {
  259. var constructor;
  260. var sizeInBytes = PixelDatatype.sizeInBytes(pixelDatatype);
  261. if (sizeInBytes === Uint8Array.BYTES_PER_ELEMENT) {
  262. constructor = Uint8Array;
  263. } else if (sizeInBytes === Uint16Array.BYTES_PER_ELEMENT) {
  264. constructor = Uint16Array;
  265. } else if (sizeInBytes === Float32Array.BYTES_PER_ELEMENT && pixelDatatype === PixelDatatype.FLOAT) {
  266. constructor = Float32Array;
  267. } else {
  268. constructor = Uint32Array;
  269. }
  270. var size = PixelFormat.componentsLength(pixelFormat) * width * height;
  271. return new constructor(size);
  272. },
  273. /**
  274. * @private
  275. */
  276. flipY : function(bufferView, pixelFormat, pixelDatatype, width, height) {
  277. if (height === 1) {
  278. return bufferView;
  279. }
  280. var flipped = PixelFormat.createTypedArray(pixelFormat, pixelDatatype, width, height);
  281. var numberOfComponents = PixelFormat.componentsLength(pixelFormat);
  282. var textureWidth = width * numberOfComponents;
  283. for (var i = 0; i < height; ++i) {
  284. var row = i * height * numberOfComponents;
  285. var flippedRow = (height - i - 1) * height * numberOfComponents;
  286. for (var j = 0; j < textureWidth; ++j) {
  287. flipped[flippedRow + j] = bufferView[row + j];
  288. }
  289. }
  290. return flipped;
  291. }
  292. };
  293. export default freezeObject(PixelFormat);