UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

156 lines 11.8 kB
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Zhby92YW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQTtBQUt2QyxNQUFNLE9BQU8sY0FBYztJQVd2QixZQUNvQixFQUEwQixFQUN6QixPQUFvQixFQUNwQixRQUFpQyxFQUMxQyxRQUFrQztRQUgxQixPQUFFLEdBQUYsRUFBRSxDQUF3QjtRQUN6QixZQUFPLEdBQVAsT0FBTyxDQUFhO1FBQ3BCLGFBQVEsR0FBUixRQUFRLENBQXlCO1FBQzFDLGFBQVEsR0FBUixRQUFRLENBQTBCO1FBWjdCLGdCQUFXLEdBQWdCLEVBQUUsQ0FBQTtRQUM3QixlQUFVLEdBQXFCLElBQUksQ0FBQTtRQUNuQyxvQkFBZSxHQUFHLElBQUksR0FBRyxFQUFhLENBQUE7UUFDdkQ7O1dBRUc7UUFDSyxnQkFBVyxHQUFHLENBQUMsQ0FBQTtRQVFuQixNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQTtRQUNsQyxJQUFJLENBQUMsR0FBRztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQTtRQUVoRSxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQTtRQUNkLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTTtRQUVqQyxFQUFFLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ3ZCLElBQUksQ0FBQyxXQUFXLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3hDLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQTtZQUMvRCxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUE7WUFDYixPQUFPLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxFQUFFLE9B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