babylon.baseTexture.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. module BABYLON {
  2. export class BaseTexture {
  3. public static DEFAULT_ANISOTROPIC_FILTERING_LEVEL = 4;
  4. @serialize()
  5. public name: string;
  6. @serialize("hasAlpha")
  7. private _hasAlpha = false;
  8. public set hasAlpha(value: boolean) {
  9. if (this._hasAlpha === value) {
  10. return;
  11. }
  12. this._hasAlpha = value;
  13. if (this._scene) {
  14. this._scene.markAllMaterialsAsDirty(Material.TextureDirtyFlag | Material.MiscDirtyFlag);
  15. }
  16. }
  17. public get hasAlpha(): boolean {
  18. return this._hasAlpha;
  19. }
  20. @serialize()
  21. public getAlphaFromRGB = false;
  22. @serialize()
  23. public level = 1;
  24. @serialize()
  25. public coordinatesIndex = 0;
  26. @serialize("coordinatesMode")
  27. private _coordinatesMode = Texture.EXPLICIT_MODE;
  28. public set coordinatesMode(value: number) {
  29. if (this._coordinatesMode === value) {
  30. return;
  31. }
  32. this._coordinatesMode = value;
  33. if (this._scene) {
  34. this._scene.markAllMaterialsAsDirty(Material.TextureDirtyFlag);
  35. }
  36. }
  37. public get coordinatesMode(): number {
  38. return this._coordinatesMode;
  39. }
  40. /*
  41. * How a texture is mapped.
  42. *
  43. * | Value | Type | Description |
  44. * | ----- | ----------------------------------- | ----------- |
  45. * | 0 | EXPLICIT_MODE | |
  46. * | 1 | SPHERICAL_MODE | |
  47. * | 2 | PLANAR_MODE | |
  48. * | 3 | CUBIC_MODE | |
  49. * | 4 | PROJECTION_MODE | |
  50. * | 5 | SKYBOX_MODE | |
  51. * | 6 | INVCUBIC_MODE | |
  52. * | 7 | EQUIRECTANGULAR_MODE | |
  53. * | 8 | FIXED_EQUIRECTANGULAR_MODE | |
  54. * | 9 | FIXED_EQUIRECTANGULAR_MIRRORED_MODE | |
  55. */
  56. @serialize()
  57. public wrapU = Texture.WRAP_ADDRESSMODE;
  58. /*
  59. * | Value | Type | Description |
  60. * | ----- | ------------------ | ----------- |
  61. * | 0 | CLAMP_ADDRESSMODE | |
  62. * | 1 | WRAP_ADDRESSMODE | |
  63. * | 2 | MIRROR_ADDRESSMODE | |
  64. */
  65. @serialize()
  66. public wrapV = Texture.WRAP_ADDRESSMODE;
  67. @serialize()
  68. public wrapR = Texture.WRAP_ADDRESSMODE;
  69. @serialize()
  70. public anisotropicFilteringLevel = BaseTexture.DEFAULT_ANISOTROPIC_FILTERING_LEVEL;
  71. @serialize()
  72. public isCube = false;
  73. @serialize()
  74. public is3D = false;
  75. @serialize()
  76. public gammaSpace = true;
  77. @serialize()
  78. public invertZ = false;
  79. @serialize()
  80. public lodLevelInAlpha = false;
  81. @serialize()
  82. public lodGenerationOffset = 0.0;
  83. @serialize()
  84. public lodGenerationScale = 0.8;
  85. @serialize()
  86. public isRenderTarget = false;
  87. public get uid(): string {
  88. if (!this._uid) {
  89. this._uid = Tools.RandomId();
  90. }
  91. return this._uid;
  92. }
  93. public toString(): string {
  94. return this.name;
  95. }
  96. public getClassName(): string {
  97. return "BaseTexture";
  98. }
  99. public animations = new Array<Animation>();
  100. /**
  101. * An event triggered when the texture is disposed.
  102. * @type {BABYLON.Observable}
  103. */
  104. public onDisposeObservable = new Observable<BaseTexture>();
  105. private _onDisposeObserver: Nullable<Observer<BaseTexture>>;
  106. public set onDispose(callback: () => void) {
  107. if (this._onDisposeObserver) {
  108. this.onDisposeObservable.remove(this._onDisposeObserver);
  109. }
  110. this._onDisposeObserver = this.onDisposeObservable.add(callback);
  111. }
  112. public delayLoadState = Engine.DELAYLOADSTATE_NONE;
  113. private _scene: Nullable<Scene>;
  114. public _texture: Nullable<InternalTexture>;
  115. private _uid: Nullable<string>;
  116. public get isBlocking(): boolean {
  117. return true;
  118. }
  119. constructor(scene: Nullable<Scene>) {
  120. this._scene = scene || Engine.LastCreatedScene;
  121. if (this._scene) {
  122. this._scene.textures.push(this);
  123. }
  124. this._uid = null;
  125. }
  126. public getScene(): Nullable<Scene> {
  127. return this._scene;
  128. }
  129. public getTextureMatrix(): Matrix {
  130. return Matrix.IdentityReadOnly;
  131. }
  132. public getReflectionTextureMatrix(): Matrix {
  133. return Matrix.IdentityReadOnly;
  134. }
  135. public getInternalTexture(): Nullable<InternalTexture> {
  136. return this._texture;
  137. }
  138. public isReadyOrNotBlocking(): boolean {
  139. return !this.isBlocking || this.isReady();
  140. }
  141. public isReady(): boolean {
  142. if (this.delayLoadState === Engine.DELAYLOADSTATE_NOTLOADED) {
  143. this.delayLoad();
  144. return false;
  145. }
  146. if (this._texture) {
  147. return this._texture.isReady;
  148. }
  149. return false;
  150. }
  151. public getSize(): ISize {
  152. if (this._texture && this._texture.width) {
  153. return new Size(this._texture.width, this._texture.height);
  154. }
  155. if (this._texture && this._texture._size) {
  156. return new Size(this._texture._size, this._texture._size);
  157. }
  158. return Size.Zero();
  159. }
  160. public getBaseSize(): ISize {
  161. if (!this.isReady() || !this._texture)
  162. return Size.Zero();
  163. if (this._texture._size) {
  164. return new Size(this._texture._size, this._texture._size);
  165. }
  166. return new Size(this._texture.baseWidth, this._texture.baseHeight);
  167. }
  168. public scale(ratio: number): void {
  169. }
  170. public get canRescale(): boolean {
  171. return false;
  172. }
  173. public _getFromCache(url: Nullable<string>, noMipmap: boolean, sampling?: number): Nullable<InternalTexture> {
  174. if (!this._scene) {
  175. return null
  176. }
  177. var texturesCache = this._scene.getEngine().getLoadedTexturesCache();
  178. for (var index = 0; index < texturesCache.length; index++) {
  179. var texturesCacheEntry = texturesCache[index];
  180. if (texturesCacheEntry.url === url && texturesCacheEntry.generateMipMaps === !noMipmap) {
  181. if (!sampling || sampling === texturesCacheEntry.samplingMode) {
  182. texturesCacheEntry.incrementReferences();
  183. return texturesCacheEntry;
  184. }
  185. }
  186. }
  187. return null;
  188. }
  189. public _rebuild(): void {
  190. }
  191. public delayLoad(): void {
  192. }
  193. public clone(): Nullable<BaseTexture> {
  194. return null;
  195. }
  196. public get textureType(): number {
  197. if (!this._texture) {
  198. return Engine.TEXTURETYPE_UNSIGNED_INT;
  199. }
  200. return (this._texture.type !== undefined) ? this._texture.type : Engine.TEXTURETYPE_UNSIGNED_INT;
  201. }
  202. public get textureFormat(): number {
  203. if (!this._texture) {
  204. return Engine.TEXTUREFORMAT_RGBA;
  205. }
  206. return (this._texture.format !== undefined) ? this._texture.format : Engine.TEXTUREFORMAT_RGBA;
  207. }
  208. public readPixels(faceIndex = 0): Nullable<ArrayBufferView> {
  209. if (!this._texture) {
  210. return null;
  211. }
  212. var size = this.getSize();
  213. let scene = this.getScene();
  214. if (!scene) {
  215. return null;
  216. }
  217. var engine = scene.getEngine();
  218. if (this._texture.isCube) {
  219. return engine._readTexturePixels(this._texture, size.width, size.height, faceIndex);
  220. }
  221. return engine._readTexturePixels(this._texture, size.width, size.height, -1);
  222. }
  223. public releaseInternalTexture(): void {
  224. if (this._texture) {
  225. this._texture.dispose();
  226. this._texture = null;
  227. }
  228. }
  229. public get sphericalPolynomial(): Nullable<SphericalPolynomial> {
  230. if (!this._texture || !CubeMapToSphericalPolynomialTools || !this.isReady()) {
  231. return null;
  232. }
  233. if (!this._texture._sphericalPolynomial) {
  234. this._texture._sphericalPolynomial =
  235. CubeMapToSphericalPolynomialTools.ConvertCubeMapTextureToSphericalPolynomial(this);
  236. }
  237. return this._texture._sphericalPolynomial;
  238. }
  239. public set sphericalPolynomial(value: Nullable<SphericalPolynomial>) {
  240. if (this._texture) {
  241. this._texture._sphericalPolynomial = value;
  242. }
  243. }
  244. public get _lodTextureHigh(): Nullable<BaseTexture> {
  245. if (this._texture) {
  246. return this._texture._lodTextureHigh;
  247. }
  248. return null;
  249. }
  250. public get _lodTextureMid(): Nullable<BaseTexture> {
  251. if (this._texture) {
  252. return this._texture._lodTextureMid;
  253. }
  254. return null;
  255. }
  256. public get _lodTextureLow(): Nullable<BaseTexture> {
  257. if (this._texture) {
  258. return this._texture._lodTextureLow;
  259. }
  260. return null;
  261. }
  262. public dispose(): void {
  263. if (!this._scene) {
  264. return;
  265. }
  266. // Animations
  267. this._scene.stopAnimation(this);
  268. // Remove from scene
  269. this._scene._removePendingData(this);
  270. var index = this._scene.textures.indexOf(this);
  271. if (index >= 0) {
  272. this._scene.textures.splice(index, 1);
  273. }
  274. if (this._texture === undefined) {
  275. return;
  276. }
  277. // Release
  278. this.releaseInternalTexture();
  279. // Callback
  280. this.onDisposeObservable.notifyObservers(this);
  281. this.onDisposeObservable.clear();
  282. }
  283. public serialize(): any {
  284. if (!this.name) {
  285. return null;
  286. }
  287. var serializationObject = SerializationHelper.Serialize(this);
  288. // Animations
  289. Animation.AppendSerializedAnimations(this, serializationObject);
  290. return serializationObject;
  291. }
  292. public static WhenAllReady(textures: BaseTexture[], callback: () => void): void {
  293. let numRemaining = textures.length;
  294. if (numRemaining === 0) {
  295. callback();
  296. return;
  297. }
  298. for (var i = 0; i < textures.length; i++) {
  299. var texture = textures[i];
  300. if (texture.isReady()) {
  301. if (--numRemaining === 0) {
  302. callback();
  303. }
  304. }
  305. else {
  306. var onLoadObservable = (texture as any).onLoadObservable as Observable<Texture>;
  307. let onLoadCallback = () => {
  308. onLoadObservable.removeCallback(onLoadCallback);
  309. if (--numRemaining === 0) {
  310. callback();
  311. }
  312. };
  313. onLoadObservable.add(onLoadCallback);
  314. }
  315. }
  316. }
  317. }
  318. }