Cleanup buffer.ts

This commit is contained in:
Lucas Dower 2022-02-12 17:59:19 +00:00
parent 2eedb7dd0e
commit 8549901a43
2 changed files with 71 additions and 100 deletions

View File

@ -1,19 +1,18 @@
import { Renderer } from './renderer';
import * as twgl from 'twgl.js';
import { ASSERT } from './util';
interface Attribute {
name: string,
numComponents: number
}
interface CompleteBuffer {
buffer: BottomlessBufferData,
numElements: number,
}
interface BottomlessBufferData {
indices: BottomlessAttributeData,
[name: string]: BottomlessAttributeData
}
interface BottomlessAttributeData {
numComponents: number,
data: Array<number>
@ -27,23 +26,18 @@ export interface VoxelData {
}
export class RenderBuffer {
public WebGLBuffers: Array<{
private _WebGLBuffer?: {
buffer: twgl.BufferInfo,
numElements: number
}>;
private _completeBuffers: Array<CompleteBuffer>;
};
private _buffer!: BottomlessBufferData;
private _attributes: {[name: string]: Attribute};
private _maxIndex: number = 0;
private _compiled: boolean = false;
private _sanityCheck: boolean = false;
constructor(attributes: Array<Attribute>) {
this._completeBuffers = [];
public constructor(attributes: Array<Attribute>) {
this._compiled = false;
this.WebGLBuffers = [];
this._attributes = {};
for (const attr of attributes) {
@ -58,63 +52,7 @@ export class RenderBuffer {
this._getNewBuffer();
}
_getNewBuffer() {
this._buffer = {
indices: {numComponents: 1, data: []},
};
for (const attr in this._attributes) {
this._buffer[attr] = {
numComponents: this._attributes[attr].numComponents,
data: [],
};
}
}
_cycle() {
// console.log('Cycle');
this._completeBuffers.push({
buffer: this._buffer,
numElements: this._buffer.indices.data.length,
});
this._getNewBuffer();
this._maxIndex = 0;
}
_willOverflow(data: VoxelData) {
// Check for indices Uint16 overflow
// const dataMaxIndex = Math.max(...data.indices);
const dataMaxIndex = data.indices.reduce((a, v) => Math.max(a, v));
return ((this._maxIndex + dataMaxIndex) > 65535);
}
_checkDataMatchesAttributes(data: VoxelData) {
if (!('indices' in data)) {
throw Error('Given data does not have indices data');
}
const setsRequired = data.indices.reduce((a, v) => Math.max(a, v)) + 1;
for (const attr in this._attributes) {
if (!(attr in data)) {
throw Error(`Given data does not have ${attr} data`);
}
if (data.custom[attr].length % this._attributes[attr].numComponents != 0) {
throw Error(`Not enough/too much ${attr} data given`);
}
const numSets = data.custom[attr].length / this._attributes[attr].numComponents;
if (numSets != setsRequired) {
// throw `Number of indices does not match number of ${attr} components given`;
throw Error(`Expected ${setsRequired * this._attributes[attr].numComponents} values for ${attr}, got ${data.custom[attr].length}`);
}
}
}
add(data: VoxelData) {
/*
if (this._willOverflow(data)) {
this._cycle();
}
*/
public add(data: VoxelData) {
if (this._sanityCheck) {
this._checkDataMatchesAttributes(data);
}
@ -134,33 +72,74 @@ export class RenderBuffer {
}
}
compile(gl: WebGLRenderingContext) {
public attachNewAttribute(data: VoxelData) {
}
public removeAttribute(attribute: string) {
}
public getWebGLBuffer() {
this._compile();
ASSERT(this._WebGLBuffer !== undefined);
return this._WebGLBuffer;
}
private _compile() {
if (this._compiled) {
return;
}
this._cycle();
this.WebGLBuffers = new Array(this._completeBuffers.length);
this._completeBuffers.forEach((buffer, i) => {
const newBuffer : { indices: { data: Uint32Array, numComponents: number }, [arr: string]: { data: (Float32Array | Uint32Array), numComponents: number }} = {
indices: { data: Uint32Array.from(buffer.buffer.indices.data), numComponents: buffer.buffer.indices.numComponents },
};
for (const key in buffer.buffer) {
if (key !== 'indices') {
newBuffer[key] = {
data: Float32Array.from(buffer.buffer[key].data),
numComponents: buffer.buffer[key].numComponents,
};
}
const newBuffer: { indices: { data: Uint32Array, numComponents: number }, [arr: string]: { data: (Float32Array | Uint32Array), numComponents: number }} = {
indices: { data: Uint32Array.from(this._buffer.indices.data), numComponents: this._buffer.indices.numComponents },
};
for (const key in this._buffer) {
if (key !== 'indices') {
newBuffer[key] = {
data: Float32Array.from(this._buffer[key].data),
numComponents: this._buffer[key].numComponents,
};
}
this.WebGLBuffers[i] = {
buffer: twgl.createBufferInfoFromArrays(gl, newBuffer),
numElements: buffer.numElements,
};
});
}
this._WebGLBuffer = {
buffer: twgl.createBufferInfoFromArrays(Renderer.Get._gl, newBuffer),
numElements: this._buffer.indices.data.length,
};
this._compiled = true;
}
private _getNewBuffer() {
this._buffer = {
indices: {numComponents: 1, data: []},
};
for (const attr in this._attributes) {
this._buffer[attr] = {
numComponents: this._attributes[attr].numComponents,
data: [],
};
}
}
private _checkDataMatchesAttributes(data: VoxelData) {
if (!('indices' in data)) {
throw Error('Given data does not have indices data');
}
const setsRequired = data.indices.reduce((a, v) => Math.max(a, v)) + 1;
for (const attr in this._attributes) {
if (!(attr in data)) {
throw Error(`Given data does not have ${attr} data`);
}
if (data.custom[attr].length % this._attributes[attr].numComponents != 0) {
throw Error(`Not enough/too much ${attr} data given`);
}
const numSets = data.custom[attr].length / this._attributes[attr].numComponents;
if (numSets != setsRequired) {
// throw `Number of indices does not match number of ${attr} components given`;
throw Error(`Expected ${setsRequired * this._attributes[attr].numComponents} values for ${attr}, got ${data.custom[attr].length}`);
}
}
}
}

View File

@ -124,10 +124,6 @@ export class Renderer {
}
}
this._materialBuffers.forEach((materialBuffer) => {
materialBuffer.buffer.compile(Renderer.Get._gl);
});
this._meshToUse = MeshType.TriangleMesh;
}
@ -135,7 +131,6 @@ export class Renderer {
LOG('Using voxel mesh');
LOG(voxelMesh);
this._buffer = voxelMesh.createBuffer(ambientOcclusionEnabled);
this._buffer.compile(this._gl);
this._meshToUse = MeshType.VoxelMesh;
this._voxelSize = voxelMesh?.getVoxelSize();
}
@ -144,7 +139,6 @@ export class Renderer {
LOG('Using block mesh');
LOG(blockMesh);
this._buffer = blockMesh.createBuffer(ambientOcclusionEnabled);
this._buffer.compile(this._gl);
this._meshToUse = MeshType.BlockMesh;
this._voxelSize = blockMesh.getVoxelMesh().getVoxelSize();
}
@ -190,9 +184,7 @@ export class Renderer {
// /////////////////////////////////////////////////////////////////////////
private _drawRegister(register: RenderBuffer, shaderProgram: twgl.ProgramInfo, uniforms: any) {
for (const buffer of register.WebGLBuffers) {
this._drawBuffer(this._gl.TRIANGLES, buffer, shaderProgram, uniforms);
}
this._drawBuffer(this._gl.TRIANGLES, register.getWebGLBuffer(), shaderProgram, uniforms);
}
private _setupOcclusions() {