Hi! I have a question about drawing a rounded rectangle in Codea.
I currently draw a semi-transparent black rectangle like this:
rectMode(CENTER)
noStroke()
fill(0, 0, 0, 191)
rect(
panelX,
panelY,
panelW,
panelH
)
The rectangle is approximately 1856 × 1138 px. It’s Works but cant add corners.
I would like to give it strongly rounded corners, with a radius of around 200–220 px, but the radius does not work.
What is the correct way to draw a filled rounded rectangle with a custom corner radius in the current version of Codea?
Ideally, I’m looking for a clean solution without manually constructing the shape from rectangles and circles.
This will let you customize the corner radius:
--# RoundedRect
-- A cheap rounded rect: one mesh and one shader, built once and restyled on
-- every call rather than rebuilt. The original version of this shader mixed
-- fillColor and strokeColor backwards, so the interior painted as the stroke
-- and the border painted as the fill; the mix() arguments below are swapped
-- to fix that.
RoundedRectVertexShader = [[
precision highp float;
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec2 texCoord;
varying highp vec2 vTexCoord;
void main() {
vTexCoord = texCoord;
gl_Position = modelViewProjection * position;
}
]]
RoundedRectFragmentShader = [[
precision highp float;
uniform lowp vec4 fillColor;
uniform lowp vec4 strokeColor;
uniform vec2 rectSize;
uniform float cornerRadius;
uniform float strokeWidth;
uniform float edgeSoftness;
varying highp vec2 vTexCoord;
float sdRoundedRect(vec2 p, vec2 halfSize, float r) {
vec2 q = abs(p) - (halfSize - vec2(r));
return length(max(q, vec2(0.0))) + min(max(q.x, q.y), 0.0) - r;
}
void main() {
vec2 halfSize = rectSize * 0.5;
vec2 p = (vTexCoord - 0.5) * rectSize;
float d = sdRoundedRect(p, halfSize, cornerRadius);
float aa = max(edgeSoftness, 0.75);
float shapeAlpha = 1.0 - smoothstep(0.0, aa, d);
// 0 in the deep interior, 1 once within strokeWidth of the edge
float towardEdge = smoothstep(-strokeWidth - aa, -strokeWidth + aa, d);
lowp vec4 c = mix(fillColor, strokeColor, towardEdge);
gl_FragColor = vec4(c.rgb, c.a * shapeAlpha);
}
]]
local sharedMesh = nil
function roundedRectMesh()
if sharedMesh then return sharedMesh end
sharedMesh = mesh()
local rect = sharedMesh:addRect(0, 0, 1, 1)
sharedMesh:setRectTex(rect, 0, 0, 1, 1)
sharedMesh.shader = shader(RoundedRectVertexShader, RoundedRectFragmentShader)
return sharedMesh
end
function drawRoundedRect(x, y, w, h, radius, fillCol, strokeCol, strokeW)
local m = roundedRectMesh()
m.shader.fillColor = fillCol
m.shader.strokeColor = strokeCol or color(0, 0, 0, 0)
m.shader.rectSize = vec2(w, h)
m.shader.cornerRadius = radius or 0
m.shader.strokeWidth = strokeW or 0
m.shader.edgeSoftness = 1.0
pushMatrix()
translate(x + w * 0.5, y + h * 0.5)
scale(w, h)
m:draw()
popMatrix()
end
I got it off a dude used to come around named @yojimbo2000