Преглед изворни кода

Trying to make the mipmaps work in the rendering...

Popov72 пре 5 година
родитељ
комит
c267145aa5

+ 23 - 12
src/Misc/KTX2/KTX2WorkerThread.ts

@@ -17,13 +17,19 @@ const COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00;
 const COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
 const COMPRESSED_RGB8_ETC2 = 0x9274;
 const COMPRESSED_RGB_ETC1_WEBGL = 0x8D64;
-const RGBAFormat = 0x3FF;
+const RGBA8Format = 0x8058;
 
 export interface IMipmap {
     data: Nullable<Uint8Array>;
     width: number;
     height: number;
+}
+
+export interface IDecodedData {
+    width: number;
+    height: number;
     transcodedFormat: number;
+    mipmaps: Array<IMipmap>;
 }
 
 export function workerFunc(): void {
@@ -41,8 +47,8 @@ export function workerFunc(): void {
             case "createMipmaps":
                 try {
                     const kfr = new KTX2FileReader(event.data.data);
-                    _createMipmaps(kfr, event.data.caps).then((mipmaps) => {
-                        postMessage({ action: "mipmapsCreated", success: true, id: event.data.id, mipmaps: mipmaps.mipmaps }, mipmaps.mipmapsData);
+                    _createMipmaps(kfr, event.data.caps).then((data) => {
+                        postMessage({ action: "mipmapsCreated", success: true, id: event.data.id, decodedData: data.decodedData }, data.mipmapBuffers);
                     }).catch((reason) => {
                         postMessage({ action: "mipmapsCreated", success: false, id: event.data.id, msg: reason });
                     });
@@ -53,7 +59,7 @@ export function workerFunc(): void {
         }
     };
 
-    const _createMipmaps = (kfr: KTX2FileReader, caps: { [name: string]: any }): Promise<{ mipmaps: Array<IMipmap>, mipmapsData: Array<ArrayBuffer> }> => {
+    const _createMipmaps = (kfr: KTX2FileReader, caps: { [name: string]: any }): Promise<{ decodedData: IDecodedData, mipmapBuffers: Array<ArrayBuffer> }> => {
         const width = kfr.header.pixelWidth;
         const height = kfr.header.pixelHeight;
         const srcTexFormat = kfr.textureFormat;
@@ -88,7 +94,7 @@ export function workerFunc(): void {
             transcodedFormat = COMPRESSED_RGB_ETC1_WEBGL;
         } else {
             targetFormat = transcodeTarget.RGBA32;
-            transcodedFormat = RGBAFormat;
+            transcodedFormat = RGBA8Format;
         }
 
         const transcoder = transcoderMgr.findTranscoder(srcTexFormat, targetFormat);
@@ -98,8 +104,9 @@ export function workerFunc(): void {
         }
 
         const mipmaps: Array<IMipmap> = [];
-        const texturePromises: Array<Promise<Nullable<Uint8Array>>> = [];
-        const mipmapsData: Array<ArrayBuffer> = [];
+        const dataPromises: Array<Promise<Nullable<Uint8Array>>> = [];
+        const mipmapBuffers: Array<ArrayBuffer> = [];
+        const decodedData: IDecodedData = { width: 0, height: 0, transcodedFormat, mipmaps };
 
         let firstImageDescIndex = 0;
 
@@ -125,6 +132,11 @@ export function workerFunc(): void {
                 levelDataOffset = 0;
             }
 
+            if (level === 0) {
+                decodedData.width = levelWidth;
+                decodedData.height = levelHeight;
+            }
+
             for (let imageIndex = 0; imageIndex < numImagesInLevel; imageIndex ++) {
                 let encodedData: Uint8Array;
                 let imageDesc: Nullable<IKTX2_ImageDesc> = null;
@@ -143,14 +155,13 @@ export function workerFunc(): void {
                     data: null,
                     width: levelWidth,
                     height: levelHeight,
-                    transcodedFormat: transcodedFormat
                 };
 
                 const transcodedData = transcoder.transcode(srcTexFormat, targetFormat, level, levelWidth, levelHeight, levelUncompressedByteLength, kfr, imageDesc, encodedData).
                         then((data) => {
                             mipmap.data = data;
                             if (data) {
-                                mipmapsData.push(data.buffer);
+                                mipmapBuffers.push(data.buffer);
                             }
                             return data;
                         }
@@ -158,12 +169,12 @@ export function workerFunc(): void {
 
                 mipmaps.push(mipmap);
 
-                texturePromises.push(transcodedData);
+                dataPromises.push(transcodedData);
             }
         }
 
-        return Promise.all(texturePromises).then(() => {
-            return { mipmaps, mipmapsData };
+        return Promise.all(dataPromises).then(() => {
+            return { decodedData, mipmapBuffers };
         });
     };
 }

+ 20 - 14
src/Misc/KTX2/KTX2WorkerThreadJS.ts

@@ -1,5 +1,6 @@
 // @ts-nocheck
 // tslint:disable
+
 export function workerFunc() {
 
     var COMPRESSED_RGBA_BPTC_UNORM_EXT = 0x8E8C;
@@ -11,7 +12,7 @@ export function workerFunc() {
     var COMPRESSED_RGBA8_ETC2_EAC = 0x9278;
     var COMPRESSED_RGB8_ETC2 = 0x9274;
     var COMPRESSED_RGB_ETC1_WEBGL = 0x8D64;
-    var RGBAFormat = 0x3FF;
+    var RGBA8Format = 0x8058;
     
     var __extends = (this && this.__extends) || (function () {
         var extendStatics = function (d, b) {
@@ -334,8 +335,8 @@ export function workerFunc() {
         return MSCTranscoder;
     }(Transcoder));
 
-    TranscoderManager.registerTranscoder(LiteTranscoder_UASTC_ASTC);
-    TranscoderManager.registerTranscoder(LiteTranscoder_UASTC_BC7);
+    //TranscoderManager.registerTranscoder(LiteTranscoder_UASTC_ASTC);
+    //TranscoderManager.registerTranscoder(LiteTranscoder_UASTC_BC7);
     TranscoderManager.registerTranscoder(MSCTranscoder);
 
     /**
@@ -777,8 +778,8 @@ export function workerFunc() {
             case "createMipmaps":
                 try {
                     var kfr = new KTX2FileReader(event.data.data);
-                    _createMipmaps(kfr, event.data.caps).then(function (mipmaps) {
-                        postMessage({ action: "mipmapsCreated", success: true, id: event.data.id, mipmaps: mipmaps.mipmaps }, mipmaps.mipmapsData);
+                    _createMipmaps(kfr, event.data.caps).then(function (data) {
+                        postMessage({ action: "mipmapsCreated", success: true, id: event.data.id, decodedData: data.decodedData }, data.mipmapBuffers);
                     }).catch(function (reason) {
                         postMessage({ action: "mipmapsCreated", success: false, id: event.data.id, msg: reason });
                     });
@@ -796,7 +797,6 @@ export function workerFunc() {
         var isPowerOfTwo = function (value) {
             return (value & (value - 1)) === 0 && value !== 0;
         };
-
         // PVRTC1 transcoders (from both ETC1S and UASTC) only support power of 2 dimensions.
         var pvrtcTranscodable = isPowerOfTwo(width) && isPowerOfTwo(height);
         var targetFormat = transcodeTarget.BC7_M5_RGBA;
@@ -827,15 +827,18 @@ export function workerFunc() {
         }
         else {
             targetFormat = transcodeTarget.RGBA32;
-            transcodedFormat = RGBAFormat;
+            transcodedFormat = RGBA8Format;
         }
+        targetFormat = transcodeTarget.RGBA32;
+        transcodedFormat = RGBA8Format;
         var transcoder = transcoderMgr.findTranscoder(srcTexFormat, targetFormat);
         if (transcoder === null) {
             throw new Error("no transcoder found to transcode source texture format \"" + sourceTextureFormat[srcTexFormat] + "\" to format \"" + transcodeTarget[targetFormat] + "\"");
         }
         var mipmaps = [];
-        var texturePromises = [];
-        var mipmapsData = [];
+        var dataPromises = [];
+        var mipmapBuffers = [];
+        var decodedData = { width: 0, height: 0, transcodedFormat: transcodedFormat, mipmaps: mipmaps };
         var firstImageDescIndex = 0;
         for (var level = 0; level < kfr.header.levelCount; level++) {
             if (level > 0) {
@@ -853,6 +856,10 @@ export function workerFunc() {
                 //levelDataBuffer = this.zstd.decode(new Uint8Array(levelDataBuffer, levelDataOffset, levelByteLength), levelUncompressedByteLength);
                 levelDataOffset = 0;
             }
+            if (level === 0) {
+                decodedData.width = levelWidth;
+                decodedData.height = levelHeight;
+            }
             var _loop_1 = function (imageIndex) {
                 var encodedData = void 0;
                 var imageDesc = null;
@@ -868,25 +875,24 @@ export function workerFunc() {
                     data: null,
                     width: levelWidth,
                     height: levelHeight,
-                    transcodedFormat: transcodedFormat
                 };
                 var transcodedData = transcoder.transcode(srcTexFormat, targetFormat, level, levelWidth, levelHeight, levelUncompressedByteLength, kfr, imageDesc, encodedData).
                     then(function (data) {
                     mipmap.data = data;
                     if (data) {
-                        mipmapsData.push(data.buffer);
+                        mipmapBuffers.push(data.buffer);
                     }
                     return data;
                 });
                 mipmaps.push(mipmap);
-                texturePromises.push(transcodedData);
+                dataPromises.push(transcodedData);
             };
             for (var imageIndex = 0; imageIndex < numImagesInLevel; imageIndex++) {
                 _loop_1(imageIndex);
             }
         }
-        return Promise.all(texturePromises).then(function () {
-            return { mipmaps: mipmaps, mipmapsData: mipmapsData };
+        return Promise.all(dataPromises).then(function () {
+            return { decodedData: decodedData, mipmapBuffers: mipmapBuffers };
         });
     };
 }

+ 41 - 19
src/Misc/KTX2/khronosTextureContainer2.ts

@@ -1,16 +1,12 @@
 import { InternalTexture } from "../../Materials/Textures/internalTexture";
 import { ThinEngine } from "../../Engines/thinEngine";
-//import { EngineCapabilities } from '../../Engines/engineCapabilities';
-//import { Tools } from '../tools';
 import { Nullable } from '../../types';
 
-import { IMipmap } from "./KTX2WorkerThread";
+import { IDecodedData } from "./KTX2WorkerThread";
 import { workerFunc } from "./KTX2WorkerThreadJS";
 import { KTX2FileReader } from './KTX2FileReader';
 import { Tools } from '../tools';
-
-//const RGB_S3TC_DXT1_Format = 33776;
-//const RGBA_S3TC_DXT5_Format = 33779;
+import { Constants } from '../../Engines/constants';
 
 /**
  * Class for loading KTX2 files
@@ -78,7 +74,7 @@ export class KhronosTextureContainer2 {
                         if (!msg.data.success) {
                             rej({ message: msg.data.msg });
                         }else {
-                            this._createTexture(msg.data.mipmaps, internalTexture);
+                            this._createTexture(msg.data.decodedData, internalTexture);
                             res();
                         }
                     }
@@ -106,9 +102,21 @@ export class KhronosTextureContainer2 {
         });
     }
 
-    protected _createTexture(mipmaps: Array<IMipmap>, internalTexture: InternalTexture) {
-        for (let t = 0; t < mipmaps.length; ++t) {
-            let mipmap = mipmaps[t];
+    protected _createTexture(data: IDecodedData, internalTexture: InternalTexture) {
+        this._engine._bindTextureDirectly(this._engine._gl.TEXTURE_2D, internalTexture);
+
+        internalTexture.generateMipMaps = false;
+        internalTexture.invertY = false;
+        internalTexture.width = internalTexture.baseWidth = data.width;
+        internalTexture.height = internalTexture.baseHeight = data.height;
+        internalTexture.samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;
+
+        console.log("transcoded format=", data.transcodedFormat);
+
+        for (let t = 0; t < data.mipmaps.length; ++t) {
+            let mipmap = data.mipmaps[t];
+
+            if (t !== 0) break;
 
             if (!mipmap || !mipmap.data) {
                 throw new Error("KTX2 container - could not transcode one of the image");
@@ -116,17 +124,31 @@ export class KhronosTextureContainer2 {
 
             console.log(`mipmap #${t} byte length=`, mipmap.data.byteLength);
 
-            internalTexture.width = internalTexture.baseWidth = mipmap.width;
-            internalTexture.height = internalTexture.baseHeight = mipmap.height;
-            internalTexture.generateMipMaps = false;
-            internalTexture.invertY = false;
+            if (data.transcodedFormat === 0x8058 /* RGBA8 */) {
+                // uncompressed RGBA
+                internalTexture.width = internalTexture.baseWidth = mipmap.width;
+                internalTexture.height = internalTexture.baseHeight = mipmap.height;
+
+                internalTexture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;
+                internalTexture.format = Constants.TEXTUREFORMAT_RGBA;
+
+                const gl = this._engine._gl;
+                //this._engine._uploadDataToTextureDirectly(internalTexture, mipmap.data, 0, t, undefined, true);
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+                gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
+                gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, mipmap.width, mipmap.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, mipmap.data);
+                gl.generateMipmap(gl.TEXTURE_2D);
+            } else {
+                this._engine._uploadCompressedDataToTextureDirectly(internalTexture, data.transcodedFormat, mipmap.width, mipmap.height, mipmap.data, 0, t);
+            }
+        }
 
-            this._engine._bindTextureDirectly(this._engine._gl.TEXTURE_2D, internalTexture);
-            this._engine._uploadCompressedDataToTextureDirectly(internalTexture, mipmap.transcodedFormat, mipmap.width, mipmap.height, mipmap.data, 0, 0);
+        internalTexture.isReady = true;
 
-            internalTexture.isReady = true;
-            break;
-        }
+        internalTexture.width = internalTexture.baseWidth = data.width;
+        internalTexture.height = internalTexture.baseHeight = data.height;
+
+        this._engine._bindTextureDirectly(this._engine._gl.TEXTURE_2D, null);
     }
 
     /**