Skip to content

Commit

Permalink
Merge pull request #5789 from ShenpaiSharma/rounded_rect
Browse files Browse the repository at this point in the history
Added round corner property for rect() in WebGL mode
  • Loading branch information
davepagurek authored Sep 9, 2022
2 parents aeda6d2 + 979353a commit 5c2d252
Showing 1 changed file with 113 additions and 43 deletions.
156 changes: 113 additions & 43 deletions src/webgl/3d_primitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -1217,56 +1217,126 @@ p5.RendererGL.prototype.arc = function(args) {
};

p5.RendererGL.prototype.rect = function(args) {
const perPixelLighting = this._pInst._glAttributes.perPixelLighting;
const x = args[0];
const y = args[1];
const width = args[2];
const height = args[3];
const detailX = args[4] || (perPixelLighting ? 1 : 24);
const detailY = args[5] || (perPixelLighting ? 1 : 16);
const gId = `rect|${detailX}|${detailY}`;
if (!this.geometryInHash(gId)) {
const _rect = function() {
for (let i = 0; i <= this.detailY; i++) {
const v = i / this.detailY;
for (let j = 0; j <= this.detailX; j++) {
const u = j / this.detailX;
const p = new p5.Vector(u, v, 0);
this.vertices.push(p);
this.uvs.push(u, v);

if (typeof args[4] === 'undefined') {
// Use the retained mode for drawing rectangle,
// if args for rounding rectangle is not provided by user.
const perPixelLighting = this._pInst._glAttributes.perPixelLighting;
const detailX = args[4] || (perPixelLighting ? 1 : 24);
const detailY = args[5] || (perPixelLighting ? 1 : 16);
const gId = `rect|${detailX}|${detailY}`;
if (!this.geometryInHash(gId)) {
const _rect = function() {
for (let i = 0; i <= this.detailY; i++) {
const v = i / this.detailY;
for (let j = 0; j <= this.detailX; j++) {
const u = j / this.detailX;
const p = new p5.Vector(u, v, 0);
this.vertices.push(p);
this.uvs.push(u, v);
}
}
}
// using stroke indices to avoid stroke over face(s) of rectangle
if (detailX > 0 && detailY > 0) {
this.strokeIndices = [
[0, detailX],
[detailX, (detailX + 1) * (detailY + 1) - 1],
[(detailX + 1) * (detailY + 1) - 1, (detailX + 1) * detailY],
[(detailX + 1) * detailY, 0]
];
}
};
const rectGeom = new p5.Geometry(detailX, detailY, _rect);
rectGeom
.computeFaces()
.computeNormals()
._makeTriangleEdges()
._edgesToVertices();
this.createBuffers(gId, rectGeom);
}
// using stroke indices to avoid stroke over face(s) of rectangle
if (detailX > 0 && detailY > 0) {
this.strokeIndices = [
[0, detailX],
[detailX, (detailX + 1) * (detailY + 1) - 1],
[(detailX + 1) * (detailY + 1) - 1, (detailX + 1) * detailY],
[(detailX + 1) * detailY, 0]
];
}
};
const rectGeom = new p5.Geometry(detailX, detailY, _rect);
rectGeom
.computeFaces()
.computeNormals()
._makeTriangleEdges()
._edgesToVertices();
this.createBuffers(gId, rectGeom);
}

// only a single rectangle (of a given detail) is cached: a square with
// opposite corners at (0,0) & (1,1).
//
// before rendering, this square is scaled & moved to the required location.
const uMVMatrix = this.uMVMatrix.copy();
try {
this.uMVMatrix.translate([x, y, 0]);
this.uMVMatrix.scale(width, height, 1);
// only a single rectangle (of a given detail) is cached: a square with
// opposite corners at (0,0) & (1,1).
//
// before rendering, this square is scaled & moved to the required location.
const uMVMatrix = this.uMVMatrix.copy();
try {
this.uMVMatrix.translate([x, y, 0]);
this.uMVMatrix.scale(width, height, 1);

this.drawBuffers(gId);
} finally {
this.uMVMatrix = uMVMatrix;
}
} else {
// Use Immediate mode to round the rectangle corner,
// if args for rounding corners is provided by user
let tl = args[4];
let tr = typeof args[5] === 'undefined' ? tl : args[5];
let br = typeof args[6] === 'undefined' ? tr : args[6];
let bl = typeof args[7] === 'undefined' ? br : args[7];

let a = x;
let b = y;
let c = width;
let d = height;

c += a;
d += b;

if (a > c) {
const temp = a;
a = c;
c = temp;
}

this.drawBuffers(gId);
} finally {
this.uMVMatrix = uMVMatrix;
if (b > d) {
const temp = b;
b = d;
d = temp;
}

const maxRounding = Math.min((c - a) / 2, (d - b) / 2);
if (tl > maxRounding) tl = maxRounding;
if (tr > maxRounding) tr = maxRounding;
if (br > maxRounding) br = maxRounding;
if (bl > maxRounding) bl = maxRounding;

let x1 = a;
let y1 = b;
let x2 = c;
let y2 = d;

this.beginShape();
if (tr !== 0) {
this.vertex(x2 - tr, y1);
this.quadraticVertex(x2, y1, x2, y1 + tr);
} else {
this.vertex(x2, y1);
}
if (br !== 0) {
this.vertex(x2, y2 - br);
this.quadraticVertex(x2, y2, x2 - br, y2);
} else {
this.vertex(x2, y2);
}
if (bl !== 0) {
this.vertex(x1 + bl, y2);
this.quadraticVertex(x1, y2, x1, y2 - bl);
} else {
this.vertex(x1, y2);
}
if (tl !== 0) {
this.vertex(x1, y1 + tl);
this.quadraticVertex(x1, y1, x1 + tl, y1);
} else {
this.vertex(x1, y1);
}
this.endShape(constants.CLOSE);
}
return this;
};
Expand Down

0 comments on commit 5c2d252

Please sign in to comment.