UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

331 lines (328 loc) 11.7 kB
import EventEmitter from 'eventemitter3'; import { isPow2 } from '../../../../../maths/misc/pow2.mjs'; import { definedProps } from '../../../../../scene/container/utils/definedProps.mjs'; import { uid } from '../../../../../utils/data/uid.mjs'; import { TextureStyle } from '../TextureStyle.mjs'; "use strict"; const _TextureSource = class _TextureSource extends EventEmitter { /** * @param options - options for creating a new TextureSource */ constructor(options = {}) { super(); this.options = options; /** unique id for this Texture source */ this.uid = uid("textureSource"); /** * The resource type used by this TextureSource. This is used by the bind groups to determine * how to handle this resource. * @internal */ this._resourceType = "textureSource"; /** * i unique resource id, used by the bind group systems. * This can change if the texture is resized or its resource changes * @internal */ this._resourceId = uid("resource"); /** * this is how the backends know how to upload this texture to the GPU * It changes depending on the resource type. Classes that extend TextureSource * should override this property. * @internal */ this.uploadMethodId = "unknown"; /** @internal */ this._resolution = 1; /** the pixel width of this texture source. This is the REAL pure number, not accounting resolution */ this.pixelWidth = 1; /** the pixel height of this texture source. This is the REAL pure number, not accounting resolution */ this.pixelHeight = 1; /** * the width of this texture source, accounting for resolution * eg pixelWidth 200, resolution 2, then width will be 100 */ this.width = 1; /** * the height of this texture source, accounting for resolution * eg pixelHeight 200, resolution 2, then height will be 100 */ this.height = 1; /** * The number of samples of a multisample texture. This is always 1 for non-multisample textures. * To enable multisample for a texture, set antialias to true * @internal */ this.sampleCount = 1; /** The number of mip levels to generate for this texture. this is overridden if autoGenerateMipmaps is true */ this.mipLevelCount = 1; /** * Should we auto generate mipmaps for this texture? This will automatically generate mipmaps * for this texture when uploading to the GPU. Mipmapped textures take up more memory, but * can look better when scaled down. * * For performance reasons, it is recommended to NOT use this with RenderTextures, as they are often updated every frame. * If you do, make sure to call `updateMipmaps` after you update the texture. */ this.autoGenerateMipmaps = false; /** the format that the texture data has */ this.format = "rgba8unorm"; /** how many dimensions does this texture have? currently v8 only supports 2d */ this.dimension = "2d"; /** * Only really affects RenderTextures. * Should we use antialiasing for this texture. It will look better, but may impact performance as a * Blit operation will be required to resolve the texture. */ this.antialias = false; /** * Used by automatic texture Garbage Collection, stores last GC tick when it was bound * @protected */ this._touched = 0; /** * Used by the batcher to build texture batches. faster to have the variable here! * @protected */ this._batchTick = -1; /** * A temporary batch location for the texture batching. Here for performance reasons only! * @protected */ this._textureBindLocation = -1; options = { ..._TextureSource.defaultOptions, ...options }; this.label = options.label ?? ""; this.resource = options.resource; this.autoGarbageCollect = options.autoGarbageCollect; this._resolution = options.resolution; if (options.width) { this.pixelWidth = options.width * this._resolution; } else { this.pixelWidth = this.resource ? this.resourceWidth ?? 1 : 1; } if (options.height) { this.pixelHeight = options.height * this._resolution; } else { this.pixelHeight = this.resource ? this.resourceHeight ?? 1 : 1; } this.width = this.pixelWidth / this._resolution; this.height = this.pixelHeight / this._resolution; this.format = options.format; this.dimension = options.dimensions; this.mipLevelCount = options.mipLevelCount; this.autoGenerateMipmaps = options.autoGenerateMipmaps; this.sampleCount = options.sampleCount; this.antialias = options.antialias; this.alphaMode = options.alphaMode; this.style = new TextureStyle(definedProps(options)); this.destroyed = false; this._refreshPOT(); } /** returns itself */ get source() { return this; } /** the style of the texture */ get style() { return this._style; } set style(value) { if (this.style === value) return; this._style?.off("change", this._onStyleChange, this); this._style = value; this._style?.on("change", this._onStyleChange, this); this._onStyleChange(); } /** setting this will set wrapModeU,wrapModeV and wrapModeW all at once! */ get addressMode() { return this._style.addressMode; } set addressMode(value) { this._style.addressMode = value; } /** setting this will set wrapModeU,wrapModeV and wrapModeW all at once! */ get repeatMode() { return this._style.addressMode; } set repeatMode(value) { this._style.addressMode = value; } /** Specifies the sampling behavior when the sample footprint is smaller than or equal to one texel. */ get magFilter() { return this._style.magFilter; } set magFilter(value) { this._style.magFilter = value; } /** Specifies the sampling behavior when the sample footprint is larger than one texel. */ get minFilter() { return this._style.minFilter; } set minFilter(value) { this._style.minFilter = value; } /** Specifies behavior for sampling between mipmap levels. */ get mipmapFilter() { return this._style.mipmapFilter; } set mipmapFilter(value) { this._style.mipmapFilter = value; } /** Specifies the minimum and maximum levels of detail, respectively, used internally when sampling a texture. */ get lodMinClamp() { return this._style.lodMinClamp; } set lodMinClamp(value) { this._style.lodMinClamp = value; } /** Specifies the minimum and maximum levels of detail, respectively, used internally when sampling a texture. */ get lodMaxClamp() { return this._style.lodMaxClamp; } set lodMaxClamp(value) { this._style.lodMaxClamp = value; } _onStyleChange() { this.emit("styleChange", this); } /** call this if you have modified the texture outside of the constructor */ update() { if (this.resource) { const resolution = this._resolution; const didResize = this.resize(this.resourceWidth / resolution, this.resourceHeight / resolution); if (didResize) return; } this.emit("update", this); } /** Destroys this texture source */ destroy() { this.destroyed = true; this.emit("destroy", this); this.emit("change", this); if (this._style) { this._style.destroy(); this._style = null; } this.uploadMethodId = null; this.resource = null; this.removeAllListeners(); } /** * This will unload the Texture source from the GPU. This will free up the GPU memory * As soon as it is required fore rendering, it will be re-uploaded. */ unload() { this._resourceId = uid("resource"); this.emit("change", this); this.emit("unload", this); } /** the width of the resource. This is the REAL pure number, not accounting resolution */ get resourceWidth() { const { resource } = this; return resource.naturalWidth || resource.videoWidth || resource.displayWidth || resource.width; } /** the height of the resource. This is the REAL pure number, not accounting resolution */ get resourceHeight() { const { resource } = this; return resource.naturalHeight || resource.videoHeight || resource.displayHeight || resource.height; } /** * the resolution of the texture. Changing this number, will not change the number of pixels in the actual texture * but will the size of the texture when rendered. * * changing the resolution of this texture to 2 for example will make it appear twice as small when rendered (as pixel * density will have increased) */ get resolution() { return this._resolution; } set resolution(resolution) { if (this._resolution === resolution) return; this._resolution = resolution; this.width = this.pixelWidth / resolution; this.height = this.pixelHeight / resolution; } /** * Resize the texture, this is handy if you want to use the texture as a render texture * @param width - the new width of the texture * @param height - the new height of the texture * @param resolution - the new resolution of the texture * @returns - if the texture was resized */ resize(width, height, resolution) { resolution || (resolution = this._resolution); width || (width = this.width); height || (height = this.height); const newPixelWidth = Math.round(width * resolution); const newPixelHeight = Math.round(height * resolution); this.width = newPixelWidth / resolution; this.height = newPixelHeight / resolution; this._resolution = resolution; if (this.pixelWidth === newPixelWidth && this.pixelHeight === newPixelHeight) { return false; } this._refreshPOT(); this.pixelWidth = newPixelWidth; this.pixelHeight = newPixelHeight; this.emit("resize", this); this._resourceId = uid("resource"); this.emit("change", this); return true; } /** * Lets the renderer know that this texture has been updated and its mipmaps should be re-generated. * This is only important for RenderTexture instances, as standard Texture instances will have their * mipmaps generated on upload. You should call this method after you make any change to the texture * * The reason for this is is can be quite expensive to update mipmaps for a texture. So by default, * We want you, the developer to specify when this action should happen. * * Generally you don't want to have mipmaps generated on Render targets that are changed every frame, */ updateMipmaps() { if (this.autoGenerateMipmaps && this.mipLevelCount > 1) { this.emit("updateMipmaps", this); } } set wrapMode(value) { this._style.wrapMode = value; } get wrapMode() { return this._style.wrapMode; } set scaleMode(value) { this._style.scaleMode = value; } /** setting this will set magFilter,minFilter and mipmapFilter all at once! */ get scaleMode() { return this._style.scaleMode; } /** * Refresh check for isPowerOfTwo texture based on size * @private */ _refreshPOT() { this.isPowerOfTwo = isPow2(this.pixelWidth) && isPow2(this.pixelHeight); } static test(_resource) { throw new Error("Unimplemented"); } }; /** The default options used when creating a new TextureSource. override these to add your own defaults */ _TextureSource.defaultOptions = { resolution: 1, format: "bgra8unorm", alphaMode: "premultiply-alpha-on-upload", dimensions: "2d", mipLevelCount: 1, autoGenerateMipmaps: false, sampleCount: 1, antialias: false, autoGarbageCollect: false }; let TextureSource = _TextureSource; export { TextureSource }; //# sourceMappingURL=TextureSource.mjs.map