@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
156 lines • 11.8 kB
JavaScript
import { TgdBuffer } from "./../buffer/index.js";
export class TgdVertexArray {
constructor(gl, program, datasets, elements) {
this.gl = gl;
this.program = program;
this.datasets = datasets;
this.elements = elements;
this.drawBuffers = [];
this.elemBuffer = null;
this.buffersToDelete = new Set();
/**
* Number of owners that share this VAO.
*/
this.ownersCount = 1;
const vao = gl.createVertexArray();
if (!vao)
throw new Error("Unable to create VertexArrayObject!");
this.vao = vao;
if (!program || !datasets)
return;
gl.bindVertexArray(vao);
this.drawBuffers = datasets.map((dataset) => {
const buffer = resolveBuffer(gl, dataset, this.buffersToDelete);
buffer.bind();
dataset.defineAttributes(gl, program);
return buffer;
});
if (elements) {
const buffer = new TgdBuffer(gl, {
data: elements,
target: "ELEMENT_ARRAY_BUFFER",
});
buffer.bind();
this.elemBuffer = buffer;
}
gl.bindVertexArray(null);
}
share() {
this.ownersCount++;
}
/**
* When you change the data of a dataset,
* you must call this function to update the VAO.
* Because datasets do not own any buffer.
*/
updateDataset(dataset) {
const { datasets } = this;
if (!datasets) {
console.error("You cannot update any dataset because no dataset has been attached to this VAO yet!");
return false;
}
const index = datasets.indexOf(dataset);
if (index === -1) {
console.error("This dataset is not bound to this VAO!");
dataset.debug();
this.debug();
return false;
}
const buffer = this.getBuffer(index);
if (!buffer) {
console.error(`There is no buffer with index #${index} in this VAO!`);
this.debug();
return false;
}
buffer.bufferData({
data: dataset.data,
});
return true;
}
updateElements(elements) {
if (!this.elements) {
throw new Error("This VAO has no elements data!");
}
if (!this.elemBuffer) {
throw new Error("This VAO has no elements buffer!");
}
switch (this.elements.BYTES_PER_ELEMENT) {
case 1:
this.elements = new Uint8Array(elements);
break;
case 2:
this.elements = new Uint16Array(elements);
break;
case 4:
this.elements = new Uint32Array(elements);
break;
default:
throw new Error(`Don't know how to deal with ${this.elements.BYTES_PER_ELEMENT} bytes per element!`);
}
this.elemBuffer.bufferData({ data: this.elements });
}
getBuffer(index) {
return this.drawBuffers[index];
}
toCode({ indent = "" } = {}) {
const lines = [
"function createVAO(",
" gl: WebGL2RenderingContext,",
` prg: WebGLProgram${this.datasets?.map((_ds, index) => `, data${index}: ArrayBuffer`).join("")}`,
") {",
" const vao = gl.createVertexArray()",
" gl.bindVertexArray(vao)",
];
if (this.datasets)
for (const [index, dataset] of this.datasets.entries()) {
lines.push(` const buff${index} = gl.createBuffer()`, ` gl.bindBuffer(gl.${dataset.target}, buff${index})`, ` gl.bufferData(gl.${dataset.target}, data${index}, gl.${dataset.usage})`, dataset.toCode({ indent: `${indent} ` }));
}
lines.push(" return vao", "}");
return lines.map((line) => `${indent}${line}`).join("\n");
}
debug(caption = "TgdVertexArray") {
console.debug(caption);
if (this.program)
this.program.debug();
if (this.datasets) {
for (const [index, dataset] of this.datasets.entries()) {
dataset.debug(` Dataset #${index}`);
}
}
if (this.elements)
console.debug("Elements:", this.elements);
}
bind() {
this.gl.bindVertexArray(this.vao);
}
unbind() {
this.gl.bindVertexArray(null);
}
delete() {
this.ownersCount--;
if (this.ownersCount > 0)
return;
const { gl, vao, drawBuffers, elemBuffer } = this;
gl.deleteVertexArray(vao);
for (const buff of drawBuffers) {
if (this.buffersToDelete.has(buff))
buff.delete();
}
if (elemBuffer)
elemBuffer.delete();
}
}
function resolveBuffer(gl, dataset, buffersToDelete) {
const buffer = dataset.buffer ??
new TgdBuffer(gl, {
data: dataset.data,
target: dataset.target,
usage: dataset.usage,
});
if (!dataset.buffer) {
// Delete only buffers created here.
buffersToDelete.add(buffer);
}
return buffer;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Zhby92YW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUt2QyxNQUFNLE9BQU8sY0FBYztJQVd2QixZQUNvQixFQUEwQixFQUN6QixPQUFvQixFQUNwQixRQUFpQyxFQUMxQyxRQUFrQztRQUgxQixPQUFFLEdBQUYsRUFBRSxDQUF3QjtRQUN6QixZQUFPLEdBQVAsT0FBTyxDQUFhO1FBQ3BCLGFBQVEsR0FBUixRQUFRLENBQXlCO1FBQzFDLGFBQVEsR0FBUixRQUFRLENBQTBCO1FBWjdCLGdCQUFXLEdBQWdCLEVBQUUsQ0FBQTtRQUM3QixlQUFVLEdBQXFCLElBQUksQ0FBQTtRQUNuQyxvQkFBZSxHQUFHLElBQUksR0FBRyxFQUFhLENBQUE7UUFDdkQ7O1dBRUc7UUFDSyxnQkFBVyxHQUFHLENBQUMsQ0FBQTtRQVFuQixNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtRQUNsQyxJQUFJLENBQUMsR0FBRztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQTtRQUVoRSxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQTtRQUNkLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTTtRQUVqQyxFQUFFLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ3ZCLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3hDLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQTtZQUMvRCxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDYixPQUFPLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1lBQ3JDLE9BQU8sTUFBTSxDQUFBO1FBQ2pCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUNYLE1BQU0sTUFBTSxHQUFHLElBQUksU0FBUyxDQUFDLEVBQUUsRUFBRTtnQkFDN0IsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsTUFBTSxFQUFFLHNCQUFzQjthQUNqQyxDQUFDLENBQUE7WUFDRixNQUFNLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDYixJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQTtRQUM1QixDQUFDO1FBQ0QsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM1QixDQUFDO0lBRUQsS0FBSztRQUNELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUN0QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGFBQWEsQ0FBQyxPQUFtQjtRQUM3QixNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFBO1FBQ3pCLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNaLE9BQU8sQ0FBQyxLQUFLLENBQUMscUZBQXFGLENBQUMsQ0FBQTtZQUNwRyxPQUFPLEtBQUssQ0FBQTtRQUNoQixDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN2QyxJQUFJLEtBQUssS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEtBQUssQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFBO1lBQ3ZELE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQTtZQUNmLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQTtZQUNaLE9BQU8sS0FBSyxDQUFBO1FBQ2hCLENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3BDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLEtBQUssZUFBZSxDQUFDLENBQUE7WUFDckUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFBO1lBQ1osT0FBTyxLQUFLLENBQUE7UUFDaEIsQ0FBQztRQUNELE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDZCxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7U0FDckIsQ0FBQyxDQUFBO1FBQ0YsT0FBTyxJQUFJLENBQUE7SUFDZixDQUFDO0lBRUQsY0FBYyxDQUFDLFFBQWtCO1FBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBQyxDQUFBO1FBQ3JELENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsa0NBQWtDLENBQUMsQ0FBQTtRQUN2RCxDQUFDO1FBQ0QsUUFBUSxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDdEMsS0FBSyxDQUFDO2dCQUNGLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7Z0JBQ3hDLE1BQUs7WUFDVCxLQUFLLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQTtnQkFDekMsTUFBSztZQUNULEtBQUssQ0FBQztnQkFDRixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFBO2dCQUN6QyxNQUFLO1lBQ1Q7Z0JBQ0ksTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIscUJBQXFCLENBQUMsQ0FBQTtRQUM1RyxDQUFDO1FBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7SUFDdkQsQ0FBQztJQUVELFNBQVMsQ0FBQyxLQUFhO1FBQ25CLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNsQyxDQUFDO0lBRUQsTUFBTSxDQUFDLEVBQUUsTUFBTSxHQUFHLEVBQUUsS0FBa0MsRUFBRTtRQUNwRCxNQUFNLEtBQUssR0FBYTtZQUNwQixxQkFBcUI7WUFDckIsK0JBQStCO1lBQy9CLHNCQUFzQixJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLFNBQVMsS0FBSyxlQUFlLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUU7WUFDbEcsS0FBSztZQUNMLHNDQUFzQztZQUN0QywyQkFBMkI7U0FDOUIsQ0FBQTtRQUNELElBQUksSUFBSSxDQUFDLFFBQVE7WUFDYixLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO2dCQUNyRCxLQUFLLENBQUMsSUFBSSxDQUNOLGVBQWUsS0FBSyxzQkFBc0IsRUFDMUMsc0JBQXNCLE9BQU8sQ0FBQyxNQUFNLFNBQVMsS0FBSyxHQUFHLEVBQ3JELHNCQUFzQixPQUFPLENBQUMsTUFBTSxTQUFTLEtBQUssUUFBUSxPQUFPLENBQUMsS0FBSyxHQUFHLEVBQzFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUksRUFBRSxDQUFDLENBQzVDLENBQUE7WUFDTCxDQUFDO1FBQ0wsS0FBSyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFDL0IsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxHQUFHLE1BQU0sR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUM3RCxDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQU8sR0FBRyxnQkFBZ0I7UUFDNUIsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN0QixJQUFJLElBQUksQ0FBQyxPQUFPO1lBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUN0QyxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNoQixLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO2dCQUNyRCxPQUFPLENBQUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxFQUFFLENBQUMsQ0FBQTtZQUN6QyxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDaEUsQ0FBQztJQUVELElBQUk7UUFDQSxJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDckMsQ0FBQztJQUVELE1BQU07UUFDRixJQUFJLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUNqQyxDQUFDO0lBRUQsTUFBTTtRQUNGLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtRQUNsQixJQUFJLElBQUksQ0FBQyxXQUFXLEdBQUcsQ0FBQztZQUFFLE9BQU07UUFFaEMsTUFBTSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxHQUFHLElBQUksQ0FBQTtRQUNqRCxFQUFFLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDekIsS0FBSyxNQUFNLElBQUksSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUM3QixJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztnQkFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUE7UUFDckQsQ0FBQztRQUNELElBQUksVUFBVTtZQUFFLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQTtJQUN2QyxDQUFDO0NBQ0o7QUFFRCxTQUFTLGFBQWEsQ0FDbEIsRUFBMEIsRUFDMUIsT0FBNkIsRUFDN0IsZUFBK0I7SUFFL0IsTUFBTSxNQUFNLEdBQ1IsT0FBTyxDQUFDLE1BQU07UUFDZCxJQUFJLFNBQVMsQ0FBQyxFQUFFLEVBQUU7WUFDZCxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3RCLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztTQUN2QixDQUFDLENBQUE7SUFDTixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2xCLG9DQUFvQztRQUNwQyxlQUFlLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQTtBQUNqQixDQUFDIn0=