Skip to content

Commit 5c2d252

Browse files
authored
Merge pull request #5789 from ShenpaiSharma/rounded_rect
Added round corner property for rect() in WebGL mode
2 parents aeda6d2 + 979353a commit 5c2d252

File tree

1 file changed

+113
-43
lines changed

1 file changed

+113
-43
lines changed

src/webgl/3d_primitives.js

+113-43
Original file line numberDiff line numberDiff line change
@@ -1217,56 +1217,126 @@ p5.RendererGL.prototype.arc = function(args) {
12171217
};
12181218

12191219
p5.RendererGL.prototype.rect = function(args) {
1220-
const perPixelLighting = this._pInst._glAttributes.perPixelLighting;
12211220
const x = args[0];
12221221
const y = args[1];
12231222
const width = args[2];
12241223
const height = args[3];
1225-
const detailX = args[4] || (perPixelLighting ? 1 : 24);
1226-
const detailY = args[5] || (perPixelLighting ? 1 : 16);
1227-
const gId = `rect|${detailX}|${detailY}`;
1228-
if (!this.geometryInHash(gId)) {
1229-
const _rect = function() {
1230-
for (let i = 0; i <= this.detailY; i++) {
1231-
const v = i / this.detailY;
1232-
for (let j = 0; j <= this.detailX; j++) {
1233-
const u = j / this.detailX;
1234-
const p = new p5.Vector(u, v, 0);
1235-
this.vertices.push(p);
1236-
this.uvs.push(u, v);
1224+
1225+
if (typeof args[4] === 'undefined') {
1226+
// Use the retained mode for drawing rectangle,
1227+
// if args for rounding rectangle is not provided by user.
1228+
const perPixelLighting = this._pInst._glAttributes.perPixelLighting;
1229+
const detailX = args[4] || (perPixelLighting ? 1 : 24);
1230+
const detailY = args[5] || (perPixelLighting ? 1 : 16);
1231+
const gId = `rect|${detailX}|${detailY}`;
1232+
if (!this.geometryInHash(gId)) {
1233+
const _rect = function() {
1234+
for (let i = 0; i <= this.detailY; i++) {
1235+
const v = i / this.detailY;
1236+
for (let j = 0; j <= this.detailX; j++) {
1237+
const u = j / this.detailX;
1238+
const p = new p5.Vector(u, v, 0);
1239+
this.vertices.push(p);
1240+
this.uvs.push(u, v);
1241+
}
12371242
}
1238-
}
1239-
// using stroke indices to avoid stroke over face(s) of rectangle
1240-
if (detailX > 0 && detailY > 0) {
1241-
this.strokeIndices = [
1242-
[0, detailX],
1243-
[detailX, (detailX + 1) * (detailY + 1) - 1],
1244-
[(detailX + 1) * (detailY + 1) - 1, (detailX + 1) * detailY],
1245-
[(detailX + 1) * detailY, 0]
1246-
];
1247-
}
1248-
};
1249-
const rectGeom = new p5.Geometry(detailX, detailY, _rect);
1250-
rectGeom
1251-
.computeFaces()
1252-
.computeNormals()
1253-
._makeTriangleEdges()
1254-
._edgesToVertices();
1255-
this.createBuffers(gId, rectGeom);
1256-
}
1243+
// using stroke indices to avoid stroke over face(s) of rectangle
1244+
if (detailX > 0 && detailY > 0) {
1245+
this.strokeIndices = [
1246+
[0, detailX],
1247+
[detailX, (detailX + 1) * (detailY + 1) - 1],
1248+
[(detailX + 1) * (detailY + 1) - 1, (detailX + 1) * detailY],
1249+
[(detailX + 1) * detailY, 0]
1250+
];
1251+
}
1252+
};
1253+
const rectGeom = new p5.Geometry(detailX, detailY, _rect);
1254+
rectGeom
1255+
.computeFaces()
1256+
.computeNormals()
1257+
._makeTriangleEdges()
1258+
._edgesToVertices();
1259+
this.createBuffers(gId, rectGeom);
1260+
}
12571261

1258-
// only a single rectangle (of a given detail) is cached: a square with
1259-
// opposite corners at (0,0) & (1,1).
1260-
//
1261-
// before rendering, this square is scaled & moved to the required location.
1262-
const uMVMatrix = this.uMVMatrix.copy();
1263-
try {
1264-
this.uMVMatrix.translate([x, y, 0]);
1265-
this.uMVMatrix.scale(width, height, 1);
1262+
// only a single rectangle (of a given detail) is cached: a square with
1263+
// opposite corners at (0,0) & (1,1).
1264+
//
1265+
// before rendering, this square is scaled & moved to the required location.
1266+
const uMVMatrix = this.uMVMatrix.copy();
1267+
try {
1268+
this.uMVMatrix.translate([x, y, 0]);
1269+
this.uMVMatrix.scale(width, height, 1);
1270+
1271+
this.drawBuffers(gId);
1272+
} finally {
1273+
this.uMVMatrix = uMVMatrix;
1274+
}
1275+
} else {
1276+
// Use Immediate mode to round the rectangle corner,
1277+
// if args for rounding corners is provided by user
1278+
let tl = args[4];
1279+
let tr = typeof args[5] === 'undefined' ? tl : args[5];
1280+
let br = typeof args[6] === 'undefined' ? tr : args[6];
1281+
let bl = typeof args[7] === 'undefined' ? br : args[7];
1282+
1283+
let a = x;
1284+
let b = y;
1285+
let c = width;
1286+
let d = height;
1287+
1288+
c += a;
1289+
d += b;
1290+
1291+
if (a > c) {
1292+
const temp = a;
1293+
a = c;
1294+
c = temp;
1295+
}
12661296

1267-
this.drawBuffers(gId);
1268-
} finally {
1269-
this.uMVMatrix = uMVMatrix;
1297+
if (b > d) {
1298+
const temp = b;
1299+
b = d;
1300+
d = temp;
1301+
}
1302+
1303+
const maxRounding = Math.min((c - a) / 2, (d - b) / 2);
1304+
if (tl > maxRounding) tl = maxRounding;
1305+
if (tr > maxRounding) tr = maxRounding;
1306+
if (br > maxRounding) br = maxRounding;
1307+
if (bl > maxRounding) bl = maxRounding;
1308+
1309+
let x1 = a;
1310+
let y1 = b;
1311+
let x2 = c;
1312+
let y2 = d;
1313+
1314+
this.beginShape();
1315+
if (tr !== 0) {
1316+
this.vertex(x2 - tr, y1);
1317+
this.quadraticVertex(x2, y1, x2, y1 + tr);
1318+
} else {
1319+
this.vertex(x2, y1);
1320+
}
1321+
if (br !== 0) {
1322+
this.vertex(x2, y2 - br);
1323+
this.quadraticVertex(x2, y2, x2 - br, y2);
1324+
} else {
1325+
this.vertex(x2, y2);
1326+
}
1327+
if (bl !== 0) {
1328+
this.vertex(x1 + bl, y2);
1329+
this.quadraticVertex(x1, y2, x1, y2 - bl);
1330+
} else {
1331+
this.vertex(x1, y2);
1332+
}
1333+
if (tl !== 0) {
1334+
this.vertex(x1, y1 + tl);
1335+
this.quadraticVertex(x1, y1, x1 + tl, y1);
1336+
} else {
1337+
this.vertex(x1, y1);
1338+
}
1339+
this.endShape(constants.CLOSE);
12701340
}
12711341
return this;
12721342
};

0 commit comments

Comments
 (0)