babylon.baseTexture.ts 11 KB

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