htmlElementTexture.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import { Nullable } from "../../types";
  2. import { BaseTexture } from "../../Materials/Textures/baseTexture";
  3. import { Constants } from "../../Engines/constants";
  4. import { Matrix } from '../../Maths/math.vector';
  5. import "../../Engines/Extensions/engine.dynamicTexture";
  6. import "../../Engines/Extensions/engine.videoTexture";
  7. declare type ThinEngine = import("../../Engines/thinEngine").ThinEngine;
  8. declare type Scene = import("../../scene").Scene;
  9. /**
  10. * Defines the options related to the creation of an HtmlElementTexture
  11. */
  12. export interface IHtmlElementTextureOptions {
  13. /**
  14. * Defines wether mip maps should be created or not.
  15. */
  16. generateMipMaps?: boolean;
  17. /**
  18. * Defines the sampling mode of the texture.
  19. */
  20. samplingMode?: number;
  21. /**
  22. * Defines the engine instance to use the texture with. It is not mandatory if you define a scene.
  23. */
  24. engine: Nullable<ThinEngine>;
  25. /**
  26. * Defines the scene the texture belongs to. It is not mandatory if you define an engine.
  27. */
  28. scene: Nullable<Scene>;
  29. }
  30. /**
  31. * This represents the smallest workload to use an already existing element (Canvas or Video) as a texture.
  32. * To be as efficient as possible depending on your constraints nothing aside the first upload
  33. * is automatically managed.
  34. * It is a cheap VideoTexture or DynamicTexture if you prefer to keep full control of the elements
  35. * in your application.
  36. *
  37. * As the update is not automatic, you need to call them manually.
  38. */
  39. export class HtmlElementTexture extends BaseTexture {
  40. /**
  41. * The texture URL.
  42. */
  43. public element: HTMLVideoElement | HTMLCanvasElement;
  44. private static readonly DefaultOptions: IHtmlElementTextureOptions = {
  45. generateMipMaps: false,
  46. samplingMode: Constants.TEXTURE_BILINEAR_SAMPLINGMODE,
  47. engine: null,
  48. scene: null
  49. };
  50. private _textureMatrix: Matrix;
  51. private _engine: ThinEngine;
  52. private _isVideo: boolean;
  53. private _generateMipMaps: boolean;
  54. private _samplingMode: number;
  55. /**
  56. * Instantiates a HtmlElementTexture from the following parameters.
  57. *
  58. * @param name Defines the name of the texture
  59. * @param element Defines the video or canvas the texture is filled with
  60. * @param options Defines the other none mandatory texture creation options
  61. */
  62. constructor(name: string, element: HTMLVideoElement | HTMLCanvasElement, options: IHtmlElementTextureOptions) {
  63. super(options.scene);
  64. if (!element || (!options.engine && !options.scene)) {
  65. return;
  66. }
  67. options = {
  68. ...HtmlElementTexture.DefaultOptions,
  69. ...options
  70. };
  71. this._engine = options.engine || options.scene!.getEngine();
  72. this._generateMipMaps = options.generateMipMaps!;
  73. this._samplingMode = options.samplingMode!;
  74. this._textureMatrix = Matrix.Identity();
  75. this.name = name;
  76. this.element = element;
  77. this._isVideo = (element instanceof HTMLVideoElement);
  78. this.anisotropicFilteringLevel = 1;
  79. this._createInternalTexture();
  80. }
  81. private _createInternalTexture(): void {
  82. let width = 0;
  83. let height = 0;
  84. if (this._isVideo) {
  85. width = (this.element as HTMLVideoElement).videoWidth;
  86. height = (this.element as HTMLVideoElement).videoHeight;
  87. }
  88. else {
  89. width = this.element.width;
  90. height = this.element.height;
  91. }
  92. this._texture = this._engine.createDynamicTexture(
  93. width,
  94. height,
  95. this._generateMipMaps,
  96. this._samplingMode
  97. );
  98. this.update();
  99. }
  100. /**
  101. * Returns the texture matrix used in most of the material.
  102. */
  103. public getTextureMatrix(): Matrix {
  104. return this._textureMatrix;
  105. }
  106. /**
  107. * Updates the content of the texture.
  108. * @param invertY Defines wether the texture should be inverted on Y (false by default on video and true on canvas)
  109. */
  110. public update(invertY: Nullable<boolean> = null): void {
  111. if (this._texture == null) {
  112. return;
  113. }
  114. if (this._isVideo) {
  115. const videoElement = this.element as HTMLVideoElement;
  116. if (videoElement.readyState < videoElement.HAVE_CURRENT_DATA) {
  117. return;
  118. }
  119. this._engine.updateVideoTexture(this._texture,
  120. videoElement,
  121. invertY === null ? true : invertY);
  122. }
  123. else {
  124. const canvasElement = this.element as HTMLCanvasElement;
  125. this._engine.updateDynamicTexture(this._texture,
  126. canvasElement,
  127. invertY === null ? true : invertY,
  128. false);
  129. }
  130. }
  131. }