Source: packages/core/src/textures/resources/CubeResource.js

packages/core/src/textures/resources/CubeResource.js

import { AbstractMultiResource } from './AbstractMultiResource';
import { TARGETS } from '@pixi/constants';
/**
 * Resource for a CubeTexture which contains six resources.
 *
 * @class
 * @extends PIXI.resources.ArrayResource
 * @memberof PIXI.resources
 * @param {Array<string|PIXI.resources.Resource>} [source] - Collection of URLs or resources
 *        to use as the sides of the cube.
 * @param {object} [options] - ImageResource options
 * @param {number} [options.width] - Width of resource
 * @param {number} [options.height] - Height of resource
 * @param {number} [options.autoLoad=true] - Whether to auto-load resources
 * @param {number} [options.linkBaseTexture=true] - In case BaseTextures are supplied,
 *   whether to copy them or use
 */
export class CubeResource extends AbstractMultiResource {
    constructor(source, options) {
        const { width, height, autoLoad, linkBaseTexture } = options || {};
        if (source && source.length !== CubeResource.SIDES) {
            throw new Error(`Invalid length. Got ${source.length}, expected 6`);
        }
        super(6, { width, height });
        for (let i = 0; i < CubeResource.SIDES; i++) {
            this.items[i].target = TARGETS.TEXTURE_CUBE_MAP_POSITIVE_X + i;
        }
        /**
         * In case BaseTextures are supplied, whether to use same resource or bind baseTexture itself
         * @member {boolean}
         * @protected
         */
        this.linkBaseTexture = linkBaseTexture !== false;
        if (source) {
            this.initFromArray(source, options);
        }
        if (autoLoad !== false) {
            this.load();
        }
    }
    /**
     * Add binding
     *
     * @override
     * @param {PIXI.BaseTexture} baseTexture - parent base texture
     */
    bind(baseTexture) {
        super.bind(baseTexture);
        baseTexture.target = TARGETS.TEXTURE_CUBE_MAP;
    }
    addBaseTextureAt(baseTexture, index, linkBaseTexture) {
        if (linkBaseTexture === undefined) {
            linkBaseTexture = this.linkBaseTexture;
        }
        if (!this.items[index]) {
            throw new Error(`Index ${index} is out of bounds`);
        }
        if (!this.linkBaseTexture
            || baseTexture.parentTextureArray
            || Object.keys(baseTexture._glTextures).length > 0) {
            // copy mode
            if (baseTexture.resource) {
                this.addResourceAt(baseTexture.resource, index);
            }
            else {
                throw new Error(`CubeResource does not support copying of renderTexture.`);
            }
        }
        else {
            // link mode, the difficult one!
            baseTexture.target = TARGETS.TEXTURE_CUBE_MAP_POSITIVE_X + index;
            baseTexture.parentTextureArray = this.baseTexture;
            this.items[index] = baseTexture;
        }
        if (baseTexture.valid && !this.valid) {
            this.resize(baseTexture.realWidth, baseTexture.realHeight);
        }
        this.items[index] = baseTexture;
        return this;
    }
    /**
     * Upload the resource
     *
     * @returns {boolean} true is success
     */
    upload(renderer, _baseTexture, glTexture) {
        const dirty = this.itemDirtyIds;
        for (let i = 0; i < CubeResource.SIDES; i++) {
            const side = this.items[i];
            if (dirty[i] < side.dirtyId) {
                if (side.valid && side.resource) {
                    side.resource.upload(renderer, side, glTexture);
                    dirty[i] = side.dirtyId;
                }
                else if (dirty[i] < -1) {
                    // either item is not valid yet, either its a renderTexture
                    // allocate the memory
                    renderer.gl.texImage2D(side.target, 0, glTexture.internalFormat, _baseTexture.realWidth, _baseTexture.realHeight, 0, _baseTexture.format, glTexture.type, null);
                    dirty[i] = -1;
                }
            }
        }
        return true;
    }
    /**
     * Used to auto-detect the type of resource.
     *
     * @static
     * @param {object} source - The source object
     * @return {boolean} `true` if source is an array of 6 elements
     */
    static test(source) {
        return Array.isArray(source) && source.length === CubeResource.SIDES;
    }
}
/**
 * Number of texture sides to store for CubeResources
 *
 * @name PIXI.resources.CubeResource.SIDES
 * @static
 * @member {number}
 * @default 6
 */
CubeResource.SIDES = 6;