@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
124 lines (97 loc) • 3.9 kB
JavaScript
import { computeFileExtension } from "../../../../core/path/computeFileExtension.js";
import { convertTexture2Sampler2D } from "../../../graphics/texture/sampler/convertTexture2Sampler2D.js";
import { GameAssetType } from "../../GameAssetType.js";
import { ArrayBufferLoader } from "../ArrayBufferLoader.js";
import { AssetLoader } from "../AssetLoader.js";
import { CodecWithFallback } from "./codec/CodecWithFallback.js";
import { NativeImageDecoder } from "./codec/NativeImageDecoder.js";
import { ThreadedImageDecoder } from "./codec/ThreadedImageDecoder.js";
import { ImageRGBADataAsset } from "./ImageRGBADataAsset.js";
const ASSET_TYPE_ARRAY_BUFFER = "arraybuffer";
export class ImageRGBADataLoader extends AssetLoader {
/**
*
* @param {string} [worker_path] Path to decoder worker, allows flexibility in deployment
*/
constructor({
worker_path
} = {}) {
super();
/**
*
* @type {CodecWithFallback<{data, width:number, height:number, itemSize:number, bitDepth:number}>}
*/
this.decoder = new CodecWithFallback(
new ThreadedImageDecoder({ worker_path }),
new NativeImageDecoder()
);
}
async link(assetManager, engine) {
if (assetManager.getLoaderByType(ASSET_TYPE_ARRAY_BUFFER) === undefined) {
await assetManager.registerLoader(ASSET_TYPE_ARRAY_BUFFER, new ArrayBufferLoader());
}
await super.link(assetManager, engine);
}
/**
*
* @param {string} path
* @param {AssetRequestScope} scope
* @returns {Promise<{data:ArrayBuffer, width: number, height:number, itemSize: number, bitDepth:number}>}
* @private
*/
async __decode_via_worker(path, scope) {
const asset = await this.assetManager.promise(path, ASSET_TYPE_ARRAY_BUFFER, { scope });
/**
* @type {ArrayBuffer}
*/
const array_buffer = asset.create();
return await this.decoder.decode(new Uint8Array(array_buffer));
}
/**
*
* @param {String} path
* @param {AssetRequestScope} scope
* @return {Promise<ImageRGBADataAsset>}
* @private
*/
async __standard(path, scope) {
const bitmap = await this.__decode_via_worker(path, scope);
let data;
const bitDepth = bitmap.bitDepth;
switch (bitDepth) {
case 8:
data = new Uint8Array(bitmap.data);
break
case 16:
data = new Uint16Array(bitmap.data);
break;
default:
throw new Error(`Unsupported bit depth '${bitDepth}'. path='${path}'`);
}
return new ImageRGBADataAsset(data, bitmap.width, bitmap.height, bitmap.itemSize);
}
load(scope, path, success, failure, progress) {
const extension = computeFileExtension(path);
if (extension === 'dds') {
//compressed texture
this.assetManager.get({
path: path,
scope,
type: GameAssetType.Texture,
callback: asset => {
/**
*
* @type {Texture}
*/
const texture = asset.create();
const sampler2D = convertTexture2Sampler2D(texture);
texture.dispose();
const f = new ImageRGBADataAsset(sampler2D.data, sampler2D.width, sampler2D.height, sampler2D.itemSize);
success(f);
}, failure: failure, progress: progress
});
} else {
this.__standard(path, scope).then(success, failure);
}
}
}