Jelajahi Sumber

Merge pull request #7513 from bghgary/texture-loader-fixes

Use ArrayBufferView for texture loaders
David Catuhe 5 tahun lalu
induk
melakukan
a1511e1060

+ 11 - 11
src/Engines/Extensions/engine.cubeTexture.ts

@@ -76,10 +76,10 @@ declare module "../../Engines/thinEngine" {
             format: number | undefined, forcedExtension: any, createPolynomials: boolean, lodScale: number, lodOffset: number): InternalTexture;
 
         /** @hidden */
-        _partialLoadFile(url: string, index: number, loadedFiles: (string | ArrayBuffer)[], onfinish: (files: (string | ArrayBuffer)[]) => void, onErrorCallBack: Nullable<(message?: string, exception?: any) => void>): void;
+        _partialLoadFile(url: string, index: number, loadedFiles: ArrayBuffer[], onfinish: (files: ArrayBuffer[]) => void, onErrorCallBack: Nullable<(message?: string, exception?: any) => void>): void;
 
         /** @hidden */
-        _cascadeLoadFiles(scene: Nullable<Scene>, onfinish: (images: (string | ArrayBuffer)[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void>): void;
+        _cascadeLoadFiles(scene: Nullable<Scene>, onfinish: (images: ArrayBuffer[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void>): void;
 
         /** @hidden */
         _cascadeLoadImgs(scene: Nullable<Scene>, onfinish: (images: HTMLImageElement[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void>, mimeType?: string): void;
@@ -130,9 +130,9 @@ ThinEngine.prototype._createDepthStencilCubeTexture = function(size: number, opt
     return internalTexture;
 };
 
-ThinEngine.prototype._partialLoadFile = function(url: string, index: number, loadedFiles: (string | ArrayBuffer)[],
-    onfinish: (files: (string | ArrayBuffer)[]) => void, onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null): void {
-    var onload = (data: string | ArrayBuffer) => {
+ThinEngine.prototype._partialLoadFile = function(url: string, index: number, loadedFiles: ArrayBuffer[],
+    onfinish: (files: ArrayBuffer[]) => void, onErrorCallBack: Nullable<(message?: string, exception?: any) => void> = null): void {
+    var onload = (data: ArrayBuffer) => {
         loadedFiles[index] = data;
         (<any>loadedFiles)._internalCount++;
 
@@ -147,11 +147,11 @@ ThinEngine.prototype._partialLoadFile = function(url: string, index: number, loa
         }
     };
 
-    this._loadFile(url, onload, undefined, undefined, true, onerror);
+    this._loadFile(url, onload as (data: string | ArrayBuffer) => void, undefined, undefined, true, onerror);
 };
 
-ThinEngine.prototype._cascadeLoadFiles = function(scene: Nullable<Scene>, onfinish: (images: (string | ArrayBuffer)[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void> = null): void {
-    var loadedFiles: (string | ArrayBuffer)[] = [];
+ThinEngine.prototype._cascadeLoadFiles = function(scene: Nullable<Scene>, onfinish: (images: ArrayBuffer[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void> = null): void {
+    var loadedFiles: ArrayBuffer[] = [];
     (<any>loadedFiles)._internalCount = 0;
 
     for (let index = 0; index < 6; index++) {
@@ -262,13 +262,13 @@ ThinEngine.prototype.createCubeTexture = function(rootUrl: string, scene: Nullab
     if (loader) {
         rootUrl = loader.transformUrl(rootUrl, filteredFormat);
 
-        const onloaddata = (data: any) => {
+        const onloaddata = (data: ArrayBufferView | ArrayBufferView[]) => {
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
             loader!.loadCubeData(data, texture, createPolynomials, onLoad, onError);
         };
         if (files && files.length === 6) {
             if (loader.supportCascades) {
-                this._cascadeLoadFiles(scene, onloaddata, files, onError);
+                this._cascadeLoadFiles(scene, (images) => onloaddata(images.map((image) => new Uint8Array(image))), files, onError);
             }
             else {
                 if (onError) {
@@ -279,7 +279,7 @@ ThinEngine.prototype.createCubeTexture = function(rootUrl: string, scene: Nullab
             }
         }
         else {
-            this._loadFile(rootUrl, onloaddata, undefined, undefined, true, onInternalError);
+            this._loadFile(rootUrl, (data) => onloaddata(new Uint8Array(data as ArrayBuffer)), undefined, undefined, true, onInternalError);
         }
     }
     else {

+ 2 - 4
src/Engines/nativeEngine.ts

@@ -1076,9 +1076,7 @@ export class NativeEngine extends Engine {
         var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "");
 
         if (extension === ".env") {
-            const onloaddata = (data: any) => {
-                data = data as ArrayBuffer;
-
+            const onloaddata = (data: ArrayBufferView) => {
                 var info = EnvironmentTextureTools.GetEnvInfo(data)!;
                 texture.width = info.width;
                 texture.height = info.width;
@@ -1122,7 +1120,7 @@ export class NativeEngine extends Engine {
                     }
                 };
 
-                this._loadFile(rootUrl, onloaddata, undefined, undefined, true, onInternalError);
+                this._loadFile(rootUrl, (data) => onloaddata(new Uint8Array(data as ArrayBuffer)), undefined, undefined, true, onInternalError);
             }
         }
         else {

+ 7 - 5
src/Engines/thinEngine.ts

@@ -2874,8 +2874,8 @@ export class ThinEngine {
 
         // processing for non-image formats
         if (loader) {
-            var callback = (data: string | ArrayBuffer) => {
-                loader!.loadData(data as ArrayBuffer, texture, (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void, loadFailed) => {
+            var callback = (data: ArrayBufferView) => {
+                loader!.loadData(data, texture, (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void, loadFailed) => {
                     if (loadFailed) {
                         onInternalError("TextureLoader failed to load data");
                     } else {
@@ -2888,17 +2888,19 @@ export class ThinEngine {
             };
 
             if (!buffer) {
-                this._loadFile(url, callback, undefined, scene ? scene.offlineProvider : undefined, true, (request?: IWebRequest, exception?: any) => {
+                this._loadFile(url, (data) => callback(new Uint8Array(data as ArrayBuffer)), undefined, scene ? scene.offlineProvider : undefined, true, (request?: IWebRequest, exception?: any) => {
                     onInternalError("Unable to load " + (request ? request.responseURL : url, exception));
                 });
             } else {
-                //callback(buffer as ArrayBuffer);
                 if (buffer instanceof ArrayBuffer) {
+                    callback(new Uint8Array(buffer));
+                }
+                else if (ArrayBuffer.isView(buffer)) {
                     callback(buffer);
                 }
                 else {
                     if (onError) {
-                        onError("Unable to load: only ArrayBuffer supported here", null);
+                        onError("Unable to load: only ArrayBuffer or ArrayBufferView is supported", null);
                     }
                 }
             }

+ 3 - 3
src/Materials/Textures/Loaders/basisTextureLoader.ts

@@ -56,7 +56,7 @@ export class _BasisTextureLoader implements IInternalTextureLoader {
      * @param onLoad defines the callback to trigger once the texture is ready
      * @param onError defines the callback to trigger in case of error
      */
-    public loadCubeData(data: string | ArrayBuffer | (string | ArrayBuffer)[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
+    public loadCubeData(data: ArrayBufferView | ArrayBufferView[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
         if (Array.isArray(data)) {
             return;
         }
@@ -69,7 +69,7 @@ export class _BasisTextureLoader implements IInternalTextureLoader {
                 etc2: caps.etc2 ? true : false
             }
         };
-        BasisTools.TranscodeAsync(data as ArrayBuffer, transcodeConfig).then((result) => {
+        BasisTools.TranscodeAsync(data, transcodeConfig).then((result) => {
             var hasMipmap = result.fileInfo.images[0].levels.length > 1 && texture.generateMipMaps;
             BasisTools.LoadTextureFromTranscodeResult(texture, result);
             (texture.getEngine() as Engine)._setCubeMapTextureParams(hasMipmap);
@@ -91,7 +91,7 @@ export class _BasisTextureLoader implements IInternalTextureLoader {
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      */
-    public loadData(data: ArrayBuffer, texture: InternalTexture,
+    public loadData(data: ArrayBufferView, texture: InternalTexture,
         callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => void): void {
         var caps = texture.getEngine().getCaps();
         var transcodeConfig = {

+ 2 - 2
src/Materials/Textures/Loaders/ddsTextureLoader.ts

@@ -56,7 +56,7 @@ export class _DDSTextureLoader implements IInternalTextureLoader {
      * @param onLoad defines the callback to trigger once the texture is ready
      * @param onError defines the callback to trigger in case of error
      */
-    public loadCubeData(imgs: string | ArrayBuffer | (string | ArrayBuffer)[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
+    public loadCubeData(imgs: ArrayBufferView | ArrayBufferView[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
         var engine = texture.getEngine() as Engine;
         var info: DDSInfo | undefined;
         var loadMipmap: boolean = false;
@@ -116,7 +116,7 @@ export class _DDSTextureLoader implements IInternalTextureLoader {
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      */
-    public loadData(data: ArrayBuffer, texture: InternalTexture,
+    public loadData(data: ArrayBufferView, texture: InternalTexture,
         callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => void): void {
         var info = DDSTools.GetDDSInfo(data);
 

+ 2 - 3
src/Materials/Textures/Loaders/envTextureLoader.ts

@@ -55,12 +55,11 @@ export class _ENVTextureLoader implements IInternalTextureLoader {
      * @param onLoad defines the callback to trigger once the texture is ready
      * @param onError defines the callback to trigger in case of error
      */
-    public loadCubeData(data: string | ArrayBuffer | (string | ArrayBuffer)[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
+    public loadCubeData(data: ArrayBufferView | ArrayBufferView[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
         if (Array.isArray(data)) {
             return;
         }
 
-        data = data as ArrayBuffer;
         var info = EnvironmentTextureTools.GetEnvInfo(data);
         if (info) {
             texture.width = info.width;
@@ -87,7 +86,7 @@ export class _ENVTextureLoader implements IInternalTextureLoader {
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      */
-    public loadData(data: ArrayBuffer, texture: InternalTexture,
+    public loadData(data: ArrayBufferView, texture: InternalTexture,
         callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => void): void {
         throw ".env not supported in 2d.";
     }

+ 2 - 2
src/Materials/Textures/Loaders/ktxTextureLoader.ts

@@ -65,7 +65,7 @@ export class _KTXTextureLoader implements IInternalTextureLoader {
      * @param onLoad defines the callback to trigger once the texture is ready
      * @param onError defines the callback to trigger in case of error
      */
-    public loadCubeData(data: string | ArrayBuffer | (string | ArrayBuffer)[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
+    public loadCubeData(data: ArrayBufferView | ArrayBufferView[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
         if (Array.isArray(data)) {
             return;
         }
@@ -100,7 +100,7 @@ export class _KTXTextureLoader implements IInternalTextureLoader {
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      */
-    public loadData(data: ArrayBuffer, texture: InternalTexture,
+    public loadData(data: ArrayBufferView, texture: InternalTexture,
         callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void, loadFailed: boolean) => void): void {
         // Need to invert vScale as invertY via UNPACK_FLIP_Y_WEBGL is not supported by compressed texture
         texture._invertVScale = !texture.invertY;

+ 5 - 5
src/Materials/Textures/Loaders/tgaTextureLoader.ts

@@ -55,7 +55,7 @@ export class _TGATextureLoader implements IInternalTextureLoader {
      * @param onLoad defines the callback to trigger once the texture is ready
      * @param onError defines the callback to trigger in case of error
      */
-    public loadCubeData(data: string | ArrayBuffer | (string | ArrayBuffer)[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
+    public loadCubeData(data: ArrayBufferView | ArrayBufferView[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void {
         throw ".env not supported in Cube.";
     }
 
@@ -65,13 +65,13 @@ export class _TGATextureLoader implements IInternalTextureLoader {
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      */
-    public loadData(data: ArrayBuffer, texture: InternalTexture,
+    public loadData(data: ArrayBufferView, texture: InternalTexture,
         callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void) => void): void {
-        var uintData = new Uint8Array(data);
+        var bytes = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
 
-        var header = TGATools.GetTGAHeader(uintData);
+        var header = TGATools.GetTGAHeader(bytes);
         callback(header.width, header.height, texture.generateMipMaps, false, () => {
-            TGATools.UploadContent(texture, uintData);
+            TGATools.UploadContent(texture, bytes);
         });
     }
 }

+ 2 - 2
src/Materials/Textures/internalTextureLoader.ts

@@ -45,7 +45,7 @@ export interface IInternalTextureLoader {
      * @param onLoad defines the callback to trigger once the texture is ready
      * @param onError defines the callback to trigger in case of error
      */
-    loadCubeData(data: string | ArrayBuffer | (string | ArrayBuffer)[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void;
+    loadCubeData(data: ArrayBufferView | ArrayBufferView[], texture: InternalTexture, createPolynomials: boolean, onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>): void;
 
     /**
      * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
@@ -53,6 +53,6 @@ export interface IInternalTextureLoader {
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      */
-    loadData(data: ArrayBuffer, texture: InternalTexture,
+    loadData(data: ArrayBufferView, texture: InternalTexture,
         callback: (width: number, height: number, loadMipmap: boolean, isCompressed: boolean, done: () => void, loadFailed?: boolean) => void): void;
 }

+ 9 - 4
src/Misc/basis.ts

@@ -151,11 +151,13 @@ export class BasisTools {
 
     /**
      * Transcodes a loaded image file to compressed pixel data
-     * @param imageData image data to transcode
+     * @param data image data to transcode
      * @param config configuration options for the transcoding
      * @returns a promise resulting in the transcoded image
      */
-    public static TranscodeAsync(imageData: ArrayBuffer, config: BasisTranscodeConfiguration): Promise<TranscodeResult> {
+    public static TranscodeAsync(data: ArrayBuffer | ArrayBufferView, config: BasisTranscodeConfiguration): Promise<TranscodeResult> {
+        const dataView = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
+
         return new Promise((res, rej) => {
             this._CreateWorkerAsync().then(() => {
                 var actionId = this._actionId++;
@@ -170,7 +172,10 @@ export class BasisTools {
                     }
                 };
                 this._Worker!.addEventListener("message", messageHandler);
-                this._Worker!.postMessage({action: "transcode", id: actionId, imageData: imageData, config: config, ignoreSupportedFormats: this._IgnoreSupportedFormats}, [imageData]);
+
+                const dataViewCopy = new Uint8Array(dataView.byteLength);
+                dataViewCopy.set(new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength));
+                this._Worker!.postMessage({action: "transcode", id: actionId, imageData: dataViewCopy, config: config, ignoreSupportedFormats: this._IgnoreSupportedFormats}, [dataViewCopy.buffer]);
             });
         });
     }
@@ -274,7 +279,7 @@ function workerFunc(): void {
             // Transcode the basis image and return the resulting pixels
             var config: BasisTranscodeConfiguration = event.data.config;
             var imgData = event.data.imageData;
-            var loadedFile = new Module.BasisFile(new Uint8Array(imgData));
+            var loadedFile = new Module.BasisFile(imgData);
             var fileInfo = GetFileInfo(loadedFile);
             var format = event.data.ignoreSupportedFormats ? null : GetSupportedTranscodeFormat(event.data.config, fileInfo);
 

+ 18 - 18
src/Misc/dds.ts

@@ -165,12 +165,12 @@ export class DDSTools {
 
     /**
      * Gets DDS information from an array buffer
-     * @param arrayBuffer defines the array buffer to read data from
+     * @param data defines the array buffer view to read data from
      * @returns the DDS information
      */
-    public static GetDDSInfo(arrayBuffer: any): DDSInfo {
-        var header = new Int32Array(arrayBuffer, 0, headerLengthInt);
-        var extendedHeader = new Int32Array(arrayBuffer, 0, headerLengthInt + 4);
+    public static GetDDSInfo(data: ArrayBufferView): DDSInfo {
+        var header = new Int32Array(data.buffer, data.byteOffset, headerLengthInt);
+        var extendedHeader = new Int32Array(data.buffer, data.byteOffset, headerLengthInt + 4);
 
         var mipmapCount = 1;
         if (header[off_flags] & DDSD_MIPMAPCOUNT) {
@@ -445,14 +445,14 @@ export class DDSTools {
      * Uploads DDS Levels to a Babylon Texture
      * @hidden
      */
-    public static UploadDDSLevels(engine: ThinEngine, texture: InternalTexture, arrayBuffer: any, info: DDSInfo, loadMipmaps: boolean, faces: number, lodIndex = -1, currentFace?: number) {
+    public static UploadDDSLevels(engine: ThinEngine, texture: InternalTexture, data: ArrayBufferView, info: DDSInfo, loadMipmaps: boolean, faces: number, lodIndex = -1, currentFace?: number) {
         var sphericalPolynomialFaces: Nullable<Array<ArrayBufferView>> = null;
         if (info.sphericalPolynomial) {
             sphericalPolynomialFaces = new Array<ArrayBufferView>();
         }
         var ext = engine.getCaps().s3tc;
 
-        var header = new Int32Array(arrayBuffer, 0, headerLengthInt);
+        var header = new Int32Array(data.buffer, data.byteOffset, headerLengthInt);
         var fourCC: number, width: number, height: number, dataLength: number = 0, dataOffset: number;
         var byteArray: Uint8Array, mipmapCount: number, mip: number;
         let internalCompressedFormat = 0;
@@ -558,15 +558,15 @@ export class DDSTools {
 
                         if (engine._badOS || engine._badDesktopOS || (!engine.getCaps().textureHalfFloat && !engine.getCaps().textureFloat)) { // Required because iOS has many issues with float and half float generation
                             if (bpp === 128) {
-                                floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                floatArray = DDSTools._GetFloatAsUIntRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);
                                 if (sphericalPolynomialFaces && i == 0) {
-                                    sphericalPolynomialFaces.push(DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i));
+                                    sphericalPolynomialFaces.push(DDSTools._GetFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i));
                                 }
                             }
                             else if (bpp === 64) {
-                                floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                floatArray = DDSTools._GetHalfFloatAsUIntRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);
                                 if (sphericalPolynomialFaces && i == 0) {
-                                    sphericalPolynomialFaces.push(DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i));
+                                    sphericalPolynomialFaces.push(DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i));
                                 }
                             }
 
@@ -575,21 +575,21 @@ export class DDSTools {
                         else {
                             if (bpp === 128) {
                                 texture.type = Constants.TEXTURETYPE_FLOAT;
-                                floatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                floatArray = DDSTools._GetFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);
                                 if (sphericalPolynomialFaces && i == 0) {
                                     sphericalPolynomialFaces.push(floatArray);
                                 }
                             } else if (bpp === 64 && !engine.getCaps().textureHalfFloat) {
                                 texture.type = Constants.TEXTURETYPE_FLOAT;
-                                floatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                floatArray = DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);
                                 if (sphericalPolynomialFaces && i == 0) {
                                     sphericalPolynomialFaces.push(floatArray);
                                 }
                             } else { // 64
                                 texture.type = Constants.TEXTURETYPE_HALF_FLOAT;
-                                floatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i);
+                                floatArray = DDSTools._GetHalfFloatRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, i);
                                 if (sphericalPolynomialFaces && i == 0) {
-                                    sphericalPolynomialFaces.push(DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, i));
+                                    sphericalPolynomialFaces.push(DDSTools._GetHalfFloatAsFloatRGBAArrayBuffer(width, height, dataOffset, dataLength, data.buffer, i));
                                 }
                             }
                         }
@@ -602,12 +602,12 @@ export class DDSTools {
                         if (bpp === 24) {
                             texture.format = Constants.TEXTUREFORMAT_RGB;
                             dataLength = width * height * 3;
-                            byteArray = DDSTools._GetRGBArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, rOffset, gOffset, bOffset);
+                            byteArray = DDSTools._GetRGBArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, rOffset, gOffset, bOffset);
                             engine._uploadDataToTextureDirectly(texture, byteArray, face, i);
                         } else { // 32
                             texture.format = Constants.TEXTUREFORMAT_RGBA;
                             dataLength = width * height * 4;
-                            byteArray = DDSTools._GetRGBAArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer, rOffset, gOffset, bOffset, aOffset);
+                            byteArray = DDSTools._GetRGBAArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer, rOffset, gOffset, bOffset, aOffset);
                             engine._uploadDataToTextureDirectly(texture, byteArray, face, i);
                         }
                     } else if (info.isLuminance) {
@@ -616,14 +616,14 @@ export class DDSTools {
                         var paddedRowSize = Math.floor((width + unpackAlignment - 1) / unpackAlignment) * unpackAlignment;
                         dataLength = paddedRowSize * (height - 1) + unpaddedRowSize;
 
-                        byteArray = DDSTools._GetLuminanceArrayBuffer(width, height, dataOffset, dataLength, arrayBuffer);
+                        byteArray = DDSTools._GetLuminanceArrayBuffer(width, height, data.byteOffset + dataOffset, dataLength, data.buffer);
                         texture.format = Constants.TEXTUREFORMAT_LUMINANCE;
                         texture.type = Constants.TEXTURETYPE_UNSIGNED_INT;
 
                         engine._uploadDataToTextureDirectly(texture, byteArray, face, i);
                     } else {
                         dataLength = Math.max(4, width) / 4 * Math.max(4, height) / 4 * blockBytes;
-                        byteArray = new Uint8Array(arrayBuffer, dataOffset, dataLength);
+                        byteArray = new Uint8Array(data.buffer, data.byteOffset + dataOffset, dataLength);
 
                         texture.type = Constants.TEXTURETYPE_UNSIGNED_INT;
                         engine._uploadCompressedDataToTextureDirectly(texture, internalCompressedFormat, width, height, byteArray, face, i);

+ 8 - 8
src/Misc/environmentTextureTools.ts

@@ -111,8 +111,8 @@ export class EnvironmentTextureTools {
      * @param data The array buffer containing the .env bytes.
      * @returns the environment file info (the json header) if successfully parsed.
      */
-    public static GetEnvInfo(data: ArrayBuffer): Nullable<EnvironmentTextureInfo> {
-        let dataView = new DataView(data);
+    public static GetEnvInfo(data: ArrayBufferView): Nullable<EnvironmentTextureInfo> {
+        let dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);
         let pos = 0;
 
         for (let i = 0; i < EnvironmentTextureTools._MagicBytes.length; i++) {
@@ -326,11 +326,11 @@ export class EnvironmentTextureTools {
 
     /**
      * Creates the ArrayBufferViews used for initializing environment texture image data.
-     * @param arrayBuffer the underlying ArrayBuffer to which the views refer
+     * @param data the image data
      * @param info parameters that determine what views will be created for accessing the underlying buffer
      * @return the views described by info providing access to the underlying buffer
      */
-    public static CreateImageDataArrayBufferViews(arrayBuffer: any, info: EnvironmentTextureInfo): Array<Array<ArrayBufferView>> {
+    public static CreateImageDataArrayBufferViews(data: ArrayBufferView, info: EnvironmentTextureInfo): Array<Array<ArrayBufferView>> {
         if (info.version !== 1) {
             throw new Error(`Unsupported babylon environment map version "${info.version}"`);
         }
@@ -349,7 +349,7 @@ export class EnvironmentTextureTools {
             imageData[i] = new Array<ArrayBufferView>(6);
             for (let face = 0; face < 6; face++) {
                 const imageInfo = specularInfo.mipmaps[i * 6 + face];
-                imageData[i][face] = new Uint8Array(arrayBuffer, specularInfo.specularDataPosition! + imageInfo.position, imageInfo.length);
+                imageData[i][face] = new Uint8Array(data.buffer, data.byteOffset + specularInfo.specularDataPosition! + imageInfo.position, imageInfo.length);
             }
         }
 
@@ -359,11 +359,11 @@ export class EnvironmentTextureTools {
     /**
      * Uploads the texture info contained in the env file to the GPU.
      * @param texture defines the internal texture to upload to
-     * @param arrayBuffer defines the buffer cotaining the data to load
+     * @param data defines the data to load
      * @param info defines the texture info retrieved through the GetEnvInfo method
      * @returns a promise
      */
-    public static UploadEnvLevelsAsync(texture: InternalTexture, arrayBuffer: any, info: EnvironmentTextureInfo): Promise<void> {
+    public static UploadEnvLevelsAsync(texture: InternalTexture, data: ArrayBufferView, info: EnvironmentTextureInfo): Promise<void> {
         if (info.version !== 1) {
             throw new Error(`Unsupported babylon environment map version "${info.version}"`);
         }
@@ -376,7 +376,7 @@ export class EnvironmentTextureTools {
 
         texture._lodGenerationScale = specularInfo.lodGenerationScale;
 
-        const imageData = EnvironmentTextureTools.CreateImageDataArrayBufferViews(arrayBuffer, info);
+        const imageData = EnvironmentTextureTools.CreateImageDataArrayBufferViews(data, info);
 
         return EnvironmentTextureTools.UploadLevelsAsync(texture, imageData);
     }

+ 6 - 6
src/Misc/khronosTextureContainer.ts

@@ -74,18 +74,18 @@ export class KhronosTextureContainer {
 
     /**
      * Creates a new KhronosTextureContainer
-     * @param arrayBuffer contents of the KTX container file
+     * @param data contents of the KTX container file
      * @param facesExpected should be either 1 or 6, based whether a cube texture or or
      * @param threeDExpected provision for indicating that data should be a 3D texture, not implemented
      * @param textureArrayExpected provision for indicating that data should be a texture array, not implemented
      */
     public constructor(
         /** contents of the KTX container file */
-        public arrayBuffer: any, facesExpected: number, threeDExpected?: boolean, textureArrayExpected?: boolean) {
+        public data: ArrayBufferView, facesExpected: number, threeDExpected?: boolean, textureArrayExpected?: boolean) {
         // Test that it is a ktx formatted file, based on the first 12 bytes, character representation is:
         // '�', 'K', 'T', 'X', ' ', '1', '1', '�', '\r', '\n', '\x1A', '\n'
         // 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A
-        var identifier = new Uint8Array(this.arrayBuffer, 0, 12);
+        var identifier = new Uint8Array(this.data.buffer, this.data.byteOffset, 12);
         if (identifier[0] !== 0xAB || identifier[1] !== 0x4B || identifier[2] !== 0x54 || identifier[3] !== 0x58 || identifier[4] !== 0x20 || identifier[5] !== 0x31 ||
             identifier[6] !== 0x31 || identifier[7] !== 0xBB || identifier[8] !== 0x0D || identifier[9] !== 0x0A || identifier[10] !== 0x1A || identifier[11] !== 0x0A) {
             this.isInvalid = true;
@@ -95,7 +95,7 @@ export class KhronosTextureContainer {
 
         // load the reset of the header in native 32 bit uint
         var dataSize = Uint32Array.BYTES_PER_ELEMENT;
-        var headerDataView = new DataView(this.arrayBuffer, 12, 13 * dataSize);
+        var headerDataView = new DataView(this.data.buffer, this.data.byteOffset + 12, 13 * dataSize);
         var endianness = headerDataView.getUint32(0, true);
         var littleEndian = endianness === 0x04030201;
 
@@ -166,10 +166,10 @@ export class KhronosTextureContainer {
 
         var mipmapCount = loadMipmaps ? this.numberOfMipmapLevels : 1;
         for (var level = 0; level < mipmapCount; level++) {
-            var imageSize = new Int32Array(this.arrayBuffer, dataOffset, 1)[0]; // size per face, since not supporting array cubemaps
+            var imageSize = new Int32Array(this.data.buffer, this.data.byteOffset + dataOffset, 1)[0]; // size per face, since not supporting array cubemaps
             dataOffset += 4; //image data starts from next multiple of 4 offset. Each face refers to same imagesize field above.
             for (var face = 0; face < this.numberOfFaces; face++) {
-                var byteArray = new Uint8Array(this.arrayBuffer, dataOffset, imageSize);
+                var byteArray = new Uint8Array(this.data.buffer, this.data.byteOffset + dataOffset, imageSize);
 
                 const engine = texture.getEngine();
                 engine._uploadCompressedDataToTextureDirectly(texture, this.glInternalFormat, width, height, byteArray, face, level);