pixi.js
Version:
<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">
156 lines (153 loc) • 5.82 kB
JavaScript
import { ExtensionType } from '../../extensions/Extensions.mjs';
import { getAdjustedBlendModeBlend } from '../../rendering/renderers/shared/state/getAdjustedBlendModeBlend.mjs';
import { State } from '../../rendering/renderers/shared/state/State.mjs';
import { RendererType } from '../../rendering/renderers/types.mjs';
import { color32BitToUniform } from '../graphics/gpu/colorToUniform.mjs';
import { BatchableMesh } from '../mesh/shared/BatchableMesh.mjs';
import { MeshGeometry } from '../mesh/shared/MeshGeometry.mjs';
import { TilingSpriteShader } from './shader/TilingSpriteShader.mjs';
import { QuadGeometry } from './utils/QuadGeometry.mjs';
import { setPositions } from './utils/setPositions.mjs';
import { setUvs } from './utils/setUvs.mjs';
"use strict";
const sharedQuad = new QuadGeometry();
class TilingSpriteGpuData {
constructor() {
this.canBatch = true;
this.geometry = new MeshGeometry({
indices: sharedQuad.indices.slice(),
positions: sharedQuad.positions.slice(),
uvs: sharedQuad.uvs.slice()
});
}
destroy() {
this.geometry.destroy();
this.shader?.destroy();
}
}
class TilingSpritePipe {
constructor(renderer) {
this._state = State.default2d;
this._renderer = renderer;
}
validateRenderable(renderable) {
const tilingSpriteData = this._getTilingSpriteData(renderable);
const couldBatch = tilingSpriteData.canBatch;
this._updateCanBatch(renderable);
const canBatch = tilingSpriteData.canBatch;
if (canBatch && canBatch === couldBatch) {
const { batchableMesh } = tilingSpriteData;
return !batchableMesh._batcher.checkAndUpdateTexture(
batchableMesh,
renderable.texture
);
}
return couldBatch !== canBatch;
}
addRenderable(tilingSprite, instructionSet) {
const batcher = this._renderer.renderPipes.batch;
this._updateCanBatch(tilingSprite);
const tilingSpriteData = this._getTilingSpriteData(tilingSprite);
const { geometry, canBatch } = tilingSpriteData;
if (canBatch) {
tilingSpriteData.batchableMesh || (tilingSpriteData.batchableMesh = new BatchableMesh());
const batchableMesh = tilingSpriteData.batchableMesh;
if (tilingSprite.didViewUpdate) {
this._updateBatchableMesh(tilingSprite);
batchableMesh.geometry = geometry;
batchableMesh.renderable = tilingSprite;
batchableMesh.transform = tilingSprite.groupTransform;
batchableMesh.setTexture(tilingSprite._texture);
}
batchableMesh.roundPixels = this._renderer._roundPixels | tilingSprite._roundPixels;
batcher.addToBatch(batchableMesh, instructionSet);
} else {
batcher.break(instructionSet);
tilingSpriteData.shader || (tilingSpriteData.shader = new TilingSpriteShader());
this.updateRenderable(tilingSprite);
instructionSet.add(tilingSprite);
}
}
execute(tilingSprite) {
const { shader } = this._getTilingSpriteData(tilingSprite);
shader.groups[0] = this._renderer.globalUniforms.bindGroup;
const localUniforms = shader.resources.localUniforms.uniforms;
localUniforms.uTransformMatrix = tilingSprite.groupTransform;
localUniforms.uRound = this._renderer._roundPixels | tilingSprite._roundPixels;
color32BitToUniform(
tilingSprite.groupColorAlpha,
localUniforms.uColor,
0
);
this._state.blendMode = getAdjustedBlendModeBlend(tilingSprite.groupBlendMode, tilingSprite.texture._source);
this._renderer.encoder.draw({
geometry: sharedQuad,
shader,
state: this._state
});
}
updateRenderable(tilingSprite) {
const tilingSpriteData = this._getTilingSpriteData(tilingSprite);
const { canBatch } = tilingSpriteData;
if (canBatch) {
const { batchableMesh } = tilingSpriteData;
if (tilingSprite.didViewUpdate)
this._updateBatchableMesh(tilingSprite);
batchableMesh._batcher.updateElement(batchableMesh);
} else if (tilingSprite.didViewUpdate) {
const { shader } = tilingSpriteData;
shader.updateUniforms(
tilingSprite.width,
tilingSprite.height,
tilingSprite._tileTransform.matrix,
tilingSprite.anchor.x,
tilingSprite.anchor.y,
tilingSprite.texture
);
}
}
_getTilingSpriteData(renderable) {
return renderable._gpuData[this._renderer.uid] || this._initTilingSpriteData(renderable);
}
_initTilingSpriteData(tilingSprite) {
const gpuData = new TilingSpriteGpuData();
gpuData.renderable = tilingSprite;
tilingSprite._gpuData[this._renderer.uid] = gpuData;
return gpuData;
}
_updateBatchableMesh(tilingSprite) {
const renderableData = this._getTilingSpriteData(tilingSprite);
const { geometry } = renderableData;
const style = tilingSprite.texture.source.style;
if (style.addressMode !== "repeat") {
style.addressMode = "repeat";
style.update();
}
setUvs(tilingSprite, geometry.uvs);
setPositions(tilingSprite, geometry.positions);
}
destroy() {
this._renderer = null;
}
_updateCanBatch(tilingSprite) {
const renderableData = this._getTilingSpriteData(tilingSprite);
const texture = tilingSprite.texture;
let _nonPowOf2wrapping = true;
if (this._renderer.type === RendererType.WEBGL) {
_nonPowOf2wrapping = this._renderer.context.supports.nonPowOf2wrapping;
}
renderableData.canBatch = texture.textureMatrix.isSimple && (_nonPowOf2wrapping || texture.source.isPowerOfTwo);
return renderableData.canBatch;
}
}
/** @ignore */
TilingSpritePipe.extension = {
type: [
ExtensionType.WebGLPipes,
ExtensionType.WebGPUPipes,
ExtensionType.CanvasPipes
],
name: "tilingSprite"
};
export { TilingSpriteGpuData, TilingSpritePipe };
//# sourceMappingURL=TilingSpritePipe.mjs.map