createBasisTexture = data => {
const basisFile = new BasisFile(new Uint8Array(data));
function cleanup() {
basisFile.close();
basisFile.delete();
}
const width = basisFile.getImageWidth(0, 0);
const height = basisFile.getImageHeight(0, 0);
const images = basisFile.getNumImages();
const levels = basisFile.getNumLevels(0);
const has_alpha = basisFile.getHasAlpha();
console.log(images, levels);
if (!width || !height || !images || !levels) {
cleanup();
throw new Error('Invalid .basis file');
}
let format;
if (SUPPORTS.astc) {
format = BASIS_FORMAT.ASTC_4x4;
} else if (SUPPORTS.bc7) {
format = BASIS_FORMAT.BC7;
} else if (SUPPORTS.dxt) {
format = has_alpha ? BASIS_FORMAT.BC3 : BASIS_FORMAT.BC1;
} else if (SUPPORTS.pvrtc) {
format = has_alpha ? BASIS_FORMAT.PVRTC1_4_RGBA : BASIS_FORMAT.PVRTC1_4_RGB;
if (((width & (width - 1)) != 0) || ((height & (height - 1)) != 0))
console.warn('ERROR: PVRTC1 requires square power of 2 textures');
if (width != height)
console.warn('ERROR: PVRTC1 requires square power of 2 textures');
} else if (SUPPORTS.etc) {
format = BASIS_FORMAT.ETC1;
} else {
format = BASIS_FORMAT.RGB565;
}
if (!basisFile.startTranscoding()) {
cleanup();
throw new Error('startTranscoding failed');
}
const dstSize = basisFile.getImageTranscodedSizeInBytes(0, 0, format);
const dst = new Uint8Array(dstSize);
if (!basisFile.transcodeImage(dst, 0, 0, format, 0, 0)) {
cleanup();
throw new Error('transcodeImage failed');
}
const dstSize2 = basisFile.getImageTranscodedSizeInBytes(1, 0, format);
const dst2 = new Uint8Array(dstSize2);
if (!basisFile.transcodeImage(dst2, 1, 0, format, 0, 0)) {
cleanup();
throw new Error('transcodeImage failed');
}
console.log({dstSize, dstSize2});
const dst0 = new Uint8Array(dstSize*2);
dst0.set(dst);
dst0.set(dst, dst.size);
cleanup();
const alignedWidth = (width + 3) & ~3;
const alignedHeight = (height + 3) & ~3;
console.log({width, alignedWidth, height, alignedHeight, format, formats: BASIS_FORMAT});
let tex;
if (format === BASIS_FORMAT.ASTC_4x4) {
tex = createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED.RGBA_ASTC_4x4_KHR);
} else if (format == BASIS_FORMAT.BC3) {
tex = createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED.RGBA_S3TC_DXT5_EXT);
} else if (format == BASIS_FORMAT.BC1) {
// tex = createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED.RGB_S3TC_DXT1_EXT);
tex = createCompressedTexture3D([dst, dst2], alignedWidth, alignedHeight, COMPRESSED.RGB_S3TC_DXT1_EXT);
} else if (format == BASIS_FORMAT.BC7) {
tex = createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED.RGBA_BPTC_UNORM);
} else if (format === BASIS_FORMAT.ETC1) {
tex = createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED.RGB_ETC1_WEBGL);
} else if (format === BASIS_FORMAT.PVRTC1_4_RGB) {
tex = createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED.RGB_PVRTC_4BPPV1_IMG);
} else if (format === BASIS_FORMAT.PVRTC1_4_RGBA) {
tex = createCompressedTexture(dst, alignedWidth, alignedHeight, COMPRESSED.RGBA_PVRTC_4BPPV1_IMG);
} else {
// Create 565 texture.
const dstTex = new Uint16Array(width * height);
// Convert the array of bytes to an array of uint16's.
var pix = 0;
for (var y = 0; y < height; y++)
for (var x = 0; x < width; x++, pix++)
dstTex[pix] = dst[2 * pix + 0] | (dst[2 * pix + 1] << 8);
tex = createRgb565Texture(dstTex, width, height);
}
console.log({tex});
return tex;
}