- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
import { ALPHA_MODES, MIPMAP_MODES } from '@pixi/constants';
import type { ExtensionMetadata } from '@pixi/core';
import { BaseTexture, ExtensionType, Texture } from '@pixi/core';
import { LoaderResource } from '@pixi/loaders';
import { registerCompressedTextures } from './registerCompressedTextures';
import { parseKTX } from '../parsers';
// Set KTX files to be loaded as an ArrayBuffer
LoaderResource.setExtensionXhrType('ktx', LoaderResource.XHR_RESPONSE_TYPE.BUFFER);
/**
* Loader plugin for handling KTX texture container files.
*
* This KTX loader does not currently support the following features:
* * cube textures
* * 3D textures
* * endianness conversion for big-endian machines
* * embedded *.basis files
*
* It does supports the following features:
* * multiple textures per file
* * mipmapping (only for compressed formats)
* * vendor-specific key/value data parsing (enable {@link PIXI.KTXLoader.loadKeyValueData})
* @class
* @memberof PIXI
* @implements {PIXI.ILoaderPlugin}
*/
export class KTXLoader
{
/** @ignore */
static extension: ExtensionMetadata = ExtensionType.Loader;
/**
* If set to `true`, {@link PIXI.KTXLoader} will parse key-value data in KTX textures. This feature relies
* on the [Encoding Standard]{@link https://encoding.spec.whatwg.org}.
*
* The key-value data will be available on the base-textures as {@code PIXI.BaseTexture.ktxKeyValueData}. They
* will hold a reference to the texture data buffer, so make sure to delete key-value data once you are done
* using it.
*/
static loadKeyValueData = false;
/**
* Called after a KTX file is loaded.
*
* This will parse the KTX file header and add a {@code BaseTexture} to the texture
* cache.
* @see PIXI.Loader.loaderMiddleware
* @param resource - loader resource that is checked to see if it is a KTX file
* @param next - callback Function to call when done
*/
public static use(resource: LoaderResource, next: (...args: any[]) => void): void
{
if (resource.extension === 'ktx' && resource.data)
{
try
{
const url = resource.name || resource.url;
const { compressed, uncompressed, kvData } = parseKTX(url, resource.data, this.loadKeyValueData);
if (compressed)
{
const result = registerCompressedTextures(
url,
compressed,
resource.metadata,
);
if (kvData && result.textures)
{
for (const textureId in result.textures)
{
result.textures[textureId].baseTexture.ktxKeyValueData = kvData;
}
}
Object.assign(resource, result);
}
else if (uncompressed)
{
const textures: Record<string, Texture> = {};
uncompressed.forEach((image, i) =>
{
const texture = new Texture(new BaseTexture(
image.resource,
{
mipmap: MIPMAP_MODES.OFF,
alphaMode: ALPHA_MODES.NO_PREMULTIPLIED_ALPHA,
type: image.type,
format: image.format,
}
));
const cacheID = `${url}-${i + 1}`;
if (kvData) texture.baseTexture.ktxKeyValueData = kvData;
BaseTexture.addToCache(texture.baseTexture, cacheID);
Texture.addToCache(texture, cacheID);
if (i === 0)
{
textures[url] = texture;
BaseTexture.addToCache(texture.baseTexture, url);
Texture.addToCache(texture, url);
}
textures[cacheID] = texture;
});
Object.assign(resource, { textures });
}
}
catch (err)
{
next(err);
return;
}
}
next();
}
}