ColorTexture2D.js

  1. 'use strict';
  2. const Texture2D = require('./Texture2D');
  3. const ImageLoader = require('../util/ImageLoader');
  4. const Util = require('../util/Util');
  5. const MAG_FILTERS = {
  6. NEAREST: true,
  7. LINEAR: true
  8. };
  9. const MIN_FILTERS = {
  10. NEAREST: true,
  11. LINEAR: true,
  12. NEAREST_MIPMAP_NEAREST: true,
  13. LINEAR_MIPMAP_NEAREST: true,
  14. NEAREST_MIPMAP_LINEAR: true,
  15. LINEAR_MIPMAP_LINEAR: true
  16. };
  17. const WRAP_MODES = {
  18. REPEAT: true,
  19. MIRRORED_REPEAT: true,
  20. CLAMP_TO_EDGE: true
  21. };
  22. const TYPES = {
  23. UNSIGNED_BYTE: true,
  24. FLOAT: true
  25. };
  26. const FORMATS = {
  27. RGB: true,
  28. RGBA: true
  29. };
  30. /**
  31. * The default type for color textures.
  32. * @private
  33. * @constant {string}
  34. */
  35. const DEFAULT_TYPE = 'UNSIGNED_BYTE';
  36. /**
  37. * The default format for color textures.
  38. * @private
  39. * @constant {string}
  40. */
  41. const DEFAULT_FORMAT = 'RGBA';
  42. /**
  43. * The default wrap mode for color textures.
  44. * @private
  45. * @constant {string}
  46. */
  47. const DEFAULT_WRAP = 'REPEAT';
  48. /**
  49. * The default min / mag filter for color textures.
  50. * @private
  51. * @constant {string}
  52. */
  53. const DEFAULT_FILTER = 'LINEAR';
  54. /**
  55. * The default for whether alpha premultiplying is enabled.
  56. * @private
  57. * @constant {boolean}
  58. */
  59. const DEFAULT_PREMULTIPLY_ALPHA = true;
  60. /**
  61. * The default for whether mipmapping is enabled.
  62. * @private
  63. * @constant {boolean}
  64. */
  65. const DEFAULT_MIPMAP = true;
  66. /**
  67. * The default for whether invert-y is enabled.
  68. * @private
  69. * @constant {boolean}
  70. */
  71. const DEFAULT_INVERT_Y = true;
  72. /**
  73. * A texture class to represent a 2D color texture.
  74. * @augments Texture2D
  75. */
  76. class ColorTexture2D extends Texture2D {
  77. /**
  78. * Instantiates a ColorTexture2D object.
  79. *
  80. * @param {Object} spec - The specification arguments.
  81. * @param {ArrayBuffer|ImageData|HTMLImageElement|HTMLCanvasElement|HTMLVideoElement} spec.image - The HTMLImageElement to buffer.
  82. * @param {string} spec.url - The HTMLImageElement URL to load and buffer.
  83. * @param {Uint8Array|Float32Array} spec.src - The data to buffer.
  84. * @param {number} spec.width - The width of the texture.
  85. * @param {number} spec.height - The height of the texture.
  86. * @param {string} spec.wrap - The wrapping type over both S and T dimension.
  87. * @param {string} spec.wrapS - The wrapping type over the S dimension.
  88. * @param {string} spec.wrapT - The wrapping type over the T dimension.
  89. * @param {string} spec.filter - The min / mag filter used during scaling.
  90. * @param {string} spec.minFilter - The minification filter used during scaling.
  91. * @param {string} spec.magFilter - The magnification filter used during scaling.
  92. * @param {bool} spec.mipMap - Whether or not mip-mapping is enabled.
  93. * @param {bool} spec.invertY - Whether or not invert-y is enabled.
  94. * @param {bool} spec.premultiplyAlpha - Whether or not alpha premultiplying is enabled.
  95. * @param {string} spec.format - The texture pixel format.
  96. * @param {string} spec.type - The texture pixel component type.
  97. * @param {Function} callback - The callback to be executed if the data is loaded asynchronously via a URL.
  98. */
  99. constructor(spec = {}, callback = null) {
  100. // get specific params
  101. spec.wrapS = spec.wrapS || spec.wrap;
  102. spec.wrapT = spec.wrapT || spec.wrap;
  103. spec.minFilter = spec.minFilter || spec.filter;
  104. spec.magFilter = spec.magFilter || spec.filter;
  105. // set texture params
  106. spec.wrapS = WRAP_MODES[spec.wrapS] ? spec.wrapS : DEFAULT_WRAP;
  107. spec.wrapT = WRAP_MODES[spec.wrapT] ? spec.wrapT : DEFAULT_WRAP;
  108. spec.minFilter = MIN_FILTERS[spec.minFilter] ? spec.minFilter : DEFAULT_FILTER;
  109. spec.magFilter = MAG_FILTERS[spec.magFilter] ? spec.magFilter : DEFAULT_FILTER;
  110. // set other properties
  111. spec.mipMap = spec.mipMap !== undefined ? spec.mipMap : DEFAULT_MIPMAP;
  112. spec.invertY = spec.invertY !== undefined ? spec.invertY : DEFAULT_INVERT_Y;
  113. spec.premultiplyAlpha = spec.premultiplyAlpha !== undefined ? spec.premultiplyAlpha : DEFAULT_PREMULTIPLY_ALPHA;
  114. // set format
  115. spec.format = FORMATS[spec.format] ? spec.format : DEFAULT_FORMAT;
  116. // buffer the texture based on argument type
  117. if (typeof spec.src === 'string') {
  118. // request source from url
  119. spec.type = 'UNSIGNED_BYTE';
  120. // call base constructor
  121. super(spec);
  122. // TODO: put extension handling for arraybuffer / image / video differentiation
  123. ImageLoader.load({
  124. url: spec.src,
  125. success: image => {
  126. // set to unsigned byte type
  127. image = Util.resizeCanvas(spec, image);
  128. // now buffer
  129. this.bufferData(image, spec.width, spec.height);
  130. this.setParameters(this);
  131. // execute callback
  132. if (callback) {
  133. callback(null, this);
  134. }
  135. },
  136. error: err => {
  137. if (callback) {
  138. callback(err, null);
  139. }
  140. }
  141. });
  142. } else if (Util.isCanvasType(spec.src)) {
  143. // is image / canvas / video type
  144. // set to unsigned byte type
  145. spec.type = 'UNSIGNED_BYTE';
  146. spec.src = Util.resizeCanvas(spec, spec.src);
  147. // call base constructor
  148. super(spec);
  149. } else {
  150. // array, arraybuffer, or null
  151. if (spec.src === undefined || spec.src === null) {
  152. // if no data is provided, assume this texture will be rendered
  153. // to. In this case disable mipmapping, there is no need and it
  154. // will only introduce very peculiar and difficult to discern
  155. // rendering phenomena in which the texture 'transforms' at
  156. // certain angles / distances to the mipmapped (empty) portions.
  157. spec.mipMap = false;
  158. }
  159. // buffer from arg
  160. spec.type = TYPES[spec.type] ? spec.type : DEFAULT_TYPE;
  161. // call base constructor
  162. super(spec);
  163. }
  164. }
  165. }
  166. module.exports = ColorTexture2D;