round rect and rounded filled rect
Some checks failed
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Some checks failed
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
This commit is contained in:
@@ -31,7 +31,7 @@ render.initialize = function(config)
|
||||
|
||||
prosperon.window = prosperon.engine_start({width:500,height:500})
|
||||
console.log(prosperon.window)
|
||||
context = prosperon.window.make_renderer("metal")
|
||||
context = prosperon.window.make_renderer()
|
||||
}
|
||||
|
||||
// img here is the engine surface
|
||||
@@ -55,6 +55,7 @@ render.image = function(image, rect)
|
||||
|
||||
rect.width ??= image.texture.width
|
||||
rect.height ??= image.texture.height
|
||||
var T =
|
||||
context.texture(image.texture, rect);
|
||||
}
|
||||
|
||||
@@ -90,6 +91,131 @@ render.circle = function(pos, radius, color = Color.white)
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* Rounded-rect outline – any stroke width ≥ 1 *
|
||||
*------------------------------------------------------------*/
|
||||
render.round_rect = function(rect, radius, line_width = 1,
|
||||
color = Color.white)
|
||||
{
|
||||
if (line_width <= 0) return
|
||||
|
||||
radius = Math.min(radius, rect.width >> 1, rect.height >> 1)
|
||||
if (radius <= 0) { render.rectangle(rect, color); return }
|
||||
|
||||
const x0 = rect.x,
|
||||
y0 = rect.y,
|
||||
x1 = rect.x + rect.width - 1, // inclusive
|
||||
y1 = rect.y + rect.height - 1
|
||||
|
||||
/* fast-path: stroke swallows the whole thing → just fill */
|
||||
if ((line_width << 1) >= rect.width ||
|
||||
(line_width << 1) >= rect.height) {
|
||||
render.fill_round_rect(rect, radius, color)
|
||||
return
|
||||
}
|
||||
|
||||
const cx_l = x0 + radius, cx_r = x1 - radius
|
||||
const cy_t = y0 + radius, cy_b = y1 - radius
|
||||
const r_out = radius
|
||||
const r_in = Math.max(radius - line_width, 0)
|
||||
|
||||
context.draw_color(color)
|
||||
|
||||
/* straight bands ---------------------------------------------------------*/
|
||||
context.rects([
|
||||
{ x:x0 + radius, y:y0, width:rect.width - (radius << 1),
|
||||
height:line_width }, // top
|
||||
{ x:x0 + radius, y:y1 - line_width + 1,
|
||||
width:rect.width - (radius << 1), height:line_width }, // bottom
|
||||
{ x:x0, y:y0 + radius, width:line_width,
|
||||
height:rect.height - (radius << 1) }, // left
|
||||
{ x:x1 - line_width + 1, y:y0 + radius, width:line_width,
|
||||
height:rect.height - (radius << 1) } // right
|
||||
])
|
||||
|
||||
/* corner arcs ------------------------------------------------------------*/
|
||||
const strips = [] // batch for speed
|
||||
|
||||
for (let dy = 0; dy < radius; ++dy) {
|
||||
const dy_sq = dy * dy
|
||||
const dx_out = Math.floor(Math.sqrt(r_out * r_out - dy_sq))
|
||||
const dx_in = (r_in && dy < r_in)
|
||||
? Math.floor(Math.sqrt(r_in * r_in - dy_sq))
|
||||
: -1 // no inner rim
|
||||
const w = dx_out - dx_in // strip width
|
||||
if (w <= 0) continue
|
||||
|
||||
/* top */
|
||||
strips.push(
|
||||
{ x:cx_l - dx_out, y:cy_t - dy, width:w, height:1 }, // NW
|
||||
{ x:cx_r + dx_in + 1, y:cy_t - dy, width:w, height:1 } // NE
|
||||
)
|
||||
|
||||
/* bottom */
|
||||
strips.push(
|
||||
{ x:cx_l - dx_out, y:cy_b + dy, width:w, height:1 }, // SW
|
||||
{ x:cx_r + dx_in + 1, y:cy_b + dy, width:w, height:1 } // SE
|
||||
)
|
||||
}
|
||||
|
||||
context.rects(strips)
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*
|
||||
* Filled rounded-rect *
|
||||
*------------------------------------------------------------*/
|
||||
render.fill_round_rect = function(rect, radius,
|
||||
color = Color.white)
|
||||
{
|
||||
radius = Math.min(radius, rect.width >> 1, rect.height >> 1)
|
||||
if (radius <= 0) { context.draw_color(color); context.rects([rect]); return }
|
||||
|
||||
const x0 = rect.x,
|
||||
y0 = rect.y,
|
||||
x1 = rect.x + rect.width - 1,
|
||||
y1 = rect.y + rect.height - 1
|
||||
|
||||
context.draw_color(color)
|
||||
|
||||
/* main rectangle column (everything between the caps) ----*/
|
||||
context.rects([
|
||||
{ x:x0 + radius, y:y0, width:rect.width - (radius << 1),
|
||||
height:rect.height }
|
||||
])
|
||||
|
||||
/* side columns (left & right) -----------------------------*/
|
||||
context.rects([
|
||||
{ x:x0, y:y0 + radius, width:radius,
|
||||
height:rect.height - (radius << 1) },
|
||||
{ x:x1 - radius + 1, y:y0 + radius, width:radius,
|
||||
height:rect.height - (radius << 1) }
|
||||
])
|
||||
|
||||
/* corner caps --------------------------------------------*/
|
||||
const cx_l = x0 + radius, cx_r = x1 - radius
|
||||
const cy_t = y0 + radius, cy_b = y1 - radius
|
||||
const caps = []
|
||||
|
||||
for (let dy = 0; dy < radius; ++dy) {
|
||||
const dx = Math.floor(Math.sqrt(radius * radius - dy * dy))
|
||||
const w = (dx << 1) + 1
|
||||
|
||||
/* top */
|
||||
caps.push(
|
||||
{ x:cx_l - dx, y:cy_t - dy, width:w, height:1 },
|
||||
{ x:cx_r - dx, y:cy_t - dy, width:w, height:1 }
|
||||
)
|
||||
|
||||
/* bottom */
|
||||
caps.push(
|
||||
{ x:cx_l - dx, y:cy_b + dy, width:w, height:1 },
|
||||
{ x:cx_r - dx, y:cy_b + dy, width:w, height:1 }
|
||||
)
|
||||
}
|
||||
|
||||
context.rects(caps)
|
||||
}
|
||||
|
||||
render.ellipse = function(pos, radiuses, color = Color.white)
|
||||
{
|
||||
var rx = radiuses[0], ry = radiuses[1]
|
||||
|
||||
@@ -2566,14 +2566,9 @@ static const JSCFunctionListEntry js_camera_funcs[] = {
|
||||
|
||||
JSC_SCALL(SDL_Window_make_renderer,
|
||||
SDL_Window *win = js2SDL_Window(js,self);
|
||||
SDL_PropertiesID props = SDL_CreateProperties();
|
||||
SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 0);
|
||||
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, win);
|
||||
SDL_SetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, str);
|
||||
renderer_ctx *ctx = malloc(sizeof(*ctx));
|
||||
ctx->sdl = SDL_CreateRendererWithProperties(props);
|
||||
ctx->sdl = SDL_CreateRenderer(win, NULL);
|
||||
ctx->cam = (shader_globals){0};
|
||||
SDL_DestroyProperties(props);
|
||||
if (!ctx->sdl) {
|
||||
free(ctx);
|
||||
return JS_ThrowReferenceError(js, "Error creating renderer: %s",SDL_GetError());
|
||||
|
||||
@@ -44,6 +44,8 @@ function loop()
|
||||
render.circle([200,200],40)
|
||||
render.ellipse([300,300],[20,40])
|
||||
render.rectangle({x:150,y:150,width:50,height:50})
|
||||
render.round_rect({x:100, y:60, width:200, height:60}, 20, 2)
|
||||
render.fill_round_rect({x:350, y:60, width:200, height:120}, 10)
|
||||
//render.image("button_grey", [100,100])
|
||||
// draw.rectangle({x:50,y:-50,width:50,height:50})
|
||||
render.present()
|
||||
|
||||
Reference in New Issue
Block a user