diff --git a/src/core/constants.js b/src/core/constants.js
index bb120fa712..5ffefa0b46 100644
--- a/src/core/constants.js
+++ b/src/core/constants.js
@@ -60,6 +60,18 @@ export const WEBGL2 = Symbol('webgl2');
* @final
*/
export const ARROW = 'default';
+
+/**
+ * @property {String} SIMPLE
+ * @final
+ */
+export const SIMPLE = 'simple';
+/**
+ * @property {String} FULL
+ * @final
+ */
+export const FULL = 'full';
+
/**
* @typedef {'crosshair'} CROSS
* @property {CROSS} CROSS
@@ -1318,4 +1330,4 @@ export const HALF_FLOAT = 'half-float';
* @property {RGBA} RGBA
* @final
*/
-export const RGBA = 'rgba';
+export const RGBA = 'rgba';
\ No newline at end of file
diff --git a/src/webgl/3d_primitives.js b/src/webgl/3d_primitives.js
index 869b7ab240..96b0593a1b 100644
--- a/src/webgl/3d_primitives.js
+++ b/src/webgl/3d_primitives.js
@@ -520,6 +520,93 @@ function primitives3D(p5, fn){
return this._renderer.endGeometry();
};
+
+/**
+ * Sets the stroke rendering mode to balance performance and visual features when drawing lines.
+ *
+ * `strokeMode()` offers two modes:
+ *
+ * - `SIMPLE`: Optimizes for speed by disabling caps, joins, and stroke color features.
+ * Use this mode for faster line rendering when these visual details are unnecessary.
+ * - `FULL`: Enables caps, joins, and stroke color for lines.
+ * This mode provides enhanced visuals but may reduce performance due to additional processing.
+ *
+ * Choose the mode that best suits your application's needs to either improve rendering speed or enhance visual quality.
+ *
+ * @method strokeMode
+ * @param {string} mode - The stroke mode to set. Possible values are:
+ * - `'SIMPLE'`: Fast rendering without caps, joins, or stroke color.
+ * - `'FULL'`: Detailed rendering with caps, joins, and stroke color.
+ *
+ * @example
+ *
+ *
+ * function setup() {
+ * createCanvas(300, 300, WEBGL);
+ *
+ * describe('A sphere with red stroke and a red, wavy line on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(128);
+ * strokeMode(FULL); // Enables detailed rendering with caps, joins, and stroke color.
+ * push();
+ * strokeWeight(1);
+ * translate(0, -50, 0);
+ * sphere(50);
+ * pop();
+ *
+ * noFill();
+ * strokeWeight(15);
+ * beginShape();
+ * vertex(-150, 100);
+ * stroke('red');
+ * bezierVertex(-50, -100, 30, 300, 130, 50);
+ * endShape();
+ * }
+ *
+ *
+ *
+ *
+ *
+ * function setup() {
+ * createCanvas(300, 300, WEBGL);
+ *
+ * describe('A sphere with red stroke and a wavy line without full curve decorations without caps and color on a gray background.');
+ * }
+ *
+ * function draw() {
+ * background(128);
+ * strokeMode(SIMPLE); // Enables simple rendering without caps, joins, and stroke color.
+ * push();
+ * strokeWeight(1);
+ * translate(0, -50, 0);
+ * sphere(50);
+ * pop();
+ *
+ * noFill();
+ * strokeWeight(15);
+ * beginShape();
+ * vertex(-150, 100);
+ * stroke('red');
+ * bezierVertex(-50, -100, 30, 300, 130, 50);
+ * endShape();
+ * }
+ *
+ *
+ */
+
+ fn.strokeMode = function (mode) {
+ if (mode === undefined) {
+ return this._renderer._simpleLines ? constants.SIMPLE : constants.FULL;
+ } else if (mode === constants.SIMPLE) {
+ this._renderer._simpleLines = true;
+ } else if (mode === constants.FULL) {
+ this._renderer._simpleLines = false;
+ } else {
+ throw Error('no such parameter');
+ }
+ }
/**
* Creates a custom p5.Geometry object from
* simpler 3D shapes.
@@ -2109,7 +2196,7 @@ function primitives3D(p5, fn){
this.faces = [[0, 1, 2]];
this.uvs = [0, 0, 1, 0, 1, 1];
};
- const triGeom = new Geometry(1, 1, _triangle);
+ const triGeom = new Geometry(1, 1, _triangle, this);
triGeom._edgesToVertices();
triGeom.computeNormals();
triGeom.gid = gid;
@@ -2245,7 +2332,7 @@ function primitives3D(p5, fn){
}
};
- const arcGeom = new Geometry(detail, 1, _arc);
+ const arcGeom = new Geometry(detail, 1, _arc, this);
arcGeom.computeNormals();
if (detail <= 50) {
@@ -2308,7 +2395,7 @@ function primitives3D(p5, fn){
];
}
};
- const rectGeom = new Geometry(detailX, detailY, _rect);
+ const rectGeom = new Geometry(detailX, detailY, _rect, this);
rectGeom
.computeFaces()
.computeNormals()
@@ -2440,7 +2527,7 @@ function primitives3D(p5, fn){
this.uvs.push([pctx, pcty]);
}
}
- });
+ }, this);
quadGeom.faces = [];
for(let y = 0; y < detailY-1; y++){
@@ -3362,7 +3449,7 @@ function primitives3D(p5, fn){
}
}
};
- const planeGeom = new Geometry(detailX, detailY, _plane);
+ const planeGeom = new Geometry(detailX, detailY, _plane, this);
planeGeom.computeFaces().computeNormals();
if (detailX <= 1 && detailY <= 1) {
planeGeom._makeTriangleEdges()._edgesToVertices();
@@ -3442,7 +3529,7 @@ function primitives3D(p5, fn){
this.faces.push([v + 2, v + 1, v + 3]);
});
};
- const boxGeom = new Geometry(detailX, detailY, _box);
+ const boxGeom = new Geometry(detailX, detailY, _box, this);
boxGeom.computeNormals();
if (detailX <= 4 && detailY <= 4) {
boxGeom._edgesToVertices();
@@ -3498,7 +3585,7 @@ function primitives3D(p5, fn){
}
}
};
- const ellipsoidGeom = new Geometry(detailX, detailY, _ellipsoid);
+ const ellipsoidGeom = new Geometry(detailX, detailY, _ellipsoid, this);
ellipsoidGeom.computeFaces();
if (detailX <= 24 && detailY <= 24) {
ellipsoidGeom._makeTriangleEdges()._edgesToVertices();
@@ -3525,17 +3612,18 @@ function primitives3D(p5, fn){
) {
const gid = `cylinder|${detailX}|${detailY}|${bottomCap}|${topCap}`;
if (!this.geometryInHash(gid)) {
- const cylinderGeom = new p5.Geometry(detailX, detailY);
- _truncatedCone.call(
- cylinderGeom,
- 1,
- 1,
- 1,
- detailX,
- detailY,
- bottomCap,
- topCap
- );
+ const cylinderGeom = new p5.Geometry(detailX, detailY, function() {
+ _truncatedCone.call(
+ this,
+ 1,
+ 1,
+ 1,
+ detailX,
+ detailY,
+ bottomCap,
+ topCap
+ );
+ }, this);
// normals are computed in call to _truncatedCone
if (detailX <= 24 && detailY <= 16) {
cylinderGeom._makeTriangleEdges()._edgesToVertices();
@@ -3561,8 +3649,18 @@ function primitives3D(p5, fn){
) {
const gid = `cone|${detailX}|${detailY}|${cap}`;
if (!this.geometryInHash(gid)) {
- const coneGeom = new Geometry(detailX, detailY);
- _truncatedCone.call(coneGeom, 1, 0, 1, detailX, detailY, cap, false);
+ const coneGeom = new Geometry(detailX, detailY, function() {
+ _truncatedCone.call(
+ this,
+ 1,
+ 0,
+ 1,
+ detailX,
+ detailY,
+ cap,
+ false
+ );
+ }, this);
if (detailX <= 24 && detailY <= 16) {
coneGeom._makeTriangleEdges()._edgesToVertices();
} else if (this.states.doStroke) {
@@ -3624,7 +3722,7 @@ function primitives3D(p5, fn){
}
}
};
- const torusGeom = new Geometry(detailX, detailY, _torus);
+ const torusGeom = new Geometry(detailX, detailY, _torus, this);
torusGeom.computeFaces();
if (detailX <= 24 && detailY <= 16) {
torusGeom._makeTriangleEdges()._edgesToVertices();
diff --git a/src/webgl/GeometryBuilder.js b/src/webgl/GeometryBuilder.js
index a5691db31e..6d269282c2 100644
--- a/src/webgl/GeometryBuilder.js
+++ b/src/webgl/GeometryBuilder.js
@@ -13,7 +13,7 @@ class GeometryBuilder {
renderer._pInst.push();
this.identityMatrix = new Matrix();
renderer.states.uModelMatrix = new Matrix();
- this.geometry = new Geometry();
+ this.geometry = new Geometry(undefined, undefined, undefined, this.renderer);
this.geometry.gid = `_p5_GeometryBuilder_${GeometryBuilder.nextGeometryId}`;
GeometryBuilder.nextGeometryId++;
this.hasTransform = false;
diff --git a/src/webgl/ShapeBuilder.js b/src/webgl/ShapeBuilder.js
index 258f8c07e8..12d8798d63 100644
--- a/src/webgl/ShapeBuilder.js
+++ b/src/webgl/ShapeBuilder.js
@@ -21,7 +21,7 @@ export class ShapeBuilder {
constructor(renderer) {
this.renderer = renderer;
this.shapeMode = constants.TESS;
- this.geometry = new Geometry();
+ this.geometry = new Geometry(undefined, undefined, undefined, this.renderer);
this.geometry.gid = '__IMMEDIATE_MODE_GEOMETRY__';
this.contourIndices = [];
diff --git a/src/webgl/loading.js b/src/webgl/loading.js
index 66270dbb0a..28c6099432 100755
--- a/src/webgl/loading.js
+++ b/src/webgl/loading.js
@@ -377,7 +377,7 @@ function loading(p5, fn){
fileType = '.obj';
}
- const model = new Geometry();
+ const model = new Geometry(undefined, undefined, undefined, this._renderer);
model.gid = `${path}|${normalize}`;
async function getMaterials(lines) {
diff --git a/src/webgl/p5.Geometry.js b/src/webgl/p5.Geometry.js
index a5d5297b21..afaf4c3b7c 100644
--- a/src/webgl/p5.Geometry.js
+++ b/src/webgl/p5.Geometry.js
@@ -13,7 +13,8 @@ import { DataArray } from './p5.DataArray';
import { Vector } from '../math/p5.Vector';
class Geometry {
- constructor(detailX, detailY, callback) {
+ constructor(detailX, detailY, callback, renderer) {
+ this.renderer = renderer;
this.vertices = [];
this.boundingBoxCache = null;
@@ -489,7 +490,7 @@ class Geometry {
if (binary) {
let offset = 80;
const bufferLength =
- this.faces.length * 2 + this.faces.length * 3 * 4 * 4 + 80 + 4;
+ this.faces.length * 2 + this.faces.length * 3 * 4 * 4 + 80 + 4;
const arrayBuffer = new ArrayBuffer(bufferLength);
modelOutput = new DataView(arrayBuffer);
modelOutput.setUint32(offset, this.faces.length, true);
@@ -1398,88 +1399,89 @@ class Geometry {
if (dirOK) {
this._addSegment(begin, end, fromColor, toColor, dir);
}
-
- if (i > 0 && prevEdge[1] === currEdge[0]) {
- if (!connected.has(currEdge[0])) {
- connected.add(currEdge[0]);
- potentialCaps.delete(currEdge[0]);
- // Add a join if this segment shares a vertex with the previous. Skip
- // actually adding join vertices if either the previous segment or this
- // one has a length of 0.
- //
- // Don't add a join if the tangents point in the same direction, which
- // would mean the edges line up exactly, and there is no need for a join.
- if (lastValidDir && dirOK && dir.dot(lastValidDir) < 1 - 1e-8) {
- this._addJoin(begin, lastValidDir, dir, fromColor);
- }
- }
- } else {
- // Start a new line
- if (dirOK && !connected.has(currEdge[0])) {
- const existingCap = potentialCaps.get(currEdge[0]);
- if (existingCap) {
- this._addJoin(
- begin,
- existingCap.dir,
- dir,
- fromColor
- );
- potentialCaps.delete(currEdge[0]);
+ if (!this.renderer?._simpleLines) {
+ if (i > 0 && prevEdge[1] === currEdge[0]) {
+ if (!connected.has(currEdge[0])) {
connected.add(currEdge[0]);
- } else {
- potentialCaps.set(currEdge[0], {
- point: begin,
- dir: dir.copy().mult(-1),
- color: fromColor
- });
+ potentialCaps.delete(currEdge[0]);
+ // Add a join if this segment shares a vertex with the previous. Skip
+ // actually adding join vertices if either the previous segment or this
+ // one has a length of 0.
+ //
+ // Don't add a join if the tangents point in the same direction, which
+ // would mean the edges line up exactly, and there is no need for a join.
+ if (lastValidDir && dirOK && dir.dot(lastValidDir) < 1 - 1e-8) {
+ this._addJoin(begin, lastValidDir, dir, fromColor);
+ }
+ }
+ } else {
+ // Start a new line
+ if (dirOK && !connected.has(currEdge[0])) {
+ const existingCap = potentialCaps.get(currEdge[0]);
+ if (existingCap) {
+ this._addJoin(
+ begin,
+ existingCap.dir,
+ dir,
+ fromColor
+ );
+ potentialCaps.delete(currEdge[0]);
+ connected.add(currEdge[0]);
+ } else {
+ potentialCaps.set(currEdge[0], {
+ point: begin,
+ dir: dir.copy().mult(-1),
+ color: fromColor
+ });
+ }
+ }
+ if (lastValidDir && !connected.has(prevEdge[1])) {
+ const existingCap = potentialCaps.get(prevEdge[1]);
+ if (existingCap) {
+ this._addJoin(
+ this.vertices[prevEdge[1]],
+ lastValidDir,
+ existingCap.dir.copy().mult(-1),
+ fromColor
+ );
+ potentialCaps.delete(prevEdge[1]);
+ connected.add(prevEdge[1]);
+ } else {
+ // Close off the last segment with a cap
+ potentialCaps.set(prevEdge[1], {
+ point: this.vertices[prevEdge[1]],
+ dir: lastValidDir,
+ color: fromColor
+ });
+ }
+ lastValidDir = undefined;
}
}
- if (lastValidDir && !connected.has(prevEdge[1])) {
- const existingCap = potentialCaps.get(prevEdge[1]);
+
+ if (i === this.edges.length - 1 && !connected.has(currEdge[1])) {
+ const existingCap = potentialCaps.get(currEdge[1]);
if (existingCap) {
this._addJoin(
- this.vertices[prevEdge[1]],
- lastValidDir,
+ end,
+ dir,
existingCap.dir.copy().mult(-1),
- fromColor
+ toColor
);
- potentialCaps.delete(prevEdge[1]);
- connected.add(prevEdge[1]);
+ potentialCaps.delete(currEdge[1]);
+ connected.add(currEdge[1]);
} else {
- // Close off the last segment with a cap
- potentialCaps.set(prevEdge[1], {
- point: this.vertices[prevEdge[1]],
- dir: lastValidDir,
- color: fromColor
+ potentialCaps.set(currEdge[1], {
+ point: end,
+ dir,
+ color: toColor
});
}
- lastValidDir = undefined;
}
- }
- if (i === this.edges.length - 1 && !connected.has(currEdge[1])) {
- const existingCap = potentialCaps.get(currEdge[1]);
- if (existingCap) {
- this._addJoin(
- end,
- dir,
- existingCap.dir.copy().mult(-1),
- toColor
- );
- potentialCaps.delete(currEdge[1]);
- connected.add(currEdge[1]);
- } else {
- potentialCaps.set(currEdge[1], {
- point: end,
- dir,
- color: toColor
- });
+ if (dirOK) {
+ lastValidDir = dir;
}
}
-
- if (dirOK) {
- lastValidDir = dir;
- }
}
for (const { point, dir, color } of potentialCaps.values()) {
this._addCap(point, dir, color);
@@ -1520,14 +1522,16 @@ class Geometry {
}
}
this.lineVertices.push(...a, ...b, ...a, ...b, ...b, ...a);
- this.lineVertexColors.push(
- ...fromColor,
- ...toColor,
- ...fromColor,
- ...toColor,
- ...toColor,
- ...fromColor
- );
+ if (!this.renderer?._simpleLines) {
+ this.lineVertexColors.push(
+ ...fromColor,
+ ...toColor,
+ ...fromColor,
+ ...toColor,
+ ...toColor,
+ ...fromColor
+ );
+ }
return this;
}
@@ -1684,110 +1688,110 @@ class Geometry {
return this;
}
-/** Sets the shader's vertex property or attribute variables.
- *
- * An vertex property or vertex attribute is a variable belonging to a vertex in a shader. p5.js provides some
- * default properties, such as `aPosition`, `aNormal`, `aVertexColor`, etc. These are
- * set using vertex(), normal()
- * and fill() respectively. Custom properties can also
- * be defined within beginShape() and
- * endShape().
- *
- * The first parameter, `propertyName`, is a string with the property's name.
- * This is the same variable name which should be declared in the shader, as in
- * `in vec3 aProperty`, similar to .`setUniform()`.
- *
- * The second parameter, `data`, is the value assigned to the shader variable. This value
- * will be pushed directly onto the Geometry object. There should be the same number
- * of custom property values as vertices, this method should be invoked once for each
- * vertex.
- *
- * The `data` can be a Number or an array of numbers. Tn the shader program the type
- * can be declared according to the WebGL specification. Common types include `float`,
- * `vec2`, `vec3`, `vec4` or matrices.
- *
- * See also the global vertexProperty() function.
- *
- * @example
- *
- *
- * let geo;
- *
- * function cartesianToSpherical(x, y, z) {
- * let r = sqrt(pow(x, x) + pow(y, y) + pow(z, z));
- * let theta = acos(z / r);
- * let phi = atan2(y, x);
- * return { theta, phi };
- * }
- *
- * function setup() {
- * createCanvas(100, 100, WEBGL);
- *
- * // Modify the material shader to display roughness.
- * const myShader = materialShader().modify({
- * vertexDeclarations:`in float aRoughness;
- * out float vRoughness;`,
- * fragmentDeclarations: 'in float vRoughness;',
- * 'void afterVertex': `() {
- * vRoughness = aRoughness;
- * }`,
- * 'vec4 combineColors': `(ColorComponents components) {
- * vec4 color = vec4(0.);
- * color.rgb += components.diffuse * components.baseColor * (1.0-vRoughness);
- * color.rgb += components.ambient * components.ambientColor;
- * color.rgb += components.specular * components.specularColor * (1.0-vRoughness);
- * color.a = components.opacity;
- * return color;
- * }`
- * });
- *
- * // Create the Geometry object.
- * beginGeometry();
- * fill('hotpink');
- * sphere(45, 50, 50);
- * geo = endGeometry();
- *
- * // Set the roughness value for every vertex.
- * for (let v of geo.vertices){
- *
- * // convert coordinates to spherical coordinates
- * let spherical = cartesianToSpherical(v.x, v.y, v.z);
- *
- * // Set the custom roughness vertex property.
- * let roughness = noise(spherical.theta*5, spherical.phi*5);
- * geo.vertexProperty('aRoughness', roughness);
- * }
- *
- * // Use the custom shader.
- * shader(myShader);
- *
- * describe('A rough pink sphere rotating on a blue background.');
- * }
- *
- * function draw() {
- * // Set some styles and lighting
- * background('lightblue');
- * noStroke();
- *
- * specularMaterial(255,125,100);
- * shininess(2);
- *
- * directionalLight('white', -1, 1, -1);
- * ambientLight(320);
- *
- * rotateY(millis()*0.001);
- *
- * // Draw the geometry
- * model(geo);
- * }
- *
- *
- *
- * @method vertexProperty
- * @param {String} propertyName the name of the vertex property.
- * @param {Number|Number[]} data the data tied to the vertex property.
- * @param {Number} [size] optional size of each unit of data.
- */
+ /** Sets the shader's vertex property or attribute variables.
+ *
+ * An vertex property or vertex attribute is a variable belonging to a vertex in a shader. p5.js provides some
+ * default properties, such as `aPosition`, `aNormal`, `aVertexColor`, etc. These are
+ * set using vertex(), normal()
+ * and fill() respectively. Custom properties can also
+ * be defined within beginShape() and
+ * endShape().
+ *
+ * The first parameter, `propertyName`, is a string with the property's name.
+ * This is the same variable name which should be declared in the shader, as in
+ * `in vec3 aProperty`, similar to .`setUniform()`.
+ *
+ * The second parameter, `data`, is the value assigned to the shader variable. This value
+ * will be pushed directly onto the Geometry object. There should be the same number
+ * of custom property values as vertices, this method should be invoked once for each
+ * vertex.
+ *
+ * The `data` can be a Number or an array of numbers. Tn the shader program the type
+ * can be declared according to the WebGL specification. Common types include `float`,
+ * `vec2`, `vec3`, `vec4` or matrices.
+ *
+ * See also the global vertexProperty() function.
+ *
+ * @example
+ *
+ *
+ * let geo;
+ *
+ * function cartesianToSpherical(x, y, z) {
+ * let r = sqrt(pow(x, x) + pow(y, y) + pow(z, z));
+ * let theta = acos(z / r);
+ * let phi = atan2(y, x);
+ * return { theta, phi };
+ * }
+ *
+ * function setup() {
+ * createCanvas(100, 100, WEBGL);
+ *
+ * // Modify the material shader to display roughness.
+ * const myShader = materialShader().modify({
+ * vertexDeclarations:`in float aRoughness;
+ * out float vRoughness;`,
+ * fragmentDeclarations: 'in float vRoughness;',
+ * 'void afterVertex': `() {
+ * vRoughness = aRoughness;
+ * }`,
+ * 'vec4 combineColors': `(ColorComponents components) {
+ * vec4 color = vec4(0.);
+ * color.rgb += components.diffuse * components.baseColor * (1.0-vRoughness);
+ * color.rgb += components.ambient * components.ambientColor;
+ * color.rgb += components.specular * components.specularColor * (1.0-vRoughness);
+ * color.a = components.opacity;
+ * return color;
+ * }`
+ * });
+ *
+ * // Create the Geometry object.
+ * beginGeometry();
+ * fill('hotpink');
+ * sphere(45, 50, 50);
+ * geo = endGeometry();
+ *
+ * // Set the roughness value for every vertex.
+ * for (let v of geo.vertices){
+ *
+ * // convert coordinates to spherical coordinates
+ * let spherical = cartesianToSpherical(v.x, v.y, v.z);
+ *
+ * // Set the custom roughness vertex property.
+ * let roughness = noise(spherical.theta*5, spherical.phi*5);
+ * geo.vertexProperty('aRoughness', roughness);
+ * }
+ *
+ * // Use the custom shader.
+ * shader(myShader);
+ *
+ * describe('A rough pink sphere rotating on a blue background.');
+ * }
+ *
+ * function draw() {
+ * // Set some styles and lighting
+ * background('lightblue');
+ * noStroke();
+ *
+ * specularMaterial(255,125,100);
+ * shininess(2);
+ *
+ * directionalLight('white', -1, 1, -1);
+ * ambientLight(320);
+ *
+ * rotateY(millis()*0.001);
+ *
+ * // Draw the geometry
+ * model(geo);
+ * }
+ *
+ *
+ *
+ * @method vertexProperty
+ * @param {String} propertyName the name of the vertex property.
+ * @param {Number|Number[]} data the data tied to the vertex property.
+ * @param {Number} [size] optional size of each unit of data.
+ */
vertexProperty(propertyName, data, size){
let prop;
if (!this.userVertexProperties[propertyName]){
diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js
index 93f9f14f53..b695e0d967 100644
--- a/src/webgl/p5.RendererGL.js
+++ b/src/webgl/p5.RendererGL.js
@@ -242,6 +242,9 @@ class RendererGL extends Renderer {
// erasing
this._isErasing = false;
+ // simple lines
+ this._simpleLines = false;
+
// clipping
this._clipDepths = [];
this._isClipApplied = false;
@@ -2150,6 +2153,7 @@ class RendererGL extends Renderer {
_setStrokeUniforms(strokeShader) {
// set the uniform values
+ strokeShader.setUniform('uSimpleLines', this._simpleLines);
strokeShader.setUniform('uUseLineColor', this._useLineColor);
strokeShader.setUniform('uMaterialColor', this.states.curStrokeColor);
strokeShader.setUniform('uStrokeWeight', this.curStrokeWeight);
diff --git a/src/webgl/shaders/line.vert b/src/webgl/shaders/line.vert
index ed8329f8d1..9609fc38d4 100644
--- a/src/webgl/shaders/line.vert
+++ b/src/webgl/shaders/line.vert
@@ -26,6 +26,7 @@ uniform mat4 uProjectionMatrix;
uniform float uStrokeWeight;
uniform bool uUseLineColor;
+uniform bool uSimpleLines;
uniform vec4 uMaterialColor;
uniform vec4 uViewport;
@@ -67,16 +68,18 @@ vec2 lineIntersection(vec2 aPoint, vec2 aDir, vec2 bPoint, vec2 bDir) {
void main() {
HOOK_beforeVertex();
- // Caps have one of either the in or out tangent set to 0
- vCap = (aTangentIn == vec3(0.)) != (aTangentOut == (vec3(0.)))
- ? 1. : 0.;
- // Joins have two unique, defined tangents
- vJoin = (
- aTangentIn != vec3(0.) &&
- aTangentOut != vec3(0.) &&
- aTangentIn != aTangentOut
- ) ? 1. : 0.;
+ if (!uSimpleLines) {
+ // Caps have one of either the in or out tangent set to 0
+ vCap = (aTangentIn == vec3(0.)) != (aTangentOut == vec3(0.)) ? 1. : 0.;
+
+ // Joins have two unique, defined tangents
+ vJoin = (
+ aTangentIn != vec3(0.) &&
+ aTangentOut != vec3(0.) &&
+ aTangentIn != aTangentOut
+ ) ? 1. : 0.;
+ }
vec4 localPosition = vec4(HOOK_getLocalPosition(aPosition.xyz), 1.);
vec4 posp = vec4(HOOK_getWorldPosition((uModelViewMatrix * localPosition).xyz), 1.);
@@ -171,7 +174,7 @@ void main() {
}
vec2 offset;
- if (vJoin == 1.) {
+ if (vJoin == 1. && !uSimpleLines) {
vTangent = normalize(tangentIn + tangentOut);
vec2 normalIn = vec2(-tangentIn.y, tangentIn.x);
vec2 normalOut = vec2(-tangentOut.y, tangentOut.x);
diff --git a/src/webgl/text.js b/src/webgl/text.js
index b8355f0c9a..ffef73167b 100644
--- a/src/webgl/text.js
+++ b/src/webgl/text.js
@@ -702,7 +702,7 @@ function text(p5, fn){
this.uvs.push(j, i);
}
}
- }));
+ }, this) );
geom.computeFaces().computeNormals();
g = this.geometryBufferCache.ensureCached(geom);
}
diff --git a/test/unit/webgl/p5.Geometry.js b/test/unit/webgl/p5.Geometry.js
index 636dd29387..cb42cb32a2 100644
--- a/test/unit/webgl/p5.Geometry.js
+++ b/test/unit/webgl/p5.Geometry.js
@@ -19,7 +19,7 @@ suite('p5.Geometry', function() {
let geom;
beforeEach(function() {
- geom = new p5.Geometry();
+ geom = new p5.Geometry(undefined, undefined, undefined, myp5._renderer);
vi.spyOn(geom, '_addCap');
vi.spyOn(geom, '_addJoin');
vi.spyOn(geom, '_addSegment');
diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js
index 931aa0ef24..8fd8b0fa06 100644
--- a/test/unit/webgl/p5.RendererGL.js
+++ b/test/unit/webgl/p5.RendererGL.js
@@ -2058,7 +2058,7 @@ suite('p5.RendererGL', function() {
0, 1, 0, 1
);
this._edgesToVertices();
- });
+ }, myp5._renderer);
myp5.background(255);
myp5.fill(255);
myp5.strokeWeight(4);
@@ -2239,7 +2239,7 @@ suite('p5.RendererGL', function() {
this.faces.push([0, 1, 2]);
this.faces.push([0, 2, 3]);
this.computeNormals();
- });
+ }, myp5._renderer);
myp5.fill(255);
myp5.noStroke();