Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/webgl/ShapeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ export class ShapeBuilder {
this.shapeMode = constants.TRIANGLES;
}

if (
!this.renderer.geometryBuilder &&
this.shapeMode === constants.TRIANGLE_FAN &&
!this.renderer.supportsTriangleFan()
) {
this._convertFanToTriangles();
this.shapeMode = constants.TRIANGLES;
}

if (
this.renderer.states.textureMode === constants.IMAGE &&
this.renderer.states._tex !== null &&
Expand All @@ -205,6 +214,46 @@ export class ShapeBuilder {
}
}

_remapVertices(newIndices) {
this.geometry.vertices = newIndices.map(i => this.geometry.vertices[i]);
this.geometry.vertexNormals = newIndices.map(i => this.geometry.vertexNormals[i]);

const remapFlat = (arr, stride) => {
const result = [];
for (const i of newIndices) {
for (let j = 0; j < stride; j++) {
result.push(arr[i * stride + j]);
}
}
return result;
};

this.geometry.uvs = remapFlat(this.geometry.uvs, 2);
this.geometry.vertexColors = remapFlat(this.geometry.vertexColors, 4);
this.geometry.vertexStrokeColors = remapFlat(this.geometry.vertexStrokeColors, 4);

for (const propName in this.geometry.userVertexProperties) {
const prop = this.geometry.userVertexProperties[propName];
const size = prop.getDataSize();
const oldData = prop.getSrcArray();
prop.resetSrcArray();
for (const i of newIndices) {
prop.setCurrentData(oldData.slice(i * size, i * size + size));
prop.pushCurrentData();
}
}
}

_convertFanToTriangles() {
const n = this.geometry.vertices.length;
if (n < 3) return;
const newIndices = [];
for (let i = 2; i < n; i++) {
newIndices.push(0, i - 1, i);
}
this._remapVertices(newIndices);
}

_resetUserVertexProperties() {
const properties = this.geometry.userVertexProperties;
for (const propName in properties){
Expand Down
13 changes: 12 additions & 1 deletion src/webgl/p5.RendererGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,14 @@ class RendererGL extends Renderer3D {
}
}
} else {
const glMode = mode === constants.TRIANGLES ? gl.TRIANGLES : gl.TRIANGLE_STRIP;
let glMode;
if (mode === constants.TRIANGLES) {
glMode = gl.TRIANGLES;
} else if (mode === constants.TRIANGLE_FAN) {
glMode = gl.TRIANGLE_FAN;
} else {
glMode = gl.TRIANGLE_STRIP;
}
if (count === 1) {
gl.drawArrays(glMode, 0, geometry.vertices.length);
} else {
Expand Down Expand Up @@ -595,6 +602,10 @@ class RendererGL extends Renderer3D {
return 10;
}

supportsTriangleFan() {
return true;
}

viewport(w, h) {
this._viewport = [0, 0, w, h];
this.GL.viewport(0, 0, w, h);
Expand Down
4 changes: 4 additions & 0 deletions src/webgpu/p5.RendererWebGPU.js
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,10 @@ function rendererWebGPU(p5, fn) {
);
}

supportsTriangleFan() {
return false;
}

viewport() {}

zClipRange() {
Expand Down
66 changes: 66 additions & 0 deletions test/unit/visual/cases/webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -1627,6 +1627,72 @@ visualTest('randomGaussian() in a fragment loop averages to the mean', (p5, scre
p5.rect(-20, -20, 40, 40, 20);
screenshot();
});

visualTest('TRIANGLE_FAN with per-vertex fills', function(p5, screenshot) {
p5.createCanvas(50, 50, p5.WEBGL);
p5.background(255);
p5.beginShape(p5.TRIANGLE_FAN);
p5.fill('red');
p5.vertex(0, 0);
const n = 10;
const r = 20;
p5.fill('blue');
for (let i = 0; i <= n; i++) {
const angle = i/n * p5.TWO_PI;
p5.vertex(r*p5.cos(angle), r*p5.sin(angle));
}
p5.endShape();
screenshot();
});

visualTest('TRIANGLE_FAN in p5.Geometry with per-vertex fills', function(p5, screenshot) {
p5.createCanvas(50, 50, p5.WEBGL);
p5.background(255);
const geom = p5.buildGeometry(() => {
p5.beginShape(p5.TRIANGLE_FAN);
p5.fill('red');
p5.vertex(0, 0);
const n = 10;
const r = 20;
p5.fill('blue');
for (let i = 0; i <= n; i++) {
const angle = i/n * p5.TWO_PI;
p5.vertex(r*p5.cos(angle), r*p5.sin(angle));
}
p5.endShape();
});
p5.model(geom);
screenshot();
});

visualTest('TRIANGLE_STRIP with per-vertex fills', function(p5, screenshot) {
p5.createCanvas(50, 50, p5.WEBGL);
p5.background(255);
p5.beginShape(p5.TRIANGLE_STRIP);
const n = 6;
for (let i = 0; i < n; i++) {
p5.fill(i % 2 === 0 ? 'red' : 'blue');
p5.vertex(p5.map(i, 0, n - 1, -20, 20), i % 2 === 0 ? -10 : 10);
}
p5.endShape();
screenshot();
});

visualTest('TRIANGLE_STRIP in p5.Geometry with per-vertex fills', function(p5, screenshot) {
p5.createCanvas(50, 50, p5.WEBGL);
p5.background(255);
const geom = p5.buildGeometry(() => {
p5.beginShape(p5.TRIANGLE_STRIP);
const n = 6;
for (let i = 0; i < n; i++) {
p5.fill(i % 2 === 0 ? 'red' : 'blue');
p5.vertex(p5.map(i, 0, n - 1, -20, 20), i % 2 === 0 ? -10 : 10);
}
p5.endShape();
});
p5.model(geom);
screenshot();
});
});

visualSuite('3D Primitives', function() {
Expand Down
70 changes: 69 additions & 1 deletion test/unit/visual/cases/webgpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ visualSuite("WebGPU", function () {
p5.shader(shader);
p5.plane(20, 20);
await screenshot();
}, { focus: true });
});
});

visualTest('randomGaussian() colors a basic shader (WebGPU)', async function(p5, screenshot) {
Expand Down Expand Up @@ -1664,6 +1664,74 @@ visualTest('randomGaussian() in a fragment loop averages to the mean (WebGPU)',
);
});

visualSuite('2D Shapes', function() {
visualTest('TRIANGLE_FAN with per-vertex fills', async function(p5, screenshot) {
await p5.createCanvas(50, 50, p5.WEBGPU);
p5.background(255);
p5.beginShape(p5.TRIANGLE_FAN);
p5.fill('red');
p5.vertex(0, 0);
const n = 10;
const r = 20;
p5.fill('blue');
for (let i = 0; i <= n; i++) {
const angle = i/n * p5.TWO_PI;
p5.vertex(r*p5.cos(angle), r*p5.sin(angle));
}
p5.endShape();
await screenshot();
});

visualTest('TRIANGLE_FAN in p5.Geometry with per-vertex fills', async function(p5, screenshot) {
await p5.createCanvas(50, 50, p5.WEBGPU);
p5.background(255);
const geom = p5.buildGeometry(() => {
p5.beginShape(p5.TRIANGLE_FAN);
p5.fill('red');
p5.vertex(0, 0);
const n = 10;
const r = 20;
p5.fill('blue');
for (let i = 0; i <= n; i++) {
const angle = i/n * p5.TWO_PI;
p5.vertex(r*p5.cos(angle), r*p5.sin(angle));
}
p5.endShape();
});
p5.model(geom);
await screenshot();
});

visualTest('TRIANGLE_STRIP with per-vertex fills', async function(p5, screenshot) {
await p5.createCanvas(50, 50, p5.WEBGPU);
p5.background(255);
p5.beginShape(p5.TRIANGLE_STRIP);
const n = 6;
for (let i = 0; i < n; i++) {
p5.fill(i % 2 === 0 ? 'red' : 'blue');
p5.vertex(p5.map(i, 0, n - 1, -20, 20), i % 2 === 0 ? -10 : 10);
}
p5.endShape();
await screenshot();
});

visualTest('TRIANGLE_STRIP in p5.Geometry with per-vertex fills', async function(p5, screenshot) {
await p5.createCanvas(50, 50, p5.WEBGPU);
p5.background(255);
const geom = p5.buildGeometry(() => {
p5.beginShape(p5.TRIANGLE_STRIP);
const n = 6;
for (let i = 0; i < n; i++) {
p5.fill(i % 2 === 0 ? 'red' : 'blue');
p5.vertex(p5.map(i, 0, n - 1, -20, 20), i % 2 === 0 ? -10 : 10);
}
p5.endShape();
});
p5.model(geom);
await screenshot();
});
});

visualSuite('Feedback', function() {
visualTest(
'Drawing accumulates across frames when background is set in setup',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"numScreenshots": 1
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"numScreenshots": 1
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"numScreenshots": 1
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"numScreenshots": 1
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"numScreenshots": 1
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"numScreenshots": 1
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"numScreenshots": 1
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"numScreenshots": 1
}
Loading