engine.rawTexture.ts 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. import { Nullable } from "../../types";
  2. import { Engine } from "../../Engines/engine";
  3. import { _TimeToken } from "../../Instrumentation/timeToken";
  4. import { InternalTexture } from '../../Materials/Textures/internalTexture';
  5. import { Logger } from '../../Misc/logger';
  6. import { Tools } from '../../Misc/tools';
  7. import { Scene } from '../../scene';
  8. import { WebRequest } from '../../Misc/webRequest';
  9. declare module "../../Engines/engine" {
  10. export interface Engine {
  11. /**
  12. * Creates a raw texture
  13. * @param data defines the data to store in the texture
  14. * @param width defines the width of the texture
  15. * @param height defines the height of the texture
  16. * @param format defines the format of the data
  17. * @param generateMipMaps defines if the engine should generate the mip levels
  18. * @param invertY defines if data must be stored with Y axis inverted
  19. * @param samplingMode defines the required sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
  20. * @param compression defines the compression used (null by default)
  21. * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
  22. * @returns the raw texture inside an InternalTexture
  23. */
  24. createRawTexture(data: Nullable<ArrayBufferView>, width: number, height: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string>, type: number): InternalTexture;
  25. /**
  26. * Update a raw texture
  27. * @param texture defines the texture to update
  28. * @param data defines the data to store in the texture
  29. * @param format defines the format of the data
  30. * @param invertY defines if data must be stored with Y axis inverted
  31. */
  32. updateRawTexture(texture: Nullable<InternalTexture>, data: Nullable<ArrayBufferView>, format: number, invertY: boolean): void;
  33. /**
  34. * Update a raw texture
  35. * @param texture defines the texture to update
  36. * @param data defines the data to store in the texture
  37. * @param format defines the format of the data
  38. * @param invertY defines if data must be stored with Y axis inverted
  39. * @param compression defines the compression used (null by default)
  40. * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
  41. */
  42. updateRawTexture(texture: Nullable<InternalTexture>, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string>, type: number): void;
  43. /**
  44. * Creates a new raw cube texture
  45. * @param data defines the array of data to use to create each face
  46. * @param size defines the size of the textures
  47. * @param format defines the format of the data
  48. * @param type defines the type of the data (like Engine.TEXTURETYPE_UNSIGNED_INT)
  49. * @param generateMipMaps defines if the engine should generate the mip levels
  50. * @param invertY defines if data must be stored with Y axis inverted
  51. * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
  52. * @param compression defines the compression used (null by default)
  53. * @returns the cube texture as an InternalTexture
  54. */
  55. createRawCubeTexture(data: Nullable<ArrayBufferView[]>, size: number, format: number, type: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string>): InternalTexture;
  56. /**
  57. * Update a raw cube texture
  58. * @param texture defines the texture to udpdate
  59. * @param data defines the data to store
  60. * @param format defines the data format
  61. * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
  62. * @param invertY defines if data must be stored with Y axis inverted
  63. */
  64. updateRawCubeTexture(texture: InternalTexture, data: ArrayBufferView[], format: number, type: number, invertY: boolean): void;
  65. /**
  66. * Update a raw cube texture
  67. * @param texture defines the texture to udpdate
  68. * @param data defines the data to store
  69. * @param format defines the data format
  70. * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
  71. * @param invertY defines if data must be stored with Y axis inverted
  72. * @param compression defines the compression used (null by default)
  73. */
  74. updateRawCubeTexture(texture: InternalTexture, data: ArrayBufferView[], format: number, type: number, invertY: boolean, compression: Nullable<string>): void;
  75. /**
  76. * Update a raw cube texture
  77. * @param texture defines the texture to udpdate
  78. * @param data defines the data to store
  79. * @param format defines the data format
  80. * @param type defines the type fo the data (Engine.TEXTURETYPE_UNSIGNED_INT by default)
  81. * @param invertY defines if data must be stored with Y axis inverted
  82. * @param compression defines the compression used (null by default)
  83. * @param level defines which level of the texture to update
  84. */
  85. updateRawCubeTexture(texture: InternalTexture, data: ArrayBufferView[], format: number, type: number, invertY: boolean, compression: Nullable<string>, level: number): void;
  86. /**
  87. * Creates a new raw cube texture from a specified url
  88. * @param url defines the url where the data is located
  89. * @param scene defines the current scene
  90. * @param size defines the size of the textures
  91. * @param format defines the format of the data
  92. * @param type defines the type fo the data (like Engine.TEXTURETYPE_UNSIGNED_INT)
  93. * @param noMipmap defines if the engine should avoid generating the mip levels
  94. * @param callback defines a callback used to extract texture data from loaded data
  95. * @param mipmapGenerator defines to provide an optional tool to generate mip levels
  96. * @param onLoad defines a callback called when texture is loaded
  97. * @param onError defines a callback called if there is an error
  98. * @returns the cube texture as an InternalTexture
  99. */
  100. createRawCubeTextureFromUrl(url: string, scene: Scene, size: number, format: number, type: number, noMipmap: boolean,
  101. callback: (ArrayBuffer: ArrayBuffer) => Nullable<ArrayBufferView[]>,
  102. mipmapGenerator: Nullable<((faces: ArrayBufferView[]) => ArrayBufferView[][])>,
  103. onLoad: Nullable<() => void>,
  104. onError: Nullable<(message?: string, exception?: any) => void>): InternalTexture;
  105. /**
  106. * Creates a new raw cube texture from a specified url
  107. * @param url defines the url where the data is located
  108. * @param scene defines the current scene
  109. * @param size defines the size of the textures
  110. * @param format defines the format of the data
  111. * @param type defines the type fo the data (like Engine.TEXTURETYPE_UNSIGNED_INT)
  112. * @param noMipmap defines if the engine should avoid generating the mip levels
  113. * @param callback defines a callback used to extract texture data from loaded data
  114. * @param mipmapGenerator defines to provide an optional tool to generate mip levels
  115. * @param onLoad defines a callback called when texture is loaded
  116. * @param onError defines a callback called if there is an error
  117. * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
  118. * @param invertY defines if data must be stored with Y axis inverted
  119. * @returns the cube texture as an InternalTexture
  120. */
  121. createRawCubeTextureFromUrl(url: string, scene: Scene, size: number, format: number, type: number, noMipmap: boolean,
  122. callback: (ArrayBuffer: ArrayBuffer) => Nullable<ArrayBufferView[]>,
  123. mipmapGenerator: Nullable<((faces: ArrayBufferView[]) => ArrayBufferView[][])>,
  124. onLoad: Nullable<() => void>,
  125. onError: Nullable<(message?: string, exception?: any) => void>,
  126. samplingMode: number,
  127. invertY: boolean): InternalTexture;
  128. /**
  129. * Creates a new raw 3D texture
  130. * @param data defines the data used to create the texture
  131. * @param width defines the width of the texture
  132. * @param height defines the height of the texture
  133. * @param depth defines the depth of the texture
  134. * @param format defines the format of the texture
  135. * @param generateMipMaps defines if the engine must generate mip levels
  136. * @param invertY defines if data must be stored with Y axis inverted
  137. * @param samplingMode defines the required sampling mode (like Texture.NEAREST_SAMPLINGMODE)
  138. * @param compression defines the compressed used (can be null)
  139. * @param textureType defines the compressed used (can be null)
  140. * @returns a new raw 3D texture (stored in an InternalTexture)
  141. */
  142. createRawTexture3D(data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string>, textureType: number): InternalTexture;
  143. /**
  144. * Update a raw 3D texture
  145. * @param texture defines the texture to update
  146. * @param data defines the data to store
  147. * @param format defines the data format
  148. * @param invertY defines if data must be stored with Y axis inverted
  149. */
  150. updateRawTexture3D(texture: InternalTexture, data: Nullable<ArrayBufferView>, format: number, invertY: boolean): void;
  151. /**
  152. * Update a raw 3D texture
  153. * @param texture defines the texture to update
  154. * @param data defines the data to store
  155. * @param format defines the data format
  156. * @param invertY defines if data must be stored with Y axis inverted
  157. * @param compression defines the used compression (can be null)
  158. * @param textureType defines the texture Type (Engine.TEXTURETYPE_UNSIGNED_INT, Engine.TEXTURETYPE_FLOAT...)
  159. */
  160. updateRawTexture3D(texture: InternalTexture, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string>, textureType: number): void;
  161. }
  162. }
  163. Engine.prototype.updateRawTexture = function(texture: Nullable<InternalTexture>, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null, type: number = Engine.TEXTURETYPE_UNSIGNED_INT): void {
  164. if (!texture) {
  165. return;
  166. }
  167. // Babylon's internalSizedFomat but gl's texImage2D internalFormat
  168. var internalSizedFomat = this._getRGBABufferInternalSizedFormat(type, format);
  169. // Babylon's internalFormat but gl's texImage2D format
  170. var internalFormat = this._getInternalFormat(format);
  171. var textureType = this._getWebGLTextureType(type);
  172. this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
  173. this._unpackFlipY(invertY === undefined ? true : (invertY ? true : false));
  174. if (!this._doNotHandleContextLost) {
  175. texture._bufferView = data;
  176. texture.format = format;
  177. texture.type = type;
  178. texture.invertY = invertY;
  179. texture._compression = compression;
  180. }
  181. if (texture.width % 4 !== 0) {
  182. this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
  183. }
  184. if (compression && data) {
  185. this._gl.compressedTexImage2D(this._gl.TEXTURE_2D, 0, (<any>this.getCaps().s3tc)[compression], texture.width, texture.height, 0, <DataView>data);
  186. } else {
  187. this._gl.texImage2D(this._gl.TEXTURE_2D, 0, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, data);
  188. }
  189. if (texture.generateMipMaps) {
  190. this._gl.generateMipmap(this._gl.TEXTURE_2D);
  191. }
  192. this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
  193. // this.resetTextureCache();
  194. texture.isReady = true;
  195. };
  196. Engine.prototype.createRawTexture = function(data: Nullable<ArrayBufferView>, width: number, height: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null, type: number = Engine.TEXTURETYPE_UNSIGNED_INT): InternalTexture {
  197. var texture = new InternalTexture(this, InternalTexture.DATASOURCE_RAW);
  198. texture.baseWidth = width;
  199. texture.baseHeight = height;
  200. texture.width = width;
  201. texture.height = height;
  202. texture.format = format;
  203. texture.generateMipMaps = generateMipMaps;
  204. texture.samplingMode = samplingMode;
  205. texture.invertY = invertY;
  206. texture._compression = compression;
  207. texture.type = type;
  208. if (!this._doNotHandleContextLost) {
  209. texture._bufferView = data;
  210. }
  211. this.updateRawTexture(texture, data, format, invertY, compression, type);
  212. this._bindTextureDirectly(this._gl.TEXTURE_2D, texture, true);
  213. // Filters
  214. var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
  215. this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MAG_FILTER, filters.mag);
  216. this._gl.texParameteri(this._gl.TEXTURE_2D, this._gl.TEXTURE_MIN_FILTER, filters.min);
  217. if (generateMipMaps) {
  218. this._gl.generateMipmap(this._gl.TEXTURE_2D);
  219. }
  220. this._bindTextureDirectly(this._gl.TEXTURE_2D, null);
  221. this._internalTexturesCache.push(texture);
  222. return texture;
  223. };
  224. Engine.prototype.createRawCubeTexture = function(data: Nullable<ArrayBufferView[]>, size: number, format: number, type: number,
  225. generateMipMaps: boolean, invertY: boolean, samplingMode: number,
  226. compression: Nullable<string> = null): InternalTexture {
  227. var gl = this._gl;
  228. var texture = new InternalTexture(this, InternalTexture.DATASOURCE_CUBERAW);
  229. texture.isCube = true;
  230. texture.format = format;
  231. texture.type = type;
  232. if (!this._doNotHandleContextLost) {
  233. texture._bufferViewArray = data;
  234. }
  235. var textureType = this._getWebGLTextureType(type);
  236. var internalFormat = this._getInternalFormat(format);
  237. if (internalFormat === gl.RGB) {
  238. internalFormat = gl.RGBA;
  239. }
  240. // Mipmap generation needs a sized internal format that is both color-renderable and texture-filterable
  241. if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
  242. generateMipMaps = false;
  243. samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
  244. Logger.Warn("Float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
  245. }
  246. else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
  247. generateMipMaps = false;
  248. samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
  249. Logger.Warn("Half float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
  250. }
  251. else if (textureType === gl.FLOAT && !this._caps.textureFloatRender) {
  252. generateMipMaps = false;
  253. Logger.Warn("Render to float textures is not supported. Mipmap generation forced to false.");
  254. }
  255. else if (textureType === gl.HALF_FLOAT && !this._caps.colorBufferFloat) {
  256. generateMipMaps = false;
  257. Logger.Warn("Render to half float textures is not supported. Mipmap generation forced to false.");
  258. }
  259. var width = size;
  260. var height = width;
  261. texture.width = width;
  262. texture.height = height;
  263. // Double check on POT to generate Mips.
  264. var isPot = !this.needPOTTextures || (Tools.IsExponentOfTwo(texture.width) && Tools.IsExponentOfTwo(texture.height));
  265. if (!isPot) {
  266. generateMipMaps = false;
  267. }
  268. // Upload data if needed. The texture won't be ready until then.
  269. if (data) {
  270. this.updateRawCubeTexture(texture, data, format, type, invertY, compression);
  271. }
  272. this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, texture, true);
  273. // Filters
  274. if (data && generateMipMaps) {
  275. this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
  276. }
  277. var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
  278. gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
  279. gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
  280. gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  281. gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  282. this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
  283. texture.generateMipMaps = generateMipMaps;
  284. return texture;
  285. };
  286. Engine.prototype.updateRawCubeTexture = function(texture: InternalTexture, data: ArrayBufferView[], format: number, type: number, invertY: boolean, compression: Nullable<string> = null, level: number = 0): void {
  287. texture._bufferViewArray = data;
  288. texture.format = format;
  289. texture.type = type;
  290. texture.invertY = invertY;
  291. texture._compression = compression;
  292. var gl = this._gl;
  293. var textureType = this._getWebGLTextureType(type);
  294. var internalFormat = this._getInternalFormat(format);
  295. var internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);
  296. var needConversion = false;
  297. if (internalFormat === gl.RGB) {
  298. internalFormat = gl.RGBA;
  299. needConversion = true;
  300. }
  301. this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
  302. this._unpackFlipY(invertY === undefined ? true : (invertY ? true : false));
  303. if (texture.width % 4 !== 0) {
  304. gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
  305. }
  306. // Data are known to be in +X +Y +Z -X -Y -Z
  307. for (let faceIndex = 0; faceIndex < 6; faceIndex++) {
  308. let faceData = data[faceIndex];
  309. if (compression) {
  310. gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, (<any>(this.getCaps().s3tc))[compression], texture.width, texture.height, 0, <DataView>faceData);
  311. } else {
  312. if (needConversion) {
  313. faceData = this._convertRGBtoRGBATextureData(faceData, texture.width, texture.height, type);
  314. }
  315. gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, level, internalSizedFomat, texture.width, texture.height, 0, internalFormat, textureType, faceData);
  316. }
  317. }
  318. var isPot = !this.needPOTTextures || (Tools.IsExponentOfTwo(texture.width) && Tools.IsExponentOfTwo(texture.height));
  319. if (isPot && texture.generateMipMaps && level === 0) {
  320. this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
  321. }
  322. this._bindTextureDirectly(this._gl.TEXTURE_CUBE_MAP, null);
  323. // this.resetTextureCache();
  324. texture.isReady = true;
  325. };
  326. Engine.prototype.createRawCubeTextureFromUrl = function(url: string, scene: Scene, size: number, format: number, type: number, noMipmap: boolean,
  327. callback: (ArrayBuffer: ArrayBuffer) => Nullable<ArrayBufferView[]>,
  328. mipmapGenerator: Nullable<((faces: ArrayBufferView[]) => ArrayBufferView[][])>,
  329. onLoad: Nullable<() => void> = null,
  330. onError: Nullable<(message?: string, exception?: any) => void> = null,
  331. samplingMode: number = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE,
  332. invertY: boolean = false): InternalTexture {
  333. var gl = this._gl;
  334. var texture = this.createRawCubeTexture(null, size, format, type, !noMipmap, invertY, samplingMode);
  335. scene._addPendingData(texture);
  336. texture.url = url;
  337. this._internalTexturesCache.push(texture);
  338. var onerror = (request?: WebRequest, exception?: any) => {
  339. scene._removePendingData(texture);
  340. if (onError && request) {
  341. onError(request.status + " " + request.statusText, exception);
  342. }
  343. };
  344. var internalCallback = (data: any) => {
  345. var width = texture.width;
  346. var faceDataArrays = callback(data);
  347. if (!faceDataArrays) {
  348. return;
  349. }
  350. if (mipmapGenerator) {
  351. var textureType = this._getWebGLTextureType(type);
  352. var internalFormat = this._getInternalFormat(format);
  353. var internalSizedFomat = this._getRGBABufferInternalSizedFormat(type);
  354. var needConversion = false;
  355. if (internalFormat === gl.RGB) {
  356. internalFormat = gl.RGBA;
  357. needConversion = true;
  358. }
  359. this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
  360. this._unpackFlipY(false);
  361. var mipData = mipmapGenerator(faceDataArrays);
  362. for (var level = 0; level < mipData.length; level++) {
  363. var mipSize = width >> level;
  364. for (var faceIndex = 0; faceIndex < 6; faceIndex++) {
  365. let mipFaceData = mipData[level][faceIndex];
  366. if (needConversion) {
  367. mipFaceData = this._convertRGBtoRGBATextureData(mipFaceData, mipSize, mipSize, type);
  368. }
  369. gl.texImage2D(faceIndex, level, internalSizedFomat, mipSize, mipSize, 0, internalFormat, textureType, mipFaceData);
  370. }
  371. }
  372. this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
  373. }
  374. else {
  375. this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
  376. }
  377. texture.isReady = true;
  378. // this.resetTextureCache();
  379. scene._removePendingData(texture);
  380. if (onLoad) {
  381. onLoad();
  382. }
  383. };
  384. this._loadFile(url, (data) => {
  385. internalCallback(data);
  386. }, undefined, scene.offlineProvider, true, onerror);
  387. return texture;
  388. };
  389. Engine.prototype.createRawTexture3D = function(data: Nullable<ArrayBufferView>, width: number, height: number, depth: number, format: number, generateMipMaps: boolean, invertY: boolean, samplingMode: number, compression: Nullable<string> = null, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT): InternalTexture {
  390. var texture = new InternalTexture(this, InternalTexture.DATASOURCE_RAW3D);
  391. texture.baseWidth = width;
  392. texture.baseHeight = height;
  393. texture.baseDepth = depth;
  394. texture.width = width;
  395. texture.height = height;
  396. texture.depth = depth;
  397. texture.format = format;
  398. texture.type = textureType;
  399. texture.generateMipMaps = generateMipMaps;
  400. texture.samplingMode = samplingMode;
  401. texture.is3D = true;
  402. if (!this._doNotHandleContextLost) {
  403. texture._bufferView = data;
  404. }
  405. this.updateRawTexture3D(texture, data, format, invertY, compression, textureType);
  406. this._bindTextureDirectly(this._gl.TEXTURE_3D, texture, true);
  407. // Filters
  408. var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
  409. this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MAG_FILTER, filters.mag);
  410. this._gl.texParameteri(this._gl.TEXTURE_3D, this._gl.TEXTURE_MIN_FILTER, filters.min);
  411. if (generateMipMaps) {
  412. this._gl.generateMipmap(this._gl.TEXTURE_3D);
  413. }
  414. this._bindTextureDirectly(this._gl.TEXTURE_3D, null);
  415. this._internalTexturesCache.push(texture);
  416. return texture;
  417. };
  418. Engine.prototype.updateRawTexture3D = function(texture: InternalTexture, data: Nullable<ArrayBufferView>, format: number, invertY: boolean, compression: Nullable<string> = null, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT): void {
  419. var internalType = this._getWebGLTextureType(textureType);
  420. var internalFormat = this._getInternalFormat(format);
  421. var internalSizedFomat = this._getRGBABufferInternalSizedFormat(textureType, format);
  422. this._bindTextureDirectly(this._gl.TEXTURE_3D, texture, true);
  423. this._unpackFlipY(invertY === undefined ? true : (invertY ? true : false));
  424. if (!this._doNotHandleContextLost) {
  425. texture._bufferView = data;
  426. texture.format = format;
  427. texture.invertY = invertY;
  428. texture._compression = compression;
  429. }
  430. if (texture.width % 4 !== 0) {
  431. this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 1);
  432. }
  433. if (compression && data) {
  434. this._gl.compressedTexImage3D(this._gl.TEXTURE_3D, 0, (<any>this.getCaps().s3tc)[compression], texture.width, texture.height, texture.depth, 0, data);
  435. } else {
  436. this._gl.texImage3D(this._gl.TEXTURE_3D, 0, internalSizedFomat, texture.width, texture.height, texture.depth, 0, internalFormat, internalType, data);
  437. }
  438. if (texture.generateMipMaps) {
  439. this._gl.generateMipmap(this._gl.TEXTURE_3D);
  440. }
  441. this._bindTextureDirectly(this._gl.TEXTURE_3D, null);
  442. // this.resetTextureCache();
  443. texture.isReady = true;
  444. };