Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGL mode refactor #7355

Merged
merged 9 commits into from
Nov 4, 2024
210 changes: 110 additions & 100 deletions src/webgl/3d_primitives.js

Large diffs are not rendered by default.

109 changes: 109 additions & 0 deletions src/webgl/GeometryBufferCache.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
export class GeometryBufferCache {
constructor(renderer) {
this.renderer = renderer;
this.cache = {};
}

numCached() {
return Object.keys(this.cache).length;
}

isCached(gid) {
return this.cache[gid] !== undefined;
}

getGeometryByID(gid) {
return this.cache[gid]?.geometry;
}

getCached(model) {
return this.getCachedID(model.gid);
}

getCachedID(gid) {
return this.cache[gid];
}

ensureCached(geometry) {
const gid = geometry.gid;
if (!gid) {
throw new Error('The p5.Geometry you passed in has no gid property!');
}

if (this.isCached(geometry.gid)) return this.getCached(geometry);

const gl = this.renderer.GL;

//initialize the gl buffers for our geom groups
this.freeBuffers(gid);

if (Object.keys(this.cache).length > 1000) {
const key = Object.keys(this.cache)[0];
this.freeBuffers(key);
}

//create a new entry in our cache
const buffers = {};
this.cache[gid] = buffers;

buffers.geometry = geometry;

let indexBuffer = buffers.indexBuffer;

if (geometry.faces.length) {
// allocate space for faces
if (!indexBuffer) indexBuffer = buffers.indexBuffer = gl.createBuffer();
const vals = geometry.faces.flat();

// If any face references a vertex with an index greater than the maximum
// un-singed 16 bit integer, then we need to use a Uint32Array instead of a
// Uint16Array
const hasVertexIndicesOverMaxUInt16 = vals.some(v => v > 65535);
let type = hasVertexIndicesOverMaxUInt16 ? Uint32Array : Uint16Array;
this.renderer._bindBuffer(indexBuffer, gl.ELEMENT_ARRAY_BUFFER, vals, type);

// If we're using a Uint32Array for our indexBuffer we will need to pass a
// different enum value to WebGL draw triangles. This happens in
// the _drawElements function.
buffers.indexBufferType = hasVertexIndicesOverMaxUInt16
? gl.UNSIGNED_INT
: gl.UNSIGNED_SHORT;
} else {
// the index buffer is unused, remove it
if (indexBuffer) {
gl.deleteBuffer(indexBuffer);
buffers.indexBuffer = null;
}
}

return buffers;
}

freeBuffers(gid) {
const buffers = this.cache[gid];
if (!buffers) {
return;
}

delete this.cache[gid];

const gl = this.renderer.GL;
if (buffers.indexBuffer) {
gl.deleteBuffer(buffers.indexBuffer);
}

function freeBuffers(defs) {
for (const def of defs) {
if (buffers[def.dst]) {
gl.deleteBuffer(buffers[def.dst]);
buffers[def.dst] = null;
}
}
}

// free all the buffers
freeBuffers(this.renderer.buffers.stroke);
freeBuffers(this.renderer.buffers.fill);
freeBuffers(this.renderer.buffers.user);
}
}
6 changes: 2 additions & 4 deletions src/webgl/GeometryBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,7 @@ class GeometryBuilder {
* Adds geometry from the renderer's immediate mode into the builder's
* combined geometry.
*/
addImmediate() {
const geometry = this.renderer.immediateMode.geometry;
const shapeMode = this.renderer.immediateMode.shapeMode;
addImmediate(geometry, shapeMode) {
const faces = [];

if (this.renderer.states.doFill) {
Expand Down Expand Up @@ -143,7 +141,7 @@ class GeometryBuilder {
* combined geometry.
*/
addRetained(geometry) {
this.addGeometry(geometry.model);
this.addGeometry(geometry);
}

/**
Expand Down
Loading
Loading