engine.textureSelector.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { Nullable } from '../../types';
  2. import { Engine } from '../engine';
  3. declare module "../../Engines/engine" {
  4. export interface Engine {
  5. /** @hidden */
  6. _excludedCompressedTextures: string[];
  7. /** @hidden */
  8. _textureFormatInUse: string;
  9. /**
  10. * Gets the list of texture formats supported
  11. */
  12. readonly texturesSupported: Array<string>;
  13. /**
  14. * Gets the texture format in use
  15. */
  16. readonly textureFormatInUse: Nullable<string>;
  17. /**
  18. * Set the compressed texture extensions or file names to skip.
  19. *
  20. * @param skippedFiles defines the list of those texture files you want to skip
  21. * Example: [".dds", ".env", "myfile.png"]
  22. */
  23. setCompressedTextureExclusions(skippedFiles: Array<string>): void;
  24. /**
  25. * Set the compressed texture format to use, based on the formats you have, and the formats
  26. * supported by the hardware / browser.
  27. *
  28. * Khronos Texture Container (.ktx) files are used to support this. This format has the
  29. * advantage of being specifically designed for OpenGL. Header elements directly correspond
  30. * to API arguments needed to compressed textures. This puts the burden on the container
  31. * generator to house the arcane code for determining these for current & future formats.
  32. *
  33. * for description see https://www.khronos.org/opengles/sdk/tools/KTX/
  34. * for file layout see https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
  35. *
  36. * Note: The result of this call is not taken into account when a texture is base64.
  37. *
  38. * @param formatsAvailable defines the list of those format families you have created
  39. * on your server. Syntax: '-' + format family + '.ktx'. (Case and order do not matter.)
  40. *
  41. * Current families are astc, dxt, pvrtc, etc2, & etc1.
  42. * @returns The extension selected.
  43. */
  44. setTextureFormatToUse(formatsAvailable: Array<string>): Nullable<string>;
  45. }
  46. }
  47. function transformTextureUrl(this: Engine, url: string): string {
  48. const excludeFn = (entry: string) => {
  49. const strRegExPattern: string = '\\b' + entry + '\\b';
  50. return (url && (url === entry || url.match(new RegExp(strRegExPattern, 'g'))));
  51. };
  52. if (this._excludedCompressedTextures && this._excludedCompressedTextures.some(excludeFn)) {
  53. return url;
  54. }
  55. const lastDot = url.lastIndexOf('.');
  56. return (lastDot > -1 ? url.substring(0, lastDot) : url) + this._textureFormatInUse;
  57. }
  58. Object.defineProperty(Engine.prototype, "texturesSupported", {
  59. get: function(this: Engine) {
  60. // Intelligently add supported compressed formats in order to check for.
  61. // Check for ASTC support first as it is most powerful and to be very cross platform.
  62. // Next PVRTC & DXT, which are probably superior to ETC1/2.
  63. // Likely no hardware which supports both PVR & DXT, so order matters little.
  64. // ETC2 is newer and handles ETC1 (no alpha capability), so check for first.
  65. const texturesSupported = new Array<string>();
  66. if (this._caps.astc) { texturesSupported.push('-astc.ktx'); }
  67. if (this._caps.s3tc) { texturesSupported.push('-dxt.ktx'); }
  68. if (this._caps.pvrtc) { texturesSupported.push('-pvrtc.ktx'); }
  69. if (this._caps.etc2) { texturesSupported.push('-etc2.ktx'); }
  70. if (this._caps.etc1) { texturesSupported.push('-etc1.ktx'); }
  71. return texturesSupported;
  72. },
  73. enumerable: true,
  74. configurable: true
  75. });
  76. Object.defineProperty(Engine.prototype, "textureFormatInUse", {
  77. get: function(this: Engine) {
  78. return this._textureFormatInUse || null;
  79. },
  80. enumerable: true,
  81. configurable: true
  82. });
  83. Engine.prototype.setCompressedTextureExclusions = function(skippedFiles: Array<string>): void {
  84. this._excludedCompressedTextures = skippedFiles;
  85. };
  86. Engine.prototype.setTextureFormatToUse = function(formatsAvailable: Array<string>): Nullable<string> {
  87. const texturesSupported = this.texturesSupported;
  88. for (let i = 0, len1 = texturesSupported.length; i < len1; i++) {
  89. for (let j = 0, len2 = formatsAvailable.length; j < len2; j++) {
  90. if (texturesSupported[i] === formatsAvailable[j].toLowerCase()) {
  91. this._transformTextureUrl = transformTextureUrl.bind(this);
  92. return this._textureFormatInUse = texturesSupported[i];
  93. }
  94. }
  95. }
  96. // actively set format to nothing, to allow this to be called more than once
  97. // and possibly fail the 2nd time
  98. delete this._textureFormatInUse;
  99. delete this._transformTextureUrl;
  100. return null;
  101. };