Browse Source

Proposed fix for issue where non-webgl enabled engine instances encounter null reference when reading glTexture information. added additional null checking in engine before gl context is invoked, added error handling to invoking parameters, and backed out texture export in case of error when exporting.

Nicholas Barlow 5 years ago
parent
commit
d2e571c403

+ 7 - 2
serializers/src/glTF/2.0/glTFMaterialExporter.ts

@@ -1138,7 +1138,7 @@ export class _GLTFMaterialExporter {
         return this._finishMaterial(promises, glTFMaterial, babylonPBRMaterial, mimeType);
         return this._finishMaterial(promises, glTFMaterial, babylonPBRMaterial, mimeType);
     }
     }
 
 
-    private getPixelsFromTexture(babylonTexture: BaseTexture): Uint8Array | Float32Array {
+    private getPixelsFromTexture(babylonTexture: BaseTexture): Nullable<Uint8Array | Float32Array> {
         const pixels = babylonTexture.textureType === Constants.TEXTURETYPE_UNSIGNED_INT ? babylonTexture.readPixels() as Uint8Array : babylonTexture.readPixels() as Float32Array;
         const pixels = babylonTexture.textureType === Constants.TEXTURETYPE_UNSIGNED_INT ? babylonTexture.readPixels() as Uint8Array : babylonTexture.readPixels() as Float32Array;
         return pixels;
         return pixels;
     }
     }
@@ -1170,6 +1170,11 @@ export class _GLTFMaterialExporter {
                 return this._textureMap[textureUid];
                 return this._textureMap[textureUid];
             }
             }
             else {
             else {
+                const pixels = this.getPixelsFromTexture(babylonTexture);
+                if (!pixels) {
+                    return null;
+                }
+
                 const samplers = this._exporter._samplers;
                 const samplers = this._exporter._samplers;
                 const sampler = this._getGLTFTextureSampler(babylonTexture);
                 const sampler = this._getGLTFTextureSampler(babylonTexture);
                 let samplerIndex: Nullable<number> = null;
                 let samplerIndex: Nullable<number> = null;
@@ -1184,6 +1189,7 @@ export class _GLTFMaterialExporter {
                         break;
                         break;
                     }
                     }
                 }
                 }
+
                 if (foundSamplerIndex == null) {
                 if (foundSamplerIndex == null) {
                     samplers.push(sampler);
                     samplers.push(sampler);
                     samplerIndex = samplers.length - 1;
                     samplerIndex = samplers.length - 1;
@@ -1191,7 +1197,6 @@ export class _GLTFMaterialExporter {
                 else {
                 else {
                     samplerIndex = foundSamplerIndex;
                     samplerIndex = foundSamplerIndex;
                 }
                 }
-                const pixels = this.getPixelsFromTexture(babylonTexture);
                 const size = babylonTexture.getSize();
                 const size = babylonTexture.getSize();
 
 
                 return this._createBase64FromCanvasAsync(pixels, size.width, size.height, mimeType).then((base64Data) => {
                 return this._createBase64FromCanvasAsync(pixels, size.width, size.height, mimeType).then((base64Data) => {

+ 3 - 0
src/Engines/engine.ts

@@ -1779,6 +1779,9 @@ export class Engine extends ThinEngine {
     /** @hidden */
     /** @hidden */
     public _readTexturePixels(texture: InternalTexture, width: number, height: number, faceIndex = -1, level = 0, buffer: Nullable<ArrayBufferView> = null): ArrayBufferView {
     public _readTexturePixels(texture: InternalTexture, width: number, height: number, faceIndex = -1, level = 0, buffer: Nullable<ArrayBufferView> = null): ArrayBufferView {
         let gl = this._gl;
         let gl = this._gl;
+        if (!gl) {
+            throw new Error ("Engine does not have gl rendering context.");
+        }
         if (!this._dummyFramebuffer) {
         if (!this._dummyFramebuffer) {
             let dummy = gl.createFramebuffer();
             let dummy = gl.createFramebuffer();
 
 

+ 8 - 4
src/Materials/Textures/baseTexture.ts

@@ -669,11 +669,15 @@ export class BaseTexture implements IAnimatable {
             height = Math.round(height);
             height = Math.round(height);
         }
         }
 
 
-        if (this._texture.isCube) {
-            return engine._readTexturePixels(this._texture, width, height, faceIndex, level, buffer);
-        }
+        try {
+            if (this._texture.isCube) {
+                return engine._readTexturePixels(this._texture, width, height, faceIndex, level, buffer);
+            }
 
 
-        return engine._readTexturePixels(this._texture, width, height, -1, level, buffer);
+            return engine._readTexturePixels(this._texture, width, height, -1, level, buffer);
+        } catch (e) {
+            return null;
+        }
     }
     }
 
 
     /**
     /**