-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
Adding strokeMode() to access SIMPLE lines. #7390
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -520,6 +520,94 @@ 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. | ||
* - `FULLY`: 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. | ||
* - `'FULLY'`: Detailed rendering with caps, joins, and stroke color. | ||
* | ||
* @example | ||
* <div> | ||
* <code> | ||
* function setup() { | ||
* createCanvas(100, 100, WEBGL); | ||
* strokeWeight(10); | ||
* stroke(0); | ||
* | ||
* describe('A red, horizontal, rectangular shape with rounded edges (resembling a pill or capsule) in a grey background'); | ||
* } | ||
* | ||
* function draw() { | ||
* strokeMode(FULLY); // Enables detailed rendering with caps, joins, and stroke color. | ||
* stroke('red'); | ||
* | ||
* background(128); | ||
* | ||
* let centerX = 0; | ||
* let centerY = 0; | ||
* | ||
* // Length of the small centered line | ||
* let lineLength = 50; | ||
* | ||
* beginShape(LINES); | ||
* vertex(centerX - lineLength / 2, centerY, 0); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do you feel about having a 3D shape like a default We can also make the examples more than 100x100 if that makes it easier to see since I think the new site's layout accommodates that decently. |
||
* vertex(centerX + lineLength / 2, centerY, 0); | ||
* endShape(); | ||
* } | ||
* </code> | ||
* </div> | ||
* | ||
* <div> | ||
* <code> | ||
* function setup() { | ||
* createCanvas(100, 100, WEBGL); | ||
* strokeWeight(10); | ||
* stroke(0); | ||
* | ||
* describe('A black, horizontal, rectangular shape without rounded edges in a grey background'); | ||
* } | ||
* | ||
* function draw() { | ||
* strokeMode(SIMPLE); // Enables detailed rendering with caps, joins, and stroke color. | ||
* stroke(`red`); | ||
* background(128); | ||
* | ||
* let centerX = 0; | ||
* let centerY = 0; | ||
* | ||
* // Length of the small centered line | ||
* let lineLength = 50; | ||
* | ||
* beginShape(LINES); | ||
* vertex(centerX - lineLength / 2, centerY, 0); | ||
* vertex(centerX + lineLength / 2, centerY, 0); | ||
* endShape(); | ||
* } | ||
* </code> | ||
* </div> | ||
*/ | ||
|
||
fn.strokeMode = function(mode){ | ||
if(mode === constants.SIMPLE){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we make this return the current mode if we call it with no arguments? |
||
this._renderer._simpleLines = true; | ||
} else if (mode === constants.FULLY) { | ||
this._renderer._simpleLines = false; | ||
} else { | ||
throw Error('no such parameter'); | ||
} | ||
} | ||
/** | ||
* Creates a custom <a href="#/p5.Geometry">p5.Geometry</a> object from | ||
* simpler 3D shapes. | ||
|
@@ -2109,7 +2197,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 +2333,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 +2396,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 +2528,7 @@ function primitives3D(p5, fn){ | |
this.uvs.push([pctx, pcty]); | ||
} | ||
} | ||
}); | ||
}, this); | ||
|
||
quadGeom.faces = []; | ||
for(let y = 0; y < detailY-1; y++){ | ||
|
@@ -3362,7 +3450,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 +3530,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 +3586,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 +3613,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 +3650,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 +3723,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(); | ||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -13,7 +13,8 @@ | |||||
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; | ||||||
|
@@ -1398,7 +1399,7 @@ | |||||
if (dirOK) { | ||||||
this._addSegment(begin, end, fromColor, toColor, dir); | ||||||
} | ||||||
|
||||||
if(!this.renderer._simpleLines){ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, do you think we could intent the block inside this to keep the indentation consistent everywhere? |
||||||
if (i > 0 && prevEdge[1] === currEdge[0]) { | ||||||
if (!connected.has(currEdge[0])) { | ||||||
connected.add(currEdge[0]); | ||||||
|
@@ -1481,6 +1482,7 @@ | |||||
lastValidDir = dir; | ||||||
} | ||||||
} | ||||||
} | ||||||
for (const { point, dir, color } of potentialCaps.values()) { | ||||||
this._addCap(point, dir, color); | ||||||
} | ||||||
|
@@ -1520,6 +1522,7 @@ | |||||
} | ||||||
} | ||||||
this.lineVertices.push(...a, ...b, ...a, ...b, ...b, ...a); | ||||||
if(!this.renderer._simpleLines){ | ||||||
Check failure on line 1525 in src/webgl/p5.Geometry.js GitHub Actions / testtest/unit/webgl/p5.RendererGL.js > p5.RendererGL > interpolation of vertex colors > geom with vertex colors use their color (noLight)
Check failure on line 1525 in src/webgl/p5.Geometry.js GitHub Actions / testtest/unit/webgl/p5.RendererGL.js > p5.RendererGL > interpolation of vertex colors > geom with vertex colors use their color (light)
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly here, we might need to check for the existence of the renderer first:
Suggested change
|
||||||
this.lineVertexColors.push( | ||||||
...fromColor, | ||||||
...toColor, | ||||||
|
@@ -1528,6 +1531,7 @@ | |||||
...toColor, | ||||||
...fromColor | ||||||
); | ||||||
} | ||||||
return this; | ||||||
} | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ uniform mat4 uProjectionMatrix; | |
uniform float uStrokeWeight; | ||
|
||
uniform bool uUseLineColor; | ||
uniform bool uSimpleLines; | ||
uniform vec4 uMaterialColor; | ||
|
||
uniform vec4 uViewport; | ||
|
@@ -67,6 +68,8 @@ vec2 lineIntersection(vec2 aPoint, vec2 aDir, vec2 bPoint, vec2 bDir) { | |
|
||
void main() { | ||
HOOK_beforeVertex(); | ||
|
||
if(!uSimpleLines){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we indent the block below? |
||
// Caps have one of either the in or out tangent set to 0 | ||
vCap = (aTangentIn == vec3(0.)) != (aTangentOut == (vec3(0.))) | ||
? 1. : 0.; | ||
|
@@ -77,6 +80,7 @@ void main() { | |
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 +175,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); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A minor note, could we call this FULL instead of FULLY to use the same adjective form as SIMPLE?