From b2b0723b4c3feba6bbab2b73c77aef8a1b6e1832 Mon Sep 17 00:00:00 2001 From: Dave Pagurek Date: Tue, 7 Jul 2026 13:09:55 -0400 Subject: [PATCH] Fix TRIANGLE_FAN immediate mode support --- src/webgl/ShapeBuilder.js | 49 ++++++++++++ src/webgl/p5.RendererGL.js | 13 +++- src/webgpu/p5.RendererWebGPU.js | 4 + test/unit/visual/cases/webgl.js | 66 +++++++++++++++++ test/unit/visual/cases/webgpu.js | 70 +++++++++++++++++- .../000.png | Bin 0 -> 2253 bytes .../metadata.json | 3 + .../000.png | Bin 0 -> 2253 bytes .../metadata.json | 3 + .../000.png | Bin 0 -> 825 bytes .../metadata.json | 3 + .../000.png | Bin 0 -> 825 bytes .../metadata.json | 3 + .../000.png | Bin 0 -> 2266 bytes .../metadata.json | 3 + .../000.png | Bin 0 -> 2257 bytes .../metadata.json | 3 + .../000.png | Bin 0 -> 805 bytes .../metadata.json | 3 + .../000.png | Bin 0 -> 805 bytes .../metadata.json | 3 + 21 files changed, 224 insertions(+), 2 deletions(-) create mode 100644 test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/000.png create mode 100644 test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/metadata.json create mode 100644 test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN with per-vertex fills/000.png create mode 100644 test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN with per-vertex fills/metadata.json create mode 100644 test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/000.png create mode 100644 test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/metadata.json create mode 100644 test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP with per-vertex fills/000.png create mode 100644 test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP with per-vertex fills/metadata.json create mode 100644 test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/000.png create mode 100644 test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/metadata.json create mode 100644 test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN with per-vertex fills/000.png create mode 100644 test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN with per-vertex fills/metadata.json create mode 100644 test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/000.png create mode 100644 test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/metadata.json create mode 100644 test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP with per-vertex fills/000.png create mode 100644 test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP with per-vertex fills/metadata.json diff --git a/src/webgl/ShapeBuilder.js b/src/webgl/ShapeBuilder.js index 9fbcf5955c..03afb2105b 100644 --- a/src/webgl/ShapeBuilder.js +++ b/src/webgl/ShapeBuilder.js @@ -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 && @@ -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){ diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 2fa7b51d6c..502a5c6af8 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -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 { @@ -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); diff --git a/src/webgpu/p5.RendererWebGPU.js b/src/webgpu/p5.RendererWebGPU.js index 3b909230b7..47f20b700d 100644 --- a/src/webgpu/p5.RendererWebGPU.js +++ b/src/webgpu/p5.RendererWebGPU.js @@ -1325,6 +1325,10 @@ function rendererWebGPU(p5, fn) { ); } + supportsTriangleFan() { + return false; + } + viewport() {} zClipRange() { diff --git a/test/unit/visual/cases/webgl.js b/test/unit/visual/cases/webgl.js index 972d9bc5f0..618078bc81 100644 --- a/test/unit/visual/cases/webgl.js +++ b/test/unit/visual/cases/webgl.js @@ -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() { diff --git a/test/unit/visual/cases/webgpu.js b/test/unit/visual/cases/webgpu.js index 4fc098850b..c789520258 100644 --- a/test/unit/visual/cases/webgpu.js +++ b/test/unit/visual/cases/webgpu.js @@ -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) { @@ -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', diff --git a/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/000.png b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/000.png new file mode 100644 index 0000000000000000000000000000000000000000..f0534658c386dca21f647998ff9012ba3d049596 GIT binary patch literal 2253 zcmV;;2r~DHP)WH>71_RhI}=4iLxYzl<@*~_5eaY{ zhaFBGKXI-l1=&|tRwAUFeT3trgh)VIS{gOZAVL1Z5RFV{LsH0O8S-grD09V3wmK;b zkqDh?CR@m3qd^H8S-fVhLvbOS3sv61jsyuFy&@;g}fU7^;SB z;M0yemQ6)r_!+lW#f<6goEsK6G(PpX^^2KRhF=?($ic2vY8-|jq zOk5!nAY`+dtE@CB?s5|d(1Q>(V!T+&{dCbzF5z*w!bx{;4*4#R*EbNs+s`gHW+ux} z4kQ?Hg~&IJ6$E*bnf#7En(5$Cb3gV04HA7FFv*ltMGLifKlA}(dnb3rJcOXx7cR5c zjddp%Ospr#pgLhy;tEk)WwDtlTw^NtGM8U+JD;P8a`bdk&`1P~h#=i$(N8Dm@K&XX zIv$|ZB-c%V9(N8Jdy7u?A#Obk6iac1bcPaEC8iLSQ^+=fMP@OFZ?Tk}9HpAKd3iLM zKty5>QNlSoi4@XhthH9m3|}8{oi$nE{t zd4k#IXFvPsqMaaPVq}v|AGRug;$N)c9wKejYBg*%46`Za0hGM_G+WqvwHI+lOd)Ek zES9?Dmeg;qqKwCRn8P%?u!*iGp97r1R-}zf+(!VruWFsA1Nn->k2`YhHhzTTI5DO8 z3XuqJTiKJb%UbSY6D_>Nd1SBl`jrv3f$8p=_7<9J*(x~;+1hK(e)s7N z5o`DgQALtzD+TmIC;vS2Xd%Q2!tCXJj?>FYuDEM&vY2%gBy3qPukPcu*Ek^(ff?7> zNjJ}+FQ<$A0=++-nelhxrvw^AhK2B}6INM4sSoM%I4K zzg-*I%16H95Z7@I8Q+5_hGHqEVk-ybqMX$7>KHs@oRA|&jv!-?T}rpFGcfA6jLgyN z$y^L`gcU1RjH4JQWZSlF$ao4{(5uOGHZYU#Q@}dzVGTvBqJ)Q7!h@7k$ro78m-swi z<+D7(e7?=ye234_Odp%b!;T@+-L(?4CL7txN50|^mpH{;#3~d^F%?@mC>P~~85I>3 z=6CeJaYD51I1V51Q?8-ToETo9gL^r_B9rh!rm=(^HgG$O$#vHr<84k5PKmppWB7?s z&b~slp%WY+Gb&)B``>bglU!!ENm-}9*Ia*>Pt!*>^3|I5_VW(1jXWsrC%W%v7wQ;% zhOZDA4^oq~h<4uNY5v9_8B|lnT$8-M<8|_d%tGJj&(nq0v?m+c%16FdKq4_}`3YAf z+4icViRXBgyD30#wn|obgC2^RL5Pv>_BG69ADw7VkgXtJaab|2=6+(gl?vor5p4)+ zFA>K&sb&sy!TeOSgEFc{lT@MyIEy~aVMgAzYS-F5BxBb{>o%X6cC zSNOThwbeuG|NqVt&N=`900v1! bK~w_()fyW2C9RnU00000NkvXXu0mjfiDfL} literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/metadata.json b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN with per-vertex fills/000.png b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN with per-vertex fills/000.png new file mode 100644 index 0000000000000000000000000000000000000000..f0534658c386dca21f647998ff9012ba3d049596 GIT binary patch literal 2253 zcmV;;2r~DHP)WH>71_RhI}=4iLxYzl<@*~_5eaY{ zhaFBGKXI-l1=&|tRwAUFeT3trgh)VIS{gOZAVL1Z5RFV{LsH0O8S-grD09V3wmK;b zkqDh?CR@m3qd^H8S-fVhLvbOS3sv61jsyuFy&@;g}fU7^;SB z;M0yemQ6)r_!+lW#f<6goEsK6G(PpX^^2KRhF=?($ic2vY8-|jq zOk5!nAY`+dtE@CB?s5|d(1Q>(V!T+&{dCbzF5z*w!bx{;4*4#R*EbNs+s`gHW+ux} z4kQ?Hg~&IJ6$E*bnf#7En(5$Cb3gV04HA7FFv*ltMGLifKlA}(dnb3rJcOXx7cR5c zjddp%Ospr#pgLhy;tEk)WwDtlTw^NtGM8U+JD;P8a`bdk&`1P~h#=i$(N8Dm@K&XX zIv$|ZB-c%V9(N8Jdy7u?A#Obk6iac1bcPaEC8iLSQ^+=fMP@OFZ?Tk}9HpAKd3iLM zKty5>QNlSoi4@XhthH9m3|}8{oi$nE{t zd4k#IXFvPsqMaaPVq}v|AGRug;$N)c9wKejYBg*%46`Za0hGM_G+WqvwHI+lOd)Ek zES9?Dmeg;qqKwCRn8P%?u!*iGp97r1R-}zf+(!VruWFsA1Nn->k2`YhHhzTTI5DO8 z3XuqJTiKJb%UbSY6D_>Nd1SBl`jrv3f$8p=_7<9J*(x~;+1hK(e)s7N z5o`DgQALtzD+TmIC;vS2Xd%Q2!tCXJj?>FYuDEM&vY2%gBy3qPukPcu*Ek^(ff?7> zNjJ}+FQ<$A0=++-nelhxrvw^AhK2B}6INM4sSoM%I4K zzg-*I%16H95Z7@I8Q+5_hGHqEVk-ybqMX$7>KHs@oRA|&jv!-?T}rpFGcfA6jLgyN z$y^L`gcU1RjH4JQWZSlF$ao4{(5uOGHZYU#Q@}dzVGTvBqJ)Q7!h@7k$ro78m-swi z<+D7(e7?=ye234_Odp%b!;T@+-L(?4CL7txN50|^mpH{;#3~d^F%?@mC>P~~85I>3 z=6CeJaYD51I1V51Q?8-ToETo9gL^r_B9rh!rm=(^HgG$O$#vHr<84k5PKmppWB7?s z&b~slp%WY+Gb&)B``>bglU!!ENm-}9*Ia*>Pt!*>^3|I5_VW(1jXWsrC%W%v7wQ;% zhOZDA4^oq~h<4uNY5v9_8B|lnT$8-M<8|_d%tGJj&(nq0v?m+c%16FdKq4_}`3YAf z+4icViRXBgyD30#wn|obgC2^RL5Pv>_BG69ADw7VkgXtJaab|2=6+(gl?vor5p4)+ zFA>K&sb&sy!TeOSgEFc{lT@MyIEy~aVMgAzYS-F5BxBb{>o%X6cC zSNOThwbeuG|NqVt&N=`900v1! bK~w_()fyW2C9RnU00000NkvXXu0mjfiDfL} literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN with per-vertex fills/metadata.json b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN with per-vertex fills/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_FAN with per-vertex fills/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/000.png b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/000.png new file mode 100644 index 0000000000000000000000000000000000000000..029920bec7cd15708794cc5f5c14d3cebd344abc GIT binary patch literal 825 zcmV-91IGM`P)|^an(+yq_?`IP>1Td*?FaFucP(%zJn4ci#EV_r1kS{cn;;(Ik-&X*3}d zMG{47G=aogH5zQyWfMiJ9$k%qi6S)`Y}I9(Tak1+&35MW^t7`wWs0cCtKdHC!Go$Y z2m*ZZnM}r?NMBzculdI<+MV+>J5c!IH4N2p$udO*R-qBr`OPk;e8?I-v@t|GBlzLd z#@;wYD3RgeVMfV0kr3%QR=L3eu5l1wyoQNGgc1>6g~rJ7hn-d_JDp-T$Jw`e{<loMi?%RyZ%LQcBt6ILl>t(}MMiBqDn~<#VC2O3lbp^Zej2hYIH} z(~U1)uD~)Pi3qPk6BcA9`9v2Tl#(5wn+Z?6t-UG|kt$PUiF;2LSm7dP%Fgw37GJ!E ziA7W-BD@Ms@xE-@`RUK|lOx7b9dw1B>E|52cpFt>iD07AOZ%Kzqs66A5+W?n*Bf4jHY!Uk@`XK|2>oA;pJV`Eyj(#{#1au+g=P$y(syN+7syhj`=$5Y z3^3z~kF%E*5vh`83Qf2;S6JXEgJt{0XLQ}k6@2j;CKbYpi0~?u`WxANF(eeL>fVb;vO1Rk>Vb$t`j0wW2)n!M3FiU+v-t?B35In z6Iu6_FQB9-B1^@s6|Nlt{;a30v00v1!K~w_(p9CD)O)v#*00000NkvXXu0mjf D{keL> literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/metadata.json b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP with per-vertex fills/000.png b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP with per-vertex fills/000.png new file mode 100644 index 0000000000000000000000000000000000000000..029920bec7cd15708794cc5f5c14d3cebd344abc GIT binary patch literal 825 zcmV-91IGM`P)|^an(+yq_?`IP>1Td*?FaFucP(%zJn4ci#EV_r1kS{cn;;(Ik-&X*3}d zMG{47G=aogH5zQyWfMiJ9$k%qi6S)`Y}I9(Tak1+&35MW^t7`wWs0cCtKdHC!Go$Y z2m*ZZnM}r?NMBzculdI<+MV+>J5c!IH4N2p$udO*R-qBr`OPk;e8?I-v@t|GBlzLd z#@;wYD3RgeVMfV0kr3%QR=L3eu5l1wyoQNGgc1>6g~rJ7hn-d_JDp-T$Jw`e{<loMi?%RyZ%LQcBt6ILl>t(}MMiBqDn~<#VC2O3lbp^Zej2hYIH} z(~U1)uD~)Pi3qPk6BcA9`9v2Tl#(5wn+Z?6t-UG|kt$PUiF;2LSm7dP%Fgw37GJ!E ziA7W-BD@Ms@xE-@`RUK|lOx7b9dw1B>E|52cpFt>iD07AOZ%Kzqs66A5+W?n*Bf4jHY!Uk@`XK|2>oA;pJV`Eyj(#{#1au+g=P$y(syN+7syhj`=$5Y z3^3z~kF%E*5vh`83Qf2;S6JXEgJt{0XLQ}k6@2j;CKbYpi0~?u`WxANF(eeL>fVb;vO1Rk>Vb$t`j0wW2)n!M3FiU+v-t?B35In z6Iu6_FQB9-B1^@s6|Nlt{;a30v00v1!K~w_(p9CD)O)v#*00000NkvXXu0mjf D{keL> literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP with per-vertex fills/metadata.json b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP with per-vertex fills/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGL/2D Shapes/TRIANGLE_STRIP with per-vertex fills/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/000.png b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/000.png new file mode 100644 index 0000000000000000000000000000000000000000..78d1441c5559c626cc56f7724336104ae60f7d3c GIT binary patch literal 2266 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 literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/metadata.json b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN in p5.Geometry with per-vertex fills/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN with per-vertex fills/000.png b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN with per-vertex fills/000.png new file mode 100644 index 0000000000000000000000000000000000000000..71c91bb91df6d47b10687116c7abaa7a0784c242 GIT binary patch literal 2257 zcmV;?2rl=DP)4mzX zW&!zQi&Fy`6ZcDFT%$o2+tM;Bb8FEijE)~;ZM3UO2Dh}OEp2_j=jOdV_s6;SwwGjv z@Ro;j&-*^l_xXO`=XuXPZT8e_@5ADPRoT+O3t*(7Z!rZG4{R#ui% zNirC-7NVV$h>q4x6tLb{IXO&_%WLLyD5=RuoC_#7e(TK!Jf3lNW-P>3VN0-uc?=Su z0zX5JNk~4!W=`|orfPhQhn*P3&gZ)h*4E(UtSd7kAy&k}*41Vw{}3S}GCm`qgmwIv zr_EX@sf}=$1(cx}KSL3m02`e1m6bK~R!dumTB)u!$W`n!B-clhi-^yN@EbzcQi`fF z&LIK}dfGX;xainoenAcsv{OwVyG)XJ5q=}=b}DJ7nE-=P*2hV5 z3AdGxcrkjK3Hus8g>uc~W|TXZ$5K9)QwquFdk&ZYWsCSarQF9cUgRBKh=_3$D`SD7 z+(*Ch2rwRT)nqwyi9f`?`#~S<7>dz$Uii z7U3scrJE=;^V99MpANoESww{O`wvGE#sF_4%tDqrxN``1fxV_`FHa$ukxjU*<}w}y zZtp9(orUJ7k|vKdSjbm+1d*1HuGZ{*s`l~} zqA#SY_`U;fK@(l;sN!Mn;S{}S*Dc9g@X^f~3J5v2m*cFX7`rZCnPP>J2-`iEOQq9Z zc#MQX61A1x84K>dFXdW(z~{(ef<~G-&c6`h6$I#^pS_&mA&Q(it;t8eicxGLOwGA- z=w9vRbxslrk?3qDi3Lh^|1}n~oU7SDC(m;Vz0m*Ch_Y>^IjybbdgLo|)>2_>Jz0At z6q0URSrYE+gOuUpmoSmF?=CpRie3q|UjC@nwyDLo0NGL=VQ3+E4+w~sa z=g0h+338~Xj>U$!UR0i?AAQ4@QiLj{IjzY@zKT(-#YrV*f=0B-F&doPghI3;G3m5d zGwnRX%jk_)CbF_!^cfM034gB_P{sn@U>L2*pX9AoNx01f2WEz@>v-nWCd6;W8_k7XuE~z zvs!6C9ZsC}wXwPuvkqbFL7-e#jM^$AArhnZ((A#1*{wV(Dd9PXh!Q6<5p1Iw{WT>- zxUKAU7(egvF2neeV(1G{x!z-;@q3C18k4paW+bhMc0o4EHs;YpE}IOn9}$ry5^{*w zD58`>rrXMXp3ib;?Ie8;PHem|Wtvwm9>NrjkoXD1|Pgf~zEx7nobIknXS z$_T|&!`?6DUOH(?3rjhxYqA{<;*!i#3XzDGmKN%RISf)@tTT#4teB&`jNXw3iLZ#} zM)09C;1(Z?p%;GrO-nhITO5*!&{|3%a+2xb>pkZJcbMJYkx)(P4rX(n0O$BwM9{x^hHR=CH1o-91Rw793b#^# zhG6ZiL}13OgqS#|>}s`for#3xS6;oBy?uba|Kr5%0WhBIcN|36vIaueMADy98 zCVxGVWELlr>m?B)0unP*%d`s0YweN=v49`e^@@-WYv;Z4UN#l^9{>OV|NrTAac2Mk f00v1!K~w_((AFCFipB;J00000NkvXXu0mjfxC<~r literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN with per-vertex fills/metadata.json b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN with per-vertex fills/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_FAN with per-vertex fills/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/000.png b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/000.png new file mode 100644 index 0000000000000000000000000000000000000000..8257a3adda334bbce49e344806090e0754009163 GIT binary patch literal 805 zcmV+=1KRwFP)rz2C3fab`f+koY zU5Lc4s-Qv(S~nW1LJ3rz6KEPHlgXQTNgBdjxOC?AotJy=cOOaOUzbFJE{WJkr-6)# z#6()ufq1l9)Y!8+Dna*@$vEUA*a~Eb^1f+YyP6J(W{wConx9cMkJJ(SxWq3SE#(l1~c?CLLal1 zdW|+A!q-SLnPh?WP$p!0jv|*i$W;ztt8W?+QJHtg=3@hfzmmz-d#uF*Xl$5t;QN&=#x5ou*6&x@Kn@WwSU%v8;~zDuf8BbK++H=<%> zMB}yUGVu~AkYSLEc-Ot}N14V}-!vkkvdouC(FL9{$R)f*`@Q!u!rtjQw5AcW)z_mE%815modt@_(ZfxGiuU_oFE_B&H;ss>BsfD6 z{csPLe|U?+R_|vf6cH7X&1SjnoaL6&6Db|XvDT}Zs--$Z8ReN@*F`40d9|Nq<- jN#Xzi00v1!K~w_(JqRw@PB?k?00000NkvXXu0mjf4`O+Y literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/metadata.json b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP in p5.Geometry with per-vertex fills/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file diff --git a/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP with per-vertex fills/000.png b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP with per-vertex fills/000.png new file mode 100644 index 0000000000000000000000000000000000000000..8257a3adda334bbce49e344806090e0754009163 GIT binary patch literal 805 zcmV+=1KRwFP)rz2C3fab`f+koY zU5Lc4s-Qv(S~nW1LJ3rz6KEPHlgXQTNgBdjxOC?AotJy=cOOaOUzbFJE{WJkr-6)# z#6()ufq1l9)Y!8+Dna*@$vEUA*a~Eb^1f+YyP6J(W{wConx9cMkJJ(SxWq3SE#(l1~c?CLLal1 zdW|+A!q-SLnPh?WP$p!0jv|*i$W;ztt8W?+QJHtg=3@hfzmmz-d#uF*Xl$5t;QN&=#x5ou*6&x@Kn@WwSU%v8;~zDuf8BbK++H=<%> zMB}yUGVu~AkYSLEc-Ot}N14V}-!vkkvdouC(FL9{$R)f*`@Q!u!rtjQw5AcW)z_mE%815modt@_(ZfxGiuU_oFE_B&H;ss>BsfD6 z{csPLe|U?+R_|vf6cH7X&1SjnoaL6&6Db|XvDT}Zs--$Z8ReN@*F`40d9|Nq<- jN#Xzi00v1!K~w_(JqRw@PB?k?00000NkvXXu0mjf4`O+Y literal 0 HcmV?d00001 diff --git a/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP with per-vertex fills/metadata.json b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP with per-vertex fills/metadata.json new file mode 100644 index 0000000000..2d4bfe30da --- /dev/null +++ b/test/unit/visual/screenshots/WebGPU/2D Shapes/TRIANGLE_STRIP with per-vertex fills/metadata.json @@ -0,0 +1,3 @@ +{ + "numScreenshots": 1 +} \ No newline at end of file