This commit is contained in:
Akko
2025-08-04 18:57:35 +02:00
parent 8cf6e78a79
commit 9495868c2e
5030 changed files with 518594 additions and 17609 deletions

View File

@@ -0,0 +1,4 @@
import { Geometry } from '../../renderers/shared/geometry/Geometry';
export declare class BatchGeometry extends Geometry {
constructor();
}

View File

@@ -0,0 +1,60 @@
'use strict';
var Buffer = require('../../renderers/shared/buffer/Buffer.js');
var _const = require('../../renderers/shared/buffer/const.js');
var Geometry = require('../../renderers/shared/geometry/Geometry.js');
"use strict";
const placeHolderBufferData = new Float32Array(1);
const placeHolderIndexData = new Uint32Array(1);
class BatchGeometry extends Geometry.Geometry {
constructor() {
const vertexSize = 6;
const attributeBuffer = new Buffer.Buffer({
data: placeHolderBufferData,
label: "attribute-batch-buffer",
usage: _const.BufferUsage.VERTEX | _const.BufferUsage.COPY_DST,
shrinkToFit: false
});
const indexBuffer = new Buffer.Buffer({
data: placeHolderIndexData,
label: "index-batch-buffer",
usage: _const.BufferUsage.INDEX | _const.BufferUsage.COPY_DST,
// | BufferUsage.STATIC,
shrinkToFit: false
});
const stride = vertexSize * 4;
super({
attributes: {
aPosition: {
buffer: attributeBuffer,
format: "float32x2",
stride,
offset: 0
},
aUV: {
buffer: attributeBuffer,
format: "float32x2",
stride,
offset: 2 * 4
},
aColor: {
buffer: attributeBuffer,
format: "unorm8x4",
stride,
offset: 4 * 4
},
aTextureIdAndRound: {
buffer: attributeBuffer,
format: "uint16x2",
stride,
offset: 5 * 4
}
},
indexBuffer
});
}
}
exports.BatchGeometry = BatchGeometry;
//# sourceMappingURL=BatchGeometry.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchGeometry.js","sources":["../../../../src/rendering/batcher/shared/BatchGeometry.ts"],"sourcesContent":["import { Buffer } from '../../renderers/shared/buffer/Buffer';\nimport { BufferUsage } from '../../renderers/shared/buffer/const';\nimport { Geometry } from '../../renderers/shared/geometry/Geometry';\n\nconst placeHolderBufferData = new Float32Array(1);\nconst placeHolderIndexData = new Uint32Array(1);\n\nexport class BatchGeometry extends Geometry\n{\n constructor()\n {\n const vertexSize = 6;\n\n const attributeBuffer = new Buffer({\n data: placeHolderBufferData,\n label: 'attribute-batch-buffer',\n usage: BufferUsage.VERTEX | BufferUsage.COPY_DST,\n shrinkToFit: false,\n });\n\n const indexBuffer = new Buffer({\n data: placeHolderIndexData,\n label: 'index-batch-buffer',\n usage: BufferUsage.INDEX | BufferUsage.COPY_DST, // | BufferUsage.STATIC,\n shrinkToFit: false,\n });\n\n const stride = vertexSize * 4;\n\n super({\n attributes: {\n aPosition: {\n buffer: attributeBuffer,\n format: 'float32x2',\n stride,\n offset: 0,\n },\n aUV: {\n buffer: attributeBuffer,\n format: 'float32x2',\n stride,\n offset: 2 * 4,\n },\n aColor: {\n buffer: attributeBuffer,\n format: 'unorm8x4',\n stride,\n offset: 4 * 4,\n },\n aTextureIdAndRound: {\n buffer: attributeBuffer,\n format: 'uint16x2',\n stride,\n offset: 5 * 4,\n },\n },\n indexBuffer\n });\n }\n}\n\n"],"names":["Geometry","Buffer","BufferUsage"],"mappings":";;;;;;;AAIA,MAAM,qBAAA,GAAwB,IAAI,YAAA,CAAa,CAAC,CAAA,CAAA;AAChD,MAAM,oBAAA,GAAuB,IAAI,WAAA,CAAY,CAAC,CAAA,CAAA;AAEvC,MAAM,sBAAsBA,iBACnC,CAAA;AAAA,EACI,WACA,GAAA;AACI,IAAA,MAAM,UAAa,GAAA,CAAA,CAAA;AAEnB,IAAM,MAAA,eAAA,GAAkB,IAAIC,aAAO,CAAA;AAAA,MAC/B,IAAM,EAAA,qBAAA;AAAA,MACN,KAAO,EAAA,wBAAA;AAAA,MACP,KAAA,EAAOC,kBAAY,CAAA,MAAA,GAASA,kBAAY,CAAA,QAAA;AAAA,MACxC,WAAa,EAAA,KAAA;AAAA,KAChB,CAAA,CAAA;AAED,IAAM,MAAA,WAAA,GAAc,IAAID,aAAO,CAAA;AAAA,MAC3B,IAAM,EAAA,oBAAA;AAAA,MACN,KAAO,EAAA,oBAAA;AAAA,MACP,KAAA,EAAOC,kBAAY,CAAA,KAAA,GAAQA,kBAAY,CAAA,QAAA;AAAA;AAAA,MACvC,WAAa,EAAA,KAAA;AAAA,KAChB,CAAA,CAAA;AAED,IAAA,MAAM,SAAS,UAAa,GAAA,CAAA,CAAA;AAE5B,IAAM,KAAA,CAAA;AAAA,MACF,UAAY,EAAA;AAAA,QACR,SAAW,EAAA;AAAA,UACP,MAAQ,EAAA,eAAA;AAAA,UACR,MAAQ,EAAA,WAAA;AAAA,UACR,MAAA;AAAA,UACA,MAAQ,EAAA,CAAA;AAAA,SACZ;AAAA,QACA,GAAK,EAAA;AAAA,UACD,MAAQ,EAAA,eAAA;AAAA,UACR,MAAQ,EAAA,WAAA;AAAA,UACR,MAAA;AAAA,UACA,QAAQ,CAAI,GAAA,CAAA;AAAA,SAChB;AAAA,QACA,MAAQ,EAAA;AAAA,UACJ,MAAQ,EAAA,eAAA;AAAA,UACR,MAAQ,EAAA,UAAA;AAAA,UACR,MAAA;AAAA,UACA,QAAQ,CAAI,GAAA,CAAA;AAAA,SAChB;AAAA,QACA,kBAAoB,EAAA;AAAA,UAChB,MAAQ,EAAA,eAAA;AAAA,UACR,MAAQ,EAAA,UAAA;AAAA,UACR,MAAA;AAAA,UACA,QAAQ,CAAI,GAAA,CAAA;AAAA,SAChB;AAAA,OACJ;AAAA,MACA,WAAA;AAAA,KACH,CAAA,CAAA;AAAA,GACL;AACJ;;;;"}

View File

@@ -0,0 +1,58 @@
import { Buffer } from '../../renderers/shared/buffer/Buffer.mjs';
import { BufferUsage } from '../../renderers/shared/buffer/const.mjs';
import { Geometry } from '../../renderers/shared/geometry/Geometry.mjs';
"use strict";
const placeHolderBufferData = new Float32Array(1);
const placeHolderIndexData = new Uint32Array(1);
class BatchGeometry extends Geometry {
constructor() {
const vertexSize = 6;
const attributeBuffer = new Buffer({
data: placeHolderBufferData,
label: "attribute-batch-buffer",
usage: BufferUsage.VERTEX | BufferUsage.COPY_DST,
shrinkToFit: false
});
const indexBuffer = new Buffer({
data: placeHolderIndexData,
label: "index-batch-buffer",
usage: BufferUsage.INDEX | BufferUsage.COPY_DST,
// | BufferUsage.STATIC,
shrinkToFit: false
});
const stride = vertexSize * 4;
super({
attributes: {
aPosition: {
buffer: attributeBuffer,
format: "float32x2",
stride,
offset: 0
},
aUV: {
buffer: attributeBuffer,
format: "float32x2",
stride,
offset: 2 * 4
},
aColor: {
buffer: attributeBuffer,
format: "unorm8x4",
stride,
offset: 4 * 4
},
aTextureIdAndRound: {
buffer: attributeBuffer,
format: "uint16x2",
stride,
offset: 5 * 4
}
},
indexBuffer
});
}
}
export { BatchGeometry };
//# sourceMappingURL=BatchGeometry.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchGeometry.mjs","sources":["../../../../src/rendering/batcher/shared/BatchGeometry.ts"],"sourcesContent":["import { Buffer } from '../../renderers/shared/buffer/Buffer';\nimport { BufferUsage } from '../../renderers/shared/buffer/const';\nimport { Geometry } from '../../renderers/shared/geometry/Geometry';\n\nconst placeHolderBufferData = new Float32Array(1);\nconst placeHolderIndexData = new Uint32Array(1);\n\nexport class BatchGeometry extends Geometry\n{\n constructor()\n {\n const vertexSize = 6;\n\n const attributeBuffer = new Buffer({\n data: placeHolderBufferData,\n label: 'attribute-batch-buffer',\n usage: BufferUsage.VERTEX | BufferUsage.COPY_DST,\n shrinkToFit: false,\n });\n\n const indexBuffer = new Buffer({\n data: placeHolderIndexData,\n label: 'index-batch-buffer',\n usage: BufferUsage.INDEX | BufferUsage.COPY_DST, // | BufferUsage.STATIC,\n shrinkToFit: false,\n });\n\n const stride = vertexSize * 4;\n\n super({\n attributes: {\n aPosition: {\n buffer: attributeBuffer,\n format: 'float32x2',\n stride,\n offset: 0,\n },\n aUV: {\n buffer: attributeBuffer,\n format: 'float32x2',\n stride,\n offset: 2 * 4,\n },\n aColor: {\n buffer: attributeBuffer,\n format: 'unorm8x4',\n stride,\n offset: 4 * 4,\n },\n aTextureIdAndRound: {\n buffer: attributeBuffer,\n format: 'uint16x2',\n stride,\n offset: 5 * 4,\n },\n },\n indexBuffer\n });\n }\n}\n\n"],"names":[],"mappings":";;;;;AAIA,MAAM,qBAAA,GAAwB,IAAI,YAAA,CAAa,CAAC,CAAA,CAAA;AAChD,MAAM,oBAAA,GAAuB,IAAI,WAAA,CAAY,CAAC,CAAA,CAAA;AAEvC,MAAM,sBAAsB,QACnC,CAAA;AAAA,EACI,WACA,GAAA;AACI,IAAA,MAAM,UAAa,GAAA,CAAA,CAAA;AAEnB,IAAM,MAAA,eAAA,GAAkB,IAAI,MAAO,CAAA;AAAA,MAC/B,IAAM,EAAA,qBAAA;AAAA,MACN,KAAO,EAAA,wBAAA;AAAA,MACP,KAAA,EAAO,WAAY,CAAA,MAAA,GAAS,WAAY,CAAA,QAAA;AAAA,MACxC,WAAa,EAAA,KAAA;AAAA,KAChB,CAAA,CAAA;AAED,IAAM,MAAA,WAAA,GAAc,IAAI,MAAO,CAAA;AAAA,MAC3B,IAAM,EAAA,oBAAA;AAAA,MACN,KAAO,EAAA,oBAAA;AAAA,MACP,KAAA,EAAO,WAAY,CAAA,KAAA,GAAQ,WAAY,CAAA,QAAA;AAAA;AAAA,MACvC,WAAa,EAAA,KAAA;AAAA,KAChB,CAAA,CAAA;AAED,IAAA,MAAM,SAAS,UAAa,GAAA,CAAA,CAAA;AAE5B,IAAM,KAAA,CAAA;AAAA,MACF,UAAY,EAAA;AAAA,QACR,SAAW,EAAA;AAAA,UACP,MAAQ,EAAA,eAAA;AAAA,UACR,MAAQ,EAAA,WAAA;AAAA,UACR,MAAA;AAAA,UACA,MAAQ,EAAA,CAAA;AAAA,SACZ;AAAA,QACA,GAAK,EAAA;AAAA,UACD,MAAQ,EAAA,eAAA;AAAA,UACR,MAAQ,EAAA,WAAA;AAAA,UACR,MAAA;AAAA,UACA,QAAQ,CAAI,GAAA,CAAA;AAAA,SAChB;AAAA,QACA,MAAQ,EAAA;AAAA,UACJ,MAAQ,EAAA,eAAA;AAAA,UACR,MAAQ,EAAA,UAAA;AAAA,UACR,MAAA;AAAA,UACA,QAAQ,CAAI,GAAA,CAAA;AAAA,SAChB;AAAA,QACA,kBAAoB,EAAA;AAAA,UAChB,MAAQ,EAAA,eAAA;AAAA,UACR,MAAQ,EAAA,UAAA;AAAA,UACR,MAAA;AAAA,UACA,QAAQ,CAAI,GAAA,CAAA;AAAA,SAChB;AAAA,OACJ;AAAA,MACA,WAAA;AAAA,KACH,CAAA,CAAA;AAAA,GACL;AACJ;;;;"}

View File

@@ -0,0 +1,16 @@
import type { TextureSource } from '../../renderers/shared/texture/sources/TextureSource';
/**
* Used by the batcher to build texture batches. Holds list of textures and their respective locations.
* @memberof rendering
*/
export declare class BatchTextureArray {
/** Inside textures array. */
textures: TextureSource[];
/** Respective locations for textures. */
ids: Record<number, number>;
/** Number of filled elements. */
count: number;
constructor();
/** Clear the textures and their locations. */
clear(): void;
}

View File

@@ -0,0 +1,23 @@
'use strict';
"use strict";
class BatchTextureArray {
constructor() {
/** Respective locations for textures. */
this.ids = /* @__PURE__ */ Object.create(null);
this.textures = [];
this.count = 0;
}
/** Clear the textures and their locations. */
clear() {
for (let i = 0; i < this.count; i++) {
const t = this.textures[i];
this.textures[i] = null;
this.ids[t.uid] = null;
}
this.count = 0;
}
}
exports.BatchTextureArray = BatchTextureArray;
//# sourceMappingURL=BatchTextureArray.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchTextureArray.js","sources":["../../../../src/rendering/batcher/shared/BatchTextureArray.ts"],"sourcesContent":["import type { TextureSource } from '../../renderers/shared/texture/sources/TextureSource';\n\n/**\n * Used by the batcher to build texture batches. Holds list of textures and their respective locations.\n * @memberof rendering\n */\nexport class BatchTextureArray\n{\n /** Inside textures array. */\n public textures: TextureSource[];\n\n /** Respective locations for textures. */\n public ids: Record<number, number> = Object.create(null);\n\n /** Number of filled elements. */\n public count: number;\n\n constructor()\n {\n this.textures = [];\n this.count = 0;\n }\n\n /** Clear the textures and their locations. */\n public clear(): void\n {\n for (let i = 0; i < this.count; i++)\n {\n const t = this.textures[i];\n\n this.textures[i] = null;\n this.ids[t.uid] = null;\n }\n\n this.count = 0;\n }\n}\n"],"names":[],"mappings":";;;AAMO,MAAM,iBACb,CAAA;AAAA,EAUI,WACA,GAAA;AANA;AAAA,IAAO,IAAA,CAAA,GAAA,mBAAqC,MAAA,CAAA,MAAA,CAAO,IAAI,CAAA,CAAA;AAOnD,IAAA,IAAA,CAAK,WAAW,EAAC,CAAA;AACjB,IAAA,IAAA,CAAK,KAAQ,GAAA,CAAA,CAAA;AAAA,GACjB;AAAA;AAAA,EAGO,KACP,GAAA;AACI,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,IAAA,CAAK,OAAO,CAChC,EAAA,EAAA;AACI,MAAM,MAAA,CAAA,GAAI,IAAK,CAAA,QAAA,CAAS,CAAC,CAAA,CAAA;AAEzB,MAAK,IAAA,CAAA,QAAA,CAAS,CAAC,CAAI,GAAA,IAAA,CAAA;AACnB,MAAK,IAAA,CAAA,GAAA,CAAI,CAAE,CAAA,GAAG,CAAI,GAAA,IAAA,CAAA;AAAA,KACtB;AAEA,IAAA,IAAA,CAAK,KAAQ,GAAA,CAAA,CAAA;AAAA,GACjB;AACJ;;;;"}

View File

@@ -0,0 +1,21 @@
"use strict";
class BatchTextureArray {
constructor() {
/** Respective locations for textures. */
this.ids = /* @__PURE__ */ Object.create(null);
this.textures = [];
this.count = 0;
}
/** Clear the textures and their locations. */
clear() {
for (let i = 0; i < this.count; i++) {
const t = this.textures[i];
this.textures[i] = null;
this.ids[t.uid] = null;
}
this.count = 0;
}
}
export { BatchTextureArray };
//# sourceMappingURL=BatchTextureArray.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"BatchTextureArray.mjs","sources":["../../../../src/rendering/batcher/shared/BatchTextureArray.ts"],"sourcesContent":["import type { TextureSource } from '../../renderers/shared/texture/sources/TextureSource';\n\n/**\n * Used by the batcher to build texture batches. Holds list of textures and their respective locations.\n * @memberof rendering\n */\nexport class BatchTextureArray\n{\n /** Inside textures array. */\n public textures: TextureSource[];\n\n /** Respective locations for textures. */\n public ids: Record<number, number> = Object.create(null);\n\n /** Number of filled elements. */\n public count: number;\n\n constructor()\n {\n this.textures = [];\n this.count = 0;\n }\n\n /** Clear the textures and their locations. */\n public clear(): void\n {\n for (let i = 0; i < this.count; i++)\n {\n const t = this.textures[i];\n\n this.textures[i] = null;\n this.ids[t.uid] = null;\n }\n\n this.count = 0;\n }\n}\n"],"names":[],"mappings":";AAMO,MAAM,iBACb,CAAA;AAAA,EAUI,WACA,GAAA;AANA;AAAA,IAAO,IAAA,CAAA,GAAA,mBAAqC,MAAA,CAAA,MAAA,CAAO,IAAI,CAAA,CAAA;AAOnD,IAAA,IAAA,CAAK,WAAW,EAAC,CAAA;AACjB,IAAA,IAAA,CAAK,KAAQ,GAAA,CAAA,CAAA;AAAA,GACjB;AAAA;AAAA,EAGO,KACP,GAAA;AACI,IAAA,KAAA,IAAS,CAAI,GAAA,CAAA,EAAG,CAAI,GAAA,IAAA,CAAK,OAAO,CAChC,EAAA,EAAA;AACI,MAAM,MAAA,CAAA,GAAI,IAAK,CAAA,QAAA,CAAS,CAAC,CAAA,CAAA;AAEzB,MAAK,IAAA,CAAA,QAAA,CAAS,CAAC,CAAI,GAAA,IAAA,CAAA;AACnB,MAAK,IAAA,CAAA,GAAA,CAAI,CAAE,CAAA,GAAG,CAAI,GAAA,IAAA,CAAA;AAAA,KACtB;AAEA,IAAA,IAAA,CAAK,KAAQ,GAAA,CAAA,CAAA;AAAA,GACjB;AACJ;;;;"}

View File

@@ -0,0 +1,272 @@
/// <reference types="@webgpu/types" />
import { ViewableBuffer } from '../../../utils/data/ViewableBuffer';
import { type BLEND_MODES } from '../../renderers/shared/state/const';
import { BatchTextureArray } from './BatchTextureArray';
import type { BoundsData } from '../../../scene/container/bounds/Bounds';
import type { BindGroup } from '../../renderers/gpu/shader/BindGroup';
import type { Geometry, IndexBufferArray } from '../../renderers/shared/geometry/Geometry';
import type { Instruction } from '../../renderers/shared/instructions/Instruction';
import type { InstructionSet } from '../../renderers/shared/instructions/InstructionSet';
import type { Shader } from '../../renderers/shared/shader/Shader';
import type { Texture } from '../../renderers/shared/texture/Texture';
export type BatchAction = 'startBatch' | 'renderBatch';
/**
* A batch pool is used to store batches when they are not currently in use.
* @memberof rendering
*/
export declare class Batch implements Instruction {
renderPipeId: string;
action: BatchAction;
start: number;
size: number;
textures: BatchTextureArray;
blendMode: BLEND_MODES;
canBundle: boolean;
/**
* breaking rules slightly here in the name of performance..
* storing references to these bindgroups here is just faster for access!
* keeps a reference to the GPU bind group to set when rendering this batch for WebGPU. Will be null is using WebGL.
*/
gpuBindGroup: GPUBindGroup;
/**
* breaking rules slightly here in the name of performance..
* storing references to these bindgroups here is just faster for access!
* keeps a reference to the bind group to set when rendering this batch for WebGPU. Will be null if using WebGl.
*/
bindGroup: BindGroup;
batcher: Batcher;
destroy(): void;
}
/**
* Represents an element that can be batched for rendering.
* @interface
* @memberof rendering
*/
export interface BatchableElement {
/**
* The name of the batcher to use. Must be registered.
* @type {string}
*/
batcherName: string;
/**
* The texture to be used for rendering.
* @type {Texture}
*/
texture: Texture;
/**
* The blend mode to be applied.
* @type {BLEND_MODES}
*/
blendMode: BLEND_MODES;
/**
* The size of the index data.
* @type {number}
*/
indexSize: number;
/**
* The size of the attribute data.
* @type {number}
*/
attributeSize: number;
/**
* Whether the element should be packed as a quad for better performance.
* @type {boolean}
*/
packAsQuad: boolean;
/**
* The texture ID, stored for efficient updating.
* @type {number}
* @private
*/
_textureId: number;
/**
* The starting position in the attribute buffer.
* @type {number}
* @private
*/
_attributeStart: number;
/**
* The starting position in the index buffer.
* @type {number}
* @private
*/
_indexStart: number;
/**
* Reference to the batcher.
* @type {Batcher}
* @private
*/
_batcher: Batcher;
/**
* Reference to the batch.
* @type {Batch}
* @private
*/
_batch: Batch;
}
/**
* Represents a batchable quad element.
* @extends BatchableElement
* @memberof rendering
*/
export interface BatchableQuadElement extends BatchableElement {
/**
* Indicates that this element should be packed as a quad.
* @type {true}
*/
packAsQuad: true;
/**
* The size of the attribute data for this quad element.
* @type {4}
*/
attributeSize: 4;
/**
* The size of the index data for this quad element.
* @type {6}
*/
indexSize: 6;
/**
* The bounds data for this quad element.
* @type {BoundsData}
*/
bounds: BoundsData;
}
/**
* Represents a batchable mesh element.
* @extends BatchableElement
* @memberof rendering
*/
export interface BatchableMeshElement extends BatchableElement {
/**
* The UV coordinates of the mesh.
* @type {number[] | Float32Array}
*/
uvs: number[] | Float32Array;
/**
* The vertex positions of the mesh.
* @type {number[] | Float32Array}
*/
positions: number[] | Float32Array;
/**
* The indices of the mesh.
* @type {number[] | Uint16Array | Uint32Array}
*/
indices: number[] | Uint16Array | Uint32Array;
/**
* The offset in the index buffer.
* @type {number}
*/
indexOffset: number;
/**
* The offset in the attribute buffer.
* @type {number}
*/
attributeOffset: number;
/**
* Indicates that this element should not be packed as a quad.
* @type {false}
*/
packAsQuad: false;
}
/**
* The options for the batcher.
* @memberof rendering
*/
export interface BatcherOptions {
/** The maximum number of textures per batch. */
maxTextures?: number;
attributesInitialSize?: number;
indicesInitialSize?: number;
}
/**
* A batcher is used to batch together objects with the same texture.
* It is an abstract class that must be extended. see DefaultBatcher for an example.
* @memberof rendering
*/
export declare abstract class Batcher {
static defaultOptions: Partial<BatcherOptions>;
/** unique id for this batcher */
readonly uid: number;
/** The buffer containing attribute data for all elements in the batch. */
attributeBuffer: ViewableBuffer;
/** The buffer containing index data for all elements in the batch. */
indexBuffer: IndexBufferArray;
/** The current size of the attribute data in the batch. */
attributeSize: number;
/** The current size of the index data in the batch. */
indexSize: number;
/** The total number of elements currently in the batch. */
elementSize: number;
/** The starting index of elements in the current batch. */
elementStart: number;
/** Indicates whether the batch data has been modified and needs updating. */
dirty: boolean;
/** The current index of the batch being processed. */
batchIndex: number;
/** An array of all batches created during the current rendering process. */
batches: Batch[];
private _elements;
private _batchIndexStart;
private _batchIndexSize;
/** The maximum number of textures per batch. */
readonly maxTextures: number;
/** The name of the batcher. Must be implemented by subclasses. */
abstract name: string;
/** The vertex size of the batcher. Must be implemented by subclasses. */
protected abstract vertexSize: number;
/** The geometry used by this batcher. Must be implemented by subclasses. */
abstract geometry: Geometry;
/**
* The shader used by this batcher. Must be implemented by subclasses.
* this can be shared by multiple batchers of the same type.
*/
abstract shader: Shader;
/**
* Packs the attributes of a BatchableMeshElement into the provided views.
* Must be implemented by subclasses.
* @param element - The BatchableMeshElement to pack.
* @param float32View - The Float32Array view to pack into.
* @param uint32View - The Uint32Array view to pack into.
* @param index - The starting index in the views.
* @param textureId - The texture ID to use.
*/
abstract packAttributes(element: BatchableMeshElement, float32View: Float32Array, uint32View: Uint32Array, index: number, textureId: number): void;
/**
* Packs the attributes of a BatchableQuadElement into the provided views.
* Must be implemented by subclasses.
* @param element - The BatchableQuadElement to pack.
* @param float32View - The Float32Array view to pack into.
* @param uint32View - The Uint32Array view to pack into.
* @param index - The starting index in the views.
* @param textureId - The texture ID to use.
*/
abstract packQuadAttributes(element: BatchableQuadElement, float32View: Float32Array, uint32View: Uint32Array, index: number, textureId: number): void;
constructor(options?: BatcherOptions);
begin(): void;
add(batchableObject: BatchableElement): void;
checkAndUpdateTexture(batchableObject: BatchableElement, texture: Texture): boolean;
updateElement(batchableObject: BatchableElement): void;
/**
* breaks the batcher. This happens when a batch gets too big,
* or we need to switch to a different type of rendering (a filter for example)
* @param instructionSet
*/
break(instructionSet: InstructionSet): void;
private _finishBatch;
finish(instructionSet: InstructionSet): void;
/**
* Resizes the attribute buffer to the given size (1 = 1 float32)
* @param size - the size in vertices to ensure (not bytes!)
*/
ensureAttributeBuffer(size: number): void;
/**
* Resizes the index buffer to the given size (1 = 1 float32)
* @param size - the size in vertices to ensure (not bytes!)
*/
ensureIndexBuffer(size: number): void;
private _resizeAttributeBuffer;
private _resizeIndexBuffer;
packQuadIndex(indexBuffer: IndexBufferArray, index: number, indicesOffset: number): void;
packIndex(element: BatchableMeshElement, indexBuffer: IndexBufferArray, index: number, indicesOffset: number): void;
destroy(): void;
}

View File

@@ -0,0 +1,341 @@
'use strict';
var uid = require('../../../utils/data/uid.js');
var ViewableBuffer = require('../../../utils/data/ViewableBuffer.js');
var fastCopy = require('../../renderers/shared/buffer/utils/fastCopy.js');
var getAdjustedBlendModeBlend = require('../../renderers/shared/state/getAdjustedBlendModeBlend.js');
var maxRecommendedTextures = require('../gl/utils/maxRecommendedTextures.js');
var BatchTextureArray = require('./BatchTextureArray.js');
"use strict";
class Batch {
constructor() {
this.renderPipeId = "batch";
this.action = "startBatch";
// TODO - eventually this could be useful for flagging batches as dirty and then only rebuilding those ones
// public elementStart = 0;
// public elementSize = 0;
// for drawing..
this.start = 0;
this.size = 0;
this.textures = new BatchTextureArray.BatchTextureArray();
this.blendMode = "normal";
this.canBundle = true;
}
destroy() {
this.textures = null;
this.gpuBindGroup = null;
this.bindGroup = null;
this.batcher = null;
}
}
const batchPool = [];
let batchPoolIndex = 0;
function getBatchFromPool() {
return batchPoolIndex > 0 ? batchPool[--batchPoolIndex] : new Batch();
}
function returnBatchToPool(batch) {
batchPool[batchPoolIndex++] = batch;
}
let BATCH_TICK = 0;
const _Batcher = class _Batcher {
constructor(options = {}) {
/** unique id for this batcher */
this.uid = uid.uid("batcher");
/** Indicates whether the batch data has been modified and needs updating. */
this.dirty = true;
/** The current index of the batch being processed. */
this.batchIndex = 0;
/** An array of all batches created during the current rendering process. */
this.batches = [];
this._elements = [];
_Batcher.defaultOptions.maxTextures = _Batcher.defaultOptions.maxTextures ?? maxRecommendedTextures.getMaxTexturesPerBatch();
options = { ..._Batcher.defaultOptions, ...options };
const { maxTextures, attributesInitialSize, indicesInitialSize } = options;
this.attributeBuffer = new ViewableBuffer.ViewableBuffer(attributesInitialSize * 4);
this.indexBuffer = new Uint16Array(indicesInitialSize);
this.maxTextures = maxTextures;
}
begin() {
this.elementSize = 0;
this.elementStart = 0;
this.indexSize = 0;
this.attributeSize = 0;
for (let i = 0; i < this.batchIndex; i++) {
returnBatchToPool(this.batches[i]);
}
this.batchIndex = 0;
this._batchIndexStart = 0;
this._batchIndexSize = 0;
this.dirty = true;
}
add(batchableObject) {
this._elements[this.elementSize++] = batchableObject;
batchableObject._indexStart = this.indexSize;
batchableObject._attributeStart = this.attributeSize;
batchableObject._batcher = this;
this.indexSize += batchableObject.indexSize;
this.attributeSize += batchableObject.attributeSize * this.vertexSize;
}
checkAndUpdateTexture(batchableObject, texture) {
const textureId = batchableObject._batch.textures.ids[texture._source.uid];
if (!textureId && textureId !== 0)
return false;
batchableObject._textureId = textureId;
batchableObject.texture = texture;
return true;
}
updateElement(batchableObject) {
this.dirty = true;
const attributeBuffer = this.attributeBuffer;
if (batchableObject.packAsQuad) {
this.packQuadAttributes(
batchableObject,
attributeBuffer.float32View,
attributeBuffer.uint32View,
batchableObject._attributeStart,
batchableObject._textureId
);
} else {
this.packAttributes(
batchableObject,
attributeBuffer.float32View,
attributeBuffer.uint32View,
batchableObject._attributeStart,
batchableObject._textureId
);
}
}
/**
* breaks the batcher. This happens when a batch gets too big,
* or we need to switch to a different type of rendering (a filter for example)
* @param instructionSet
*/
break(instructionSet) {
const elements = this._elements;
if (!elements[this.elementStart])
return;
let batch = getBatchFromPool();
let textureBatch = batch.textures;
textureBatch.clear();
const firstElement = elements[this.elementStart];
let blendMode = getAdjustedBlendModeBlend.getAdjustedBlendModeBlend(firstElement.blendMode, firstElement.texture._source);
if (this.attributeSize * 4 > this.attributeBuffer.size) {
this._resizeAttributeBuffer(this.attributeSize * 4);
}
if (this.indexSize > this.indexBuffer.length) {
this._resizeIndexBuffer(this.indexSize);
}
const f32 = this.attributeBuffer.float32View;
const u32 = this.attributeBuffer.uint32View;
const indexBuffer = this.indexBuffer;
let size = this._batchIndexSize;
let start = this._batchIndexStart;
let action = "startBatch";
const maxTextures = this.maxTextures;
for (let i = this.elementStart; i < this.elementSize; ++i) {
const element = elements[i];
elements[i] = null;
const texture = element.texture;
const source = texture._source;
const adjustedBlendMode = getAdjustedBlendModeBlend.getAdjustedBlendModeBlend(element.blendMode, source);
const breakRequired = blendMode !== adjustedBlendMode;
if (source._batchTick === BATCH_TICK && !breakRequired) {
element._textureId = source._textureBindLocation;
size += element.indexSize;
if (element.packAsQuad) {
this.packQuadAttributes(
element,
f32,
u32,
element._attributeStart,
element._textureId
);
this.packQuadIndex(
indexBuffer,
element._indexStart,
element._attributeStart / this.vertexSize
);
} else {
this.packAttributes(
element,
f32,
u32,
element._attributeStart,
element._textureId
);
this.packIndex(
element,
indexBuffer,
element._indexStart,
element._attributeStart / this.vertexSize
);
}
element._batch = batch;
continue;
}
source._batchTick = BATCH_TICK;
if (textureBatch.count >= maxTextures || breakRequired) {
this._finishBatch(
batch,
start,
size - start,
textureBatch,
blendMode,
instructionSet,
action
);
action = "renderBatch";
start = size;
blendMode = adjustedBlendMode;
batch = getBatchFromPool();
textureBatch = batch.textures;
textureBatch.clear();
++BATCH_TICK;
}
element._textureId = source._textureBindLocation = textureBatch.count;
textureBatch.ids[source.uid] = textureBatch.count;
textureBatch.textures[textureBatch.count++] = source;
element._batch = batch;
size += element.indexSize;
if (element.packAsQuad) {
this.packQuadAttributes(
element,
f32,
u32,
element._attributeStart,
element._textureId
);
this.packQuadIndex(
indexBuffer,
element._indexStart,
element._attributeStart / this.vertexSize
);
} else {
this.packAttributes(
element,
f32,
u32,
element._attributeStart,
element._textureId
);
this.packIndex(
element,
indexBuffer,
element._indexStart,
element._attributeStart / this.vertexSize
);
}
}
if (textureBatch.count > 0) {
this._finishBatch(
batch,
start,
size - start,
textureBatch,
blendMode,
instructionSet,
action
);
start = size;
++BATCH_TICK;
}
this.elementStart = this.elementSize;
this._batchIndexStart = start;
this._batchIndexSize = size;
}
_finishBatch(batch, indexStart, indexSize, textureBatch, blendMode, instructionSet, action) {
batch.gpuBindGroup = null;
batch.bindGroup = null;
batch.action = action;
batch.batcher = this;
batch.textures = textureBatch;
batch.blendMode = blendMode;
batch.start = indexStart;
batch.size = indexSize;
++BATCH_TICK;
this.batches[this.batchIndex++] = batch;
instructionSet.add(batch);
}
finish(instructionSet) {
this.break(instructionSet);
}
/**
* Resizes the attribute buffer to the given size (1 = 1 float32)
* @param size - the size in vertices to ensure (not bytes!)
*/
ensureAttributeBuffer(size) {
if (size * 4 <= this.attributeBuffer.size)
return;
this._resizeAttributeBuffer(size * 4);
}
/**
* Resizes the index buffer to the given size (1 = 1 float32)
* @param size - the size in vertices to ensure (not bytes!)
*/
ensureIndexBuffer(size) {
if (size <= this.indexBuffer.length)
return;
this._resizeIndexBuffer(size);
}
_resizeAttributeBuffer(size) {
const newSize = Math.max(size, this.attributeBuffer.size * 2);
const newArrayBuffer = new ViewableBuffer.ViewableBuffer(newSize);
fastCopy.fastCopy(this.attributeBuffer.rawBinaryData, newArrayBuffer.rawBinaryData);
this.attributeBuffer = newArrayBuffer;
}
_resizeIndexBuffer(size) {
const indexBuffer = this.indexBuffer;
let newSize = Math.max(size, indexBuffer.length * 1.5);
newSize += newSize % 2;
const newIndexBuffer = newSize > 65535 ? new Uint32Array(newSize) : new Uint16Array(newSize);
if (newIndexBuffer.BYTES_PER_ELEMENT !== indexBuffer.BYTES_PER_ELEMENT) {
for (let i = 0; i < indexBuffer.length; i++) {
newIndexBuffer[i] = indexBuffer[i];
}
} else {
fastCopy.fastCopy(indexBuffer.buffer, newIndexBuffer.buffer);
}
this.indexBuffer = newIndexBuffer;
}
packQuadIndex(indexBuffer, index, indicesOffset) {
indexBuffer[index] = indicesOffset + 0;
indexBuffer[index + 1] = indicesOffset + 1;
indexBuffer[index + 2] = indicesOffset + 2;
indexBuffer[index + 3] = indicesOffset + 0;
indexBuffer[index + 4] = indicesOffset + 2;
indexBuffer[index + 5] = indicesOffset + 3;
}
packIndex(element, indexBuffer, index, indicesOffset) {
const indices = element.indices;
const size = element.indexSize;
const indexOffset = element.indexOffset;
const attributeOffset = element.attributeOffset;
for (let i = 0; i < size; i++) {
indexBuffer[index++] = indicesOffset + indices[i + indexOffset] - attributeOffset;
}
}
destroy() {
for (let i = 0; i < this.batches.length; i++) {
returnBatchToPool(this.batches[i]);
}
this.batches = null;
for (let i = 0; i < this._elements.length; i++) {
this._elements[i]._batch = null;
}
this._elements = null;
this.indexBuffer = null;
this.attributeBuffer.destroy();
this.attributeBuffer = null;
}
};
_Batcher.defaultOptions = {
maxTextures: null,
attributesInitialSize: 4,
indicesInitialSize: 6
};
let Batcher = _Batcher;
exports.Batch = Batch;
exports.Batcher = Batcher;
//# sourceMappingURL=Batcher.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,338 @@
import { uid } from '../../../utils/data/uid.mjs';
import { ViewableBuffer } from '../../../utils/data/ViewableBuffer.mjs';
import { fastCopy } from '../../renderers/shared/buffer/utils/fastCopy.mjs';
import { getAdjustedBlendModeBlend } from '../../renderers/shared/state/getAdjustedBlendModeBlend.mjs';
import { getMaxTexturesPerBatch } from '../gl/utils/maxRecommendedTextures.mjs';
import { BatchTextureArray } from './BatchTextureArray.mjs';
"use strict";
class Batch {
constructor() {
this.renderPipeId = "batch";
this.action = "startBatch";
// TODO - eventually this could be useful for flagging batches as dirty and then only rebuilding those ones
// public elementStart = 0;
// public elementSize = 0;
// for drawing..
this.start = 0;
this.size = 0;
this.textures = new BatchTextureArray();
this.blendMode = "normal";
this.canBundle = true;
}
destroy() {
this.textures = null;
this.gpuBindGroup = null;
this.bindGroup = null;
this.batcher = null;
}
}
const batchPool = [];
let batchPoolIndex = 0;
function getBatchFromPool() {
return batchPoolIndex > 0 ? batchPool[--batchPoolIndex] : new Batch();
}
function returnBatchToPool(batch) {
batchPool[batchPoolIndex++] = batch;
}
let BATCH_TICK = 0;
const _Batcher = class _Batcher {
constructor(options = {}) {
/** unique id for this batcher */
this.uid = uid("batcher");
/** Indicates whether the batch data has been modified and needs updating. */
this.dirty = true;
/** The current index of the batch being processed. */
this.batchIndex = 0;
/** An array of all batches created during the current rendering process. */
this.batches = [];
this._elements = [];
_Batcher.defaultOptions.maxTextures = _Batcher.defaultOptions.maxTextures ?? getMaxTexturesPerBatch();
options = { ..._Batcher.defaultOptions, ...options };
const { maxTextures, attributesInitialSize, indicesInitialSize } = options;
this.attributeBuffer = new ViewableBuffer(attributesInitialSize * 4);
this.indexBuffer = new Uint16Array(indicesInitialSize);
this.maxTextures = maxTextures;
}
begin() {
this.elementSize = 0;
this.elementStart = 0;
this.indexSize = 0;
this.attributeSize = 0;
for (let i = 0; i < this.batchIndex; i++) {
returnBatchToPool(this.batches[i]);
}
this.batchIndex = 0;
this._batchIndexStart = 0;
this._batchIndexSize = 0;
this.dirty = true;
}
add(batchableObject) {
this._elements[this.elementSize++] = batchableObject;
batchableObject._indexStart = this.indexSize;
batchableObject._attributeStart = this.attributeSize;
batchableObject._batcher = this;
this.indexSize += batchableObject.indexSize;
this.attributeSize += batchableObject.attributeSize * this.vertexSize;
}
checkAndUpdateTexture(batchableObject, texture) {
const textureId = batchableObject._batch.textures.ids[texture._source.uid];
if (!textureId && textureId !== 0)
return false;
batchableObject._textureId = textureId;
batchableObject.texture = texture;
return true;
}
updateElement(batchableObject) {
this.dirty = true;
const attributeBuffer = this.attributeBuffer;
if (batchableObject.packAsQuad) {
this.packQuadAttributes(
batchableObject,
attributeBuffer.float32View,
attributeBuffer.uint32View,
batchableObject._attributeStart,
batchableObject._textureId
);
} else {
this.packAttributes(
batchableObject,
attributeBuffer.float32View,
attributeBuffer.uint32View,
batchableObject._attributeStart,
batchableObject._textureId
);
}
}
/**
* breaks the batcher. This happens when a batch gets too big,
* or we need to switch to a different type of rendering (a filter for example)
* @param instructionSet
*/
break(instructionSet) {
const elements = this._elements;
if (!elements[this.elementStart])
return;
let batch = getBatchFromPool();
let textureBatch = batch.textures;
textureBatch.clear();
const firstElement = elements[this.elementStart];
let blendMode = getAdjustedBlendModeBlend(firstElement.blendMode, firstElement.texture._source);
if (this.attributeSize * 4 > this.attributeBuffer.size) {
this._resizeAttributeBuffer(this.attributeSize * 4);
}
if (this.indexSize > this.indexBuffer.length) {
this._resizeIndexBuffer(this.indexSize);
}
const f32 = this.attributeBuffer.float32View;
const u32 = this.attributeBuffer.uint32View;
const indexBuffer = this.indexBuffer;
let size = this._batchIndexSize;
let start = this._batchIndexStart;
let action = "startBatch";
const maxTextures = this.maxTextures;
for (let i = this.elementStart; i < this.elementSize; ++i) {
const element = elements[i];
elements[i] = null;
const texture = element.texture;
const source = texture._source;
const adjustedBlendMode = getAdjustedBlendModeBlend(element.blendMode, source);
const breakRequired = blendMode !== adjustedBlendMode;
if (source._batchTick === BATCH_TICK && !breakRequired) {
element._textureId = source._textureBindLocation;
size += element.indexSize;
if (element.packAsQuad) {
this.packQuadAttributes(
element,
f32,
u32,
element._attributeStart,
element._textureId
);
this.packQuadIndex(
indexBuffer,
element._indexStart,
element._attributeStart / this.vertexSize
);
} else {
this.packAttributes(
element,
f32,
u32,
element._attributeStart,
element._textureId
);
this.packIndex(
element,
indexBuffer,
element._indexStart,
element._attributeStart / this.vertexSize
);
}
element._batch = batch;
continue;
}
source._batchTick = BATCH_TICK;
if (textureBatch.count >= maxTextures || breakRequired) {
this._finishBatch(
batch,
start,
size - start,
textureBatch,
blendMode,
instructionSet,
action
);
action = "renderBatch";
start = size;
blendMode = adjustedBlendMode;
batch = getBatchFromPool();
textureBatch = batch.textures;
textureBatch.clear();
++BATCH_TICK;
}
element._textureId = source._textureBindLocation = textureBatch.count;
textureBatch.ids[source.uid] = textureBatch.count;
textureBatch.textures[textureBatch.count++] = source;
element._batch = batch;
size += element.indexSize;
if (element.packAsQuad) {
this.packQuadAttributes(
element,
f32,
u32,
element._attributeStart,
element._textureId
);
this.packQuadIndex(
indexBuffer,
element._indexStart,
element._attributeStart / this.vertexSize
);
} else {
this.packAttributes(
element,
f32,
u32,
element._attributeStart,
element._textureId
);
this.packIndex(
element,
indexBuffer,
element._indexStart,
element._attributeStart / this.vertexSize
);
}
}
if (textureBatch.count > 0) {
this._finishBatch(
batch,
start,
size - start,
textureBatch,
blendMode,
instructionSet,
action
);
start = size;
++BATCH_TICK;
}
this.elementStart = this.elementSize;
this._batchIndexStart = start;
this._batchIndexSize = size;
}
_finishBatch(batch, indexStart, indexSize, textureBatch, blendMode, instructionSet, action) {
batch.gpuBindGroup = null;
batch.bindGroup = null;
batch.action = action;
batch.batcher = this;
batch.textures = textureBatch;
batch.blendMode = blendMode;
batch.start = indexStart;
batch.size = indexSize;
++BATCH_TICK;
this.batches[this.batchIndex++] = batch;
instructionSet.add(batch);
}
finish(instructionSet) {
this.break(instructionSet);
}
/**
* Resizes the attribute buffer to the given size (1 = 1 float32)
* @param size - the size in vertices to ensure (not bytes!)
*/
ensureAttributeBuffer(size) {
if (size * 4 <= this.attributeBuffer.size)
return;
this._resizeAttributeBuffer(size * 4);
}
/**
* Resizes the index buffer to the given size (1 = 1 float32)
* @param size - the size in vertices to ensure (not bytes!)
*/
ensureIndexBuffer(size) {
if (size <= this.indexBuffer.length)
return;
this._resizeIndexBuffer(size);
}
_resizeAttributeBuffer(size) {
const newSize = Math.max(size, this.attributeBuffer.size * 2);
const newArrayBuffer = new ViewableBuffer(newSize);
fastCopy(this.attributeBuffer.rawBinaryData, newArrayBuffer.rawBinaryData);
this.attributeBuffer = newArrayBuffer;
}
_resizeIndexBuffer(size) {
const indexBuffer = this.indexBuffer;
let newSize = Math.max(size, indexBuffer.length * 1.5);
newSize += newSize % 2;
const newIndexBuffer = newSize > 65535 ? new Uint32Array(newSize) : new Uint16Array(newSize);
if (newIndexBuffer.BYTES_PER_ELEMENT !== indexBuffer.BYTES_PER_ELEMENT) {
for (let i = 0; i < indexBuffer.length; i++) {
newIndexBuffer[i] = indexBuffer[i];
}
} else {
fastCopy(indexBuffer.buffer, newIndexBuffer.buffer);
}
this.indexBuffer = newIndexBuffer;
}
packQuadIndex(indexBuffer, index, indicesOffset) {
indexBuffer[index] = indicesOffset + 0;
indexBuffer[index + 1] = indicesOffset + 1;
indexBuffer[index + 2] = indicesOffset + 2;
indexBuffer[index + 3] = indicesOffset + 0;
indexBuffer[index + 4] = indicesOffset + 2;
indexBuffer[index + 5] = indicesOffset + 3;
}
packIndex(element, indexBuffer, index, indicesOffset) {
const indices = element.indices;
const size = element.indexSize;
const indexOffset = element.indexOffset;
const attributeOffset = element.attributeOffset;
for (let i = 0; i < size; i++) {
indexBuffer[index++] = indicesOffset + indices[i + indexOffset] - attributeOffset;
}
}
destroy() {
for (let i = 0; i < this.batches.length; i++) {
returnBatchToPool(this.batches[i]);
}
this.batches = null;
for (let i = 0; i < this._elements.length; i++) {
this._elements[i]._batch = null;
}
this._elements = null;
this.indexBuffer = null;
this.attributeBuffer.destroy();
this.attributeBuffer = null;
}
};
_Batcher.defaultOptions = {
maxTextures: null,
attributesInitialSize: 4,
indicesInitialSize: 6
};
let Batcher = _Batcher;
export { Batch, Batcher };
//# sourceMappingURL=Batcher.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,46 @@
import { ExtensionType } from '../../../extensions/Extensions';
import { State } from '../../renderers/shared/state/State';
import type { Geometry } from '../../renderers/shared/geometry/Geometry';
import type { InstructionSet } from '../../renderers/shared/instructions/InstructionSet';
import type { BatchPipe, InstructionPipe } from '../../renderers/shared/instructions/RenderPipe';
import type { Shader } from '../../renderers/shared/shader/Shader';
import type { Renderer } from '../../renderers/types';
import type { Batch, BatchableElement, Batcher } from './Batcher';
export interface BatcherAdaptor {
start(batchPipe: BatcherPipe, geometry: Geometry, shader: Shader): void;
init?(batchPipe: BatcherPipe): void;
execute(batchPipe: BatcherPipe, batch: Batch): void;
contextChange?(): void;
}
/**
* A pipe that batches elements into batches and sends them to the renderer.
*
* You can install new Batchers using ExtensionType.Batcher. Each render group will
* have a default batcher and any required ones will be created on demand.
* @memberof rendering
*/
export declare class BatcherPipe implements InstructionPipe<Batch>, BatchPipe {
/** @ignore */
static extension: {
readonly type: readonly [ExtensionType.WebGLPipes, ExtensionType.WebGPUPipes, ExtensionType.CanvasPipes];
readonly name: "batch";
};
state: State;
renderer: Renderer;
private readonly _batchersByInstructionSet;
private _adaptor;
/** A record of all active batchers, keyed by their names */
private _activeBatches;
/** The currently active batcher being used to batch elements */
private _activeBatch;
static _availableBatchers: Record<string, new () => Batcher>;
static getBatcher(name: string): Batcher;
constructor(renderer: Renderer, adaptor: BatcherAdaptor);
buildStart(instructionSet: InstructionSet): void;
addToBatch(batchableObject: BatchableElement, instructionSet: InstructionSet): void;
break(instructionSet: InstructionSet): void;
buildEnd(instructionSet: InstructionSet): void;
upload(instructionSet: InstructionSet): void;
execute(batch: Batch): void;
destroy(): void;
}

View File

@@ -0,0 +1,103 @@
'use strict';
var Extensions = require('../../../extensions/Extensions.js');
var State = require('../../renderers/shared/state/State.js');
var DefaultBatcher = require('./DefaultBatcher.js');
"use strict";
const _BatcherPipe = class _BatcherPipe {
constructor(renderer, adaptor) {
this.state = State.State.for2d();
this._batchersByInstructionSet = /* @__PURE__ */ Object.create(null);
/** A record of all active batchers, keyed by their names */
this._activeBatches = /* @__PURE__ */ Object.create(null);
this.renderer = renderer;
this._adaptor = adaptor;
this._adaptor.init?.(this);
}
static getBatcher(name) {
return new this._availableBatchers[name]();
}
buildStart(instructionSet) {
let batchers = this._batchersByInstructionSet[instructionSet.uid];
if (!batchers) {
batchers = this._batchersByInstructionSet[instructionSet.uid] = /* @__PURE__ */ Object.create(null);
batchers.default || (batchers.default = new DefaultBatcher.DefaultBatcher());
}
this._activeBatches = batchers;
this._activeBatch = this._activeBatches.default;
for (const i in this._activeBatches) {
this._activeBatches[i].begin();
}
}
addToBatch(batchableObject, instructionSet) {
if (this._activeBatch.name !== batchableObject.batcherName) {
this._activeBatch.break(instructionSet);
let batch = this._activeBatches[batchableObject.batcherName];
if (!batch) {
batch = this._activeBatches[batchableObject.batcherName] = _BatcherPipe.getBatcher(batchableObject.batcherName);
batch.begin();
}
this._activeBatch = batch;
}
this._activeBatch.add(batchableObject);
}
break(instructionSet) {
this._activeBatch.break(instructionSet);
}
buildEnd(instructionSet) {
this._activeBatch.break(instructionSet);
const batches = this._activeBatches;
for (const i in batches) {
const batch = batches[i];
const geometry = batch.geometry;
geometry.indexBuffer.setDataWithSize(batch.indexBuffer, batch.indexSize, true);
geometry.buffers[0].setDataWithSize(batch.attributeBuffer.float32View, batch.attributeSize, false);
}
}
upload(instructionSet) {
const batchers = this._batchersByInstructionSet[instructionSet.uid];
for (const i in batchers) {
const batcher = batchers[i];
const geometry = batcher.geometry;
if (batcher.dirty) {
batcher.dirty = false;
geometry.buffers[0].update(batcher.attributeSize * 4);
}
}
}
execute(batch) {
if (batch.action === "startBatch") {
const batcher = batch.batcher;
const geometry = batcher.geometry;
const shader = batcher.shader;
this._adaptor.start(this, geometry, shader);
}
this._adaptor.execute(this, batch);
}
destroy() {
this.state = null;
this.renderer = null;
this._adaptor = null;
for (const i in this._activeBatches) {
this._activeBatches[i].destroy();
}
this._activeBatches = null;
}
};
/** @ignore */
_BatcherPipe.extension = {
type: [
Extensions.ExtensionType.WebGLPipes,
Extensions.ExtensionType.WebGPUPipes,
Extensions.ExtensionType.CanvasPipes
],
name: "batch"
};
_BatcherPipe._availableBatchers = /* @__PURE__ */ Object.create(null);
let BatcherPipe = _BatcherPipe;
Extensions.extensions.handleByMap(Extensions.ExtensionType.Batcher, BatcherPipe._availableBatchers);
Extensions.extensions.add(DefaultBatcher.DefaultBatcher);
exports.BatcherPipe = BatcherPipe;
//# sourceMappingURL=BatcherPipe.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,101 @@
import { ExtensionType, extensions } from '../../../extensions/Extensions.mjs';
import { State } from '../../renderers/shared/state/State.mjs';
import { DefaultBatcher } from './DefaultBatcher.mjs';
"use strict";
const _BatcherPipe = class _BatcherPipe {
constructor(renderer, adaptor) {
this.state = State.for2d();
this._batchersByInstructionSet = /* @__PURE__ */ Object.create(null);
/** A record of all active batchers, keyed by their names */
this._activeBatches = /* @__PURE__ */ Object.create(null);
this.renderer = renderer;
this._adaptor = adaptor;
this._adaptor.init?.(this);
}
static getBatcher(name) {
return new this._availableBatchers[name]();
}
buildStart(instructionSet) {
let batchers = this._batchersByInstructionSet[instructionSet.uid];
if (!batchers) {
batchers = this._batchersByInstructionSet[instructionSet.uid] = /* @__PURE__ */ Object.create(null);
batchers.default || (batchers.default = new DefaultBatcher());
}
this._activeBatches = batchers;
this._activeBatch = this._activeBatches.default;
for (const i in this._activeBatches) {
this._activeBatches[i].begin();
}
}
addToBatch(batchableObject, instructionSet) {
if (this._activeBatch.name !== batchableObject.batcherName) {
this._activeBatch.break(instructionSet);
let batch = this._activeBatches[batchableObject.batcherName];
if (!batch) {
batch = this._activeBatches[batchableObject.batcherName] = _BatcherPipe.getBatcher(batchableObject.batcherName);
batch.begin();
}
this._activeBatch = batch;
}
this._activeBatch.add(batchableObject);
}
break(instructionSet) {
this._activeBatch.break(instructionSet);
}
buildEnd(instructionSet) {
this._activeBatch.break(instructionSet);
const batches = this._activeBatches;
for (const i in batches) {
const batch = batches[i];
const geometry = batch.geometry;
geometry.indexBuffer.setDataWithSize(batch.indexBuffer, batch.indexSize, true);
geometry.buffers[0].setDataWithSize(batch.attributeBuffer.float32View, batch.attributeSize, false);
}
}
upload(instructionSet) {
const batchers = this._batchersByInstructionSet[instructionSet.uid];
for (const i in batchers) {
const batcher = batchers[i];
const geometry = batcher.geometry;
if (batcher.dirty) {
batcher.dirty = false;
geometry.buffers[0].update(batcher.attributeSize * 4);
}
}
}
execute(batch) {
if (batch.action === "startBatch") {
const batcher = batch.batcher;
const geometry = batcher.geometry;
const shader = batcher.shader;
this._adaptor.start(this, geometry, shader);
}
this._adaptor.execute(this, batch);
}
destroy() {
this.state = null;
this.renderer = null;
this._adaptor = null;
for (const i in this._activeBatches) {
this._activeBatches[i].destroy();
}
this._activeBatches = null;
}
};
/** @ignore */
_BatcherPipe.extension = {
type: [
ExtensionType.WebGLPipes,
ExtensionType.WebGPUPipes,
ExtensionType.CanvasPipes
],
name: "batch"
};
_BatcherPipe._availableBatchers = /* @__PURE__ */ Object.create(null);
let BatcherPipe = _BatcherPipe;
extensions.handleByMap(ExtensionType.Batcher, BatcherPipe._availableBatchers);
extensions.add(DefaultBatcher);
export { BatcherPipe };
//# sourceMappingURL=BatcherPipe.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
import { ExtensionType } from '../../../extensions/Extensions';
import { Batcher } from './Batcher';
import { BatchGeometry } from './BatchGeometry';
import type { Matrix } from '../../../maths/matrix/Matrix';
import type { Shader } from '../../renderers/shared/shader/Shader';
import type { BatchableMeshElement, BatchableQuadElement } from './Batcher';
/**
* Represents the common elements for default batch rendering.
* This interface defines the properties that are used by the DefaultBatcher
* to render elements efficiently in a batch.
* @memberof rendering
*/
export interface DefaultBatchElements {
/**
* The color of the element that will be multiplied with the texture color.
* This is typically represented as a 32-bit integer in RGBA format.
*/
color: number;
/**
* Determines whether the element should be rounded to the nearest pixel.
* - 0: No rounding (default)
* - 1: Round to nearest pixel
* This can help with visual consistency, especially for pixel art styles.
*/
roundPixels: 0 | 1;
/**
* The transform matrix of the element.
* This matrix represents the position, scale, rotation, and skew of the element.
*/
transform: Matrix;
}
/**
* Represents a batchable quad element with default batch properties.
* @memberof rendering
*/
export interface DefaultBatchableQuadElement extends BatchableQuadElement, DefaultBatchElements {
}
/**
* Represents a batchable mesh element with default batch properties.
* @memberof rendering
*/
export interface DefaultBatchableMeshElement extends BatchableMeshElement, DefaultBatchElements {
}
/**
* The default batcher is used to batch quads and meshes. This batcher will batch the following elements:
* - tints
* - roundPixels
* - texture
* - transform
* @memberof rendering
*/
export declare class DefaultBatcher extends Batcher {
/** @ignore */
static extension: {
readonly type: readonly [ExtensionType.Batcher];
readonly name: "default";
};
geometry: BatchGeometry;
shader: Shader;
name: "default";
/** The size of one attribute. 1 = 32 bit. x, y, u, v, color, textureIdAndRound -> total = 6 */
vertexSize: number;
/**
* Packs the attributes of a DefaultBatchableMeshElement into the provided views.
* @param element - The DefaultBatchableMeshElement to pack.
* @param float32View - The Float32Array view to pack into.
* @param uint32View - The Uint32Array view to pack into.
* @param index - The starting index in the views.
* @param textureId - The texture ID to use.
*/
packAttributes(element: DefaultBatchableMeshElement, float32View: Float32Array, uint32View: Uint32Array, index: number, textureId: number): void;
/**
* Packs the attributes of a DefaultBatchableQuadElement into the provided views.
* @param element - The DefaultBatchableQuadElement to pack.
* @param float32View - The Float32Array view to pack into.
* @param uint32View - The Uint32Array view to pack into.
* @param index - The starting index in the views.
* @param textureId - The texture ID to use.
*/
packQuadAttributes(element: DefaultBatchableQuadElement, float32View: Float32Array, uint32View: Uint32Array, index: number, textureId: number): void;
}

View File

@@ -0,0 +1,113 @@
'use strict';
var Extensions = require('../../../extensions/Extensions.js');
var Batcher = require('./Batcher.js');
var BatchGeometry = require('./BatchGeometry.js');
var DefaultShader = require('./DefaultShader.js');
"use strict";
let defaultShader = null;
const _DefaultBatcher = class _DefaultBatcher extends Batcher.Batcher {
constructor() {
super(...arguments);
this.geometry = new BatchGeometry.BatchGeometry();
this.shader = defaultShader || (defaultShader = new DefaultShader.DefaultShader(this.maxTextures));
this.name = _DefaultBatcher.extension.name;
/** The size of one attribute. 1 = 32 bit. x, y, u, v, color, textureIdAndRound -> total = 6 */
this.vertexSize = 6;
}
/**
* Packs the attributes of a DefaultBatchableMeshElement into the provided views.
* @param element - The DefaultBatchableMeshElement to pack.
* @param float32View - The Float32Array view to pack into.
* @param uint32View - The Uint32Array view to pack into.
* @param index - The starting index in the views.
* @param textureId - The texture ID to use.
*/
packAttributes(element, float32View, uint32View, index, textureId) {
const textureIdAndRound = textureId << 16 | element.roundPixels & 65535;
const wt = element.transform;
const a = wt.a;
const b = wt.b;
const c = wt.c;
const d = wt.d;
const tx = wt.tx;
const ty = wt.ty;
const { positions, uvs } = element;
const argb = element.color;
const offset = element.attributeOffset;
const end = offset + element.attributeSize;
for (let i = offset; i < end; i++) {
const i2 = i * 2;
const x = positions[i2];
const y = positions[i2 + 1];
float32View[index++] = a * x + c * y + tx;
float32View[index++] = d * y + b * x + ty;
float32View[index++] = uvs[i2];
float32View[index++] = uvs[i2 + 1];
uint32View[index++] = argb;
uint32View[index++] = textureIdAndRound;
}
}
/**
* Packs the attributes of a DefaultBatchableQuadElement into the provided views.
* @param element - The DefaultBatchableQuadElement to pack.
* @param float32View - The Float32Array view to pack into.
* @param uint32View - The Uint32Array view to pack into.
* @param index - The starting index in the views.
* @param textureId - The texture ID to use.
*/
packQuadAttributes(element, float32View, uint32View, index, textureId) {
const texture = element.texture;
const wt = element.transform;
const a = wt.a;
const b = wt.b;
const c = wt.c;
const d = wt.d;
const tx = wt.tx;
const ty = wt.ty;
const bounds = element.bounds;
const w0 = bounds.maxX;
const w1 = bounds.minX;
const h0 = bounds.maxY;
const h1 = bounds.minY;
const uvs = texture.uvs;
const argb = element.color;
const textureIdAndRound = textureId << 16 | element.roundPixels & 65535;
float32View[index + 0] = a * w1 + c * h1 + tx;
float32View[index + 1] = d * h1 + b * w1 + ty;
float32View[index + 2] = uvs.x0;
float32View[index + 3] = uvs.y0;
uint32View[index + 4] = argb;
uint32View[index + 5] = textureIdAndRound;
float32View[index + 6] = a * w0 + c * h1 + tx;
float32View[index + 7] = d * h1 + b * w0 + ty;
float32View[index + 8] = uvs.x1;
float32View[index + 9] = uvs.y1;
uint32View[index + 10] = argb;
uint32View[index + 11] = textureIdAndRound;
float32View[index + 12] = a * w0 + c * h0 + tx;
float32View[index + 13] = d * h0 + b * w0 + ty;
float32View[index + 14] = uvs.x2;
float32View[index + 15] = uvs.y2;
uint32View[index + 16] = argb;
uint32View[index + 17] = textureIdAndRound;
float32View[index + 18] = a * w1 + c * h0 + tx;
float32View[index + 19] = d * h0 + b * w1 + ty;
float32View[index + 20] = uvs.x3;
float32View[index + 21] = uvs.y3;
uint32View[index + 22] = argb;
uint32View[index + 23] = textureIdAndRound;
}
};
/** @ignore */
_DefaultBatcher.extension = {
type: [
Extensions.ExtensionType.Batcher
],
name: "default"
};
let DefaultBatcher = _DefaultBatcher;
exports.DefaultBatcher = DefaultBatcher;
//# sourceMappingURL=DefaultBatcher.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,111 @@
import { ExtensionType } from '../../../extensions/Extensions.mjs';
import { Batcher } from './Batcher.mjs';
import { BatchGeometry } from './BatchGeometry.mjs';
import { DefaultShader } from './DefaultShader.mjs';
"use strict";
let defaultShader = null;
const _DefaultBatcher = class _DefaultBatcher extends Batcher {
constructor() {
super(...arguments);
this.geometry = new BatchGeometry();
this.shader = defaultShader || (defaultShader = new DefaultShader(this.maxTextures));
this.name = _DefaultBatcher.extension.name;
/** The size of one attribute. 1 = 32 bit. x, y, u, v, color, textureIdAndRound -> total = 6 */
this.vertexSize = 6;
}
/**
* Packs the attributes of a DefaultBatchableMeshElement into the provided views.
* @param element - The DefaultBatchableMeshElement to pack.
* @param float32View - The Float32Array view to pack into.
* @param uint32View - The Uint32Array view to pack into.
* @param index - The starting index in the views.
* @param textureId - The texture ID to use.
*/
packAttributes(element, float32View, uint32View, index, textureId) {
const textureIdAndRound = textureId << 16 | element.roundPixels & 65535;
const wt = element.transform;
const a = wt.a;
const b = wt.b;
const c = wt.c;
const d = wt.d;
const tx = wt.tx;
const ty = wt.ty;
const { positions, uvs } = element;
const argb = element.color;
const offset = element.attributeOffset;
const end = offset + element.attributeSize;
for (let i = offset; i < end; i++) {
const i2 = i * 2;
const x = positions[i2];
const y = positions[i2 + 1];
float32View[index++] = a * x + c * y + tx;
float32View[index++] = d * y + b * x + ty;
float32View[index++] = uvs[i2];
float32View[index++] = uvs[i2 + 1];
uint32View[index++] = argb;
uint32View[index++] = textureIdAndRound;
}
}
/**
* Packs the attributes of a DefaultBatchableQuadElement into the provided views.
* @param element - The DefaultBatchableQuadElement to pack.
* @param float32View - The Float32Array view to pack into.
* @param uint32View - The Uint32Array view to pack into.
* @param index - The starting index in the views.
* @param textureId - The texture ID to use.
*/
packQuadAttributes(element, float32View, uint32View, index, textureId) {
const texture = element.texture;
const wt = element.transform;
const a = wt.a;
const b = wt.b;
const c = wt.c;
const d = wt.d;
const tx = wt.tx;
const ty = wt.ty;
const bounds = element.bounds;
const w0 = bounds.maxX;
const w1 = bounds.minX;
const h0 = bounds.maxY;
const h1 = bounds.minY;
const uvs = texture.uvs;
const argb = element.color;
const textureIdAndRound = textureId << 16 | element.roundPixels & 65535;
float32View[index + 0] = a * w1 + c * h1 + tx;
float32View[index + 1] = d * h1 + b * w1 + ty;
float32View[index + 2] = uvs.x0;
float32View[index + 3] = uvs.y0;
uint32View[index + 4] = argb;
uint32View[index + 5] = textureIdAndRound;
float32View[index + 6] = a * w0 + c * h1 + tx;
float32View[index + 7] = d * h1 + b * w0 + ty;
float32View[index + 8] = uvs.x1;
float32View[index + 9] = uvs.y1;
uint32View[index + 10] = argb;
uint32View[index + 11] = textureIdAndRound;
float32View[index + 12] = a * w0 + c * h0 + tx;
float32View[index + 13] = d * h0 + b * w0 + ty;
float32View[index + 14] = uvs.x2;
float32View[index + 15] = uvs.y2;
uint32View[index + 16] = argb;
uint32View[index + 17] = textureIdAndRound;
float32View[index + 18] = a * w1 + c * h0 + tx;
float32View[index + 19] = d * h0 + b * w1 + ty;
float32View[index + 20] = uvs.x3;
float32View[index + 21] = uvs.y3;
uint32View[index + 22] = argb;
uint32View[index + 23] = textureIdAndRound;
}
};
/** @ignore */
_DefaultBatcher.extension = {
type: [
ExtensionType.Batcher
],
name: "default"
};
let DefaultBatcher = _DefaultBatcher;
export { DefaultBatcher };
//# sourceMappingURL=DefaultBatcher.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,13 @@
import { Shader } from '../../renderers/shared/shader/Shader';
/**
* DefaultShader is a specialized shader class designed for batch rendering.
* It extends the base Shader class and provides functionality for handling
* color, texture batching, and pixel rounding in both WebGL and WebGPU contexts.
*
* It is used by the default batcher
* @extends Shader
* @memberof rendering
*/
export declare class DefaultShader extends Shader {
constructor(maxTextures: number);
}

View File

@@ -0,0 +1,40 @@
'use strict';
var compileHighShaderToProgram = require('../../high-shader/compileHighShaderToProgram.js');
var colorBit = require('../../high-shader/shader-bits/colorBit.js');
var generateTextureBatchBit = require('../../high-shader/shader-bits/generateTextureBatchBit.js');
var roundPixelsBit = require('../../high-shader/shader-bits/roundPixelsBit.js');
var getBatchSamplersUniformGroup = require('../../renderers/gl/shader/getBatchSamplersUniformGroup.js');
var Shader = require('../../renderers/shared/shader/Shader.js');
"use strict";
class DefaultShader extends Shader.Shader {
constructor(maxTextures) {
const glProgram = compileHighShaderToProgram.compileHighShaderGlProgram({
name: "batch",
bits: [
colorBit.colorBitGl,
generateTextureBatchBit.generateTextureBatchBitGl(maxTextures),
roundPixelsBit.roundPixelsBitGl
]
});
const gpuProgram = compileHighShaderToProgram.compileHighShaderGpuProgram({
name: "batch",
bits: [
colorBit.colorBit,
generateTextureBatchBit.generateTextureBatchBit(maxTextures),
roundPixelsBit.roundPixelsBit
]
});
super({
glProgram,
gpuProgram,
resources: {
batchSamplers: getBatchSamplersUniformGroup.getBatchSamplersUniformGroup(maxTextures)
}
});
}
}
exports.DefaultShader = DefaultShader;
//# sourceMappingURL=DefaultShader.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DefaultShader.js","sources":["../../../../src/rendering/batcher/shared/DefaultShader.ts"],"sourcesContent":["import { compileHighShaderGlProgram, compileHighShaderGpuProgram } from '../../high-shader/compileHighShaderToProgram';\nimport { colorBit, colorBitGl } from '../../high-shader/shader-bits/colorBit';\nimport { generateTextureBatchBit, generateTextureBatchBitGl } from '../../high-shader/shader-bits/generateTextureBatchBit';\nimport { roundPixelsBit, roundPixelsBitGl } from '../../high-shader/shader-bits/roundPixelsBit';\nimport { getBatchSamplersUniformGroup } from '../../renderers/gl/shader/getBatchSamplersUniformGroup';\nimport { Shader } from '../../renderers/shared/shader/Shader';\n\n/**\n * DefaultShader is a specialized shader class designed for batch rendering.\n * It extends the base Shader class and provides functionality for handling\n * color, texture batching, and pixel rounding in both WebGL and WebGPU contexts.\n *\n * It is used by the default batcher\n * @extends Shader\n * @memberof rendering\n */\nexport class DefaultShader extends Shader\n{\n constructor(maxTextures: number)\n {\n const glProgram = compileHighShaderGlProgram({\n name: 'batch',\n bits: [\n colorBitGl,\n generateTextureBatchBitGl(maxTextures),\n roundPixelsBitGl,\n ]\n });\n\n const gpuProgram = compileHighShaderGpuProgram({\n name: 'batch',\n bits: [\n colorBit,\n generateTextureBatchBit(maxTextures),\n roundPixelsBit,\n ]\n });\n\n super({\n glProgram,\n gpuProgram,\n resources: {\n batchSamplers: getBatchSamplersUniformGroup(maxTextures),\n }\n });\n }\n}\n"],"names":["Shader","compileHighShaderGlProgram","colorBitGl","generateTextureBatchBitGl","roundPixelsBitGl","compileHighShaderGpuProgram","colorBit","generateTextureBatchBit","roundPixelsBit","getBatchSamplersUniformGroup"],"mappings":";;;;;;;;;;AAgBO,MAAM,sBAAsBA,aACnC,CAAA;AAAA,EACI,YAAY,WACZ,EAAA;AACI,IAAA,MAAM,YAAYC,qDAA2B,CAAA;AAAA,MACzC,IAAM,EAAA,OAAA;AAAA,MACN,IAAM,EAAA;AAAA,QACFC,mBAAA;AAAA,QACAC,kDAA0B,WAAW,CAAA;AAAA,QACrCC,+BAAA;AAAA,OACJ;AAAA,KACH,CAAA,CAAA;AAED,IAAA,MAAM,aAAaC,sDAA4B,CAAA;AAAA,MAC3C,IAAM,EAAA,OAAA;AAAA,MACN,IAAM,EAAA;AAAA,QACFC,iBAAA;AAAA,QACAC,gDAAwB,WAAW,CAAA;AAAA,QACnCC,6BAAA;AAAA,OACJ;AAAA,KACH,CAAA,CAAA;AAED,IAAM,KAAA,CAAA;AAAA,MACF,SAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAW,EAAA;AAAA,QACP,aAAA,EAAeC,0DAA6B,WAAW,CAAA;AAAA,OAC3D;AAAA,KACH,CAAA,CAAA;AAAA,GACL;AACJ;;;;"}

View File

@@ -0,0 +1,38 @@
import { compileHighShaderGlProgram, compileHighShaderGpuProgram } from '../../high-shader/compileHighShaderToProgram.mjs';
import { colorBitGl, colorBit } from '../../high-shader/shader-bits/colorBit.mjs';
import { generateTextureBatchBitGl, generateTextureBatchBit } from '../../high-shader/shader-bits/generateTextureBatchBit.mjs';
import { roundPixelsBitGl, roundPixelsBit } from '../../high-shader/shader-bits/roundPixelsBit.mjs';
import { getBatchSamplersUniformGroup } from '../../renderers/gl/shader/getBatchSamplersUniformGroup.mjs';
import { Shader } from '../../renderers/shared/shader/Shader.mjs';
"use strict";
class DefaultShader extends Shader {
constructor(maxTextures) {
const glProgram = compileHighShaderGlProgram({
name: "batch",
bits: [
colorBitGl,
generateTextureBatchBitGl(maxTextures),
roundPixelsBitGl
]
});
const gpuProgram = compileHighShaderGpuProgram({
name: "batch",
bits: [
colorBit,
generateTextureBatchBit(maxTextures),
roundPixelsBit
]
});
super({
glProgram,
gpuProgram,
resources: {
batchSamplers: getBatchSamplersUniformGroup(maxTextures)
}
});
}
}
export { DefaultShader };
//# sourceMappingURL=DefaultShader.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DefaultShader.mjs","sources":["../../../../src/rendering/batcher/shared/DefaultShader.ts"],"sourcesContent":["import { compileHighShaderGlProgram, compileHighShaderGpuProgram } from '../../high-shader/compileHighShaderToProgram';\nimport { colorBit, colorBitGl } from '../../high-shader/shader-bits/colorBit';\nimport { generateTextureBatchBit, generateTextureBatchBitGl } from '../../high-shader/shader-bits/generateTextureBatchBit';\nimport { roundPixelsBit, roundPixelsBitGl } from '../../high-shader/shader-bits/roundPixelsBit';\nimport { getBatchSamplersUniformGroup } from '../../renderers/gl/shader/getBatchSamplersUniformGroup';\nimport { Shader } from '../../renderers/shared/shader/Shader';\n\n/**\n * DefaultShader is a specialized shader class designed for batch rendering.\n * It extends the base Shader class and provides functionality for handling\n * color, texture batching, and pixel rounding in both WebGL and WebGPU contexts.\n *\n * It is used by the default batcher\n * @extends Shader\n * @memberof rendering\n */\nexport class DefaultShader extends Shader\n{\n constructor(maxTextures: number)\n {\n const glProgram = compileHighShaderGlProgram({\n name: 'batch',\n bits: [\n colorBitGl,\n generateTextureBatchBitGl(maxTextures),\n roundPixelsBitGl,\n ]\n });\n\n const gpuProgram = compileHighShaderGpuProgram({\n name: 'batch',\n bits: [\n colorBit,\n generateTextureBatchBit(maxTextures),\n roundPixelsBit,\n ]\n });\n\n super({\n glProgram,\n gpuProgram,\n resources: {\n batchSamplers: getBatchSamplersUniformGroup(maxTextures),\n }\n });\n }\n}\n"],"names":[],"mappings":";;;;;;;;AAgBO,MAAM,sBAAsB,MACnC,CAAA;AAAA,EACI,YAAY,WACZ,EAAA;AACI,IAAA,MAAM,YAAY,0BAA2B,CAAA;AAAA,MACzC,IAAM,EAAA,OAAA;AAAA,MACN,IAAM,EAAA;AAAA,QACF,UAAA;AAAA,QACA,0BAA0B,WAAW,CAAA;AAAA,QACrC,gBAAA;AAAA,OACJ;AAAA,KACH,CAAA,CAAA;AAED,IAAA,MAAM,aAAa,2BAA4B,CAAA;AAAA,MAC3C,IAAM,EAAA,OAAA;AAAA,MACN,IAAM,EAAA;AAAA,QACF,QAAA;AAAA,QACA,wBAAwB,WAAW,CAAA;AAAA,QACnC,cAAA;AAAA,OACJ;AAAA,KACH,CAAA,CAAA;AAED,IAAM,KAAA,CAAA;AAAA,MACF,SAAA;AAAA,MACA,UAAA;AAAA,MACA,SAAW,EAAA;AAAA,QACP,aAAA,EAAe,6BAA6B,WAAW,CAAA;AAAA,OAC3D;AAAA,KACH,CAAA,CAAA;AAAA,GACL;AACJ;;;;"}