@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
116 lines • 11 kB
JavaScript
import { TgdPainter } from "../painter.js";
import { resolveErrorMessage, tgdTextureRecordToUniforms } from "./../../utils/index.js";
import { TgdProgram } from "./../../program/index.js";
import { TgdVertexArray } from "./../../vao/index.js";
export class TgdPainterParticles extends TgdPainter {
constructor(context, { name, dataset, shader, drawMode, textures = {}, setUniforms, prefixAttribute = "att", prefixVarying = "var", }) {
super();
this.context = context;
this.pingPong = 0;
this.name = name ?? `TgdPainterParticles#${TgdPainterParticles.counter++}`;
this.textures = textures;
this.setUniforms = setUniforms;
this.drawMode = drawMode;
try {
const { gl } = context;
const varyings = [];
const vert = shader.vert.clone();
const frag = shader.frag.clone();
const uniformsForTextures = tgdTextureRecordToUniforms(textures);
vert.uniforms = {
...vert.uniforms,
...uniformsForTextures,
};
frag.uniforms = {
...frag.uniforms,
...uniformsForTextures,
};
for (const attName of Object.keys(vert.attributes)) {
if (!attName.startsWith(prefixAttribute)) {
throw new Error(`All attributes must be prefixed with "${prefixAttribute}"! But "${attName}" is not.
You can use "prefixAttribute" to change the prefix.
If you don't want any prefix, just set "prefixAttribute" to "".`);
}
const varName = `${prefixVarying}${attName.slice(prefixAttribute.length)}`;
vert.varying[varName] = vert.attributes[attName];
vert.mainCodeHeaders.push(`${varName} = ${attName};`);
varyings.push(varName);
}
frag.varying = structuredClone(vert.varying);
dataset.usage = "DYNAMIC_READ";
this.count = dataset.count;
const prg = new TgdProgram(gl, {
vert,
frag,
transformFeedback: {
bufferMode: "INTERLEAVED_ATTRIBS",
varyings,
},
});
this.prg = prg;
prg.use();
const samplerNames = Object.keys(textures);
for (let unit = 0; unit < samplerNames.length; unit++) {
const uniformName = samplerNames[unit];
const texture = textures[uniformName];
texture.activate(unit, prg, uniformName);
}
const vaoIn = new TgdVertexArray(gl, prg, [dataset]);
const bufferIn = vaoIn.getBuffer(0);
if (!bufferIn)
throw new Error("Unable to get buffer!");
const vaoOut = new TgdVertexArray(gl, prg, [dataset.clone()]);
const bufferOut = vaoOut.getBuffer(0);
if (!bufferOut)
throw new Error("Unable to get buffer!");
this.vaos = [vaoIn, vaoOut];
this.buffers = [bufferIn, bufferOut];
vaoIn.debug("Input");
vaoOut.debug("Output");
}
catch (error) {
this.delete();
const message = resolveErrorMessage(error);
throw new Error(`[${this.name}] ${message}`);
}
}
paint(time, delta) {
const { context, textures, drawMode, prg, vaos, buffers, count, pingPong, setUniforms } = this;
const { gl } = context;
const src = pingPong;
const dst = 1 - pingPong;
prg.use();
let unit = 0;
for (const name of Object.keys(textures)) {
const texture = textures[name];
texture.activate(unit++, prg, name);
}
if (setUniforms) {
setUniforms({ time, delta, prg });
}
vaos[src].bind();
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffers[dst].buffer);
gl.beginTransformFeedback(gl[drawMode]);
gl.drawArrays(gl[drawMode], 0, count);
gl.endTransformFeedback();
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
vaos[src].unbind();
this.pingPong = dst;
}
delete() {
this.prg?.delete();
if (this.vaos) {
const [vaoIn, vaoOut] = this.vaos;
vaoIn?.delete();
vaoOut?.delete();
}
if (this.buffers) {
const [bufferIn, bufferOut] = this.buffers;
bufferIn?.delete();
bufferOut?.delete();
}
}
}
TgdPainterParticles.counter = 0;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFydGljbGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3BhaW50ZXIvcGFydGljbGVzL3BhcnRpY2xlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sWUFBWSxDQUFBO0FBR3ZDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUM1RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQ3pDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUE7QUF1QnpDLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxVQUFVO0lBZS9DLFlBQ29CLE9BQW1CLEVBQ25DLEVBQ0ksSUFBSSxFQUNKLE9BQU8sRUFDUCxNQUFNLEVBQ04sUUFBUSxFQUNSLFFBQVEsR0FBRyxFQUFFLEVBQ2IsV0FBVyxFQUNYLGVBQWUsR0FBRyxLQUFLLEVBQ3ZCLGFBQWEsR0FBRyxLQUFLLEdBQ0k7UUFFN0IsS0FBSyxFQUFFLENBQUE7UUFaUyxZQUFPLEdBQVAsT0FBTyxDQUFZO1FBSC9CLGFBQVEsR0FBRyxDQUFDLENBQUE7UUFnQmhCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLHVCQUF1QixtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFBO1FBQzFFLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFBO1FBQ3hCLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFBO1FBQzlCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFBO1FBQ3hCLElBQUksQ0FBQztZQUNELE1BQU0sRUFBRSxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUE7WUFDdEIsTUFBTSxRQUFRLEdBQWEsRUFBRSxDQUFBO1lBQzdCLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUE7WUFDaEMsTUFBTSxJQUFJLEdB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