feat: 组合器输出添加图集索引

This commit is contained in:
unanmed 2025-10-25 11:57:55 +08:00
parent dc98244a08
commit 1087de639d
3 changed files with 48 additions and 22 deletions

View File

@ -51,7 +51,8 @@ export class TextureGridComposer
start: number, start: number,
data: IGridComposerData, data: IGridComposerData,
rows: number, rows: number,
cols: number cols: number,
index: number
): IndexMarkedComposedData { ): IndexMarkedComposedData {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d')!; const ctx = canvas.getContext('2d')!;
@ -80,6 +81,7 @@ export class TextureGridComposer
const texture = new Texture(canvas); const texture = new Texture(canvas);
const composed: ITextureComposedData = { const composed: ITextureComposedData = {
index,
texture, texture,
assetMap: map assetMap: map
}; };
@ -96,12 +98,14 @@ export class TextureGridComposer
const rows = Math.floor(this.maxWidth / data.width); const rows = Math.floor(this.maxWidth / data.width);
const cols = Math.floor(this.maxHeight / data.height); const cols = Math.floor(this.maxHeight / data.height);
let arrindex = 0;
let i = 0; let i = 0;
while (i < arr.length) { while (arrindex < arr.length) {
const { asset, index } = this.nextAsset(arr, i, data, rows, cols); const res = this.nextAsset(arr, arrindex, data, rows, cols, i);
i = index + 1; arrindex = res.index + 1;
yield asset; i++;
yield res.asset;
} }
} }
} }
@ -149,6 +153,7 @@ export class TextureMaxRectsComposer
}); });
packer.addArray(rects); packer.addArray(rects);
let index = 0;
for (const bin of packer.bins) { for (const bin of packer.bins) {
const map = new Map<ITexture, IRect>(); const map = new Map<ITexture, IRect>();
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
@ -166,6 +171,7 @@ export class TextureMaxRectsComposer
}); });
const texture = new Texture(canvas); const texture = new Texture(canvas);
const data: ITextureComposedData = { const data: ITextureComposedData = {
index: index++,
texture, texture,
assetMap: map assetMap: map
}; };
@ -426,15 +432,16 @@ export class TextureMaxRectsWebGL2Composer
const indexMap = this.mapTextures(arr); const indexMap = this.mapTextures(arr);
this.setTexture(indexMap); this.setTexture(indexMap);
let index = 0;
for (const bin of packer.bins) { for (const bin of packer.bins) {
const { texMap, attrib } = this.processRects(bin.rects, indexMap); const { texMap, attrib } = this.processRects(bin.rects, indexMap);
this.renderAtlas(attrib); this.renderAtlas(attrib);
const texture = new Texture(this.canvas); const texture = new Texture(this.canvas);
const data: ITextureComposedData = { const data: ITextureComposedData = {
index: index++,
texture, texture,
assetMap: texMap assetMap: texMap
}; };
yield data; yield data;
} }

View File

@ -18,7 +18,9 @@ export class TextureGridStreamComposer implements ITextureStreamComposer<void> {
readonly cols: number; readonly cols: number;
private nowIndex: number = 0; private nowIndex: number = 0;
private outputIndex: number = 0;
private nowTexture: ITexture;
private nowCanvas: HTMLCanvasElement; private nowCanvas: HTMLCanvasElement;
private nowCtx: CanvasRenderingContext2D; private nowCtx: CanvasRenderingContext2D;
private nowMap: Map<ITexture, Readonly<IRect>>; private nowMap: Map<ITexture, Readonly<IRect>>;
@ -43,12 +45,16 @@ export class TextureGridStreamComposer implements ITextureStreamComposer<void> {
this.nowCanvas = document.createElement('canvas'); this.nowCanvas = document.createElement('canvas');
this.nowCtx = this.nowCanvas.getContext('2d')!; this.nowCtx = this.nowCanvas.getContext('2d')!;
this.nowMap = new Map(); this.nowMap = new Map();
this.nowTexture = new Texture(this.nowCanvas);
} }
private nextCanvas() { private nextCanvas() {
this.nowCanvas = document.createElement('canvas'); this.nowCanvas = document.createElement('canvas');
this.nowCtx = this.nowCanvas.getContext('2d')!; this.nowCtx = this.nowCanvas.getContext('2d')!;
this.nowMap = new Map(); this.nowMap = new Map();
this.nowIndex = 0;
this.nowTexture = new Texture(this.nowCanvas);
this.outputIndex++;
} }
*add(textures: Iterable<ITexture>): Generator<ITextureComposedData, void> { *add(textures: Iterable<ITexture>): Generator<ITextureComposedData, void> {
@ -66,13 +72,14 @@ export class TextureGridStreamComposer implements ITextureStreamComposer<void> {
this.nowCtx.drawImage(source, cx, cy, cw, ch, x, y, cw, ch); this.nowCtx.drawImage(source, cx, cy, cw, ch, x, y, cw, ch);
this.nowMap.set(tex, { x, y, w: cw, h: ch }); this.nowMap.set(tex, { x, y, w: cw, h: ch });
index++;
if (index === max) {
const data: ITextureComposedData = { const data: ITextureComposedData = {
texture: new Texture(this.nowCanvas), index: this.outputIndex,
texture: this.nowTexture,
assetMap: this.nowMap assetMap: this.nowMap
}; };
yield data; yield data;
if (++index === max) {
this.nextCanvas(); this.nextCanvas();
} }
} }
@ -94,10 +101,13 @@ export class TextureMaxRectsStreamComposer
/** Max Rects 打包器 */ /** Max Rects 打包器 */
readonly packer: MaxRectsPacker<MaxRectsRectangle>; readonly packer: MaxRectsPacker<MaxRectsRectangle>;
private outputIndex: number = 0;
private nowTexture: ITexture;
private nowCanvas: HTMLCanvasElement; private nowCanvas: HTMLCanvasElement;
private nowCtx: CanvasRenderingContext2D; private nowCtx: CanvasRenderingContext2D;
private nowMap: Map<ITexture, Readonly<IRect>>; private nowMap: Map<ITexture, Readonly<IRect>>;
private nowBins: number; private nowBin: number;
/** /**
* 使 Max Rects * 使 Max Rects
@ -122,13 +132,16 @@ export class TextureMaxRectsStreamComposer
this.nowCanvas = document.createElement('canvas'); this.nowCanvas = document.createElement('canvas');
this.nowCtx = this.nowCanvas.getContext('2d')!; this.nowCtx = this.nowCanvas.getContext('2d')!;
this.nowMap = new Map(); this.nowMap = new Map();
this.nowBins = 0; this.nowBin = 0;
this.nowTexture = new Texture(this.nowCanvas);
} }
private nextCanvas() { private nextCanvas() {
this.nowCanvas = document.createElement('canvas'); this.nowCanvas = document.createElement('canvas');
this.nowCtx = this.nowCanvas.getContext('2d')!; this.nowCtx = this.nowCanvas.getContext('2d')!;
this.nowMap = new Map(); this.nowMap = new Map();
this.outputIndex++;
this.nowTexture = new Texture(this.nowCanvas);
} }
*add(textures: Iterable<ITexture>): Generator<ITextureComposedData, void> { *add(textures: Iterable<ITexture>): Generator<ITextureComposedData, void> {
@ -144,12 +157,13 @@ export class TextureMaxRectsStreamComposer
const bins = this.packer.bins; const bins = this.packer.bins;
if (bins.length === 0) return; if (bins.length === 0) return;
const toYield: Bin<MaxRectsRectangle>[] = [bins[bins.length - 1]]; const toYield: Bin<MaxRectsRectangle>[] = [bins[bins.length - 1]];
if (bins.length > this.nowBins) { if (bins.length > this.nowBin) {
toYield.push(...bins.slice(this.nowBins)); toYield.push(...bins.slice(this.nowBin));
} }
for (const bin of toYield) { for (let i = this.nowBin; i < bins.length; i++) {
bin.rects.forEach(v => { const rects = bins[i].rects;
rects.forEach(v => {
if (this.nowMap.has(v.data)) return; if (this.nowMap.has(v.data)) return;
const target: IRect = { const target: IRect = {
x: v.x, x: v.x,
@ -163,14 +177,17 @@ export class TextureMaxRectsStreamComposer
this.nowCtx.drawImage(source, cx, cy, cw, ch, v.x, v.y, cw, ch); this.nowCtx.drawImage(source, cx, cy, cw, ch, v.x, v.y, cw, ch);
}); });
const data: ITextureComposedData = { const data: ITextureComposedData = {
texture: new Texture(this.nowCanvas), index: this.outputIndex,
texture: this.nowTexture,
assetMap: this.nowMap assetMap: this.nowMap
}; };
yield data; yield data;
if (i < bins.length - 1) {
this.nextCanvas(); this.nextCanvas();
} }
}
this.nowBins = bins.length; this.nowBin = bins.length;
} }
close(): void { close(): void {

View File

@ -22,6 +22,8 @@ export interface ITextureRenderable {
export interface ITextureComposedData { export interface ITextureComposedData {
/** 这个纹理图集的贴图对象 */ /** 这个纹理图集的贴图对象 */
readonly texture: ITexture; readonly texture: ITexture;
/** 这个纹理图集的索引 */
readonly index: number;
/** 每个参与组合的贴图对应到图集对象的矩形范围 */ /** 每个参与组合的贴图对应到图集对象的矩形范围 */
readonly assetMap: Map<ITexture, Readonly<IRect>>; readonly assetMap: Map<ITexture, Readonly<IRect>>;
} }