This commit is contained in:
2025-01-04 00:34:03 +01:00
parent 41829408dc
commit 0ca14bbc19
18111 changed files with 1871397 additions and 0 deletions

21
resources/app/node_modules/@pixi/core/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License
Copyright (c) 2013-2023 Mathew Groves, Chad Engler
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,2 @@
"use strict";
//# sourceMappingURL=IRenderer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"IRenderer.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

View File

@@ -0,0 +1,2 @@
//# sourceMappingURL=IRenderer.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"IRenderer.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}

253
resources/app/node_modules/@pixi/core/lib/Renderer.js generated vendored Normal file
View File

@@ -0,0 +1,253 @@
"use strict";
var constants = require("@pixi/constants"), extensions = require("@pixi/extensions"), math = require("@pixi/math"), settings = require("@pixi/settings"), utils = require("@pixi/utils"), UniformGroup = require("./shader/UniformGroup.js"), SystemManager = require("./system/SystemManager.js");
const _Renderer = class _Renderer2 extends SystemManager.SystemManager {
/**
* @param {PIXI.IRendererOptions} [options] - See {@link PIXI.settings.RENDER_OPTIONS} for defaults.
*/
constructor(options) {
super(), this.type = constants.RENDERER_TYPE.WEBGL, options = Object.assign({}, settings.settings.RENDER_OPTIONS, options), this.gl = null, this.CONTEXT_UID = 0, this.globalUniforms = new UniformGroup.UniformGroup({
projectionMatrix: new math.Matrix()
}, !0);
const systemConfig = {
runners: [
"init",
"destroy",
"contextChange",
"resolutionChange",
"reset",
"update",
"postrender",
"prerender",
"resize"
],
systems: _Renderer2.__systems,
priority: [
"_view",
"textureGenerator",
"background",
"_plugin",
"startup",
// low level WebGL systems
"context",
"state",
"texture",
"buffer",
"geometry",
"framebuffer",
"transformFeedback",
// high level pixi specific rendering
"mask",
"scissor",
"stencil",
"projection",
"textureGC",
"filter",
"renderTexture",
"batch",
"objectRenderer",
"_multisample"
]
};
this.setup(systemConfig), "useContextAlpha" in options && (utils.deprecation("7.0.0", "options.useContextAlpha is deprecated, use options.premultipliedAlpha and options.backgroundAlpha instead"), options.premultipliedAlpha = options.useContextAlpha && options.useContextAlpha !== "notMultiplied", options.backgroundAlpha = options.useContextAlpha === !1 ? 1 : options.backgroundAlpha), this._plugin.rendererPlugins = _Renderer2.__plugins, this.options = options, this.startup.run(this.options);
}
/**
* Create renderer if WebGL is available. Overrideable
* by the **@pixi/canvas-renderer** package to allow fallback.
* throws error if WebGL is not available.
* @param options
* @private
*/
static test(options) {
return options?.forceCanvas ? !1 : utils.isWebGLSupported();
}
/**
* Renders the object to its WebGL view.
* @param displayObject - The object to be rendered.
* @param {object} [options] - Object to use for render options.
* @param {PIXI.RenderTexture} [options.renderTexture] - The render texture to render to.
* @param {boolean} [options.clear=true] - Should the canvas be cleared before the new render.
* @param {PIXI.Matrix} [options.transform] - A transform to apply to the render texture before rendering.
* @param {boolean} [options.skipUpdateTransform=false] - Should we skip the update transform pass?
*/
render(displayObject, options) {
this.objectRenderer.render(displayObject, options);
}
/**
* Resizes the WebGL view to the specified width and height.
* @param desiredScreenWidth - The desired width of the screen.
* @param desiredScreenHeight - The desired height of the screen.
*/
resize(desiredScreenWidth, desiredScreenHeight) {
this._view.resizeView(desiredScreenWidth, desiredScreenHeight);
}
/**
* Resets the WebGL state so you can render things however you fancy!
* @returns Returns itself.
*/
reset() {
return this.runners.reset.emit(), this;
}
/** Clear the frame buffer. */
clear() {
this.renderTexture.bind(), this.renderTexture.clear();
}
/**
* Removes everything from the renderer (event listeners, spritebatch, etc...)
* @param [removeView=false] - Removes the Canvas element from the DOM.
* See: https://github.com/pixijs/pixijs/issues/2233
*/
destroy(removeView = !1) {
this.runners.destroy.items.reverse(), this.emitWithCustomOptions(this.runners.destroy, {
_view: removeView
}), super.destroy();
}
/** Collection of plugins */
get plugins() {
return this._plugin.plugins;
}
/** The number of msaa samples of the canvas. */
get multisample() {
return this._multisample.multisample;
}
/**
* Same as view.width, actual number of pixels in the canvas by horizontal.
* @member {number}
* @readonly
* @default 800
*/
get width() {
return this._view.element.width;
}
/**
* Same as view.height, actual number of pixels in the canvas by vertical.
* @default 600
*/
get height() {
return this._view.element.height;
}
/** The resolution / device pixel ratio of the renderer. */
get resolution() {
return this._view.resolution;
}
set resolution(value) {
this._view.resolution = value, this.runners.resolutionChange.emit(value);
}
/** Whether CSS dimensions of canvas view should be resized to screen dimensions automatically. */
get autoDensity() {
return this._view.autoDensity;
}
/** The canvas element that everything is drawn to.*/
get view() {
return this._view.element;
}
/**
* Measurements of the screen. (0, 0, screenWidth, screenHeight).
*
* Its safe to use as filterArea or hitArea for the whole stage.
* @member {PIXI.Rectangle}
*/
get screen() {
return this._view.screen;
}
/** the last object rendered by the renderer. Useful for other plugins like interaction managers */
get lastObjectRendered() {
return this.objectRenderer.lastObjectRendered;
}
/** Flag if we are rendering to the screen vs renderTexture */
get renderingToScreen() {
return this.objectRenderer.renderingToScreen;
}
/** When logging Pixi to the console, this is the name we will show */
get rendererLogId() {
return `WebGL ${this.context.webGLVersion}`;
}
/**
* This sets weather the screen is totally cleared between each frame withthe background color and alpha
* @deprecated since 7.0.0
*/
get clearBeforeRender() {
return utils.deprecation("7.0.0", "renderer.clearBeforeRender has been deprecated, please use renderer.background.clearBeforeRender instead."), this.background.clearBeforeRender;
}
/**
* Pass-thru setting for the canvas' context `alpha` property. This is typically
* not something you need to fiddle with. If you want transparency, use `backgroundAlpha`.
* @deprecated since 7.0.0
* @member {boolean}
*/
get useContextAlpha() {
return utils.deprecation("7.0.0", "renderer.useContextAlpha has been deprecated, please use renderer.context.premultipliedAlpha instead."), this.context.useContextAlpha;
}
/**
* readonly drawing buffer preservation
* we can only know this if Pixi created the context
* @deprecated since 7.0.0
*/
get preserveDrawingBuffer() {
return utils.deprecation("7.0.0", "renderer.preserveDrawingBuffer has been deprecated, we cannot truly know this unless pixi created the context"), this.context.preserveDrawingBuffer;
}
/**
* The background color to fill if not transparent
* @member {number}
* @deprecated since 7.0.0
*/
get backgroundColor() {
return utils.deprecation("7.0.0", "renderer.backgroundColor has been deprecated, use renderer.background.color instead."), this.background.color;
}
set backgroundColor(value) {
utils.deprecation("7.0.0", "renderer.backgroundColor has been deprecated, use renderer.background.color instead."), this.background.color = value;
}
/**
* The background color alpha. Setting this to 0 will make the canvas transparent.
* @member {number}
* @deprecated since 7.0.0
*/
get backgroundAlpha() {
return utils.deprecation("7.0.0", "renderer.backgroundAlpha has been deprecated, use renderer.background.alpha instead."), this.background.alpha;
}
/**
* @deprecated since 7.0.0
*/
set backgroundAlpha(value) {
utils.deprecation("7.0.0", "renderer.backgroundAlpha has been deprecated, use renderer.background.alpha instead."), this.background.alpha = value;
}
/**
* @deprecated since 7.0.0
*/
get powerPreference() {
return utils.deprecation("7.0.0", "renderer.powerPreference has been deprecated, we can only know this if pixi creates the context"), this.context.powerPreference;
}
/**
* Useful function that returns a texture of the display object that can then be used to create sprites
* This can be quite useful if your displayObject is complicated and needs to be reused multiple times.
* @param displayObject - The displayObject the object will be generated from.
* @param {IGenerateTextureOptions} options - Generate texture options.
* @param {PIXI.Rectangle} options.region - The region of the displayObject, that shall be rendered,
* if no region is specified, defaults to the local bounds of the displayObject.
* @param {number} [options.resolution] - If not given, the renderer's resolution is used.
* @param {PIXI.MSAA_QUALITY} [options.multisample] - If not given, the renderer's multisample is used.
* @returns A texture of the graphics object.
*/
generateTexture(displayObject, options) {
return this.textureGenerator.generateTexture(displayObject, options);
}
};
_Renderer.extension = {
type: extensions.ExtensionType.Renderer,
priority: 1
}, /**
* Collection of installed plugins. These are included by default in PIXI, but can be excluded
* by creating a custom build. Consult the README for more information about creating custom
* builds and excluding plugins.
* @private
*/
_Renderer.__plugins = {}, /**
* The collection of installed systems.
* @private
*/
_Renderer.__systems = {};
let Renderer = _Renderer;
extensions.extensions.handleByMap(extensions.ExtensionType.RendererPlugin, Renderer.__plugins);
extensions.extensions.handleByMap(extensions.ExtensionType.RendererSystem, Renderer.__systems);
extensions.extensions.add(Renderer);
exports.Renderer = Renderer;
//# sourceMappingURL=Renderer.js.map

File diff suppressed because one or more lines are too long

260
resources/app/node_modules/@pixi/core/lib/Renderer.mjs generated vendored Normal file
View File

@@ -0,0 +1,260 @@
import { RENDERER_TYPE } from "@pixi/constants";
import { ExtensionType, extensions } from "@pixi/extensions";
import { Matrix } from "@pixi/math";
import { settings } from "@pixi/settings";
import { deprecation, isWebGLSupported } from "@pixi/utils";
import { UniformGroup } from "./shader/UniformGroup.mjs";
import { SystemManager } from "./system/SystemManager.mjs";
const _Renderer = class _Renderer2 extends SystemManager {
/**
* @param {PIXI.IRendererOptions} [options] - See {@link PIXI.settings.RENDER_OPTIONS} for defaults.
*/
constructor(options) {
super(), this.type = RENDERER_TYPE.WEBGL, options = Object.assign({}, settings.RENDER_OPTIONS, options), this.gl = null, this.CONTEXT_UID = 0, this.globalUniforms = new UniformGroup({
projectionMatrix: new Matrix()
}, !0);
const systemConfig = {
runners: [
"init",
"destroy",
"contextChange",
"resolutionChange",
"reset",
"update",
"postrender",
"prerender",
"resize"
],
systems: _Renderer2.__systems,
priority: [
"_view",
"textureGenerator",
"background",
"_plugin",
"startup",
// low level WebGL systems
"context",
"state",
"texture",
"buffer",
"geometry",
"framebuffer",
"transformFeedback",
// high level pixi specific rendering
"mask",
"scissor",
"stencil",
"projection",
"textureGC",
"filter",
"renderTexture",
"batch",
"objectRenderer",
"_multisample"
]
};
this.setup(systemConfig), "useContextAlpha" in options && (deprecation("7.0.0", "options.useContextAlpha is deprecated, use options.premultipliedAlpha and options.backgroundAlpha instead"), options.premultipliedAlpha = options.useContextAlpha && options.useContextAlpha !== "notMultiplied", options.backgroundAlpha = options.useContextAlpha === !1 ? 1 : options.backgroundAlpha), this._plugin.rendererPlugins = _Renderer2.__plugins, this.options = options, this.startup.run(this.options);
}
/**
* Create renderer if WebGL is available. Overrideable
* by the **@pixi/canvas-renderer** package to allow fallback.
* throws error if WebGL is not available.
* @param options
* @private
*/
static test(options) {
return options?.forceCanvas ? !1 : isWebGLSupported();
}
/**
* Renders the object to its WebGL view.
* @param displayObject - The object to be rendered.
* @param {object} [options] - Object to use for render options.
* @param {PIXI.RenderTexture} [options.renderTexture] - The render texture to render to.
* @param {boolean} [options.clear=true] - Should the canvas be cleared before the new render.
* @param {PIXI.Matrix} [options.transform] - A transform to apply to the render texture before rendering.
* @param {boolean} [options.skipUpdateTransform=false] - Should we skip the update transform pass?
*/
render(displayObject, options) {
this.objectRenderer.render(displayObject, options);
}
/**
* Resizes the WebGL view to the specified width and height.
* @param desiredScreenWidth - The desired width of the screen.
* @param desiredScreenHeight - The desired height of the screen.
*/
resize(desiredScreenWidth, desiredScreenHeight) {
this._view.resizeView(desiredScreenWidth, desiredScreenHeight);
}
/**
* Resets the WebGL state so you can render things however you fancy!
* @returns Returns itself.
*/
reset() {
return this.runners.reset.emit(), this;
}
/** Clear the frame buffer. */
clear() {
this.renderTexture.bind(), this.renderTexture.clear();
}
/**
* Removes everything from the renderer (event listeners, spritebatch, etc...)
* @param [removeView=false] - Removes the Canvas element from the DOM.
* See: https://github.com/pixijs/pixijs/issues/2233
*/
destroy(removeView = !1) {
this.runners.destroy.items.reverse(), this.emitWithCustomOptions(this.runners.destroy, {
_view: removeView
}), super.destroy();
}
/** Collection of plugins */
get plugins() {
return this._plugin.plugins;
}
/** The number of msaa samples of the canvas. */
get multisample() {
return this._multisample.multisample;
}
/**
* Same as view.width, actual number of pixels in the canvas by horizontal.
* @member {number}
* @readonly
* @default 800
*/
get width() {
return this._view.element.width;
}
/**
* Same as view.height, actual number of pixels in the canvas by vertical.
* @default 600
*/
get height() {
return this._view.element.height;
}
/** The resolution / device pixel ratio of the renderer. */
get resolution() {
return this._view.resolution;
}
set resolution(value) {
this._view.resolution = value, this.runners.resolutionChange.emit(value);
}
/** Whether CSS dimensions of canvas view should be resized to screen dimensions automatically. */
get autoDensity() {
return this._view.autoDensity;
}
/** The canvas element that everything is drawn to.*/
get view() {
return this._view.element;
}
/**
* Measurements of the screen. (0, 0, screenWidth, screenHeight).
*
* Its safe to use as filterArea or hitArea for the whole stage.
* @member {PIXI.Rectangle}
*/
get screen() {
return this._view.screen;
}
/** the last object rendered by the renderer. Useful for other plugins like interaction managers */
get lastObjectRendered() {
return this.objectRenderer.lastObjectRendered;
}
/** Flag if we are rendering to the screen vs renderTexture */
get renderingToScreen() {
return this.objectRenderer.renderingToScreen;
}
/** When logging Pixi to the console, this is the name we will show */
get rendererLogId() {
return `WebGL ${this.context.webGLVersion}`;
}
/**
* This sets weather the screen is totally cleared between each frame withthe background color and alpha
* @deprecated since 7.0.0
*/
get clearBeforeRender() {
return deprecation("7.0.0", "renderer.clearBeforeRender has been deprecated, please use renderer.background.clearBeforeRender instead."), this.background.clearBeforeRender;
}
/**
* Pass-thru setting for the canvas' context `alpha` property. This is typically
* not something you need to fiddle with. If you want transparency, use `backgroundAlpha`.
* @deprecated since 7.0.0
* @member {boolean}
*/
get useContextAlpha() {
return deprecation("7.0.0", "renderer.useContextAlpha has been deprecated, please use renderer.context.premultipliedAlpha instead."), this.context.useContextAlpha;
}
/**
* readonly drawing buffer preservation
* we can only know this if Pixi created the context
* @deprecated since 7.0.0
*/
get preserveDrawingBuffer() {
return deprecation("7.0.0", "renderer.preserveDrawingBuffer has been deprecated, we cannot truly know this unless pixi created the context"), this.context.preserveDrawingBuffer;
}
/**
* The background color to fill if not transparent
* @member {number}
* @deprecated since 7.0.0
*/
get backgroundColor() {
return deprecation("7.0.0", "renderer.backgroundColor has been deprecated, use renderer.background.color instead."), this.background.color;
}
set backgroundColor(value) {
deprecation("7.0.0", "renderer.backgroundColor has been deprecated, use renderer.background.color instead."), this.background.color = value;
}
/**
* The background color alpha. Setting this to 0 will make the canvas transparent.
* @member {number}
* @deprecated since 7.0.0
*/
get backgroundAlpha() {
return deprecation("7.0.0", "renderer.backgroundAlpha has been deprecated, use renderer.background.alpha instead."), this.background.alpha;
}
/**
* @deprecated since 7.0.0
*/
set backgroundAlpha(value) {
deprecation("7.0.0", "renderer.backgroundAlpha has been deprecated, use renderer.background.alpha instead."), this.background.alpha = value;
}
/**
* @deprecated since 7.0.0
*/
get powerPreference() {
return deprecation("7.0.0", "renderer.powerPreference has been deprecated, we can only know this if pixi creates the context"), this.context.powerPreference;
}
/**
* Useful function that returns a texture of the display object that can then be used to create sprites
* This can be quite useful if your displayObject is complicated and needs to be reused multiple times.
* @param displayObject - The displayObject the object will be generated from.
* @param {IGenerateTextureOptions} options - Generate texture options.
* @param {PIXI.Rectangle} options.region - The region of the displayObject, that shall be rendered,
* if no region is specified, defaults to the local bounds of the displayObject.
* @param {number} [options.resolution] - If not given, the renderer's resolution is used.
* @param {PIXI.MSAA_QUALITY} [options.multisample] - If not given, the renderer's multisample is used.
* @returns A texture of the graphics object.
*/
generateTexture(displayObject, options) {
return this.textureGenerator.generateTexture(displayObject, options);
}
};
_Renderer.extension = {
type: ExtensionType.Renderer,
priority: 1
}, /**
* Collection of installed plugins. These are included by default in PIXI, but can be excluded
* by creating a custom build. Consult the README for more information about creating custom
* builds and excluding plugins.
* @private
*/
_Renderer.__plugins = {}, /**
* The collection of installed systems.
* @private
*/
_Renderer.__systems = {};
let Renderer = _Renderer;
extensions.handleByMap(ExtensionType.RendererPlugin, Renderer.__plugins);
extensions.handleByMap(ExtensionType.RendererSystem, Renderer.__systems);
extensions.add(Renderer);
export {
Renderer
};
//# sourceMappingURL=Renderer.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,12 @@
"use strict";
var extensions = require("@pixi/extensions");
const renderers = [];
extensions.extensions.handleByList(extensions.ExtensionType.Renderer, renderers);
function autoDetectRenderer(options) {
for (const RendererType of renderers)
if (RendererType.test(options))
return new RendererType(options);
throw new Error("Unable to auto-detect a suitable renderer.");
}
exports.autoDetectRenderer = autoDetectRenderer;
//# sourceMappingURL=autoDetectRenderer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"autoDetectRenderer.js","sources":["../src/autoDetectRenderer.ts"],"sourcesContent":["import { extensions, ExtensionType } from '@pixi/extensions';\n\nimport type { ICanvas } from '@pixi/settings';\nimport type { IRenderer, IRendererOptions } from './IRenderer';\n\n/**\n * Renderer options supplied to `autoDetectRenderer`.\n * @memberof PIXI\n */\nexport interface IRendererOptionsAuto extends IRendererOptions\n{\n /**\n * Force CanvasRenderer even if WebGL is supported. Only available with **pixi.js-legacy**.\n * @default false\n */\n forceCanvas?: boolean;\n}\n\nexport interface IRendererConstructor<VIEW extends ICanvas = ICanvas>\n{\n test(options?: Partial<IRendererOptionsAuto>): boolean;\n new (options?: Partial<IRendererOptionsAuto>): IRenderer<VIEW>;\n}\n\n/**\n * Collection of installed Renderers.\n * @ignore\n */\nconst renderers: IRendererConstructor<ICanvas>[] = [];\n\nextensions.handleByList(ExtensionType.Renderer, renderers);\n\n/**\n * This helper function will automatically detect which renderer you should be using.\n * WebGL is the preferred renderer as it is a lot faster. If WebGL is not supported by\n * the browser then this function will return a canvas renderer.\n * @memberof PIXI\n * @function autoDetectRenderer\n * @param options - Options to use.\n */\nexport function autoDetectRenderer<VIEW extends ICanvas = ICanvas>(options?: Partial<IRendererOptionsAuto>): IRenderer<VIEW>\n{\n for (const RendererType of renderers)\n {\n if (RendererType.test(options))\n {\n return new RendererType(options) as IRenderer<VIEW>;\n }\n }\n\n throw new Error('Unable to auto-detect a suitable renderer.');\n}\n"],"names":["extensions","ExtensionType"],"mappings":";;AA4BA,MAAM,YAA6C,CAAA;AAEnDA,WAAW,WAAA,aAAaC,WAAAA,cAAc,UAAU,SAAS;AAUlD,SAAS,mBAAmD,SACnE;AACI,aAAW,gBAAgB;AAEnB,QAAA,aAAa,KAAK,OAAO;AAElB,aAAA,IAAI,aAAa,OAAO;AAIjC,QAAA,IAAI,MAAM,4CAA4C;AAChE;;"}

View File

@@ -0,0 +1,13 @@
import { extensions, ExtensionType } from "@pixi/extensions";
const renderers = [];
extensions.handleByList(ExtensionType.Renderer, renderers);
function autoDetectRenderer(options) {
for (const RendererType of renderers)
if (RendererType.test(options))
return new RendererType(options);
throw new Error("Unable to auto-detect a suitable renderer.");
}
export {
autoDetectRenderer
};
//# sourceMappingURL=autoDetectRenderer.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"autoDetectRenderer.mjs","sources":["../src/autoDetectRenderer.ts"],"sourcesContent":["import { extensions, ExtensionType } from '@pixi/extensions';\n\nimport type { ICanvas } from '@pixi/settings';\nimport type { IRenderer, IRendererOptions } from './IRenderer';\n\n/**\n * Renderer options supplied to `autoDetectRenderer`.\n * @memberof PIXI\n */\nexport interface IRendererOptionsAuto extends IRendererOptions\n{\n /**\n * Force CanvasRenderer even if WebGL is supported. Only available with **pixi.js-legacy**.\n * @default false\n */\n forceCanvas?: boolean;\n}\n\nexport interface IRendererConstructor<VIEW extends ICanvas = ICanvas>\n{\n test(options?: Partial<IRendererOptionsAuto>): boolean;\n new (options?: Partial<IRendererOptionsAuto>): IRenderer<VIEW>;\n}\n\n/**\n * Collection of installed Renderers.\n * @ignore\n */\nconst renderers: IRendererConstructor<ICanvas>[] = [];\n\nextensions.handleByList(ExtensionType.Renderer, renderers);\n\n/**\n * This helper function will automatically detect which renderer you should be using.\n * WebGL is the preferred renderer as it is a lot faster. If WebGL is not supported by\n * the browser then this function will return a canvas renderer.\n * @memberof PIXI\n * @function autoDetectRenderer\n * @param options - Options to use.\n */\nexport function autoDetectRenderer<VIEW extends ICanvas = ICanvas>(options?: Partial<IRendererOptionsAuto>): IRenderer<VIEW>\n{\n for (const RendererType of renderers)\n {\n if (RendererType.test(options))\n {\n return new RendererType(options) as IRenderer<VIEW>;\n }\n }\n\n throw new Error('Unable to auto-detect a suitable renderer.');\n}\n"],"names":[],"mappings":";AA4BA,MAAM,YAA6C,CAAA;AAEnD,WAAW,aAAa,cAAc,UAAU,SAAS;AAUlD,SAAS,mBAAmD,SACnE;AACI,aAAW,gBAAgB;AAEnB,QAAA,aAAa,KAAK,OAAO;AAElB,aAAA,IAAI,aAAa,OAAO;AAIjC,QAAA,IAAI,MAAM,4CAA4C;AAChE;"}

View File

@@ -0,0 +1,72 @@
"use strict";
var color = require("@pixi/color"), extensions = require("@pixi/extensions");
class BackgroundSystem {
constructor() {
this.clearBeforeRender = !0, this._backgroundColor = new color.Color(0), this.alpha = 1;
}
/**
* initiates the background system
* @param {PIXI.IRendererOptions} options - the options for the background colors
*/
init(options) {
this.clearBeforeRender = options.clearBeforeRender;
const { backgroundColor, background, backgroundAlpha } = options, color2 = background ?? backgroundColor;
color2 !== void 0 && (this.color = color2), this.alpha = backgroundAlpha;
}
/**
* The background color to fill if not transparent.
* @member {PIXI.ColorSource}
*/
get color() {
return this._backgroundColor.value;
}
set color(value) {
this._backgroundColor.setValue(value);
}
/**
* The background color alpha. Setting this to 0 will make the canvas transparent.
* @member {number}
*/
get alpha() {
return this._backgroundColor.alpha;
}
set alpha(value) {
this._backgroundColor.setAlpha(value);
}
/** The background color object. */
get backgroundColor() {
return this._backgroundColor;
}
destroy() {
}
}
BackgroundSystem.defaultOptions = {
/**
* {@link PIXI.IRendererOptions.backgroundAlpha}
* @default 1
* @memberof PIXI.settings.RENDER_OPTIONS
*/
backgroundAlpha: 1,
/**
* {@link PIXI.IRendererOptions.backgroundColor}
* @default 0x000000
* @memberof PIXI.settings.RENDER_OPTIONS
*/
backgroundColor: 0,
/**
* {@link PIXI.IRendererOptions.clearBeforeRender}
* @default true
* @memberof PIXI.settings.RENDER_OPTIONS
*/
clearBeforeRender: !0
}, /** @ignore */
BackgroundSystem.extension = {
type: [
extensions.ExtensionType.RendererSystem,
extensions.ExtensionType.CanvasRendererSystem
],
name: "background"
};
extensions.extensions.add(BackgroundSystem);
exports.BackgroundSystem = BackgroundSystem;
//# sourceMappingURL=BackgroundSystem.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,74 @@
import { Color } from "@pixi/color";
import { ExtensionType, extensions } from "@pixi/extensions";
class BackgroundSystem {
constructor() {
this.clearBeforeRender = !0, this._backgroundColor = new Color(0), this.alpha = 1;
}
/**
* initiates the background system
* @param {PIXI.IRendererOptions} options - the options for the background colors
*/
init(options) {
this.clearBeforeRender = options.clearBeforeRender;
const { backgroundColor, background, backgroundAlpha } = options, color = background ?? backgroundColor;
color !== void 0 && (this.color = color), this.alpha = backgroundAlpha;
}
/**
* The background color to fill if not transparent.
* @member {PIXI.ColorSource}
*/
get color() {
return this._backgroundColor.value;
}
set color(value) {
this._backgroundColor.setValue(value);
}
/**
* The background color alpha. Setting this to 0 will make the canvas transparent.
* @member {number}
*/
get alpha() {
return this._backgroundColor.alpha;
}
set alpha(value) {
this._backgroundColor.setAlpha(value);
}
/** The background color object. */
get backgroundColor() {
return this._backgroundColor;
}
destroy() {
}
}
BackgroundSystem.defaultOptions = {
/**
* {@link PIXI.IRendererOptions.backgroundAlpha}
* @default 1
* @memberof PIXI.settings.RENDER_OPTIONS
*/
backgroundAlpha: 1,
/**
* {@link PIXI.IRendererOptions.backgroundColor}
* @default 0x000000
* @memberof PIXI.settings.RENDER_OPTIONS
*/
backgroundColor: 0,
/**
* {@link PIXI.IRendererOptions.clearBeforeRender}
* @default true
* @memberof PIXI.settings.RENDER_OPTIONS
*/
clearBeforeRender: !0
}, /** @ignore */
BackgroundSystem.extension = {
type: [
ExtensionType.RendererSystem,
ExtensionType.CanvasRendererSystem
],
name: "background"
};
extensions.add(BackgroundSystem);
export {
BackgroundSystem
};
//# sourceMappingURL=BackgroundSystem.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
"use strict";
var constants = require("@pixi/constants");
class BatchDrawCall {
constructor() {
this.texArray = null, this.blend = 0, this.type = constants.DRAW_MODES.TRIANGLES, this.start = 0, this.size = 0, this.data = null;
}
}
exports.BatchDrawCall = BatchDrawCall;
//# sourceMappingURL=BatchDrawCall.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchDrawCall.js","sources":["../../src/batch/BatchDrawCall.ts"],"sourcesContent":["import { DRAW_MODES } from '@pixi/constants';\n\nimport type { BLEND_MODES } from '@pixi/constants';\nimport type { BatchTextureArray } from './BatchTextureArray';\n\n/**\n * Used by the batcher to draw batches.\n * Each one of these contains all information required to draw a bound geometry.\n * @memberof PIXI\n */\nexport class BatchDrawCall\n{\n texArray: BatchTextureArray;\n type: DRAW_MODES;\n blend: BLEND_MODES;\n start: number;\n size: number;\n\n /** Data for uniforms or custom webgl state. */\n data: any;\n\n constructor()\n {\n this.texArray = null;\n this.blend = 0;\n this.type = DRAW_MODES.TRIANGLES;\n\n this.start = 0;\n this.size = 0;\n\n this.data = null;\n }\n}\n"],"names":["DRAW_MODES"],"mappings":";;AAUO,MAAM,cACb;AAAA,EAUI,cACA;AACI,SAAK,WAAW,MAChB,KAAK,QAAQ,GACb,KAAK,OAAOA,UAAA,WAAW,WAEvB,KAAK,QAAQ,GACb,KAAK,OAAO,GAEZ,KAAK,OAAO;AAAA,EAChB;AACJ;;"}

View File

@@ -0,0 +1,10 @@
import { DRAW_MODES } from "@pixi/constants";
class BatchDrawCall {
constructor() {
this.texArray = null, this.blend = 0, this.type = DRAW_MODES.TRIANGLES, this.start = 0, this.size = 0, this.data = null;
}
}
export {
BatchDrawCall
};
//# sourceMappingURL=BatchDrawCall.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchDrawCall.mjs","sources":["../../src/batch/BatchDrawCall.ts"],"sourcesContent":["import { DRAW_MODES } from '@pixi/constants';\n\nimport type { BLEND_MODES } from '@pixi/constants';\nimport type { BatchTextureArray } from './BatchTextureArray';\n\n/**\n * Used by the batcher to draw batches.\n * Each one of these contains all information required to draw a bound geometry.\n * @memberof PIXI\n */\nexport class BatchDrawCall\n{\n texArray: BatchTextureArray;\n type: DRAW_MODES;\n blend: BLEND_MODES;\n start: number;\n size: number;\n\n /** Data for uniforms or custom webgl state. */\n data: any;\n\n constructor()\n {\n this.texArray = null;\n this.blend = 0;\n this.type = DRAW_MODES.TRIANGLES;\n\n this.start = 0;\n this.size = 0;\n\n this.data = null;\n }\n}\n"],"names":[],"mappings":";AAUO,MAAM,cACb;AAAA,EAUI,cACA;AACI,SAAK,WAAW,MAChB,KAAK,QAAQ,GACb,KAAK,OAAO,WAAW,WAEvB,KAAK,QAAQ,GACb,KAAK,OAAO,GAEZ,KAAK,OAAO;AAAA,EAChB;AACJ;"}

View File

@@ -0,0 +1,13 @@
"use strict";
var constants = require("@pixi/constants"), Buffer = require("../geometry/Buffer.js"), Geometry = require("../geometry/Geometry.js");
class BatchGeometry extends Geometry.Geometry {
/**
* @param {boolean} [_static=false] - Optimization flag, where `false`
* is updated every frame, `true` doesn't change frame-to-frame.
*/
constructor(_static = !1) {
super(), this._buffer = new Buffer.Buffer(null, _static, !1), this._indexBuffer = new Buffer.Buffer(null, _static, !0), this.addAttribute("aVertexPosition", this._buffer, 2, !1, constants.TYPES.FLOAT).addAttribute("aTextureCoord", this._buffer, 2, !1, constants.TYPES.FLOAT).addAttribute("aColor", this._buffer, 4, !0, constants.TYPES.UNSIGNED_BYTE).addAttribute("aTextureId", this._buffer, 1, !0, constants.TYPES.FLOAT).addIndex(this._indexBuffer);
}
}
exports.BatchGeometry = BatchGeometry;
//# sourceMappingURL=BatchGeometry.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchGeometry.js","sources":["../../src/batch/BatchGeometry.ts"],"sourcesContent":["import { TYPES } from '@pixi/constants';\nimport { Buffer } from '../geometry/Buffer';\nimport { Geometry } from '../geometry/Geometry';\n\n/**\n * Geometry used to batch standard PIXI content (e.g. Mesh, Sprite, Graphics objects).\n * @memberof PIXI\n */\nexport class BatchGeometry extends Geometry\n{\n /**\n * Buffer used for position, color, texture IDs\n * @protected\n */\n _buffer: Buffer;\n\n /**\n * Index buffer data\n * @protected\n */\n _indexBuffer: Buffer;\n\n /**\n * @param {boolean} [_static=false] - Optimization flag, where `false`\n * is updated every frame, `true` doesn't change frame-to-frame.\n */\n constructor(_static = false)\n {\n super();\n\n this._buffer = new Buffer(null, _static, false);\n\n this._indexBuffer = new Buffer(null, _static, true);\n\n this.addAttribute('aVertexPosition', this._buffer, 2, false, TYPES.FLOAT)\n .addAttribute('aTextureCoord', this._buffer, 2, false, TYPES.FLOAT)\n .addAttribute('aColor', this._buffer, 4, true, TYPES.UNSIGNED_BYTE)\n .addAttribute('aTextureId', this._buffer, 1, true, TYPES.FLOAT)\n .addIndex(this._indexBuffer);\n }\n}\n"],"names":["Geometry","Buffer","TYPES"],"mappings":";;AAQO,MAAM,sBAAsBA,SAAAA,SACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBI,YAAY,UAAU,IACtB;AACU,aAED,KAAA,UAAU,IAAIC,cAAO,MAAM,SAAS,EAAK,GAE9C,KAAK,eAAe,IAAIA,OAAO,OAAA,MAAM,SAAS,EAAI,GAElD,KAAK,aAAa,mBAAmB,KAAK,SAAS,GAAG,IAAOC,UAAA,MAAM,KAAK,EACnE,aAAa,iBAAiB,KAAK,SAAS,GAAG,IAAOA,UAAA,MAAM,KAAK,EACjE,aAAa,UAAU,KAAK,SAAS,GAAG,IAAMA,UAAA,MAAM,aAAa,EACjE,aAAa,cAAc,KAAK,SAAS,GAAG,IAAMA,UAAAA,MAAM,KAAK,EAC7D,SAAS,KAAK,YAAY;AAAA,EACnC;AACJ;;"}

View File

@@ -0,0 +1,16 @@
import { TYPES } from "@pixi/constants";
import { Buffer } from "../geometry/Buffer.mjs";
import { Geometry } from "../geometry/Geometry.mjs";
class BatchGeometry extends Geometry {
/**
* @param {boolean} [_static=false] - Optimization flag, where `false`
* is updated every frame, `true` doesn't change frame-to-frame.
*/
constructor(_static = !1) {
super(), this._buffer = new Buffer(null, _static, !1), this._indexBuffer = new Buffer(null, _static, !0), this.addAttribute("aVertexPosition", this._buffer, 2, !1, TYPES.FLOAT).addAttribute("aTextureCoord", this._buffer, 2, !1, TYPES.FLOAT).addAttribute("aColor", this._buffer, 4, !0, TYPES.UNSIGNED_BYTE).addAttribute("aTextureId", this._buffer, 1, !0, TYPES.FLOAT).addIndex(this._indexBuffer);
}
}
export {
BatchGeometry
};
//# sourceMappingURL=BatchGeometry.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchGeometry.mjs","sources":["../../src/batch/BatchGeometry.ts"],"sourcesContent":["import { TYPES } from '@pixi/constants';\nimport { Buffer } from '../geometry/Buffer';\nimport { Geometry } from '../geometry/Geometry';\n\n/**\n * Geometry used to batch standard PIXI content (e.g. Mesh, Sprite, Graphics objects).\n * @memberof PIXI\n */\nexport class BatchGeometry extends Geometry\n{\n /**\n * Buffer used for position, color, texture IDs\n * @protected\n */\n _buffer: Buffer;\n\n /**\n * Index buffer data\n * @protected\n */\n _indexBuffer: Buffer;\n\n /**\n * @param {boolean} [_static=false] - Optimization flag, where `false`\n * is updated every frame, `true` doesn't change frame-to-frame.\n */\n constructor(_static = false)\n {\n super();\n\n this._buffer = new Buffer(null, _static, false);\n\n this._indexBuffer = new Buffer(null, _static, true);\n\n this.addAttribute('aVertexPosition', this._buffer, 2, false, TYPES.FLOAT)\n .addAttribute('aTextureCoord', this._buffer, 2, false, TYPES.FLOAT)\n .addAttribute('aColor', this._buffer, 4, true, TYPES.UNSIGNED_BYTE)\n .addAttribute('aTextureId', this._buffer, 1, true, TYPES.FLOAT)\n .addIndex(this._indexBuffer);\n }\n}\n"],"names":[],"mappings":";;;AAQO,MAAM,sBAAsB,SACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBI,YAAY,UAAU,IACtB;AACU,aAED,KAAA,UAAU,IAAI,OAAO,MAAM,SAAS,EAAK,GAE9C,KAAK,eAAe,IAAI,OAAO,MAAM,SAAS,EAAI,GAElD,KAAK,aAAa,mBAAmB,KAAK,SAAS,GAAG,IAAO,MAAM,KAAK,EACnE,aAAa,iBAAiB,KAAK,SAAS,GAAG,IAAO,MAAM,KAAK,EACjE,aAAa,UAAU,KAAK,SAAS,GAAG,IAAM,MAAM,aAAa,EACjE,aAAa,cAAc,KAAK,SAAS,GAAG,IAAM,MAAM,KAAK,EAC7D,SAAS,KAAK,YAAY;AAAA,EACnC;AACJ;"}

View File

@@ -0,0 +1,262 @@
"use strict";
var color = require("@pixi/color"), constants = require("@pixi/constants"), extensions = require("@pixi/extensions"), settings = require("@pixi/settings"), utils = require("@pixi/utils"), ViewableBuffer = require("../geometry/ViewableBuffer.js"), checkMaxIfStatementsInShader = require("../shader/utils/checkMaxIfStatementsInShader.js"), State = require("../state/State.js"), BaseTexture = require("../textures/BaseTexture.js"), BatchDrawCall = require("./BatchDrawCall.js"), BatchGeometry = require("./BatchGeometry.js"), BatchShaderGenerator = require("./BatchShaderGenerator.js"), BatchTextureArray = require("./BatchTextureArray.js"), canUploadSameBuffer = require("./canUploadSameBuffer.js"), maxRecommendedTextures = require("./maxRecommendedTextures.js"), ObjectRenderer = require("./ObjectRenderer.js"), texture$1 = require("./texture.frag.js"), texture = require("./texture.vert.js");
const _BatchRenderer = class _BatchRenderer2 extends ObjectRenderer.ObjectRenderer {
/**
* This will hook onto the renderer's `contextChange`
* and `prerender` signals.
* @param {PIXI.Renderer} renderer - The renderer this works for.
*/
constructor(renderer) {
super(renderer), this.setShaderGenerator(), this.geometryClass = BatchGeometry.BatchGeometry, this.vertexSize = 6, this.state = State.State.for2d(), this.size = _BatchRenderer2.defaultBatchSize * 4, this._vertexCount = 0, this._indexCount = 0, this._bufferedElements = [], this._bufferedTextures = [], this._bufferSize = 0, this._shader = null, this._packedGeometries = [], this._packedGeometryPoolSize = 2, this._flushId = 0, this._aBuffers = {}, this._iBuffers = {}, this.maxTextures = 1, this.renderer.on("prerender", this.onPrerender, this), renderer.runners.contextChange.add(this), this._dcIndex = 0, this._aIndex = 0, this._iIndex = 0, this._attributeBuffer = null, this._indexBuffer = null, this._tempBoundTextures = [];
}
/**
* The maximum textures that this device supports.
* @static
* @default 32
*/
static get defaultMaxTextures() {
return this._defaultMaxTextures = this._defaultMaxTextures ?? maxRecommendedTextures.maxRecommendedTextures(32), this._defaultMaxTextures;
}
static set defaultMaxTextures(value) {
this._defaultMaxTextures = value;
}
/**
* Can we upload the same buffer in a single frame?
* @static
*/
static get canUploadSameBuffer() {
return this._canUploadSameBuffer = this._canUploadSameBuffer ?? canUploadSameBuffer.canUploadSameBuffer(), this._canUploadSameBuffer;
}
static set canUploadSameBuffer(value) {
this._canUploadSameBuffer = value;
}
/**
* @see PIXI.BatchRenderer#maxTextures
* @deprecated since 7.1.0
* @readonly
*/
get MAX_TEXTURES() {
return utils.deprecation("7.1.0", "BatchRenderer#MAX_TEXTURES renamed to BatchRenderer#maxTextures"), this.maxTextures;
}
/**
* The default vertex shader source
* @readonly
*/
static get defaultVertexSrc() {
return texture.default;
}
/**
* The default fragment shader source
* @readonly
*/
static get defaultFragmentTemplate() {
return texture$1.default;
}
/**
* Set the shader generator.
* @param {object} [options]
* @param {string} [options.vertex=PIXI.BatchRenderer.defaultVertexSrc] - Vertex shader source
* @param {string} [options.fragment=PIXI.BatchRenderer.defaultFragmentTemplate] - Fragment shader template
*/
setShaderGenerator({
vertex = _BatchRenderer2.defaultVertexSrc,
fragment = _BatchRenderer2.defaultFragmentTemplate
} = {}) {
this.shaderGenerator = new BatchShaderGenerator.BatchShaderGenerator(vertex, fragment);
}
/**
* Handles the `contextChange` signal.
*
* It calculates `this.maxTextures` and allocating the packed-geometry object pool.
*/
contextChange() {
const gl = this.renderer.gl;
settings.settings.PREFER_ENV === constants.ENV.WEBGL_LEGACY ? this.maxTextures = 1 : (this.maxTextures = Math.min(
gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS),
_BatchRenderer2.defaultMaxTextures
), this.maxTextures = checkMaxIfStatementsInShader.checkMaxIfStatementsInShader(
this.maxTextures,
gl
)), this._shader = this.shaderGenerator.generateShader(this.maxTextures);
for (let i = 0; i < this._packedGeometryPoolSize; i++)
this._packedGeometries[i] = new this.geometryClass();
this.initFlushBuffers();
}
/** Makes sure that static and dynamic flush pooled objects have correct dimensions. */
initFlushBuffers() {
const {
_drawCallPool,
_textureArrayPool
} = _BatchRenderer2, MAX_SPRITES = this.size / 4, MAX_TA = Math.floor(MAX_SPRITES / this.maxTextures) + 1;
for (; _drawCallPool.length < MAX_SPRITES; )
_drawCallPool.push(new BatchDrawCall.BatchDrawCall());
for (; _textureArrayPool.length < MAX_TA; )
_textureArrayPool.push(new BatchTextureArray.BatchTextureArray());
for (let i = 0; i < this.maxTextures; i++)
this._tempBoundTextures[i] = null;
}
/** Handles the `prerender` signal. It ensures that flushes start from the first geometry object again. */
onPrerender() {
this._flushId = 0;
}
/**
* Buffers the "batchable" object. It need not be rendered immediately.
* @param {PIXI.DisplayObject} element - the element to render when
* using this renderer
*/
render(element) {
element._texture.valid && (this._vertexCount + element.vertexData.length / 2 > this.size && this.flush(), this._vertexCount += element.vertexData.length / 2, this._indexCount += element.indices.length, this._bufferedTextures[this._bufferSize] = element._texture.baseTexture, this._bufferedElements[this._bufferSize++] = element);
}
buildTexturesAndDrawCalls() {
const {
_bufferedTextures: textures,
maxTextures
} = this, textureArrays = _BatchRenderer2._textureArrayPool, batch = this.renderer.batch, boundTextures = this._tempBoundTextures, touch = this.renderer.textureGC.count;
let TICK = ++BaseTexture.BaseTexture._globalBatch, countTexArrays = 0, texArray = textureArrays[0], start = 0;
batch.copyBoundTextures(boundTextures, maxTextures);
for (let i = 0; i < this._bufferSize; ++i) {
const tex = textures[i];
textures[i] = null, tex._batchEnabled !== TICK && (texArray.count >= maxTextures && (batch.boundArray(texArray, boundTextures, TICK, maxTextures), this.buildDrawCalls(texArray, start, i), start = i, texArray = textureArrays[++countTexArrays], ++TICK), tex._batchEnabled = TICK, tex.touched = touch, texArray.elements[texArray.count++] = tex);
}
texArray.count > 0 && (batch.boundArray(texArray, boundTextures, TICK, maxTextures), this.buildDrawCalls(texArray, start, this._bufferSize), ++countTexArrays, ++TICK);
for (let i = 0; i < boundTextures.length; i++)
boundTextures[i] = null;
BaseTexture.BaseTexture._globalBatch = TICK;
}
/**
* Populating drawcalls for rendering
* @param texArray
* @param start
* @param finish
*/
buildDrawCalls(texArray, start, finish) {
const {
_bufferedElements: elements,
_attributeBuffer,
_indexBuffer,
vertexSize
} = this, drawCalls = _BatchRenderer2._drawCallPool;
let dcIndex = this._dcIndex, aIndex = this._aIndex, iIndex = this._iIndex, drawCall = drawCalls[dcIndex];
drawCall.start = this._iIndex, drawCall.texArray = texArray;
for (let i = start; i < finish; ++i) {
const sprite = elements[i], tex = sprite._texture.baseTexture, spriteBlendMode = utils.premultiplyBlendMode[tex.alphaMode ? 1 : 0][sprite.blendMode];
elements[i] = null, start < i && drawCall.blend !== spriteBlendMode && (drawCall.size = iIndex - drawCall.start, start = i, drawCall = drawCalls[++dcIndex], drawCall.texArray = texArray, drawCall.start = iIndex), this.packInterleavedGeometry(sprite, _attributeBuffer, _indexBuffer, aIndex, iIndex), aIndex += sprite.vertexData.length / 2 * vertexSize, iIndex += sprite.indices.length, drawCall.blend = spriteBlendMode;
}
start < finish && (drawCall.size = iIndex - drawCall.start, ++dcIndex), this._dcIndex = dcIndex, this._aIndex = aIndex, this._iIndex = iIndex;
}
/**
* Bind textures for current rendering
* @param texArray
*/
bindAndClearTexArray(texArray) {
const textureSystem = this.renderer.texture;
for (let j = 0; j < texArray.count; j++)
textureSystem.bind(texArray.elements[j], texArray.ids[j]), texArray.elements[j] = null;
texArray.count = 0;
}
updateGeometry() {
const {
_packedGeometries: packedGeometries,
_attributeBuffer: attributeBuffer,
_indexBuffer: indexBuffer
} = this;
_BatchRenderer2.canUploadSameBuffer ? (packedGeometries[this._flushId]._buffer.update(attributeBuffer.rawBinaryData), packedGeometries[this._flushId]._indexBuffer.update(indexBuffer), this.renderer.geometry.updateBuffers()) : (this._packedGeometryPoolSize <= this._flushId && (this._packedGeometryPoolSize++, packedGeometries[this._flushId] = new this.geometryClass()), packedGeometries[this._flushId]._buffer.update(attributeBuffer.rawBinaryData), packedGeometries[this._flushId]._indexBuffer.update(indexBuffer), this.renderer.geometry.bind(packedGeometries[this._flushId]), this.renderer.geometry.updateBuffers(), this._flushId++);
}
drawBatches() {
const dcCount = this._dcIndex, { gl, state: stateSystem } = this.renderer, drawCalls = _BatchRenderer2._drawCallPool;
let curTexArray = null;
for (let i = 0; i < dcCount; i++) {
const { texArray, type, size, start, blend } = drawCalls[i];
curTexArray !== texArray && (curTexArray = texArray, this.bindAndClearTexArray(texArray)), this.state.blendMode = blend, stateSystem.set(this.state), gl.drawElements(type, size, gl.UNSIGNED_SHORT, start * 2);
}
}
/** Renders the content _now_ and empties the current batch. */
flush() {
this._vertexCount !== 0 && (this._attributeBuffer = this.getAttributeBuffer(this._vertexCount), this._indexBuffer = this.getIndexBuffer(this._indexCount), this._aIndex = 0, this._iIndex = 0, this._dcIndex = 0, this.buildTexturesAndDrawCalls(), this.updateGeometry(), this.drawBatches(), this._bufferSize = 0, this._vertexCount = 0, this._indexCount = 0);
}
/** Starts a new sprite batch. */
start() {
this.renderer.state.set(this.state), this.renderer.texture.ensureSamplerType(this.maxTextures), this.renderer.shader.bind(this._shader), _BatchRenderer2.canUploadSameBuffer && this.renderer.geometry.bind(this._packedGeometries[this._flushId]);
}
/** Stops and flushes the current batch. */
stop() {
this.flush();
}
/** Destroys this `BatchRenderer`. It cannot be used again. */
destroy() {
for (let i = 0; i < this._packedGeometryPoolSize; i++)
this._packedGeometries[i] && this._packedGeometries[i].destroy();
this.renderer.off("prerender", this.onPrerender, this), this._aBuffers = null, this._iBuffers = null, this._packedGeometries = null, this._attributeBuffer = null, this._indexBuffer = null, this._shader && (this._shader.destroy(), this._shader = null), super.destroy();
}
/**
* Fetches an attribute buffer from `this._aBuffers` that can hold atleast `size` floats.
* @param size - minimum capacity required
* @returns - buffer than can hold atleast `size` floats
*/
getAttributeBuffer(size) {
const roundedP2 = utils.nextPow2(Math.ceil(size / 8)), roundedSizeIndex = utils.log2(roundedP2), roundedSize = roundedP2 * 8;
this._aBuffers.length <= roundedSizeIndex && (this._iBuffers.length = roundedSizeIndex + 1);
let buffer = this._aBuffers[roundedSize];
return buffer || (this._aBuffers[roundedSize] = buffer = new ViewableBuffer.ViewableBuffer(roundedSize * this.vertexSize * 4)), buffer;
}
/**
* Fetches an index buffer from `this._iBuffers` that can
* have at least `size` capacity.
* @param size - minimum required capacity
* @returns - buffer that can fit `size` indices.
*/
getIndexBuffer(size) {
const roundedP2 = utils.nextPow2(Math.ceil(size / 12)), roundedSizeIndex = utils.log2(roundedP2), roundedSize = roundedP2 * 12;
this._iBuffers.length <= roundedSizeIndex && (this._iBuffers.length = roundedSizeIndex + 1);
let buffer = this._iBuffers[roundedSizeIndex];
return buffer || (this._iBuffers[roundedSizeIndex] = buffer = new Uint16Array(roundedSize)), buffer;
}
/**
* Takes the four batching parameters of `element`, interleaves
* and pushes them into the batching attribute/index buffers given.
*
* It uses these properties: `vertexData` `uvs`, `textureId` and
* `indicies`. It also uses the "tint" of the base-texture, if
* present.
* @param {PIXI.DisplayObject} element - element being rendered
* @param attributeBuffer - attribute buffer.
* @param indexBuffer - index buffer
* @param aIndex - number of floats already in the attribute buffer
* @param iIndex - number of indices already in `indexBuffer`
*/
packInterleavedGeometry(element, attributeBuffer, indexBuffer, aIndex, iIndex) {
const {
uint32View,
float32View
} = attributeBuffer, packedVertices = aIndex / this.vertexSize, uvs = element.uvs, indicies = element.indices, vertexData = element.vertexData, textureId = element._texture.baseTexture._batchLocation, alpha = Math.min(element.worldAlpha, 1), argb = color.Color.shared.setValue(element._tintRGB).toPremultiplied(alpha, element._texture.baseTexture.alphaMode > 0);
for (let i = 0; i < vertexData.length; i += 2)
float32View[aIndex++] = vertexData[i], float32View[aIndex++] = vertexData[i + 1], float32View[aIndex++] = uvs[i], float32View[aIndex++] = uvs[i + 1], uint32View[aIndex++] = argb, float32View[aIndex++] = textureId;
for (let i = 0; i < indicies.length; i++)
indexBuffer[iIndex++] = packedVertices + indicies[i];
}
};
_BatchRenderer.defaultBatchSize = 4096, /** @ignore */
_BatchRenderer.extension = {
name: "batch",
type: extensions.ExtensionType.RendererPlugin
}, /**
* Pool of `BatchDrawCall` objects that `flush` used
* to create "batches" of the objects being rendered.
*
* These are never re-allocated again.
* Shared between all batch renderers because it can be only one "flush" working at the moment.
* @member {PIXI.BatchDrawCall[]}
*/
_BatchRenderer._drawCallPool = [], /**
* Pool of `BatchDrawCall` objects that `flush` used
* to create "batches" of the objects being rendered.
*
* These are never re-allocated again.
* Shared between all batch renderers because it can be only one "flush" working at the moment.
* @member {PIXI.BatchTextureArray[]}
*/
_BatchRenderer._textureArrayPool = [];
let BatchRenderer = _BatchRenderer;
extensions.extensions.add(BatchRenderer);
exports.BatchRenderer = BatchRenderer;
//# sourceMappingURL=BatchRenderer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,280 @@
import { Color } from "@pixi/color";
import { ENV } from "@pixi/constants";
import { ExtensionType, extensions } from "@pixi/extensions";
import { settings } from "@pixi/settings";
import { deprecation, premultiplyBlendMode, nextPow2, log2 } from "@pixi/utils";
import { ViewableBuffer } from "../geometry/ViewableBuffer.mjs";
import { checkMaxIfStatementsInShader } from "../shader/utils/checkMaxIfStatementsInShader.mjs";
import { State } from "../state/State.mjs";
import { BaseTexture } from "../textures/BaseTexture.mjs";
import { BatchDrawCall } from "./BatchDrawCall.mjs";
import { BatchGeometry } from "./BatchGeometry.mjs";
import { BatchShaderGenerator } from "./BatchShaderGenerator.mjs";
import { BatchTextureArray } from "./BatchTextureArray.mjs";
import { canUploadSameBuffer } from "./canUploadSameBuffer.mjs";
import { maxRecommendedTextures } from "./maxRecommendedTextures.mjs";
import { ObjectRenderer } from "./ObjectRenderer.mjs";
import defaultFragment from "./texture.frag.mjs";
import defaultVertex from "./texture.vert.mjs";
const _BatchRenderer = class _BatchRenderer2 extends ObjectRenderer {
/**
* This will hook onto the renderer's `contextChange`
* and `prerender` signals.
* @param {PIXI.Renderer} renderer - The renderer this works for.
*/
constructor(renderer) {
super(renderer), this.setShaderGenerator(), this.geometryClass = BatchGeometry, this.vertexSize = 6, this.state = State.for2d(), this.size = _BatchRenderer2.defaultBatchSize * 4, this._vertexCount = 0, this._indexCount = 0, this._bufferedElements = [], this._bufferedTextures = [], this._bufferSize = 0, this._shader = null, this._packedGeometries = [], this._packedGeometryPoolSize = 2, this._flushId = 0, this._aBuffers = {}, this._iBuffers = {}, this.maxTextures = 1, this.renderer.on("prerender", this.onPrerender, this), renderer.runners.contextChange.add(this), this._dcIndex = 0, this._aIndex = 0, this._iIndex = 0, this._attributeBuffer = null, this._indexBuffer = null, this._tempBoundTextures = [];
}
/**
* The maximum textures that this device supports.
* @static
* @default 32
*/
static get defaultMaxTextures() {
return this._defaultMaxTextures = this._defaultMaxTextures ?? maxRecommendedTextures(32), this._defaultMaxTextures;
}
static set defaultMaxTextures(value) {
this._defaultMaxTextures = value;
}
/**
* Can we upload the same buffer in a single frame?
* @static
*/
static get canUploadSameBuffer() {
return this._canUploadSameBuffer = this._canUploadSameBuffer ?? canUploadSameBuffer(), this._canUploadSameBuffer;
}
static set canUploadSameBuffer(value) {
this._canUploadSameBuffer = value;
}
/**
* @see PIXI.BatchRenderer#maxTextures
* @deprecated since 7.1.0
* @readonly
*/
get MAX_TEXTURES() {
return deprecation("7.1.0", "BatchRenderer#MAX_TEXTURES renamed to BatchRenderer#maxTextures"), this.maxTextures;
}
/**
* The default vertex shader source
* @readonly
*/
static get defaultVertexSrc() {
return defaultVertex;
}
/**
* The default fragment shader source
* @readonly
*/
static get defaultFragmentTemplate() {
return defaultFragment;
}
/**
* Set the shader generator.
* @param {object} [options]
* @param {string} [options.vertex=PIXI.BatchRenderer.defaultVertexSrc] - Vertex shader source
* @param {string} [options.fragment=PIXI.BatchRenderer.defaultFragmentTemplate] - Fragment shader template
*/
setShaderGenerator({
vertex = _BatchRenderer2.defaultVertexSrc,
fragment = _BatchRenderer2.defaultFragmentTemplate
} = {}) {
this.shaderGenerator = new BatchShaderGenerator(vertex, fragment);
}
/**
* Handles the `contextChange` signal.
*
* It calculates `this.maxTextures` and allocating the packed-geometry object pool.
*/
contextChange() {
const gl = this.renderer.gl;
settings.PREFER_ENV === ENV.WEBGL_LEGACY ? this.maxTextures = 1 : (this.maxTextures = Math.min(
gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS),
_BatchRenderer2.defaultMaxTextures
), this.maxTextures = checkMaxIfStatementsInShader(
this.maxTextures,
gl
)), this._shader = this.shaderGenerator.generateShader(this.maxTextures);
for (let i = 0; i < this._packedGeometryPoolSize; i++)
this._packedGeometries[i] = new this.geometryClass();
this.initFlushBuffers();
}
/** Makes sure that static and dynamic flush pooled objects have correct dimensions. */
initFlushBuffers() {
const {
_drawCallPool,
_textureArrayPool
} = _BatchRenderer2, MAX_SPRITES = this.size / 4, MAX_TA = Math.floor(MAX_SPRITES / this.maxTextures) + 1;
for (; _drawCallPool.length < MAX_SPRITES; )
_drawCallPool.push(new BatchDrawCall());
for (; _textureArrayPool.length < MAX_TA; )
_textureArrayPool.push(new BatchTextureArray());
for (let i = 0; i < this.maxTextures; i++)
this._tempBoundTextures[i] = null;
}
/** Handles the `prerender` signal. It ensures that flushes start from the first geometry object again. */
onPrerender() {
this._flushId = 0;
}
/**
* Buffers the "batchable" object. It need not be rendered immediately.
* @param {PIXI.DisplayObject} element - the element to render when
* using this renderer
*/
render(element) {
element._texture.valid && (this._vertexCount + element.vertexData.length / 2 > this.size && this.flush(), this._vertexCount += element.vertexData.length / 2, this._indexCount += element.indices.length, this._bufferedTextures[this._bufferSize] = element._texture.baseTexture, this._bufferedElements[this._bufferSize++] = element);
}
buildTexturesAndDrawCalls() {
const {
_bufferedTextures: textures,
maxTextures
} = this, textureArrays = _BatchRenderer2._textureArrayPool, batch = this.renderer.batch, boundTextures = this._tempBoundTextures, touch = this.renderer.textureGC.count;
let TICK = ++BaseTexture._globalBatch, countTexArrays = 0, texArray = textureArrays[0], start = 0;
batch.copyBoundTextures(boundTextures, maxTextures);
for (let i = 0; i < this._bufferSize; ++i) {
const tex = textures[i];
textures[i] = null, tex._batchEnabled !== TICK && (texArray.count >= maxTextures && (batch.boundArray(texArray, boundTextures, TICK, maxTextures), this.buildDrawCalls(texArray, start, i), start = i, texArray = textureArrays[++countTexArrays], ++TICK), tex._batchEnabled = TICK, tex.touched = touch, texArray.elements[texArray.count++] = tex);
}
texArray.count > 0 && (batch.boundArray(texArray, boundTextures, TICK, maxTextures), this.buildDrawCalls(texArray, start, this._bufferSize), ++countTexArrays, ++TICK);
for (let i = 0; i < boundTextures.length; i++)
boundTextures[i] = null;
BaseTexture._globalBatch = TICK;
}
/**
* Populating drawcalls for rendering
* @param texArray
* @param start
* @param finish
*/
buildDrawCalls(texArray, start, finish) {
const {
_bufferedElements: elements,
_attributeBuffer,
_indexBuffer,
vertexSize
} = this, drawCalls = _BatchRenderer2._drawCallPool;
let dcIndex = this._dcIndex, aIndex = this._aIndex, iIndex = this._iIndex, drawCall = drawCalls[dcIndex];
drawCall.start = this._iIndex, drawCall.texArray = texArray;
for (let i = start; i < finish; ++i) {
const sprite = elements[i], tex = sprite._texture.baseTexture, spriteBlendMode = premultiplyBlendMode[tex.alphaMode ? 1 : 0][sprite.blendMode];
elements[i] = null, start < i && drawCall.blend !== spriteBlendMode && (drawCall.size = iIndex - drawCall.start, start = i, drawCall = drawCalls[++dcIndex], drawCall.texArray = texArray, drawCall.start = iIndex), this.packInterleavedGeometry(sprite, _attributeBuffer, _indexBuffer, aIndex, iIndex), aIndex += sprite.vertexData.length / 2 * vertexSize, iIndex += sprite.indices.length, drawCall.blend = spriteBlendMode;
}
start < finish && (drawCall.size = iIndex - drawCall.start, ++dcIndex), this._dcIndex = dcIndex, this._aIndex = aIndex, this._iIndex = iIndex;
}
/**
* Bind textures for current rendering
* @param texArray
*/
bindAndClearTexArray(texArray) {
const textureSystem = this.renderer.texture;
for (let j = 0; j < texArray.count; j++)
textureSystem.bind(texArray.elements[j], texArray.ids[j]), texArray.elements[j] = null;
texArray.count = 0;
}
updateGeometry() {
const {
_packedGeometries: packedGeometries,
_attributeBuffer: attributeBuffer,
_indexBuffer: indexBuffer
} = this;
_BatchRenderer2.canUploadSameBuffer ? (packedGeometries[this._flushId]._buffer.update(attributeBuffer.rawBinaryData), packedGeometries[this._flushId]._indexBuffer.update(indexBuffer), this.renderer.geometry.updateBuffers()) : (this._packedGeometryPoolSize <= this._flushId && (this._packedGeometryPoolSize++, packedGeometries[this._flushId] = new this.geometryClass()), packedGeometries[this._flushId]._buffer.update(attributeBuffer.rawBinaryData), packedGeometries[this._flushId]._indexBuffer.update(indexBuffer), this.renderer.geometry.bind(packedGeometries[this._flushId]), this.renderer.geometry.updateBuffers(), this._flushId++);
}
drawBatches() {
const dcCount = this._dcIndex, { gl, state: stateSystem } = this.renderer, drawCalls = _BatchRenderer2._drawCallPool;
let curTexArray = null;
for (let i = 0; i < dcCount; i++) {
const { texArray, type, size, start, blend } = drawCalls[i];
curTexArray !== texArray && (curTexArray = texArray, this.bindAndClearTexArray(texArray)), this.state.blendMode = blend, stateSystem.set(this.state), gl.drawElements(type, size, gl.UNSIGNED_SHORT, start * 2);
}
}
/** Renders the content _now_ and empties the current batch. */
flush() {
this._vertexCount !== 0 && (this._attributeBuffer = this.getAttributeBuffer(this._vertexCount), this._indexBuffer = this.getIndexBuffer(this._indexCount), this._aIndex = 0, this._iIndex = 0, this._dcIndex = 0, this.buildTexturesAndDrawCalls(), this.updateGeometry(), this.drawBatches(), this._bufferSize = 0, this._vertexCount = 0, this._indexCount = 0);
}
/** Starts a new sprite batch. */
start() {
this.renderer.state.set(this.state), this.renderer.texture.ensureSamplerType(this.maxTextures), this.renderer.shader.bind(this._shader), _BatchRenderer2.canUploadSameBuffer && this.renderer.geometry.bind(this._packedGeometries[this._flushId]);
}
/** Stops and flushes the current batch. */
stop() {
this.flush();
}
/** Destroys this `BatchRenderer`. It cannot be used again. */
destroy() {
for (let i = 0; i < this._packedGeometryPoolSize; i++)
this._packedGeometries[i] && this._packedGeometries[i].destroy();
this.renderer.off("prerender", this.onPrerender, this), this._aBuffers = null, this._iBuffers = null, this._packedGeometries = null, this._attributeBuffer = null, this._indexBuffer = null, this._shader && (this._shader.destroy(), this._shader = null), super.destroy();
}
/**
* Fetches an attribute buffer from `this._aBuffers` that can hold atleast `size` floats.
* @param size - minimum capacity required
* @returns - buffer than can hold atleast `size` floats
*/
getAttributeBuffer(size) {
const roundedP2 = nextPow2(Math.ceil(size / 8)), roundedSizeIndex = log2(roundedP2), roundedSize = roundedP2 * 8;
this._aBuffers.length <= roundedSizeIndex && (this._iBuffers.length = roundedSizeIndex + 1);
let buffer = this._aBuffers[roundedSize];
return buffer || (this._aBuffers[roundedSize] = buffer = new ViewableBuffer(roundedSize * this.vertexSize * 4)), buffer;
}
/**
* Fetches an index buffer from `this._iBuffers` that can
* have at least `size` capacity.
* @param size - minimum required capacity
* @returns - buffer that can fit `size` indices.
*/
getIndexBuffer(size) {
const roundedP2 = nextPow2(Math.ceil(size / 12)), roundedSizeIndex = log2(roundedP2), roundedSize = roundedP2 * 12;
this._iBuffers.length <= roundedSizeIndex && (this._iBuffers.length = roundedSizeIndex + 1);
let buffer = this._iBuffers[roundedSizeIndex];
return buffer || (this._iBuffers[roundedSizeIndex] = buffer = new Uint16Array(roundedSize)), buffer;
}
/**
* Takes the four batching parameters of `element`, interleaves
* and pushes them into the batching attribute/index buffers given.
*
* It uses these properties: `vertexData` `uvs`, `textureId` and
* `indicies`. It also uses the "tint" of the base-texture, if
* present.
* @param {PIXI.DisplayObject} element - element being rendered
* @param attributeBuffer - attribute buffer.
* @param indexBuffer - index buffer
* @param aIndex - number of floats already in the attribute buffer
* @param iIndex - number of indices already in `indexBuffer`
*/
packInterleavedGeometry(element, attributeBuffer, indexBuffer, aIndex, iIndex) {
const {
uint32View,
float32View
} = attributeBuffer, packedVertices = aIndex / this.vertexSize, uvs = element.uvs, indicies = element.indices, vertexData = element.vertexData, textureId = element._texture.baseTexture._batchLocation, alpha = Math.min(element.worldAlpha, 1), argb = Color.shared.setValue(element._tintRGB).toPremultiplied(alpha, element._texture.baseTexture.alphaMode > 0);
for (let i = 0; i < vertexData.length; i += 2)
float32View[aIndex++] = vertexData[i], float32View[aIndex++] = vertexData[i + 1], float32View[aIndex++] = uvs[i], float32View[aIndex++] = uvs[i + 1], uint32View[aIndex++] = argb, float32View[aIndex++] = textureId;
for (let i = 0; i < indicies.length; i++)
indexBuffer[iIndex++] = packedVertices + indicies[i];
}
};
_BatchRenderer.defaultBatchSize = 4096, /** @ignore */
_BatchRenderer.extension = {
name: "batch",
type: ExtensionType.RendererPlugin
}, /**
* Pool of `BatchDrawCall` objects that `flush` used
* to create "batches" of the objects being rendered.
*
* These are never re-allocated again.
* Shared between all batch renderers because it can be only one "flush" working at the moment.
* @member {PIXI.BatchDrawCall[]}
*/
_BatchRenderer._drawCallPool = [], /**
* Pool of `BatchDrawCall` objects that `flush` used
* to create "batches" of the objects being rendered.
*
* These are never re-allocated again.
* Shared between all batch renderers because it can be only one "flush" working at the moment.
* @member {PIXI.BatchTextureArray[]}
*/
_BatchRenderer._textureArrayPool = [];
let BatchRenderer = _BatchRenderer;
extensions.add(BatchRenderer);
export {
BatchRenderer
};
//# sourceMappingURL=BatchRenderer.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,47 @@
"use strict";
var math = require("@pixi/math"), Program = require("../shader/Program.js"), Shader = require("../shader/Shader.js"), UniformGroup = require("../shader/UniformGroup.js");
class BatchShaderGenerator {
/**
* @param vertexSrc - Vertex shader
* @param fragTemplate - Fragment shader template
*/
constructor(vertexSrc, fragTemplate) {
if (this.vertexSrc = vertexSrc, this.fragTemplate = fragTemplate, this.programCache = {}, this.defaultGroupCache = {}, !fragTemplate.includes("%count%"))
throw new Error('Fragment template must contain "%count%".');
if (!fragTemplate.includes("%forloop%"))
throw new Error('Fragment template must contain "%forloop%".');
}
generateShader(maxTextures) {
if (!this.programCache[maxTextures]) {
const sampleValues = new Int32Array(maxTextures);
for (let i = 0; i < maxTextures; i++)
sampleValues[i] = i;
this.defaultGroupCache[maxTextures] = UniformGroup.UniformGroup.from({ uSamplers: sampleValues }, !0);
let fragmentSrc = this.fragTemplate;
fragmentSrc = fragmentSrc.replace(/%count%/gi, `${maxTextures}`), fragmentSrc = fragmentSrc.replace(/%forloop%/gi, this.generateSampleSrc(maxTextures)), this.programCache[maxTextures] = new Program.Program(this.vertexSrc, fragmentSrc);
}
const uniforms = {
tint: new Float32Array([1, 1, 1, 1]),
translationMatrix: new math.Matrix(),
default: this.defaultGroupCache[maxTextures]
};
return new Shader.Shader(this.programCache[maxTextures], uniforms);
}
generateSampleSrc(maxTextures) {
let src = "";
src += `
`, src += `
`;
for (let i = 0; i < maxTextures; i++)
i > 0 && (src += `
else `), i < maxTextures - 1 && (src += `if(vTextureId < ${i}.5)`), src += `
{`, src += `
color = texture2D(uSamplers[${i}], vTextureCoord);`, src += `
}`;
return src += `
`, src += `
`, src;
}
}
exports.BatchShaderGenerator = BatchShaderGenerator;
//# sourceMappingURL=BatchShaderGenerator.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchShaderGenerator.js","sources":["../../src/batch/BatchShaderGenerator.ts"],"sourcesContent":["import { Matrix } from '@pixi/math';\nimport { Program } from '../shader/Program';\nimport { Shader } from '../shader/Shader';\nimport { UniformGroup } from '../shader/UniformGroup';\n\n/**\n * Helper that generates batching multi-texture shader. Use it with your new BatchRenderer\n * @memberof PIXI\n */\nexport class BatchShaderGenerator\n{\n /** Reference to the vertex shader source. */\n public vertexSrc: string;\n\n /** Reference to the fragment shader template. Must contain \"%count%\" and \"%forloop%\". */\n public fragTemplate: string;\n\n programCache: {[key: number]: Program};\n defaultGroupCache: {[key: number]: UniformGroup};\n\n /**\n * @param vertexSrc - Vertex shader\n * @param fragTemplate - Fragment shader template\n */\n constructor(vertexSrc: string, fragTemplate: string)\n {\n this.vertexSrc = vertexSrc;\n this.fragTemplate = fragTemplate;\n\n this.programCache = {};\n this.defaultGroupCache = {};\n\n if (!fragTemplate.includes('%count%'))\n {\n throw new Error('Fragment template must contain \"%count%\".');\n }\n\n if (!fragTemplate.includes('%forloop%'))\n {\n throw new Error('Fragment template must contain \"%forloop%\".');\n }\n }\n\n generateShader(maxTextures: number): Shader\n {\n if (!this.programCache[maxTextures])\n {\n const sampleValues = new Int32Array(maxTextures);\n\n for (let i = 0; i < maxTextures; i++)\n {\n sampleValues[i] = i;\n }\n\n this.defaultGroupCache[maxTextures] = UniformGroup.from({ uSamplers: sampleValues }, true);\n\n let fragmentSrc = this.fragTemplate;\n\n fragmentSrc = fragmentSrc.replace(/%count%/gi, `${maxTextures}`);\n fragmentSrc = fragmentSrc.replace(/%forloop%/gi, this.generateSampleSrc(maxTextures));\n\n this.programCache[maxTextures] = new Program(this.vertexSrc, fragmentSrc);\n }\n\n const uniforms = {\n tint: new Float32Array([1, 1, 1, 1]),\n translationMatrix: new Matrix(),\n default: this.defaultGroupCache[maxTextures],\n };\n\n return new Shader(this.programCache[maxTextures], uniforms);\n }\n\n generateSampleSrc(maxTextures: number): string\n {\n let src = '';\n\n src += '\\n';\n src += '\\n';\n\n for (let i = 0; i < maxTextures; i++)\n {\n if (i > 0)\n {\n src += '\\nelse ';\n }\n\n if (i < maxTextures - 1)\n {\n src += `if(vTextureId < ${i}.5)`;\n }\n\n src += '\\n{';\n src += `\\n\\tcolor = texture2D(uSamplers[${i}], vTextureCoord);`;\n src += '\\n}';\n }\n\n src += '\\n';\n src += '\\n';\n\n return src;\n }\n}\n"],"names":["UniformGroup","Program","Matrix","Shader"],"mappings":";;AASO,MAAM,qBACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAcI,YAAY,WAAmB,cAC/B;AAOI,QANA,KAAK,YAAY,WACjB,KAAK,eAAe,cAEpB,KAAK,eAAe,CAAC,GACrB,KAAK,oBAAoB,CAAA,GAErB,CAAC,aAAa,SAAS,SAAS;AAE1B,YAAA,IAAI,MAAM,2CAA2C;AAG3D,QAAA,CAAC,aAAa,SAAS,WAAW;AAE5B,YAAA,IAAI,MAAM,6CAA6C;AAAA,EAErE;AAAA,EAEA,eAAe,aACf;AACI,QAAI,CAAC,KAAK,aAAa,WAAW,GAClC;AACU,YAAA,eAAe,IAAI,WAAW,WAAW;AAEtC,eAAA,IAAI,GAAG,IAAI,aAAa;AAE7B,qBAAa,CAAC,IAAI;AAGjB,WAAA,kBAAkB,WAAW,IAAIA,0BAAa,KAAK,EAAE,WAAW,aAAa,GAAG,EAAI;AAEzF,UAAI,cAAc,KAAK;AAET,oBAAA,YAAY,QAAQ,aAAa,GAAG,WAAW,EAAE,GAC/D,cAAc,YAAY,QAAQ,eAAe,KAAK,kBAAkB,WAAW,CAAC,GAEpF,KAAK,aAAa,WAAW,IAAI,IAAIC,gBAAQ,KAAK,WAAW,WAAW;AAAA,IAC5E;AAEA,UAAM,WAAW;AAAA,MACb,MAAM,IAAI,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,MACnC,mBAAmB,IAAIC,KAAAA,OAAO;AAAA,MAC9B,SAAS,KAAK,kBAAkB,WAAW;AAAA,IAAA;AAG/C,WAAO,IAAIC,OAAO,OAAA,KAAK,aAAa,WAAW,GAAG,QAAQ;AAAA,EAC9D;AAAA,EAEA,kBAAkB,aAClB;AACI,QAAI,MAAM;AAEH,WAAA;AAAA,GACP,OAAO;AAAA;AAEE,aAAA,IAAI,GAAG,IAAI,aAAa;AAEzB,UAAI,MAEJ,OAAO;AAAA,SAGP,IAAI,cAAc,MAElB,OAAO,mBAAmB,CAAC,QAG/B,OAAO;AAAA,IACP,OAAO;AAAA,+BAAmC,CAAC,sBAC3C,OAAO;AAAA;AAGJ,WAAA,OAAA;AAAA,GACP,OAAO;AAAA,GAEA;AAAA,EACX;AACJ;;"}

View File

@@ -0,0 +1,51 @@
import { Matrix } from "@pixi/math";
import { Program } from "../shader/Program.mjs";
import { Shader } from "../shader/Shader.mjs";
import { UniformGroup } from "../shader/UniformGroup.mjs";
class BatchShaderGenerator {
/**
* @param vertexSrc - Vertex shader
* @param fragTemplate - Fragment shader template
*/
constructor(vertexSrc, fragTemplate) {
if (this.vertexSrc = vertexSrc, this.fragTemplate = fragTemplate, this.programCache = {}, this.defaultGroupCache = {}, !fragTemplate.includes("%count%"))
throw new Error('Fragment template must contain "%count%".');
if (!fragTemplate.includes("%forloop%"))
throw new Error('Fragment template must contain "%forloop%".');
}
generateShader(maxTextures) {
if (!this.programCache[maxTextures]) {
const sampleValues = new Int32Array(maxTextures);
for (let i = 0; i < maxTextures; i++)
sampleValues[i] = i;
this.defaultGroupCache[maxTextures] = UniformGroup.from({ uSamplers: sampleValues }, !0);
let fragmentSrc = this.fragTemplate;
fragmentSrc = fragmentSrc.replace(/%count%/gi, `${maxTextures}`), fragmentSrc = fragmentSrc.replace(/%forloop%/gi, this.generateSampleSrc(maxTextures)), this.programCache[maxTextures] = new Program(this.vertexSrc, fragmentSrc);
}
const uniforms = {
tint: new Float32Array([1, 1, 1, 1]),
translationMatrix: new Matrix(),
default: this.defaultGroupCache[maxTextures]
};
return new Shader(this.programCache[maxTextures], uniforms);
}
generateSampleSrc(maxTextures) {
let src = "";
src += `
`, src += `
`;
for (let i = 0; i < maxTextures; i++)
i > 0 && (src += `
else `), i < maxTextures - 1 && (src += `if(vTextureId < ${i}.5)`), src += `
{`, src += `
color = texture2D(uSamplers[${i}], vTextureCoord);`, src += `
}`;
return src += `
`, src += `
`, src;
}
}
export {
BatchShaderGenerator
};
//# sourceMappingURL=BatchShaderGenerator.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchShaderGenerator.mjs","sources":["../../src/batch/BatchShaderGenerator.ts"],"sourcesContent":["import { Matrix } from '@pixi/math';\nimport { Program } from '../shader/Program';\nimport { Shader } from '../shader/Shader';\nimport { UniformGroup } from '../shader/UniformGroup';\n\n/**\n * Helper that generates batching multi-texture shader. Use it with your new BatchRenderer\n * @memberof PIXI\n */\nexport class BatchShaderGenerator\n{\n /** Reference to the vertex shader source. */\n public vertexSrc: string;\n\n /** Reference to the fragment shader template. Must contain \"%count%\" and \"%forloop%\". */\n public fragTemplate: string;\n\n programCache: {[key: number]: Program};\n defaultGroupCache: {[key: number]: UniformGroup};\n\n /**\n * @param vertexSrc - Vertex shader\n * @param fragTemplate - Fragment shader template\n */\n constructor(vertexSrc: string, fragTemplate: string)\n {\n this.vertexSrc = vertexSrc;\n this.fragTemplate = fragTemplate;\n\n this.programCache = {};\n this.defaultGroupCache = {};\n\n if (!fragTemplate.includes('%count%'))\n {\n throw new Error('Fragment template must contain \"%count%\".');\n }\n\n if (!fragTemplate.includes('%forloop%'))\n {\n throw new Error('Fragment template must contain \"%forloop%\".');\n }\n }\n\n generateShader(maxTextures: number): Shader\n {\n if (!this.programCache[maxTextures])\n {\n const sampleValues = new Int32Array(maxTextures);\n\n for (let i = 0; i < maxTextures; i++)\n {\n sampleValues[i] = i;\n }\n\n this.defaultGroupCache[maxTextures] = UniformGroup.from({ uSamplers: sampleValues }, true);\n\n let fragmentSrc = this.fragTemplate;\n\n fragmentSrc = fragmentSrc.replace(/%count%/gi, `${maxTextures}`);\n fragmentSrc = fragmentSrc.replace(/%forloop%/gi, this.generateSampleSrc(maxTextures));\n\n this.programCache[maxTextures] = new Program(this.vertexSrc, fragmentSrc);\n }\n\n const uniforms = {\n tint: new Float32Array([1, 1, 1, 1]),\n translationMatrix: new Matrix(),\n default: this.defaultGroupCache[maxTextures],\n };\n\n return new Shader(this.programCache[maxTextures], uniforms);\n }\n\n generateSampleSrc(maxTextures: number): string\n {\n let src = '';\n\n src += '\\n';\n src += '\\n';\n\n for (let i = 0; i < maxTextures; i++)\n {\n if (i > 0)\n {\n src += '\\nelse ';\n }\n\n if (i < maxTextures - 1)\n {\n src += `if(vTextureId < ${i}.5)`;\n }\n\n src += '\\n{';\n src += `\\n\\tcolor = texture2D(uSamplers[${i}], vTextureCoord);`;\n src += '\\n}';\n }\n\n src += '\\n';\n src += '\\n';\n\n return src;\n }\n}\n"],"names":[],"mappings":";;;;AASO,MAAM,qBACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAcI,YAAY,WAAmB,cAC/B;AAOI,QANA,KAAK,YAAY,WACjB,KAAK,eAAe,cAEpB,KAAK,eAAe,CAAC,GACrB,KAAK,oBAAoB,CAAA,GAErB,CAAC,aAAa,SAAS,SAAS;AAE1B,YAAA,IAAI,MAAM,2CAA2C;AAG3D,QAAA,CAAC,aAAa,SAAS,WAAW;AAE5B,YAAA,IAAI,MAAM,6CAA6C;AAAA,EAErE;AAAA,EAEA,eAAe,aACf;AACI,QAAI,CAAC,KAAK,aAAa,WAAW,GAClC;AACU,YAAA,eAAe,IAAI,WAAW,WAAW;AAEtC,eAAA,IAAI,GAAG,IAAI,aAAa;AAE7B,qBAAa,CAAC,IAAI;AAGjB,WAAA,kBAAkB,WAAW,IAAI,aAAa,KAAK,EAAE,WAAW,aAAa,GAAG,EAAI;AAEzF,UAAI,cAAc,KAAK;AAET,oBAAA,YAAY,QAAQ,aAAa,GAAG,WAAW,EAAE,GAC/D,cAAc,YAAY,QAAQ,eAAe,KAAK,kBAAkB,WAAW,CAAC,GAEpF,KAAK,aAAa,WAAW,IAAI,IAAI,QAAQ,KAAK,WAAW,WAAW;AAAA,IAC5E;AAEA,UAAM,WAAW;AAAA,MACb,MAAM,IAAI,aAAa,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;AAAA,MACnC,mBAAmB,IAAI,OAAO;AAAA,MAC9B,SAAS,KAAK,kBAAkB,WAAW;AAAA,IAAA;AAG/C,WAAO,IAAI,OAAO,KAAK,aAAa,WAAW,GAAG,QAAQ;AAAA,EAC9D;AAAA,EAEA,kBAAkB,aAClB;AACI,QAAI,MAAM;AAEH,WAAA;AAAA,GACP,OAAO;AAAA;AAEE,aAAA,IAAI,GAAG,IAAI,aAAa;AAEzB,UAAI,MAEJ,OAAO;AAAA,SAGP,IAAI,cAAc,MAElB,OAAO,mBAAmB,CAAC,QAG/B,OAAO;AAAA,IACP,OAAO;AAAA,+BAAmC,CAAC,sBAC3C,OAAO;AAAA;AAGJ,WAAA,OAAA;AAAA,GACP,OAAO;AAAA,GAEA;AAAA,EACX;AACJ;"}

View File

@@ -0,0 +1,81 @@
"use strict";
var extensions = require("@pixi/extensions"), ObjectRenderer = require("./ObjectRenderer.js");
class BatchSystem {
/**
* @param renderer - The renderer this System works for.
*/
constructor(renderer) {
this.renderer = renderer, this.emptyRenderer = new ObjectRenderer.ObjectRenderer(renderer), this.currentRenderer = this.emptyRenderer;
}
/**
* Changes the current renderer to the one given in parameter
* @param objectRenderer - The object renderer to use.
*/
setObjectRenderer(objectRenderer) {
this.currentRenderer !== objectRenderer && (this.currentRenderer.stop(), this.currentRenderer = objectRenderer, this.currentRenderer.start());
}
/**
* This should be called if you wish to do some custom rendering
* It will basically render anything that may be batched up such as sprites
*/
flush() {
this.setObjectRenderer(this.emptyRenderer);
}
/** Reset the system to an empty renderer */
reset() {
this.setObjectRenderer(this.emptyRenderer);
}
/**
* Handy function for batch renderers: copies bound textures in first maxTextures locations to array
* sets actual _batchLocation for them
* @param arr - arr copy destination
* @param maxTextures - number of copied elements
*/
copyBoundTextures(arr, maxTextures) {
const { boundTextures } = this.renderer.texture;
for (let i = maxTextures - 1; i >= 0; --i)
arr[i] = boundTextures[i] || null, arr[i] && (arr[i]._batchLocation = i);
}
/**
* Assigns batch locations to textures in array based on boundTextures state.
* All textures in texArray should have `_batchEnabled = _batchId`,
* and their count should be less than `maxTextures`.
* @param texArray - textures to bound
* @param boundTextures - current state of bound textures
* @param batchId - marker for _batchEnabled param of textures in texArray
* @param maxTextures - number of texture locations to manipulate
*/
boundArray(texArray, boundTextures, batchId, maxTextures) {
const { elements, ids, count } = texArray;
let j = 0;
for (let i = 0; i < count; i++) {
const tex = elements[i], loc = tex._batchLocation;
if (loc >= 0 && loc < maxTextures && boundTextures[loc] === tex) {
ids[i] = loc;
continue;
}
for (; j < maxTextures; ) {
const bound = boundTextures[j];
if (bound && bound._batchEnabled === batchId && bound._batchLocation === j) {
j++;
continue;
}
ids[i] = j, tex._batchLocation = j, boundTextures[j] = tex;
break;
}
}
}
/**
* @ignore
*/
destroy() {
this.renderer = null;
}
}
BatchSystem.extension = {
type: extensions.ExtensionType.RendererSystem,
name: "batch"
};
extensions.extensions.add(BatchSystem);
exports.BatchSystem = BatchSystem;
//# sourceMappingURL=BatchSystem.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,83 @@
import { ExtensionType, extensions } from "@pixi/extensions";
import { ObjectRenderer } from "./ObjectRenderer.mjs";
class BatchSystem {
/**
* @param renderer - The renderer this System works for.
*/
constructor(renderer) {
this.renderer = renderer, this.emptyRenderer = new ObjectRenderer(renderer), this.currentRenderer = this.emptyRenderer;
}
/**
* Changes the current renderer to the one given in parameter
* @param objectRenderer - The object renderer to use.
*/
setObjectRenderer(objectRenderer) {
this.currentRenderer !== objectRenderer && (this.currentRenderer.stop(), this.currentRenderer = objectRenderer, this.currentRenderer.start());
}
/**
* This should be called if you wish to do some custom rendering
* It will basically render anything that may be batched up such as sprites
*/
flush() {
this.setObjectRenderer(this.emptyRenderer);
}
/** Reset the system to an empty renderer */
reset() {
this.setObjectRenderer(this.emptyRenderer);
}
/**
* Handy function for batch renderers: copies bound textures in first maxTextures locations to array
* sets actual _batchLocation for them
* @param arr - arr copy destination
* @param maxTextures - number of copied elements
*/
copyBoundTextures(arr, maxTextures) {
const { boundTextures } = this.renderer.texture;
for (let i = maxTextures - 1; i >= 0; --i)
arr[i] = boundTextures[i] || null, arr[i] && (arr[i]._batchLocation = i);
}
/**
* Assigns batch locations to textures in array based on boundTextures state.
* All textures in texArray should have `_batchEnabled = _batchId`,
* and their count should be less than `maxTextures`.
* @param texArray - textures to bound
* @param boundTextures - current state of bound textures
* @param batchId - marker for _batchEnabled param of textures in texArray
* @param maxTextures - number of texture locations to manipulate
*/
boundArray(texArray, boundTextures, batchId, maxTextures) {
const { elements, ids, count } = texArray;
let j = 0;
for (let i = 0; i < count; i++) {
const tex = elements[i], loc = tex._batchLocation;
if (loc >= 0 && loc < maxTextures && boundTextures[loc] === tex) {
ids[i] = loc;
continue;
}
for (; j < maxTextures; ) {
const bound = boundTextures[j];
if (bound && bound._batchEnabled === batchId && bound._batchLocation === j) {
j++;
continue;
}
ids[i] = j, tex._batchLocation = j, boundTextures[j] = tex;
break;
}
}
}
/**
* @ignore
*/
destroy() {
this.renderer = null;
}
}
BatchSystem.extension = {
type: ExtensionType.RendererSystem,
name: "batch"
};
extensions.add(BatchSystem);
export {
BatchSystem
};
//# sourceMappingURL=BatchSystem.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
"use strict";
class BatchTextureArray {
constructor() {
this.elements = [], this.ids = [], this.count = 0;
}
clear() {
for (let i = 0; i < this.count; i++)
this.elements[i] = null;
this.count = 0;
}
}
exports.BatchTextureArray = BatchTextureArray;
//# sourceMappingURL=BatchTextureArray.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchTextureArray.js","sources":["../../src/batch/BatchTextureArray.ts"],"sourcesContent":["import type { BaseTexture } from '../textures/BaseTexture';\n\n/**\n * Used by the batcher to build texture batches.\n * Holds list of textures and their respective locations.\n * @memberof PIXI\n */\nexport class BatchTextureArray\n{\n /** Inside textures array. */\n public elements: BaseTexture[];\n\n /** Respective locations for textures. */\n public ids: number[];\n\n /** Number of filled elements. */\n public count: number;\n\n constructor()\n {\n this.elements = [];\n this.ids = [];\n this.count = 0;\n }\n\n clear(): void\n {\n for (let i = 0; i < this.count; i++)\n {\n this.elements[i] = null;\n }\n this.count = 0;\n }\n}\n"],"names":[],"mappings":";AAOO,MAAM,kBACb;AAAA,EAUI,cACA;AACS,SAAA,WAAW,CAAA,GAChB,KAAK,MAAM,IACX,KAAK,QAAQ;AAAA,EACjB;AAAA,EAEA,QACA;AACI,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO;AAEvB,WAAA,SAAS,CAAC,IAAI;AAEvB,SAAK,QAAQ;AAAA,EACjB;AACJ;;"}

View File

@@ -0,0 +1,14 @@
class BatchTextureArray {
constructor() {
this.elements = [], this.ids = [], this.count = 0;
}
clear() {
for (let i = 0; i < this.count; i++)
this.elements[i] = null;
this.count = 0;
}
}
export {
BatchTextureArray
};
//# sourceMappingURL=BatchTextureArray.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchTextureArray.mjs","sources":["../../src/batch/BatchTextureArray.ts"],"sourcesContent":["import type { BaseTexture } from '../textures/BaseTexture';\n\n/**\n * Used by the batcher to build texture batches.\n * Holds list of textures and their respective locations.\n * @memberof PIXI\n */\nexport class BatchTextureArray\n{\n /** Inside textures array. */\n public elements: BaseTexture[];\n\n /** Respective locations for textures. */\n public ids: number[];\n\n /** Number of filled elements. */\n public count: number;\n\n constructor()\n {\n this.elements = [];\n this.ids = [];\n this.count = 0;\n }\n\n clear(): void\n {\n for (let i = 0; i < this.count; i++)\n {\n this.elements[i] = null;\n }\n this.count = 0;\n }\n}\n"],"names":[],"mappings":"AAOO,MAAM,kBACb;AAAA,EAUI,cACA;AACS,SAAA,WAAW,CAAA,GAChB,KAAK,MAAM,IACX,KAAK,QAAQ;AAAA,EACjB;AAAA,EAEA,QACA;AACI,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO;AAEvB,WAAA,SAAS,CAAC,IAAI;AAEvB,SAAK,QAAQ;AAAA,EACjB;AACJ;"}

View File

@@ -0,0 +1,37 @@
"use strict";
class ObjectRenderer {
/**
* @param renderer - The renderer this manager works for.
*/
constructor(renderer) {
this.renderer = renderer;
}
/** Stub method that should be used to empty the current batch by rendering objects now. */
flush() {
}
/** Generic destruction method that frees all resources. This should be called by subclasses. */
destroy() {
this.renderer = null;
}
/**
* Stub method that initializes any state required before
* rendering starts. It is different from the `prerender`
* signal, which occurs every frame, in that it is called
* whenever an object requests _this_ renderer specifically.
*/
start() {
}
/** Stops the renderer. It should free up any state and become dormant. */
stop() {
this.flush();
}
/**
* Keeps the object to render. It doesn't have to be
* rendered immediately.
* @param {PIXI.DisplayObject} _object - The object to render.
*/
render(_object) {
}
}
exports.ObjectRenderer = ObjectRenderer;
//# sourceMappingURL=ObjectRenderer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ObjectRenderer.js","sources":["../../src/batch/ObjectRenderer.ts"],"sourcesContent":["import type { Renderer } from '../Renderer';\nimport type { ISystem } from '../system/ISystem';\n\n/**\n * Base for a common object renderer that can be used as a\n * system renderer plugin.\n * @memberof PIXI\n */\nexport class ObjectRenderer implements ISystem\n{\n /** The renderer this manager works for. */\n protected renderer: Renderer;\n\n /**\n * @param renderer - The renderer this manager works for.\n */\n constructor(renderer: Renderer)\n {\n this.renderer = renderer;\n }\n\n /** Stub method that should be used to empty the current batch by rendering objects now. */\n flush(): void\n {\n // flush!\n }\n\n /** Generic destruction method that frees all resources. This should be called by subclasses. */\n destroy(): void\n {\n this.renderer = null;\n }\n\n /**\n * Stub method that initializes any state required before\n * rendering starts. It is different from the `prerender`\n * signal, which occurs every frame, in that it is called\n * whenever an object requests _this_ renderer specifically.\n */\n start(): void\n {\n // set the shader..\n }\n\n /** Stops the renderer. It should free up any state and become dormant. */\n stop(): void\n {\n this.flush();\n }\n\n /**\n * Keeps the object to render. It doesn't have to be\n * rendered immediately.\n * @param {PIXI.DisplayObject} _object - The object to render.\n */\n render(_object: any): void // eslint-disable-line @typescript-eslint/explicit-module-boundary-types\n {\n // render the object\n }\n}\n"],"names":[],"mappings":";AAQO,MAAM,eACb;AAAA;AAAA;AAAA;AAAA,EAOI,YAAY,UACZ;AACI,SAAK,WAAW;AAAA,EACpB;AAAA;AAAA,EAGA,QACA;AAAA,EAEA;AAAA;AAAA,EAGA,UACA;AACI,SAAK,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QACA;AAAA,EAEA;AAAA;AAAA,EAGA,OACA;AACI,SAAK,MAAM;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,SACP;AAAA,EAEA;AACJ;;"}

View File

@@ -0,0 +1,38 @@
class ObjectRenderer {
/**
* @param renderer - The renderer this manager works for.
*/
constructor(renderer) {
this.renderer = renderer;
}
/** Stub method that should be used to empty the current batch by rendering objects now. */
flush() {
}
/** Generic destruction method that frees all resources. This should be called by subclasses. */
destroy() {
this.renderer = null;
}
/**
* Stub method that initializes any state required before
* rendering starts. It is different from the `prerender`
* signal, which occurs every frame, in that it is called
* whenever an object requests _this_ renderer specifically.
*/
start() {
}
/** Stops the renderer. It should free up any state and become dormant. */
stop() {
this.flush();
}
/**
* Keeps the object to render. It doesn't have to be
* rendered immediately.
* @param {PIXI.DisplayObject} _object - The object to render.
*/
render(_object) {
}
}
export {
ObjectRenderer
};
//# sourceMappingURL=ObjectRenderer.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ObjectRenderer.mjs","sources":["../../src/batch/ObjectRenderer.ts"],"sourcesContent":["import type { Renderer } from '../Renderer';\nimport type { ISystem } from '../system/ISystem';\n\n/**\n * Base for a common object renderer that can be used as a\n * system renderer plugin.\n * @memberof PIXI\n */\nexport class ObjectRenderer implements ISystem\n{\n /** The renderer this manager works for. */\n protected renderer: Renderer;\n\n /**\n * @param renderer - The renderer this manager works for.\n */\n constructor(renderer: Renderer)\n {\n this.renderer = renderer;\n }\n\n /** Stub method that should be used to empty the current batch by rendering objects now. */\n flush(): void\n {\n // flush!\n }\n\n /** Generic destruction method that frees all resources. This should be called by subclasses. */\n destroy(): void\n {\n this.renderer = null;\n }\n\n /**\n * Stub method that initializes any state required before\n * rendering starts. It is different from the `prerender`\n * signal, which occurs every frame, in that it is called\n * whenever an object requests _this_ renderer specifically.\n */\n start(): void\n {\n // set the shader..\n }\n\n /** Stops the renderer. It should free up any state and become dormant. */\n stop(): void\n {\n this.flush();\n }\n\n /**\n * Keeps the object to render. It doesn't have to be\n * rendered immediately.\n * @param {PIXI.DisplayObject} _object - The object to render.\n */\n render(_object: any): void // eslint-disable-line @typescript-eslint/explicit-module-boundary-types\n {\n // render the object\n }\n}\n"],"names":[],"mappings":"AAQO,MAAM,eACb;AAAA;AAAA;AAAA;AAAA,EAOI,YAAY,UACZ;AACI,SAAK,WAAW;AAAA,EACpB;AAAA;AAAA,EAGA,QACA;AAAA,EAEA;AAAA;AAAA,EAGA,UACA;AACI,SAAK,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QACA;AAAA,EAEA;AAAA;AAAA,EAGA,OACA;AACI,SAAK,MAAM;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,SACP;AAAA,EAEA;AACJ;"}

View File

@@ -0,0 +1,7 @@
"use strict";
var settings = require("@pixi/settings");
function canUploadSameBuffer() {
return !settings.isMobile.apple.device;
}
exports.canUploadSameBuffer = canUploadSameBuffer;
//# sourceMappingURL=canUploadSameBuffer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"canUploadSameBuffer.js","sources":["../../src/batch/canUploadSameBuffer.ts"],"sourcesContent":["import { isMobile } from '@pixi/settings';\n\n/**\n * Uploading the same buffer multiple times in a single frame can cause performance issues.\n * Apparent on iOS so only check for that at the moment\n * This check may become more complex if this issue pops up elsewhere.\n * @private\n * @returns {boolean} `true` if the same buffer may be uploaded more than once.\n */\nexport function canUploadSameBuffer(): boolean\n{\n return !isMobile.apple.device;\n}\n"],"names":["isMobile"],"mappings":";;AASO,SAAS,sBAChB;AACW,SAAA,CAACA,SAAAA,SAAS,MAAM;AAC3B;;"}

View File

@@ -0,0 +1,8 @@
import { isMobile } from "@pixi/settings";
function canUploadSameBuffer() {
return !isMobile.apple.device;
}
export {
canUploadSameBuffer
};
//# sourceMappingURL=canUploadSameBuffer.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"canUploadSameBuffer.mjs","sources":["../../src/batch/canUploadSameBuffer.ts"],"sourcesContent":["import { isMobile } from '@pixi/settings';\n\n/**\n * Uploading the same buffer multiple times in a single frame can cause performance issues.\n * Apparent on iOS so only check for that at the moment\n * This check may become more complex if this issue pops up elsewhere.\n * @private\n * @returns {boolean} `true` if the same buffer may be uploaded more than once.\n */\nexport function canUploadSameBuffer(): boolean\n{\n return !isMobile.apple.device;\n}\n"],"names":[],"mappings":";AASO,SAAS,sBAChB;AACW,SAAA,CAAC,SAAS,MAAM;AAC3B;"}

View File

@@ -0,0 +1,19 @@
"use strict";
var settings = require("@pixi/settings");
function maxRecommendedTextures(max) {
let allowMax = !0;
const navigator = settings.settings.ADAPTER.getNavigator();
if (settings.isMobile.tablet || settings.isMobile.phone) {
if (settings.isMobile.apple.device) {
const match = navigator.userAgent.match(/OS (\d+)_(\d+)?/);
match && parseInt(match[1], 10) < 11 && (allowMax = !1);
}
if (settings.isMobile.android.device) {
const match = navigator.userAgent.match(/Android\s([0-9.]*)/);
match && parseInt(match[1], 10) < 7 && (allowMax = !1);
}
}
return allowMax ? max : 4;
}
exports.maxRecommendedTextures = maxRecommendedTextures;
//# sourceMappingURL=maxRecommendedTextures.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"maxRecommendedTextures.js","sources":["../../src/batch/maxRecommendedTextures.ts"],"sourcesContent":["import { isMobile, settings } from '@pixi/settings';\n\n/**\n * The maximum recommended texture units to use.\n * In theory the bigger the better, and for desktop we'll use as many as we can.\n * But some mobile devices slow down if there is to many branches in the shader.\n * So in practice there seems to be a sweet spot size that varies depending on the device.\n *\n * In v4, all mobile devices were limited to 4 texture units because for this.\n * In v5, we allow all texture units to be used on modern Apple or Android devices.\n * @private\n * @param {number} max\n * @returns {number} The maximum recommended texture units to use.\n */\nexport function maxRecommendedTextures(max: number): number\n{\n let allowMax = true;\n const navigator = settings.ADAPTER.getNavigator();\n\n if (isMobile.tablet || isMobile.phone)\n {\n if (isMobile.apple.device)\n {\n const match = (navigator.userAgent).match(/OS (\\d+)_(\\d+)?/);\n\n if (match)\n {\n const majorVersion = parseInt(match[1], 10);\n\n // Limit texture units on devices below iOS 11, which will be older hardware\n if (majorVersion < 11)\n {\n allowMax = false;\n }\n }\n }\n if (isMobile.android.device)\n {\n const match = (navigator.userAgent).match(/Android\\s([0-9.]*)/);\n\n if (match)\n {\n const majorVersion = parseInt(match[1], 10);\n\n // Limit texture units on devices below Android 7 (Nougat), which will be older hardware\n if (majorVersion < 7)\n {\n allowMax = false;\n }\n }\n }\n }\n\n return allowMax ? max : 4;\n}\n"],"names":["settings","isMobile"],"mappings":";;AAcO,SAAS,uBAAuB,KACvC;AACI,MAAI,WAAW;AACT,QAAA,YAAYA,SAAAA,SAAS,QAAQ,aAAa;AAE5C,MAAAC,kBAAS,UAAUA,SAAA,SAAS,OAChC;AACQ,QAAAA,SAAA,SAAS,MAAM,QACnB;AACI,YAAM,QAAS,UAAU,UAAW,MAAM,iBAAiB;AAEvD,eAEqB,SAAS,MAAM,CAAC,GAAG,EAAE,IAGvB,OAEf,WAAW;AAAA,IAGvB;AACI,QAAAA,SAAA,SAAS,QAAQ,QACrB;AACI,YAAM,QAAS,UAAU,UAAW,MAAM,oBAAoB;AAE1D,eAEqB,SAAS,MAAM,CAAC,GAAG,EAAE,IAGvB,MAEf,WAAW;AAAA,IAGvB;AAAA,EACJ;AAEA,SAAO,WAAW,MAAM;AAC5B;;"}

View File

@@ -0,0 +1,20 @@
import { settings, isMobile } from "@pixi/settings";
function maxRecommendedTextures(max) {
let allowMax = !0;
const navigator = settings.ADAPTER.getNavigator();
if (isMobile.tablet || isMobile.phone) {
if (isMobile.apple.device) {
const match = navigator.userAgent.match(/OS (\d+)_(\d+)?/);
match && parseInt(match[1], 10) < 11 && (allowMax = !1);
}
if (isMobile.android.device) {
const match = navigator.userAgent.match(/Android\s([0-9.]*)/);
match && parseInt(match[1], 10) < 7 && (allowMax = !1);
}
}
return allowMax ? max : 4;
}
export {
maxRecommendedTextures
};
//# sourceMappingURL=maxRecommendedTextures.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"maxRecommendedTextures.mjs","sources":["../../src/batch/maxRecommendedTextures.ts"],"sourcesContent":["import { isMobile, settings } from '@pixi/settings';\n\n/**\n * The maximum recommended texture units to use.\n * In theory the bigger the better, and for desktop we'll use as many as we can.\n * But some mobile devices slow down if there is to many branches in the shader.\n * So in practice there seems to be a sweet spot size that varies depending on the device.\n *\n * In v4, all mobile devices were limited to 4 texture units because for this.\n * In v5, we allow all texture units to be used on modern Apple or Android devices.\n * @private\n * @param {number} max\n * @returns {number} The maximum recommended texture units to use.\n */\nexport function maxRecommendedTextures(max: number): number\n{\n let allowMax = true;\n const navigator = settings.ADAPTER.getNavigator();\n\n if (isMobile.tablet || isMobile.phone)\n {\n if (isMobile.apple.device)\n {\n const match = (navigator.userAgent).match(/OS (\\d+)_(\\d+)?/);\n\n if (match)\n {\n const majorVersion = parseInt(match[1], 10);\n\n // Limit texture units on devices below iOS 11, which will be older hardware\n if (majorVersion < 11)\n {\n allowMax = false;\n }\n }\n }\n if (isMobile.android.device)\n {\n const match = (navigator.userAgent).match(/Android\\s([0-9.]*)/);\n\n if (match)\n {\n const majorVersion = parseInt(match[1], 10);\n\n // Limit texture units on devices below Android 7 (Nougat), which will be older hardware\n if (majorVersion < 7)\n {\n allowMax = false;\n }\n }\n }\n }\n\n return allowMax ? max : 4;\n}\n"],"names":[],"mappings":";AAcO,SAAS,uBAAuB,KACvC;AACI,MAAI,WAAW;AACT,QAAA,YAAY,SAAS,QAAQ,aAAa;AAE5C,MAAA,SAAS,UAAU,SAAS,OAChC;AACQ,QAAA,SAAS,MAAM,QACnB;AACI,YAAM,QAAS,UAAU,UAAW,MAAM,iBAAiB;AAEvD,eAEqB,SAAS,MAAM,CAAC,GAAG,EAAE,IAGvB,OAEf,WAAW;AAAA,IAGvB;AACI,QAAA,SAAS,QAAQ,QACrB;AACI,YAAM,QAAS,UAAU,UAAW,MAAM,oBAAoB;AAE1D,eAEqB,SAAS,MAAM,CAAC,GAAG,EAAE,IAGvB,MAEf,WAAW;AAAA,IAGvB;AAAA,EACJ;AAEA,SAAO,WAAW,MAAM;AAC5B;"}

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var defaultFragment = `varying vec2 vTextureCoord;
varying vec4 vColor;
varying float vTextureId;
uniform sampler2D uSamplers[%count%];
void main(void){
vec4 color;
%forloop%
gl_FragColor = color * vColor;
}
`;
exports.default = defaultFragment;
//# sourceMappingURL=texture.frag.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"texture.frag.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,15 @@
var defaultFragment = `varying vec2 vTextureCoord;
varying vec4 vColor;
varying float vTextureId;
uniform sampler2D uSamplers[%count%];
void main(void){
vec4 color;
%forloop%
gl_FragColor = color * vColor;
}
`;
export {
defaultFragment as default
};
//# sourceMappingURL=texture.frag.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"texture.frag.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var defaultVertex = `precision highp float;
attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
attribute vec4 aColor;
attribute float aTextureId;
uniform mat3 projectionMatrix;
uniform mat3 translationMatrix;
uniform vec4 tint;
varying vec2 vTextureCoord;
varying vec4 vColor;
varying float vTextureId;
void main(void){
gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
vTextureId = aTextureId;
vColor = aColor * tint;
}
`;
exports.default = defaultVertex;
//# sourceMappingURL=texture.vert.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"texture.vert.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,26 @@
var defaultVertex = `precision highp float;
attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
attribute vec4 aColor;
attribute float aTextureId;
uniform mat3 projectionMatrix;
uniform mat3 translationMatrix;
uniform vec4 tint;
varying vec2 vTextureCoord;
varying vec4 vColor;
varying float vTextureId;
void main(void){
gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
vTextureId = aTextureId;
vColor = aColor * tint;
}
`;
export {
defaultVertex as default
};
//# sourceMappingURL=texture.vert.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"texture.vert.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,177 @@
"use strict";
var constants = require("@pixi/constants"), extensions = require("@pixi/extensions"), settings = require("@pixi/settings");
let CONTEXT_UID_COUNTER = 0;
class ContextSystem {
/** @param renderer - The renderer this System works for. */
constructor(renderer) {
this.renderer = renderer, this.webGLVersion = 1, this.extensions = {}, this.supports = {
uint32Indices: !1
}, this.handleContextLost = this.handleContextLost.bind(this), this.handleContextRestored = this.handleContextRestored.bind(this);
}
/**
* `true` if the context is lost
* @readonly
*/
get isLost() {
return !this.gl || this.gl.isContextLost();
}
/**
* Handles the context change event.
* @param {WebGLRenderingContext} gl - New WebGL context.
*/
contextChange(gl) {
this.gl = gl, this.renderer.gl = gl, this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++;
}
init(options) {
if (options.context)
this.initFromContext(options.context);
else {
const alpha = this.renderer.background.alpha < 1, premultipliedAlpha = options.premultipliedAlpha;
this.preserveDrawingBuffer = options.preserveDrawingBuffer, this.useContextAlpha = options.useContextAlpha, this.powerPreference = options.powerPreference, this.initFromOptions({
alpha,
premultipliedAlpha,
antialias: options.antialias,
stencil: !0,
preserveDrawingBuffer: options.preserveDrawingBuffer,
powerPreference: options.powerPreference
});
}
}
/**
* Initializes the context.
* @protected
* @param {WebGLRenderingContext} gl - WebGL context
*/
initFromContext(gl) {
this.gl = gl, this.validateContext(gl), this.renderer.gl = gl, this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++, this.renderer.runners.contextChange.emit(gl);
const view = this.renderer.view;
view.addEventListener !== void 0 && (view.addEventListener("webglcontextlost", this.handleContextLost, !1), view.addEventListener("webglcontextrestored", this.handleContextRestored, !1));
}
/**
* Initialize from context options
* @protected
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext
* @param {object} options - context attributes
*/
initFromOptions(options) {
const gl = this.createContext(this.renderer.view, options);
this.initFromContext(gl);
}
/**
* Helper class to create a WebGL Context
* @param canvas - the canvas element that we will get the context from
* @param options - An options object that gets passed in to the canvas element containing the
* context attributes
* @see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext
* @returns {WebGLRenderingContext} the WebGL context
*/
createContext(canvas, options) {
let gl;
if (settings.settings.PREFER_ENV >= constants.ENV.WEBGL2 && (gl = canvas.getContext("webgl2", options)), gl)
this.webGLVersion = 2;
else if (this.webGLVersion = 1, gl = canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options), !gl)
throw new Error("This browser does not support WebGL. Try using the canvas renderer");
return this.gl = gl, this.getExtensions(), this.gl;
}
/** Auto-populate the {@link PIXI.ContextSystem.extensions extensions}. */
getExtensions() {
const { gl } = this, common = {
loseContext: gl.getExtension("WEBGL_lose_context"),
anisotropicFiltering: gl.getExtension("EXT_texture_filter_anisotropic"),
floatTextureLinear: gl.getExtension("OES_texture_float_linear"),
s3tc: gl.getExtension("WEBGL_compressed_texture_s3tc"),
s3tc_sRGB: gl.getExtension("WEBGL_compressed_texture_s3tc_srgb"),
// eslint-disable-line camelcase
etc: gl.getExtension("WEBGL_compressed_texture_etc"),
etc1: gl.getExtension("WEBGL_compressed_texture_etc1"),
pvrtc: gl.getExtension("WEBGL_compressed_texture_pvrtc") || gl.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),
atc: gl.getExtension("WEBGL_compressed_texture_atc"),
astc: gl.getExtension("WEBGL_compressed_texture_astc"),
bptc: gl.getExtension("EXT_texture_compression_bptc")
};
this.webGLVersion === 1 ? Object.assign(this.extensions, common, {
drawBuffers: gl.getExtension("WEBGL_draw_buffers"),
depthTexture: gl.getExtension("WEBGL_depth_texture"),
vertexArrayObject: gl.getExtension("OES_vertex_array_object") || gl.getExtension("MOZ_OES_vertex_array_object") || gl.getExtension("WEBKIT_OES_vertex_array_object"),
uint32ElementIndex: gl.getExtension("OES_element_index_uint"),
// Floats and half-floats
floatTexture: gl.getExtension("OES_texture_float"),
floatTextureLinear: gl.getExtension("OES_texture_float_linear"),
textureHalfFloat: gl.getExtension("OES_texture_half_float"),
textureHalfFloatLinear: gl.getExtension("OES_texture_half_float_linear")
}) : this.webGLVersion === 2 && Object.assign(this.extensions, common, {
// Floats and half-floats
colorBufferFloat: gl.getExtension("EXT_color_buffer_float")
});
}
/**
* Handles a lost webgl context
* @param {WebGLContextEvent} event - The context lost event.
*/
handleContextLost(event) {
event.preventDefault(), setTimeout(() => {
this.gl.isContextLost() && this.extensions.loseContext && this.extensions.loseContext.restoreContext();
}, 0);
}
/** Handles a restored webgl context. */
handleContextRestored() {
this.renderer.runners.contextChange.emit(this.gl);
}
destroy() {
const view = this.renderer.view;
this.renderer = null, view.removeEventListener !== void 0 && (view.removeEventListener("webglcontextlost", this.handleContextLost), view.removeEventListener("webglcontextrestored", this.handleContextRestored)), this.gl.useProgram(null), this.extensions.loseContext && this.extensions.loseContext.loseContext();
}
/** Handle the post-render runner event. */
postrender() {
this.renderer.objectRenderer.renderingToScreen && this.gl.flush();
}
/**
* Validate context.
* @param {WebGLRenderingContext} gl - Render context.
*/
validateContext(gl) {
const attributes = gl.getContextAttributes(), isWebGl2 = "WebGL2RenderingContext" in globalThis && gl instanceof globalThis.WebGL2RenderingContext;
isWebGl2 && (this.webGLVersion = 2), attributes && !attributes.stencil && console.warn("Provided WebGL context does not have a stencil buffer, masks may not render correctly");
const hasuint32 = isWebGl2 || !!gl.getExtension("OES_element_index_uint");
this.supports.uint32Indices = hasuint32, hasuint32 || console.warn("Provided WebGL context does not support 32 index buffer, complex graphics may not render correctly");
}
}
ContextSystem.defaultOptions = {
/**
* {@link PIXI.IRendererOptions.context}
* @default null
* @memberof PIXI.settings.RENDER_OPTIONS
*/
context: null,
/**
* {@link PIXI.IRendererOptions.antialias}
* @default false
* @memberof PIXI.settings.RENDER_OPTIONS
*/
antialias: !1,
/**
* {@link PIXI.IRendererOptions.premultipliedAlpha}
* @default true
* @memberof PIXI.settings.RENDER_OPTIONS
*/
premultipliedAlpha: !0,
/**
* {@link PIXI.IRendererOptions.preserveDrawingBuffer}
* @default false
* @memberof PIXI.settings.RENDER_OPTIONS
*/
preserveDrawingBuffer: !1,
/**
* {@link PIXI.IRendererOptions.powerPreference}
* @default default
* @memberof PIXI.settings.RENDER_OPTIONS
*/
powerPreference: "default"
}, /** @ignore */
ContextSystem.extension = {
type: extensions.ExtensionType.RendererSystem,
name: "context"
};
extensions.extensions.add(ContextSystem);
exports.ContextSystem = ContextSystem;
//# sourceMappingURL=ContextSystem.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,180 @@
import { ENV } from "@pixi/constants";
import { ExtensionType, extensions } from "@pixi/extensions";
import { settings } from "@pixi/settings";
let CONTEXT_UID_COUNTER = 0;
class ContextSystem {
/** @param renderer - The renderer this System works for. */
constructor(renderer) {
this.renderer = renderer, this.webGLVersion = 1, this.extensions = {}, this.supports = {
uint32Indices: !1
}, this.handleContextLost = this.handleContextLost.bind(this), this.handleContextRestored = this.handleContextRestored.bind(this);
}
/**
* `true` if the context is lost
* @readonly
*/
get isLost() {
return !this.gl || this.gl.isContextLost();
}
/**
* Handles the context change event.
* @param {WebGLRenderingContext} gl - New WebGL context.
*/
contextChange(gl) {
this.gl = gl, this.renderer.gl = gl, this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++;
}
init(options) {
if (options.context)
this.initFromContext(options.context);
else {
const alpha = this.renderer.background.alpha < 1, premultipliedAlpha = options.premultipliedAlpha;
this.preserveDrawingBuffer = options.preserveDrawingBuffer, this.useContextAlpha = options.useContextAlpha, this.powerPreference = options.powerPreference, this.initFromOptions({
alpha,
premultipliedAlpha,
antialias: options.antialias,
stencil: !0,
preserveDrawingBuffer: options.preserveDrawingBuffer,
powerPreference: options.powerPreference
});
}
}
/**
* Initializes the context.
* @protected
* @param {WebGLRenderingContext} gl - WebGL context
*/
initFromContext(gl) {
this.gl = gl, this.validateContext(gl), this.renderer.gl = gl, this.renderer.CONTEXT_UID = CONTEXT_UID_COUNTER++, this.renderer.runners.contextChange.emit(gl);
const view = this.renderer.view;
view.addEventListener !== void 0 && (view.addEventListener("webglcontextlost", this.handleContextLost, !1), view.addEventListener("webglcontextrestored", this.handleContextRestored, !1));
}
/**
* Initialize from context options
* @protected
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext
* @param {object} options - context attributes
*/
initFromOptions(options) {
const gl = this.createContext(this.renderer.view, options);
this.initFromContext(gl);
}
/**
* Helper class to create a WebGL Context
* @param canvas - the canvas element that we will get the context from
* @param options - An options object that gets passed in to the canvas element containing the
* context attributes
* @see https://developer.mozilla.org/en/docs/Web/API/HTMLCanvasElement/getContext
* @returns {WebGLRenderingContext} the WebGL context
*/
createContext(canvas, options) {
let gl;
if (settings.PREFER_ENV >= ENV.WEBGL2 && (gl = canvas.getContext("webgl2", options)), gl)
this.webGLVersion = 2;
else if (this.webGLVersion = 1, gl = canvas.getContext("webgl", options) || canvas.getContext("experimental-webgl", options), !gl)
throw new Error("This browser does not support WebGL. Try using the canvas renderer");
return this.gl = gl, this.getExtensions(), this.gl;
}
/** Auto-populate the {@link PIXI.ContextSystem.extensions extensions}. */
getExtensions() {
const { gl } = this, common = {
loseContext: gl.getExtension("WEBGL_lose_context"),
anisotropicFiltering: gl.getExtension("EXT_texture_filter_anisotropic"),
floatTextureLinear: gl.getExtension("OES_texture_float_linear"),
s3tc: gl.getExtension("WEBGL_compressed_texture_s3tc"),
s3tc_sRGB: gl.getExtension("WEBGL_compressed_texture_s3tc_srgb"),
// eslint-disable-line camelcase
etc: gl.getExtension("WEBGL_compressed_texture_etc"),
etc1: gl.getExtension("WEBGL_compressed_texture_etc1"),
pvrtc: gl.getExtension("WEBGL_compressed_texture_pvrtc") || gl.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),
atc: gl.getExtension("WEBGL_compressed_texture_atc"),
astc: gl.getExtension("WEBGL_compressed_texture_astc"),
bptc: gl.getExtension("EXT_texture_compression_bptc")
};
this.webGLVersion === 1 ? Object.assign(this.extensions, common, {
drawBuffers: gl.getExtension("WEBGL_draw_buffers"),
depthTexture: gl.getExtension("WEBGL_depth_texture"),
vertexArrayObject: gl.getExtension("OES_vertex_array_object") || gl.getExtension("MOZ_OES_vertex_array_object") || gl.getExtension("WEBKIT_OES_vertex_array_object"),
uint32ElementIndex: gl.getExtension("OES_element_index_uint"),
// Floats and half-floats
floatTexture: gl.getExtension("OES_texture_float"),
floatTextureLinear: gl.getExtension("OES_texture_float_linear"),
textureHalfFloat: gl.getExtension("OES_texture_half_float"),
textureHalfFloatLinear: gl.getExtension("OES_texture_half_float_linear")
}) : this.webGLVersion === 2 && Object.assign(this.extensions, common, {
// Floats and half-floats
colorBufferFloat: gl.getExtension("EXT_color_buffer_float")
});
}
/**
* Handles a lost webgl context
* @param {WebGLContextEvent} event - The context lost event.
*/
handleContextLost(event) {
event.preventDefault(), setTimeout(() => {
this.gl.isContextLost() && this.extensions.loseContext && this.extensions.loseContext.restoreContext();
}, 0);
}
/** Handles a restored webgl context. */
handleContextRestored() {
this.renderer.runners.contextChange.emit(this.gl);
}
destroy() {
const view = this.renderer.view;
this.renderer = null, view.removeEventListener !== void 0 && (view.removeEventListener("webglcontextlost", this.handleContextLost), view.removeEventListener("webglcontextrestored", this.handleContextRestored)), this.gl.useProgram(null), this.extensions.loseContext && this.extensions.loseContext.loseContext();
}
/** Handle the post-render runner event. */
postrender() {
this.renderer.objectRenderer.renderingToScreen && this.gl.flush();
}
/**
* Validate context.
* @param {WebGLRenderingContext} gl - Render context.
*/
validateContext(gl) {
const attributes = gl.getContextAttributes(), isWebGl2 = "WebGL2RenderingContext" in globalThis && gl instanceof globalThis.WebGL2RenderingContext;
isWebGl2 && (this.webGLVersion = 2), attributes && !attributes.stencil && console.warn("Provided WebGL context does not have a stencil buffer, masks may not render correctly");
const hasuint32 = isWebGl2 || !!gl.getExtension("OES_element_index_uint");
this.supports.uint32Indices = hasuint32, hasuint32 || console.warn("Provided WebGL context does not support 32 index buffer, complex graphics may not render correctly");
}
}
ContextSystem.defaultOptions = {
/**
* {@link PIXI.IRendererOptions.context}
* @default null
* @memberof PIXI.settings.RENDER_OPTIONS
*/
context: null,
/**
* {@link PIXI.IRendererOptions.antialias}
* @default false
* @memberof PIXI.settings.RENDER_OPTIONS
*/
antialias: !1,
/**
* {@link PIXI.IRendererOptions.premultipliedAlpha}
* @default true
* @memberof PIXI.settings.RENDER_OPTIONS
*/
premultipliedAlpha: !0,
/**
* {@link PIXI.IRendererOptions.preserveDrawingBuffer}
* @default false
* @memberof PIXI.settings.RENDER_OPTIONS
*/
preserveDrawingBuffer: !1,
/**
* {@link PIXI.IRendererOptions.powerPreference}
* @default default
* @memberof PIXI.settings.RENDER_OPTIONS
*/
powerPreference: "default"
}, /** @ignore */
ContextSystem.extension = {
type: ExtensionType.RendererSystem,
name: "context"
};
extensions.add(ContextSystem);
export {
ContextSystem
};
//# sourceMappingURL=ContextSystem.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,75 @@
"use strict";
var constants = require("@pixi/constants"), Program = require("../shader/Program.js"), Shader = require("../shader/Shader.js"), State = require("../state/State.js"), defaultFilter$1 = require("./defaultFilter.frag.js"), defaultFilter = require("./defaultFilter.vert.js");
const _Filter = class _Filter2 extends Shader.Shader {
/**
* @param vertexSrc - The source of the vertex shader.
* @param fragmentSrc - The source of the fragment shader.
* @param uniforms - Custom uniforms to use to augment the built-in ones.
*/
constructor(vertexSrc, fragmentSrc, uniforms) {
const program = Program.Program.from(
vertexSrc || _Filter2.defaultVertexSrc,
fragmentSrc || _Filter2.defaultFragmentSrc
);
super(program, uniforms), this.padding = 0, this.resolution = _Filter2.defaultResolution, this.multisample = _Filter2.defaultMultisample, this.enabled = !0, this.autoFit = !0, this.state = new State.State();
}
/**
* Applies the filter
* @param {PIXI.FilterSystem} filterManager - The renderer to retrieve the filter from
* @param {PIXI.RenderTexture} input - The input render target.
* @param {PIXI.RenderTexture} output - The target to output to.
* @param {PIXI.CLEAR_MODES} [clearMode] - Should the output be cleared before rendering to it.
* @param {object} [_currentState] - It's current state of filter.
* There are some useful properties in the currentState :
* target, filters, sourceFrame, destinationFrame, renderTarget, resolution
*/
apply(filterManager, input, output, clearMode, _currentState) {
filterManager.applyFilter(this, input, output, clearMode);
}
/**
* Sets the blend mode of the filter.
* @default PIXI.BLEND_MODES.NORMAL
*/
get blendMode() {
return this.state.blendMode;
}
set blendMode(value) {
this.state.blendMode = value;
}
/**
* The resolution of the filter. Setting this to be lower will lower the quality but
* increase the performance of the filter.
* If set to `null` or `0`, the resolution of the current render target is used.
* @default PIXI.Filter.defaultResolution
*/
get resolution() {
return this._resolution;
}
set resolution(value) {
this._resolution = value;
}
/**
* The default vertex shader source
* @readonly
*/
static get defaultVertexSrc() {
return defaultFilter.default;
}
/**
* The default fragment shader source
* @readonly
*/
static get defaultFragmentSrc() {
return defaultFilter$1.default;
}
};
_Filter.defaultResolution = 1, /**
* Default filter samples for any filter.
* @static
* @type {PIXI.MSAA_QUALITY|null}
* @default PIXI.MSAA_QUALITY.NONE
*/
_Filter.defaultMultisample = constants.MSAA_QUALITY.NONE;
let Filter = _Filter;
exports.Filter = Filter;
//# sourceMappingURL=Filter.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
import { MSAA_QUALITY } from "@pixi/constants";
import { Program } from "../shader/Program.mjs";
import { Shader } from "../shader/Shader.mjs";
import { State } from "../state/State.mjs";
import defaultFragment from "./defaultFilter.frag.mjs";
import defaultVertex from "./defaultFilter.vert.mjs";
const _Filter = class _Filter2 extends Shader {
/**
* @param vertexSrc - The source of the vertex shader.
* @param fragmentSrc - The source of the fragment shader.
* @param uniforms - Custom uniforms to use to augment the built-in ones.
*/
constructor(vertexSrc, fragmentSrc, uniforms) {
const program = Program.from(
vertexSrc || _Filter2.defaultVertexSrc,
fragmentSrc || _Filter2.defaultFragmentSrc
);
super(program, uniforms), this.padding = 0, this.resolution = _Filter2.defaultResolution, this.multisample = _Filter2.defaultMultisample, this.enabled = !0, this.autoFit = !0, this.state = new State();
}
/**
* Applies the filter
* @param {PIXI.FilterSystem} filterManager - The renderer to retrieve the filter from
* @param {PIXI.RenderTexture} input - The input render target.
* @param {PIXI.RenderTexture} output - The target to output to.
* @param {PIXI.CLEAR_MODES} [clearMode] - Should the output be cleared before rendering to it.
* @param {object} [_currentState] - It's current state of filter.
* There are some useful properties in the currentState :
* target, filters, sourceFrame, destinationFrame, renderTarget, resolution
*/
apply(filterManager, input, output, clearMode, _currentState) {
filterManager.applyFilter(this, input, output, clearMode);
}
/**
* Sets the blend mode of the filter.
* @default PIXI.BLEND_MODES.NORMAL
*/
get blendMode() {
return this.state.blendMode;
}
set blendMode(value) {
this.state.blendMode = value;
}
/**
* The resolution of the filter. Setting this to be lower will lower the quality but
* increase the performance of the filter.
* If set to `null` or `0`, the resolution of the current render target is used.
* @default PIXI.Filter.defaultResolution
*/
get resolution() {
return this._resolution;
}
set resolution(value) {
this._resolution = value;
}
/**
* The default vertex shader source
* @readonly
*/
static get defaultVertexSrc() {
return defaultVertex;
}
/**
* The default fragment shader source
* @readonly
*/
static get defaultFragmentSrc() {
return defaultFragment;
}
};
_Filter.defaultResolution = 1, /**
* Default filter samples for any filter.
* @static
* @type {PIXI.MSAA_QUALITY|null}
* @default PIXI.MSAA_QUALITY.NONE
*/
_Filter.defaultMultisample = MSAA_QUALITY.NONE;
let Filter = _Filter;
export {
Filter
};
//# sourceMappingURL=Filter.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
"use strict";
var constants = require("@pixi/constants"), math = require("@pixi/math");
class FilterState {
constructor() {
this.renderTexture = null, this.target = null, this.legacy = !1, this.resolution = 1, this.multisample = constants.MSAA_QUALITY.NONE, this.sourceFrame = new math.Rectangle(), this.destinationFrame = new math.Rectangle(), this.bindingSourceFrame = new math.Rectangle(), this.bindingDestinationFrame = new math.Rectangle(), this.filters = [], this.transform = null;
}
/** Clears the state */
clear() {
this.target = null, this.filters = null, this.renderTexture = null;
}
}
exports.FilterState = FilterState;
//# sourceMappingURL=FilterState.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"FilterState.js","sources":["../../src/filters/FilterState.ts"],"sourcesContent":["import { MSAA_QUALITY } from '@pixi/constants';\nimport { Rectangle } from '@pixi/math';\n\nimport type { Matrix } from '@pixi/math';\nimport type { RenderTexture } from '../renderTexture/RenderTexture';\nimport type { Filter } from './Filter';\nimport type { IFilterTarget } from './IFilterTarget';\n\n/**\n * System plugin to the renderer to manage filter states.\n * @ignore\n */\nexport class FilterState\n{\n renderTexture: RenderTexture;\n\n /**\n * Target of the filters\n * We store for case when custom filter wants to know the element it was applied on\n * @member {PIXI.DisplayObject}\n */\n target: IFilterTarget;\n\n /**\n * Compatibility with PixiJS v4 filters\n * @default false\n */\n legacy: boolean;\n\n /**\n * Resolution of filters\n * @default 1\n */\n resolution: number;\n\n /**\n * Number of samples\n * @default MSAA_QUALITY.NONE\n */\n multisample: MSAA_QUALITY;\n\n /** Source frame. */\n sourceFrame: Rectangle;\n\n /** Destination frame. */\n destinationFrame: Rectangle;\n\n /** Original render-target source frame. */\n bindingSourceFrame: Rectangle;\n\n /** Original render-target destination frame. */\n bindingDestinationFrame: Rectangle;\n\n /** Collection of filters. */\n filters: Array<Filter>;\n\n /** Projection system transform saved by link. */\n transform: Matrix;\n\n constructor()\n {\n this.renderTexture = null;\n\n this.target = null;\n this.legacy = false;\n this.resolution = 1;\n this.multisample = MSAA_QUALITY.NONE;\n\n // next three fields are created only for root\n // re-assigned for everything else\n\n this.sourceFrame = new Rectangle();\n this.destinationFrame = new Rectangle();\n this.bindingSourceFrame = new Rectangle();\n this.bindingDestinationFrame = new Rectangle();\n this.filters = [];\n this.transform = null;\n }\n\n /** Clears the state */\n clear(): void\n {\n this.target = null;\n this.filters = null;\n this.renderTexture = null;\n }\n}\n"],"names":["MSAA_QUALITY","Rectangle"],"mappings":";;AAYO,MAAM,YACb;AAAA,EA8CI,cACA;AACI,SAAK,gBAAgB,MAErB,KAAK,SAAS,MACd,KAAK,SAAS,IACd,KAAK,aAAa,GAClB,KAAK,cAAcA,UAAAA,aAAa,MAKhC,KAAK,cAAc,IAAIC,KAAU,UAAA,GACjC,KAAK,mBAAmB,IAAIA,KAAU,UAAA,GACtC,KAAK,qBAAqB,IAAIA,KAAAA,aAC9B,KAAK,0BAA0B,IAAIA,KAAAA,UACnC,GAAA,KAAK,UAAU,CAAA,GACf,KAAK,YAAY;AAAA,EACrB;AAAA;AAAA,EAGA,QACA;AACI,SAAK,SAAS,MACd,KAAK,UAAU,MACf,KAAK,gBAAgB;AAAA,EACzB;AACJ;;"}

View File

@@ -0,0 +1,15 @@
import { MSAA_QUALITY } from "@pixi/constants";
import { Rectangle } from "@pixi/math";
class FilterState {
constructor() {
this.renderTexture = null, this.target = null, this.legacy = !1, this.resolution = 1, this.multisample = MSAA_QUALITY.NONE, this.sourceFrame = new Rectangle(), this.destinationFrame = new Rectangle(), this.bindingSourceFrame = new Rectangle(), this.bindingDestinationFrame = new Rectangle(), this.filters = [], this.transform = null;
}
/** Clears the state */
clear() {
this.target = null, this.filters = null, this.renderTexture = null;
}
}
export {
FilterState
};
//# sourceMappingURL=FilterState.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"FilterState.mjs","sources":["../../src/filters/FilterState.ts"],"sourcesContent":["import { MSAA_QUALITY } from '@pixi/constants';\nimport { Rectangle } from '@pixi/math';\n\nimport type { Matrix } from '@pixi/math';\nimport type { RenderTexture } from '../renderTexture/RenderTexture';\nimport type { Filter } from './Filter';\nimport type { IFilterTarget } from './IFilterTarget';\n\n/**\n * System plugin to the renderer to manage filter states.\n * @ignore\n */\nexport class FilterState\n{\n renderTexture: RenderTexture;\n\n /**\n * Target of the filters\n * We store for case when custom filter wants to know the element it was applied on\n * @member {PIXI.DisplayObject}\n */\n target: IFilterTarget;\n\n /**\n * Compatibility with PixiJS v4 filters\n * @default false\n */\n legacy: boolean;\n\n /**\n * Resolution of filters\n * @default 1\n */\n resolution: number;\n\n /**\n * Number of samples\n * @default MSAA_QUALITY.NONE\n */\n multisample: MSAA_QUALITY;\n\n /** Source frame. */\n sourceFrame: Rectangle;\n\n /** Destination frame. */\n destinationFrame: Rectangle;\n\n /** Original render-target source frame. */\n bindingSourceFrame: Rectangle;\n\n /** Original render-target destination frame. */\n bindingDestinationFrame: Rectangle;\n\n /** Collection of filters. */\n filters: Array<Filter>;\n\n /** Projection system transform saved by link. */\n transform: Matrix;\n\n constructor()\n {\n this.renderTexture = null;\n\n this.target = null;\n this.legacy = false;\n this.resolution = 1;\n this.multisample = MSAA_QUALITY.NONE;\n\n // next three fields are created only for root\n // re-assigned for everything else\n\n this.sourceFrame = new Rectangle();\n this.destinationFrame = new Rectangle();\n this.bindingSourceFrame = new Rectangle();\n this.bindingDestinationFrame = new Rectangle();\n this.filters = [];\n this.transform = null;\n }\n\n /** Clears the state */\n clear(): void\n {\n this.target = null;\n this.filters = null;\n this.renderTexture = null;\n }\n}\n"],"names":[],"mappings":";;AAYO,MAAM,YACb;AAAA,EA8CI,cACA;AACI,SAAK,gBAAgB,MAErB,KAAK,SAAS,MACd,KAAK,SAAS,IACd,KAAK,aAAa,GAClB,KAAK,cAAc,aAAa,MAKhC,KAAK,cAAc,IAAI,UAAU,GACjC,KAAK,mBAAmB,IAAI,UAAU,GACtC,KAAK,qBAAqB,IAAI,aAC9B,KAAK,0BAA0B,IAAI,UACnC,GAAA,KAAK,UAAU,CAAA,GACf,KAAK,YAAY;AAAA,EACrB;AAAA;AAAA,EAGA,QACA;AACI,SAAK,SAAS,MACd,KAAK,UAAU,MACf,KAAK,gBAAgB;AAAA,EACzB;AACJ;"}

View File

@@ -0,0 +1,233 @@
"use strict";
var constants = require("@pixi/constants"), extensions = require("@pixi/extensions"), math = require("@pixi/math"), RenderTexturePool = require("../renderTexture/RenderTexturePool.js"), UniformGroup = require("../shader/UniformGroup.js"), Quad = require("../utils/Quad.js"), QuadUv = require("../utils/QuadUv.js"), FilterState = require("./FilterState.js");
const tempPoints = [new math.Point(), new math.Point(), new math.Point(), new math.Point()], tempMatrix = new math.Matrix();
class FilterSystem {
/**
* @param renderer - The renderer this System works for.
*/
constructor(renderer) {
this.renderer = renderer, this.defaultFilterStack = [{}], this.texturePool = new RenderTexturePool.RenderTexturePool(), this.statePool = [], this.quad = new Quad.Quad(), this.quadUv = new QuadUv.QuadUv(), this.tempRect = new math.Rectangle(), this.activeState = {}, this.globalUniforms = new UniformGroup.UniformGroup({
outputFrame: new math.Rectangle(),
inputSize: new Float32Array(4),
inputPixel: new Float32Array(4),
inputClamp: new Float32Array(4),
resolution: 1,
// legacy variables
filterArea: new Float32Array(4),
filterClamp: new Float32Array(4)
}, !0), this.forceClear = !1, this.useMaxPadding = !1;
}
init() {
this.texturePool.setScreenSize(this.renderer.view);
}
/**
* Pushes a set of filters to be applied later to the system. This will redirect further rendering into an
* input render-texture for the rest of the filtering pipeline.
* @param {PIXI.DisplayObject} target - The target of the filter to render.
* @param filters - The filters to apply.
*/
push(target, filters) {
const renderer = this.renderer, filterStack = this.defaultFilterStack, state = this.statePool.pop() || new FilterState.FilterState(), renderTextureSystem = renderer.renderTexture;
let currentResolution, currentMultisample;
if (renderTextureSystem.current) {
const renderTexture = renderTextureSystem.current;
currentResolution = renderTexture.resolution, currentMultisample = renderTexture.multisample;
} else
currentResolution = renderer.resolution, currentMultisample = renderer.multisample;
let resolution = filters[0].resolution || currentResolution, multisample = filters[0].multisample ?? currentMultisample, padding = filters[0].padding, autoFit = filters[0].autoFit, legacy = filters[0].legacy ?? !0;
for (let i = 1; i < filters.length; i++) {
const filter = filters[i];
resolution = Math.min(resolution, filter.resolution || currentResolution), multisample = Math.min(multisample, filter.multisample ?? currentMultisample), padding = this.useMaxPadding ? Math.max(padding, filter.padding) : padding + filter.padding, autoFit = autoFit && filter.autoFit, legacy = legacy || (filter.legacy ?? !0);
}
filterStack.length === 1 && (this.defaultFilterStack[0].renderTexture = renderTextureSystem.current), filterStack.push(state), state.resolution = resolution, state.multisample = multisample, state.legacy = legacy, state.target = target, state.sourceFrame.copyFrom(target.filterArea || target.getBounds(!0)), state.sourceFrame.pad(padding);
const sourceFrameProjected = this.tempRect.copyFrom(renderTextureSystem.sourceFrame);
renderer.projection.transform && this.transformAABB(
tempMatrix.copyFrom(renderer.projection.transform).invert(),
sourceFrameProjected
), autoFit ? (state.sourceFrame.fit(sourceFrameProjected), (state.sourceFrame.width <= 0 || state.sourceFrame.height <= 0) && (state.sourceFrame.width = 0, state.sourceFrame.height = 0)) : state.sourceFrame.intersects(sourceFrameProjected) || (state.sourceFrame.width = 0, state.sourceFrame.height = 0), this.roundFrame(
state.sourceFrame,
renderTextureSystem.current ? renderTextureSystem.current.resolution : renderer.resolution,
renderTextureSystem.sourceFrame,
renderTextureSystem.destinationFrame,
renderer.projection.transform
), state.renderTexture = this.getOptimalFilterTexture(
state.sourceFrame.width,
state.sourceFrame.height,
resolution,
multisample
), state.filters = filters, state.destinationFrame.width = state.renderTexture.width, state.destinationFrame.height = state.renderTexture.height;
const destinationFrame = this.tempRect;
destinationFrame.x = 0, destinationFrame.y = 0, destinationFrame.width = state.sourceFrame.width, destinationFrame.height = state.sourceFrame.height, state.renderTexture.filterFrame = state.sourceFrame, state.bindingSourceFrame.copyFrom(renderTextureSystem.sourceFrame), state.bindingDestinationFrame.copyFrom(renderTextureSystem.destinationFrame), state.transform = renderer.projection.transform, renderer.projection.transform = null, renderTextureSystem.bind(state.renderTexture, state.sourceFrame, destinationFrame), renderer.framebuffer.clear(0, 0, 0, 0);
}
/** Pops off the filter and applies it. */
pop() {
const filterStack = this.defaultFilterStack, state = filterStack.pop(), filters = state.filters;
this.activeState = state;
const globalUniforms = this.globalUniforms.uniforms;
globalUniforms.outputFrame = state.sourceFrame, globalUniforms.resolution = state.resolution;
const inputSize = globalUniforms.inputSize, inputPixel = globalUniforms.inputPixel, inputClamp = globalUniforms.inputClamp;
if (inputSize[0] = state.destinationFrame.width, inputSize[1] = state.destinationFrame.height, inputSize[2] = 1 / inputSize[0], inputSize[3] = 1 / inputSize[1], inputPixel[0] = Math.round(inputSize[0] * state.resolution), inputPixel[1] = Math.round(inputSize[1] * state.resolution), inputPixel[2] = 1 / inputPixel[0], inputPixel[3] = 1 / inputPixel[1], inputClamp[0] = 0.5 * inputPixel[2], inputClamp[1] = 0.5 * inputPixel[3], inputClamp[2] = state.sourceFrame.width * inputSize[2] - 0.5 * inputPixel[2], inputClamp[3] = state.sourceFrame.height * inputSize[3] - 0.5 * inputPixel[3], state.legacy) {
const filterArea = globalUniforms.filterArea;
filterArea[0] = state.destinationFrame.width, filterArea[1] = state.destinationFrame.height, filterArea[2] = state.sourceFrame.x, filterArea[3] = state.sourceFrame.y, globalUniforms.filterClamp = globalUniforms.inputClamp;
}
this.globalUniforms.update();
const lastState = filterStack[filterStack.length - 1];
if (this.renderer.framebuffer.blit(), filters.length === 1)
filters[0].apply(this, state.renderTexture, lastState.renderTexture, constants.CLEAR_MODES.BLEND, state), this.returnFilterTexture(state.renderTexture);
else {
let flip = state.renderTexture, flop = this.getOptimalFilterTexture(
flip.width,
flip.height,
state.resolution
);
flop.filterFrame = flip.filterFrame;
let i = 0;
for (i = 0; i < filters.length - 1; ++i) {
i === 1 && state.multisample > 1 && (flop = this.getOptimalFilterTexture(
flip.width,
flip.height,
state.resolution
), flop.filterFrame = flip.filterFrame), filters[i].apply(this, flip, flop, constants.CLEAR_MODES.CLEAR, state);
const t = flip;
flip = flop, flop = t;
}
filters[i].apply(this, flip, lastState.renderTexture, constants.CLEAR_MODES.BLEND, state), i > 1 && state.multisample > 1 && this.returnFilterTexture(state.renderTexture), this.returnFilterTexture(flip), this.returnFilterTexture(flop);
}
state.clear(), this.statePool.push(state);
}
/**
* Binds a renderTexture with corresponding `filterFrame`, clears it if mode corresponds.
* @param filterTexture - renderTexture to bind, should belong to filter pool or filter stack
* @param clearMode - clearMode, by default its CLEAR/YES. See {@link PIXI.CLEAR_MODES}
*/
bindAndClear(filterTexture, clearMode = constants.CLEAR_MODES.CLEAR) {
const {
renderTexture: renderTextureSystem,
state: stateSystem
} = this.renderer;
if (filterTexture === this.defaultFilterStack[this.defaultFilterStack.length - 1].renderTexture ? this.renderer.projection.transform = this.activeState.transform : this.renderer.projection.transform = null, filterTexture?.filterFrame) {
const destinationFrame = this.tempRect;
destinationFrame.x = 0, destinationFrame.y = 0, destinationFrame.width = filterTexture.filterFrame.width, destinationFrame.height = filterTexture.filterFrame.height, renderTextureSystem.bind(filterTexture, filterTexture.filterFrame, destinationFrame);
} else
filterTexture !== this.defaultFilterStack[this.defaultFilterStack.length - 1].renderTexture ? renderTextureSystem.bind(filterTexture) : this.renderer.renderTexture.bind(
filterTexture,
this.activeState.bindingSourceFrame,
this.activeState.bindingDestinationFrame
);
const autoClear = stateSystem.stateId & 1 || this.forceClear;
(clearMode === constants.CLEAR_MODES.CLEAR || clearMode === constants.CLEAR_MODES.BLIT && autoClear) && this.renderer.framebuffer.clear(0, 0, 0, 0);
}
/**
* Draws a filter using the default rendering process.
*
* This should be called only by {@link PIXI.Filter#apply}.
* @param filter - The filter to draw.
* @param input - The input render target.
* @param output - The target to output to.
* @param clearMode - Should the output be cleared before rendering to it
*/
applyFilter(filter, input, output, clearMode) {
const renderer = this.renderer;
renderer.state.set(filter.state), this.bindAndClear(output, clearMode), filter.uniforms.uSampler = input, filter.uniforms.filterGlobals = this.globalUniforms, renderer.shader.bind(filter), filter.legacy = !!filter.program.attributeData.aTextureCoord, filter.legacy ? (this.quadUv.map(input._frame, input.filterFrame), renderer.geometry.bind(this.quadUv), renderer.geometry.draw(constants.DRAW_MODES.TRIANGLES)) : (renderer.geometry.bind(this.quad), renderer.geometry.draw(constants.DRAW_MODES.TRIANGLE_STRIP));
}
/**
* Multiply _input normalized coordinates_ to this matrix to get _sprite texture normalized coordinates_.
*
* Use `outputMatrix * vTextureCoord` in the shader.
* @param outputMatrix - The matrix to output to.
* @param {PIXI.Sprite} sprite - The sprite to map to.
* @returns The mapped matrix.
*/
calculateSpriteMatrix(outputMatrix, sprite) {
const { sourceFrame, destinationFrame } = this.activeState, { orig } = sprite._texture, mappedMatrix = outputMatrix.set(
destinationFrame.width,
0,
0,
destinationFrame.height,
sourceFrame.x,
sourceFrame.y
), worldTransform = sprite.worldTransform.copyTo(math.Matrix.TEMP_MATRIX);
return worldTransform.invert(), mappedMatrix.prepend(worldTransform), mappedMatrix.scale(1 / orig.width, 1 / orig.height), mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y), mappedMatrix;
}
/** Destroys this Filter System. */
destroy() {
this.renderer = null, this.texturePool.clear(!1);
}
/**
* Gets a Power-of-Two render texture or fullScreen texture
* @param minWidth - The minimum width of the render texture in real pixels.
* @param minHeight - The minimum height of the render texture in real pixels.
* @param resolution - The resolution of the render texture.
* @param multisample - Number of samples of the render texture.
* @returns - The new render texture.
*/
getOptimalFilterTexture(minWidth, minHeight, resolution = 1, multisample = constants.MSAA_QUALITY.NONE) {
return this.texturePool.getOptimalTexture(minWidth, minHeight, resolution, multisample);
}
/**
* Gets extra render texture to use inside current filter
* To be compliant with older filters, you can use params in any order
* @param input - renderTexture from which size and resolution will be copied
* @param resolution - override resolution of the renderTexture
* @param multisample - number of samples of the renderTexture
*/
getFilterTexture(input, resolution, multisample) {
if (typeof input == "number") {
const swap = input;
input = resolution, resolution = swap;
}
input = input || this.activeState.renderTexture;
const filterTexture = this.texturePool.getOptimalTexture(
input.width,
input.height,
resolution || input.resolution,
multisample || constants.MSAA_QUALITY.NONE
);
return filterTexture.filterFrame = input.filterFrame, filterTexture;
}
/**
* Frees a render texture back into the pool.
* @param renderTexture - The renderTarget to free
*/
returnFilterTexture(renderTexture) {
this.texturePool.returnTexture(renderTexture);
}
/** Empties the texture pool. */
emptyPool() {
this.texturePool.clear(!0);
}
/** Calls `texturePool.resize()`, affects fullScreen renderTextures. */
resize() {
this.texturePool.setScreenSize(this.renderer.view);
}
/**
* @param matrix - first param
* @param rect - second param
*/
transformAABB(matrix, rect) {
const lt = tempPoints[0], lb = tempPoints[1], rt = tempPoints[2], rb = tempPoints[3];
lt.set(rect.left, rect.top), lb.set(rect.left, rect.bottom), rt.set(rect.right, rect.top), rb.set(rect.right, rect.bottom), matrix.apply(lt, lt), matrix.apply(lb, lb), matrix.apply(rt, rt), matrix.apply(rb, rb);
const x0 = Math.min(lt.x, lb.x, rt.x, rb.x), y0 = Math.min(lt.y, lb.y, rt.y, rb.y), x1 = Math.max(lt.x, lb.x, rt.x, rb.x), y1 = Math.max(lt.y, lb.y, rt.y, rb.y);
rect.x = x0, rect.y = y0, rect.width = x1 - x0, rect.height = y1 - y0;
}
roundFrame(frame, resolution, bindingSourceFrame, bindingDestinationFrame, transform) {
if (!(frame.width <= 0 || frame.height <= 0 || bindingSourceFrame.width <= 0 || bindingSourceFrame.height <= 0)) {
if (transform) {
const { a, b, c, d } = transform;
if ((Math.abs(b) > 1e-4 || Math.abs(c) > 1e-4) && (Math.abs(a) > 1e-4 || Math.abs(d) > 1e-4))
return;
}
transform = transform ? tempMatrix.copyFrom(transform) : tempMatrix.identity(), transform.translate(-bindingSourceFrame.x, -bindingSourceFrame.y).scale(
bindingDestinationFrame.width / bindingSourceFrame.width,
bindingDestinationFrame.height / bindingSourceFrame.height
).translate(bindingDestinationFrame.x, bindingDestinationFrame.y), this.transformAABB(transform, frame), frame.ceil(resolution), this.transformAABB(transform.invert(), frame);
}
}
}
FilterSystem.extension = {
type: extensions.ExtensionType.RendererSystem,
name: "filter"
};
extensions.extensions.add(FilterSystem);
exports.FilterSystem = FilterSystem;
//# sourceMappingURL=FilterSystem.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,241 @@
import { CLEAR_MODES, DRAW_MODES, MSAA_QUALITY } from "@pixi/constants";
import { ExtensionType, extensions } from "@pixi/extensions";
import { Point, Matrix, Rectangle } from "@pixi/math";
import { RenderTexturePool } from "../renderTexture/RenderTexturePool.mjs";
import { UniformGroup } from "../shader/UniformGroup.mjs";
import { Quad } from "../utils/Quad.mjs";
import { QuadUv } from "../utils/QuadUv.mjs";
import { FilterState } from "./FilterState.mjs";
const tempPoints = [new Point(), new Point(), new Point(), new Point()], tempMatrix = new Matrix();
class FilterSystem {
/**
* @param renderer - The renderer this System works for.
*/
constructor(renderer) {
this.renderer = renderer, this.defaultFilterStack = [{}], this.texturePool = new RenderTexturePool(), this.statePool = [], this.quad = new Quad(), this.quadUv = new QuadUv(), this.tempRect = new Rectangle(), this.activeState = {}, this.globalUniforms = new UniformGroup({
outputFrame: new Rectangle(),
inputSize: new Float32Array(4),
inputPixel: new Float32Array(4),
inputClamp: new Float32Array(4),
resolution: 1,
// legacy variables
filterArea: new Float32Array(4),
filterClamp: new Float32Array(4)
}, !0), this.forceClear = !1, this.useMaxPadding = !1;
}
init() {
this.texturePool.setScreenSize(this.renderer.view);
}
/**
* Pushes a set of filters to be applied later to the system. This will redirect further rendering into an
* input render-texture for the rest of the filtering pipeline.
* @param {PIXI.DisplayObject} target - The target of the filter to render.
* @param filters - The filters to apply.
*/
push(target, filters) {
const renderer = this.renderer, filterStack = this.defaultFilterStack, state = this.statePool.pop() || new FilterState(), renderTextureSystem = renderer.renderTexture;
let currentResolution, currentMultisample;
if (renderTextureSystem.current) {
const renderTexture = renderTextureSystem.current;
currentResolution = renderTexture.resolution, currentMultisample = renderTexture.multisample;
} else
currentResolution = renderer.resolution, currentMultisample = renderer.multisample;
let resolution = filters[0].resolution || currentResolution, multisample = filters[0].multisample ?? currentMultisample, padding = filters[0].padding, autoFit = filters[0].autoFit, legacy = filters[0].legacy ?? !0;
for (let i = 1; i < filters.length; i++) {
const filter = filters[i];
resolution = Math.min(resolution, filter.resolution || currentResolution), multisample = Math.min(multisample, filter.multisample ?? currentMultisample), padding = this.useMaxPadding ? Math.max(padding, filter.padding) : padding + filter.padding, autoFit = autoFit && filter.autoFit, legacy = legacy || (filter.legacy ?? !0);
}
filterStack.length === 1 && (this.defaultFilterStack[0].renderTexture = renderTextureSystem.current), filterStack.push(state), state.resolution = resolution, state.multisample = multisample, state.legacy = legacy, state.target = target, state.sourceFrame.copyFrom(target.filterArea || target.getBounds(!0)), state.sourceFrame.pad(padding);
const sourceFrameProjected = this.tempRect.copyFrom(renderTextureSystem.sourceFrame);
renderer.projection.transform && this.transformAABB(
tempMatrix.copyFrom(renderer.projection.transform).invert(),
sourceFrameProjected
), autoFit ? (state.sourceFrame.fit(sourceFrameProjected), (state.sourceFrame.width <= 0 || state.sourceFrame.height <= 0) && (state.sourceFrame.width = 0, state.sourceFrame.height = 0)) : state.sourceFrame.intersects(sourceFrameProjected) || (state.sourceFrame.width = 0, state.sourceFrame.height = 0), this.roundFrame(
state.sourceFrame,
renderTextureSystem.current ? renderTextureSystem.current.resolution : renderer.resolution,
renderTextureSystem.sourceFrame,
renderTextureSystem.destinationFrame,
renderer.projection.transform
), state.renderTexture = this.getOptimalFilterTexture(
state.sourceFrame.width,
state.sourceFrame.height,
resolution,
multisample
), state.filters = filters, state.destinationFrame.width = state.renderTexture.width, state.destinationFrame.height = state.renderTexture.height;
const destinationFrame = this.tempRect;
destinationFrame.x = 0, destinationFrame.y = 0, destinationFrame.width = state.sourceFrame.width, destinationFrame.height = state.sourceFrame.height, state.renderTexture.filterFrame = state.sourceFrame, state.bindingSourceFrame.copyFrom(renderTextureSystem.sourceFrame), state.bindingDestinationFrame.copyFrom(renderTextureSystem.destinationFrame), state.transform = renderer.projection.transform, renderer.projection.transform = null, renderTextureSystem.bind(state.renderTexture, state.sourceFrame, destinationFrame), renderer.framebuffer.clear(0, 0, 0, 0);
}
/** Pops off the filter and applies it. */
pop() {
const filterStack = this.defaultFilterStack, state = filterStack.pop(), filters = state.filters;
this.activeState = state;
const globalUniforms = this.globalUniforms.uniforms;
globalUniforms.outputFrame = state.sourceFrame, globalUniforms.resolution = state.resolution;
const inputSize = globalUniforms.inputSize, inputPixel = globalUniforms.inputPixel, inputClamp = globalUniforms.inputClamp;
if (inputSize[0] = state.destinationFrame.width, inputSize[1] = state.destinationFrame.height, inputSize[2] = 1 / inputSize[0], inputSize[3] = 1 / inputSize[1], inputPixel[0] = Math.round(inputSize[0] * state.resolution), inputPixel[1] = Math.round(inputSize[1] * state.resolution), inputPixel[2] = 1 / inputPixel[0], inputPixel[3] = 1 / inputPixel[1], inputClamp[0] = 0.5 * inputPixel[2], inputClamp[1] = 0.5 * inputPixel[3], inputClamp[2] = state.sourceFrame.width * inputSize[2] - 0.5 * inputPixel[2], inputClamp[3] = state.sourceFrame.height * inputSize[3] - 0.5 * inputPixel[3], state.legacy) {
const filterArea = globalUniforms.filterArea;
filterArea[0] = state.destinationFrame.width, filterArea[1] = state.destinationFrame.height, filterArea[2] = state.sourceFrame.x, filterArea[3] = state.sourceFrame.y, globalUniforms.filterClamp = globalUniforms.inputClamp;
}
this.globalUniforms.update();
const lastState = filterStack[filterStack.length - 1];
if (this.renderer.framebuffer.blit(), filters.length === 1)
filters[0].apply(this, state.renderTexture, lastState.renderTexture, CLEAR_MODES.BLEND, state), this.returnFilterTexture(state.renderTexture);
else {
let flip = state.renderTexture, flop = this.getOptimalFilterTexture(
flip.width,
flip.height,
state.resolution
);
flop.filterFrame = flip.filterFrame;
let i = 0;
for (i = 0; i < filters.length - 1; ++i) {
i === 1 && state.multisample > 1 && (flop = this.getOptimalFilterTexture(
flip.width,
flip.height,
state.resolution
), flop.filterFrame = flip.filterFrame), filters[i].apply(this, flip, flop, CLEAR_MODES.CLEAR, state);
const t = flip;
flip = flop, flop = t;
}
filters[i].apply(this, flip, lastState.renderTexture, CLEAR_MODES.BLEND, state), i > 1 && state.multisample > 1 && this.returnFilterTexture(state.renderTexture), this.returnFilterTexture(flip), this.returnFilterTexture(flop);
}
state.clear(), this.statePool.push(state);
}
/**
* Binds a renderTexture with corresponding `filterFrame`, clears it if mode corresponds.
* @param filterTexture - renderTexture to bind, should belong to filter pool or filter stack
* @param clearMode - clearMode, by default its CLEAR/YES. See {@link PIXI.CLEAR_MODES}
*/
bindAndClear(filterTexture, clearMode = CLEAR_MODES.CLEAR) {
const {
renderTexture: renderTextureSystem,
state: stateSystem
} = this.renderer;
if (filterTexture === this.defaultFilterStack[this.defaultFilterStack.length - 1].renderTexture ? this.renderer.projection.transform = this.activeState.transform : this.renderer.projection.transform = null, filterTexture?.filterFrame) {
const destinationFrame = this.tempRect;
destinationFrame.x = 0, destinationFrame.y = 0, destinationFrame.width = filterTexture.filterFrame.width, destinationFrame.height = filterTexture.filterFrame.height, renderTextureSystem.bind(filterTexture, filterTexture.filterFrame, destinationFrame);
} else
filterTexture !== this.defaultFilterStack[this.defaultFilterStack.length - 1].renderTexture ? renderTextureSystem.bind(filterTexture) : this.renderer.renderTexture.bind(
filterTexture,
this.activeState.bindingSourceFrame,
this.activeState.bindingDestinationFrame
);
const autoClear = stateSystem.stateId & 1 || this.forceClear;
(clearMode === CLEAR_MODES.CLEAR || clearMode === CLEAR_MODES.BLIT && autoClear) && this.renderer.framebuffer.clear(0, 0, 0, 0);
}
/**
* Draws a filter using the default rendering process.
*
* This should be called only by {@link PIXI.Filter#apply}.
* @param filter - The filter to draw.
* @param input - The input render target.
* @param output - The target to output to.
* @param clearMode - Should the output be cleared before rendering to it
*/
applyFilter(filter, input, output, clearMode) {
const renderer = this.renderer;
renderer.state.set(filter.state), this.bindAndClear(output, clearMode), filter.uniforms.uSampler = input, filter.uniforms.filterGlobals = this.globalUniforms, renderer.shader.bind(filter), filter.legacy = !!filter.program.attributeData.aTextureCoord, filter.legacy ? (this.quadUv.map(input._frame, input.filterFrame), renderer.geometry.bind(this.quadUv), renderer.geometry.draw(DRAW_MODES.TRIANGLES)) : (renderer.geometry.bind(this.quad), renderer.geometry.draw(DRAW_MODES.TRIANGLE_STRIP));
}
/**
* Multiply _input normalized coordinates_ to this matrix to get _sprite texture normalized coordinates_.
*
* Use `outputMatrix * vTextureCoord` in the shader.
* @param outputMatrix - The matrix to output to.
* @param {PIXI.Sprite} sprite - The sprite to map to.
* @returns The mapped matrix.
*/
calculateSpriteMatrix(outputMatrix, sprite) {
const { sourceFrame, destinationFrame } = this.activeState, { orig } = sprite._texture, mappedMatrix = outputMatrix.set(
destinationFrame.width,
0,
0,
destinationFrame.height,
sourceFrame.x,
sourceFrame.y
), worldTransform = sprite.worldTransform.copyTo(Matrix.TEMP_MATRIX);
return worldTransform.invert(), mappedMatrix.prepend(worldTransform), mappedMatrix.scale(1 / orig.width, 1 / orig.height), mappedMatrix.translate(sprite.anchor.x, sprite.anchor.y), mappedMatrix;
}
/** Destroys this Filter System. */
destroy() {
this.renderer = null, this.texturePool.clear(!1);
}
/**
* Gets a Power-of-Two render texture or fullScreen texture
* @param minWidth - The minimum width of the render texture in real pixels.
* @param minHeight - The minimum height of the render texture in real pixels.
* @param resolution - The resolution of the render texture.
* @param multisample - Number of samples of the render texture.
* @returns - The new render texture.
*/
getOptimalFilterTexture(minWidth, minHeight, resolution = 1, multisample = MSAA_QUALITY.NONE) {
return this.texturePool.getOptimalTexture(minWidth, minHeight, resolution, multisample);
}
/**
* Gets extra render texture to use inside current filter
* To be compliant with older filters, you can use params in any order
* @param input - renderTexture from which size and resolution will be copied
* @param resolution - override resolution of the renderTexture
* @param multisample - number of samples of the renderTexture
*/
getFilterTexture(input, resolution, multisample) {
if (typeof input == "number") {
const swap = input;
input = resolution, resolution = swap;
}
input = input || this.activeState.renderTexture;
const filterTexture = this.texturePool.getOptimalTexture(
input.width,
input.height,
resolution || input.resolution,
multisample || MSAA_QUALITY.NONE
);
return filterTexture.filterFrame = input.filterFrame, filterTexture;
}
/**
* Frees a render texture back into the pool.
* @param renderTexture - The renderTarget to free
*/
returnFilterTexture(renderTexture) {
this.texturePool.returnTexture(renderTexture);
}
/** Empties the texture pool. */
emptyPool() {
this.texturePool.clear(!0);
}
/** Calls `texturePool.resize()`, affects fullScreen renderTextures. */
resize() {
this.texturePool.setScreenSize(this.renderer.view);
}
/**
* @param matrix - first param
* @param rect - second param
*/
transformAABB(matrix, rect) {
const lt = tempPoints[0], lb = tempPoints[1], rt = tempPoints[2], rb = tempPoints[3];
lt.set(rect.left, rect.top), lb.set(rect.left, rect.bottom), rt.set(rect.right, rect.top), rb.set(rect.right, rect.bottom), matrix.apply(lt, lt), matrix.apply(lb, lb), matrix.apply(rt, rt), matrix.apply(rb, rb);
const x0 = Math.min(lt.x, lb.x, rt.x, rb.x), y0 = Math.min(lt.y, lb.y, rt.y, rb.y), x1 = Math.max(lt.x, lb.x, rt.x, rb.x), y1 = Math.max(lt.y, lb.y, rt.y, rb.y);
rect.x = x0, rect.y = y0, rect.width = x1 - x0, rect.height = y1 - y0;
}
roundFrame(frame, resolution, bindingSourceFrame, bindingDestinationFrame, transform) {
if (!(frame.width <= 0 || frame.height <= 0 || bindingSourceFrame.width <= 0 || bindingSourceFrame.height <= 0)) {
if (transform) {
const { a, b, c, d } = transform;
if ((Math.abs(b) > 1e-4 || Math.abs(c) > 1e-4) && (Math.abs(a) > 1e-4 || Math.abs(d) > 1e-4))
return;
}
transform = transform ? tempMatrix.copyFrom(transform) : tempMatrix.identity(), transform.translate(-bindingSourceFrame.x, -bindingSourceFrame.y).scale(
bindingDestinationFrame.width / bindingSourceFrame.width,
bindingDestinationFrame.height / bindingSourceFrame.height
).translate(bindingDestinationFrame.x, bindingDestinationFrame.y), this.transformAABB(transform, frame), frame.ceil(resolution), this.transformAABB(transform.invert(), frame);
}
}
}
FilterSystem.extension = {
type: ExtensionType.RendererSystem,
name: "filter"
};
extensions.add(FilterSystem);
export {
FilterSystem
};
//# sourceMappingURL=FilterSystem.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
"use strict";
//# sourceMappingURL=IFilterTarget.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"IFilterTarget.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}

View File

@@ -0,0 +1,2 @@
//# sourceMappingURL=IFilterTarget.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"IFilterTarget.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var defaultFragment = `varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void){
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
`;
exports.default = defaultFragment;
//# sourceMappingURL=defaultFilter.frag.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"defaultFilter.frag.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}

View File

@@ -0,0 +1,12 @@
var defaultFragment = `varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void){
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
`;
export {
defaultFragment as default
};
//# sourceMappingURL=defaultFilter.frag.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"defaultFilter.frag.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}

View File

@@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var defaultVertex = `attribute vec2 aVertexPosition;
uniform mat3 projectionMatrix;
varying vec2 vTextureCoord;
uniform vec4 inputSize;
uniform vec4 outputFrame;
vec4 filterVertexPosition( void )
{
vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;
return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);
}
vec2 filterTextureCoord( void )
{
return aVertexPosition * (outputFrame.zw * inputSize.zw);
}
void main(void)
{
gl_Position = filterVertexPosition();
vTextureCoord = filterTextureCoord();
}
`;
exports.default = defaultVertex;
//# sourceMappingURL=defaultFilter.vert.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"defaultFilter.vert.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,31 @@
var defaultVertex = `attribute vec2 aVertexPosition;
uniform mat3 projectionMatrix;
varying vec2 vTextureCoord;
uniform vec4 inputSize;
uniform vec4 outputFrame;
vec4 filterVertexPosition( void )
{
vec2 position = aVertexPosition * max(outputFrame.zw, vec2(0.)) + outputFrame.xy;
return vec4((projectionMatrix * vec3(position, 1.0)).xy, 0.0, 1.0);
}
vec2 filterTextureCoord( void )
{
return aVertexPosition * (outputFrame.zw * inputSize.zw);
}
void main(void)
{
gl_Position = filterVertexPosition();
vTextureCoord = filterTextureCoord();
}
`;
export {
defaultVertex as default
};
//# sourceMappingURL=defaultFilter.vert.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"defaultFilter.vert.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,32 @@
"use strict";
var math = require("@pixi/math"), TextureMatrix = require("../../textures/TextureMatrix.js"), Filter = require("../Filter.js"), spriteMaskFilter$1 = require("./spriteMaskFilter.frag.js"), spriteMaskFilter = require("./spriteMaskFilter.vert.js");
class SpriteMaskFilter extends Filter.Filter {
/** @ignore */
constructor(vertexSrc, fragmentSrc, uniforms) {
let sprite = null;
typeof vertexSrc != "string" && fragmentSrc === void 0 && uniforms === void 0 && (sprite = vertexSrc, vertexSrc = void 0, fragmentSrc = void 0, uniforms = void 0), super(vertexSrc || spriteMaskFilter.default, fragmentSrc || spriteMaskFilter$1.default, uniforms), this.maskSprite = sprite, this.maskMatrix = new math.Matrix();
}
/**
* Sprite mask
* @type {PIXI.DisplayObject}
*/
get maskSprite() {
return this._maskSprite;
}
set maskSprite(value) {
this._maskSprite = value, this._maskSprite && (this._maskSprite.renderable = !1);
}
/**
* Applies the filter
* @param filterManager - The renderer to retrieve the filter from
* @param input - The input render target.
* @param output - The target to output to.
* @param clearMode - Should the output be cleared before rendering to it.
*/
apply(filterManager, input, output, clearMode) {
const maskSprite = this._maskSprite, tex = maskSprite._texture;
tex.valid && (tex.uvMatrix || (tex.uvMatrix = new TextureMatrix.TextureMatrix(tex, 0)), tex.uvMatrix.update(), this.uniforms.npmAlpha = tex.baseTexture.alphaMode ? 0 : 1, this.uniforms.mask = tex, this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite).prepend(tex.uvMatrix.mapCoord), this.uniforms.alpha = maskSprite.worldAlpha, this.uniforms.maskClamp = tex.uvMatrix.uClampFrame, filterManager.applyFilter(this, input, output, clearMode));
}
}
exports.SpriteMaskFilter = SpriteMaskFilter;
//# sourceMappingURL=SpriteMaskFilter.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
import { Matrix } from "@pixi/math";
import { TextureMatrix } from "../../textures/TextureMatrix.mjs";
import { Filter } from "../Filter.mjs";
import fragment from "./spriteMaskFilter.frag.mjs";
import vertex from "./spriteMaskFilter.vert.mjs";
class SpriteMaskFilter extends Filter {
/** @ignore */
constructor(vertexSrc, fragmentSrc, uniforms) {
let sprite = null;
typeof vertexSrc != "string" && fragmentSrc === void 0 && uniforms === void 0 && (sprite = vertexSrc, vertexSrc = void 0, fragmentSrc = void 0, uniforms = void 0), super(vertexSrc || vertex, fragmentSrc || fragment, uniforms), this.maskSprite = sprite, this.maskMatrix = new Matrix();
}
/**
* Sprite mask
* @type {PIXI.DisplayObject}
*/
get maskSprite() {
return this._maskSprite;
}
set maskSprite(value) {
this._maskSprite = value, this._maskSprite && (this._maskSprite.renderable = !1);
}
/**
* Applies the filter
* @param filterManager - The renderer to retrieve the filter from
* @param input - The input render target.
* @param output - The target to output to.
* @param clearMode - Should the output be cleared before rendering to it.
*/
apply(filterManager, input, output, clearMode) {
const maskSprite = this._maskSprite, tex = maskSprite._texture;
tex.valid && (tex.uvMatrix || (tex.uvMatrix = new TextureMatrix(tex, 0)), tex.uvMatrix.update(), this.uniforms.npmAlpha = tex.baseTexture.alphaMode ? 0 : 1, this.uniforms.mask = tex, this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite).prepend(tex.uvMatrix.mapCoord), this.uniforms.alpha = maskSprite.worldAlpha, this.uniforms.maskClamp = tex.uvMatrix.uClampFrame, filterManager.applyFilter(this, input, output, clearMode));
}
}
export {
SpriteMaskFilter
};
//# sourceMappingURL=SpriteMaskFilter.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SpriteMaskFilter.mjs","sources":["../../../src/filters/spriteMask/SpriteMaskFilter.ts"],"sourcesContent":["import { Matrix } from '@pixi/math';\nimport { TextureMatrix } from '../../textures/TextureMatrix';\nimport { Filter } from '../Filter';\nimport fragment from './spriteMaskFilter.frag';\nimport vertex from './spriteMaskFilter.vert';\n\nimport type { CLEAR_MODES } from '@pixi/constants';\nimport type { Point } from '@pixi/math';\nimport type { Dict } from '@pixi/utils';\nimport type { IMaskTarget } from '../../mask/MaskData';\nimport type { RenderTexture } from '../../renderTexture/RenderTexture';\nimport type { Texture } from '../../textures/Texture';\nimport type { FilterSystem } from '../FilterSystem';\n\nexport interface ISpriteMaskTarget extends IMaskTarget\n{\n _texture: Texture;\n worldAlpha: number;\n anchor: Point;\n}\n\nexport interface ISpriteMaskFilter extends Filter\n{\n maskSprite: IMaskTarget;\n}\n\n/**\n * This handles a Sprite acting as a mask, as opposed to a Graphic.\n *\n * WebGL only.\n * @memberof PIXI\n */\nexport class SpriteMaskFilter extends Filter\n{\n /** @private */\n _maskSprite: IMaskTarget;\n\n /** Mask matrix */\n maskMatrix: Matrix;\n\n /**\n * @param {PIXI.Sprite} sprite - The target sprite.\n */\n constructor(sprite: IMaskTarget);\n\n /**\n * @param vertexSrc - The source of the vertex shader.\n * @param fragmentSrc - The source of the fragment shader.\n * @param uniforms - Custom uniforms to use to augment the built-in ones.\n */\n constructor(vertexSrc?: string, fragmentSrc?: string, uniforms?: Dict<any>);\n\n /** @ignore */\n constructor(vertexSrc?: string | IMaskTarget, fragmentSrc?: string, uniforms?: Dict<any>)\n {\n let sprite = null;\n\n if (typeof vertexSrc !== 'string' && fragmentSrc === undefined && uniforms === undefined)\n {\n sprite = vertexSrc as IMaskTarget;\n vertexSrc = undefined;\n fragmentSrc = undefined;\n uniforms = undefined;\n }\n\n super(vertexSrc as string || vertex, fragmentSrc || fragment, uniforms);\n\n this.maskSprite = sprite;\n this.maskMatrix = new Matrix();\n }\n\n /**\n * Sprite mask\n * @type {PIXI.DisplayObject}\n */\n get maskSprite(): IMaskTarget\n {\n return this._maskSprite;\n }\n\n set maskSprite(value: IMaskTarget)\n {\n this._maskSprite = value;\n\n if (this._maskSprite)\n {\n this._maskSprite.renderable = false;\n }\n }\n\n /**\n * Applies the filter\n * @param filterManager - The renderer to retrieve the filter from\n * @param input - The input render target.\n * @param output - The target to output to.\n * @param clearMode - Should the output be cleared before rendering to it.\n */\n apply(filterManager: FilterSystem, input: RenderTexture, output: RenderTexture, clearMode: CLEAR_MODES): void\n {\n const maskSprite = this._maskSprite as ISpriteMaskTarget;\n const tex = maskSprite._texture;\n\n if (!tex.valid)\n {\n return;\n }\n if (!tex.uvMatrix)\n {\n // margin = 0.0, let it bleed a bit, shader code becomes easier\n // assuming that atlas textures were made with 1-pixel padding\n tex.uvMatrix = new TextureMatrix(tex, 0.0);\n }\n tex.uvMatrix.update();\n\n this.uniforms.npmAlpha = tex.baseTexture.alphaMode ? 0.0 : 1.0;\n this.uniforms.mask = tex;\n // get _normalized sprite texture coords_ and convert them to _normalized atlas texture coords_ with `prepend`\n this.uniforms.otherMatrix = filterManager.calculateSpriteMatrix(this.maskMatrix, maskSprite)\n .prepend(tex.uvMatrix.mapCoord);\n this.uniforms.alpha = maskSprite.worldAlpha;\n this.uniforms.maskClamp = tex.uvMatrix.uClampFrame;\n\n filterManager.applyFilter(this, input, output, clearMode);\n }\n}\n"],"names":[],"mappings":";;;;;AAgCO,MAAM,yBAAyB,OACtC;AAAA;AAAA,EAoBI,YAAY,WAAkC,aAAsB,UACpE;AACI,QAAI,SAAS;AAET,WAAO,aAAc,YAAY,gBAAgB,UAAa,aAAa,WAE3E,SAAS,WACT,YAAY,QACZ,cAAc,QACd,WAAW,SAGf,MAAM,aAAuB,QAAQ,eAAe,UAAU,QAAQ,GAEtE,KAAK,aAAa,QAClB,KAAK,aAAa,IAAI;EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,aACJ;AACI,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAI,WAAW,OACf;AACI,SAAK,cAAc,OAEf,KAAK,gBAEL,KAAK,YAAY,aAAa;AAAA,EAEtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,eAA6B,OAAsB,QAAuB,WAChF;AACI,UAAM,aAAa,KAAK,aAClB,MAAM,WAAW;AAElB,QAAI,UAIJ,IAAI,aAIL,IAAI,WAAW,IAAI,cAAc,KAAK,CAAG,IAE7C,IAAI,SAAS,UAEb,KAAK,SAAS,WAAW,IAAI,YAAY,YAAY,IAAM,GAC3D,KAAK,SAAS,OAAO,KAErB,KAAK,SAAS,cAAc,cAAc,sBAAsB,KAAK,YAAY,UAAU,EACtF,QAAQ,IAAI,SAAS,QAAQ,GAClC,KAAK,SAAS,QAAQ,WAAW,YACjC,KAAK,SAAS,YAAY,IAAI,SAAS,aAEvC,cAAc,YAAY,MAAM,OAAO,QAAQ,SAAS;AAAA,EAC5D;AACJ;"}

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var fragment = `varying vec2 vMaskCoord;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
uniform sampler2D mask;
uniform float alpha;
uniform float npmAlpha;
uniform vec4 maskClamp;
void main(void)
{
float clip = step(3.5,
step(maskClamp.x, vMaskCoord.x) +
step(maskClamp.y, vMaskCoord.y) +
step(vMaskCoord.x, maskClamp.z) +
step(vMaskCoord.y, maskClamp.w));
vec4 original = texture2D(uSampler, vTextureCoord);
vec4 masky = texture2D(mask, vMaskCoord);
float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a);
original *= (alphaMul * masky.r * alpha * clip);
gl_FragColor = original;
}
`;
exports.default = fragment;
//# sourceMappingURL=spriteMaskFilter.frag.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"spriteMaskFilter.frag.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,30 @@
var fragment = `varying vec2 vMaskCoord;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
uniform sampler2D mask;
uniform float alpha;
uniform float npmAlpha;
uniform vec4 maskClamp;
void main(void)
{
float clip = step(3.5,
step(maskClamp.x, vMaskCoord.x) +
step(maskClamp.y, vMaskCoord.y) +
step(vMaskCoord.x, maskClamp.z) +
step(vMaskCoord.y, maskClamp.w));
vec4 original = texture2D(uSampler, vTextureCoord);
vec4 masky = texture2D(mask, vMaskCoord);
float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a);
original *= (alphaMul * masky.r * alpha * clip);
gl_FragColor = original;
}
`;
export {
fragment as default
};
//# sourceMappingURL=spriteMaskFilter.frag.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"spriteMaskFilter.frag.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: !0 });
var vertex = `attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat3 projectionMatrix;
uniform mat3 otherMatrix;
varying vec2 vMaskCoord;
varying vec2 vTextureCoord;
void main(void)
{
gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;
}
`;
exports.default = vertex;
//# sourceMappingURL=spriteMaskFilter.vert.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"spriteMaskFilter.vert.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;"}

View File

@@ -0,0 +1,21 @@
var vertex = `attribute vec2 aVertexPosition;
attribute vec2 aTextureCoord;
uniform mat3 projectionMatrix;
uniform mat3 otherMatrix;
varying vec2 vMaskCoord;
varying vec2 vTextureCoord;
void main(void)
{
gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
vTextureCoord = aTextureCoord;
vMaskCoord = ( otherMatrix * vec3( aTextureCoord, 1.0) ).xy;
}
`;
export {
vertex as default
};
//# sourceMappingURL=spriteMaskFilter.vert.mjs.map

Some files were not shown because too many files have changed in this diff Show More