fix 9 slice; add tile command
This commit is contained in:
307
source/jsffi.c
307
source/jsffi.c
@@ -1005,7 +1005,6 @@ SDL_GPUStencilOpState js2SDL_GPUStencilOpState(JSContext *js, JSValue v)
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
typedef struct lrtb lrtb;
|
||||
|
||||
lrtb js2lrtb(JSContext *js, JSValue v)
|
||||
@@ -1645,16 +1644,8 @@ JSValue make_quad_indices_buffer(JSContext *js, int quads)
|
||||
return JS_DupValue(js,idx_buffer);
|
||||
}
|
||||
|
||||
JSC_CCALL(os_make_text_buffer,
|
||||
const char *s = JS_ToCString(js, argv[0]);
|
||||
rect rectpos = js2rect(js,argv[1]);
|
||||
float size = js2number(js,argv[2]);
|
||||
font *f = js2font(js,argv[5]);
|
||||
if (!size) size = f->height;
|
||||
colorf c = js2color(js,argv[3]);
|
||||
int wrap = js2number(js,argv[4]);
|
||||
HMM_Vec2 startpos = {.x = rectpos.x, .y = rectpos.y };
|
||||
text_vert *buffer = renderText(s, startpos, f, size, c, wrap);
|
||||
JSValue quads_to_mesh(JSContext *js, text_vert *buffer)
|
||||
{
|
||||
size_t verts = arrlen(buffer);
|
||||
|
||||
HMM_Vec2 *pos = malloc(arrlen(buffer)*sizeof(HMM_Vec2));
|
||||
@@ -1675,9 +1666,7 @@ JSC_CCALL(os_make_text_buffer,
|
||||
size_t count = verts/2*3;
|
||||
JSValue jsidx = make_quad_indices_buffer(js, quads);
|
||||
|
||||
JS_FreeCString(js, s);
|
||||
arrfree(buffer);
|
||||
ret = JS_NewObject(js);
|
||||
JSValue ret = JS_NewObject(js);
|
||||
JS_SetProperty(js, ret, pos_atom, jspos);
|
||||
JS_SetProperty(js, ret, uv_atom, jsuv);
|
||||
JS_SetProperty(js, ret, color_atom, jscolor);
|
||||
@@ -1686,6 +1675,21 @@ JSC_CCALL(os_make_text_buffer,
|
||||
JS_SetProperty(js,ret,num_indices_atom, number2js(js,count));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
JSC_CCALL(os_make_text_buffer,
|
||||
const char *s = JS_ToCString(js, argv[0]);
|
||||
rect rectpos = js2rect(js,argv[1]);
|
||||
float size = js2number(js,argv[2]);
|
||||
font *f = js2font(js,argv[5]);
|
||||
if (!size) size = f->height;
|
||||
colorf c = js2color(js,argv[3]);
|
||||
int wrap = js2number(js,argv[4]);
|
||||
HMM_Vec2 startpos = {.x = rectpos.x, .y = rectpos.y };
|
||||
text_vert *buffer = renderText(s, startpos, f, size, c, wrap);
|
||||
ret = quads_to_mesh(js,buffer);
|
||||
JS_FreeCString(js, s);
|
||||
arrfree(buffer);
|
||||
)
|
||||
|
||||
JSC_CCALL(spline_catmull,
|
||||
@@ -4310,6 +4314,279 @@ JSC_CCALL(gpu_compute_pipeline,
|
||||
return SDL_GPUComputePipeline2js(js,pipeline);
|
||||
)
|
||||
|
||||
static inline void add_quad(text_vert **verts, rect src, rect dst)
|
||||
{
|
||||
text_vert v = (text_vert){
|
||||
.pos = (HMM_Vec2){dst.x, dst.y},
|
||||
.uv = (HMM_Vec2){src.x,src.y},
|
||||
.color = (HMM_Vec4){1,1,1,1}
|
||||
};
|
||||
arrput(*verts, v);
|
||||
|
||||
v = (text_vert){
|
||||
.pos = (HMM_Vec2){dst.x+dst.w, dst.y},
|
||||
.uv = (HMM_Vec2){src.x+src.w,src.y},
|
||||
.color = (HMM_Vec4){1,1,1,1}
|
||||
};
|
||||
arrput(*verts, v);
|
||||
|
||||
v = (text_vert){
|
||||
.pos = (HMM_Vec2){dst.x, dst.y+dst.h},
|
||||
.uv = (HMM_Vec2){src.x,src.y+src.h},
|
||||
.color = (HMM_Vec4){1,1,1,1}
|
||||
};
|
||||
arrput(*verts, v);
|
||||
|
||||
v = (text_vert){
|
||||
.pos = (HMM_Vec2){dst.x+dst.w, dst.y+dst.h},
|
||||
.uv = (HMM_Vec2){src.x+src.w,src.y+src.h},
|
||||
.color = (HMM_Vec4){1,1,1,1}
|
||||
};
|
||||
arrput(*verts, v);
|
||||
}
|
||||
|
||||
JSC_CCALL(gpu_slice9,
|
||||
JSValue jstex = argv[0];
|
||||
rect dst = js2rect(js,argv[1]);
|
||||
rect src = (rect){
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.w = 1,
|
||||
.h = 1
|
||||
};
|
||||
lrtb src_slice = js2lrtb(js,argv[2]);
|
||||
lrtb dst_slice = src_slice;
|
||||
|
||||
HMM_Vec2 size;
|
||||
JS_GETPROP(js,size.x,jstex, width, number)
|
||||
JS_GETPROP(js,size.y,jstex,height,number)
|
||||
|
||||
/* src.x /= size.x;
|
||||
src.w /= size.x;
|
||||
src.y /= size.y;
|
||||
src.h /= size.y;*/
|
||||
src_slice.l /= size.x;
|
||||
src_slice.r /= size.x;
|
||||
src_slice.t /= size.y;
|
||||
src_slice.b /= size.y;
|
||||
|
||||
text_vert *verts = NULL;
|
||||
|
||||
rect curr_src;
|
||||
rect curr_dst;
|
||||
|
||||
// bottom left
|
||||
curr_src = src;
|
||||
curr_src.w = src_slice.l;
|
||||
curr_src.h = src_slice.b;
|
||||
curr_dst = dst;
|
||||
curr_dst.w = dst_slice.l;
|
||||
curr_dst.h = dst_slice.b;
|
||||
add_quad(&verts,curr_src, curr_dst);
|
||||
|
||||
// top left
|
||||
curr_src = src;
|
||||
curr_dst = dst;
|
||||
curr_src.y = src.y + src.h - src_slice.t;
|
||||
curr_src.h = src_slice.t;
|
||||
curr_src.w = src_slice.l;
|
||||
curr_dst.y = dst.y + dst.h - dst_slice.t;
|
||||
curr_dst.h = dst_slice.t;
|
||||
curr_dst.w = dst_slice.l;
|
||||
add_quad(&verts,curr_src,curr_dst);
|
||||
|
||||
// left bar
|
||||
curr_src = src;
|
||||
curr_dst = dst;
|
||||
curr_src.y = src.y + src_slice.b;
|
||||
curr_src.h = src.h - src_slice.t - src_slice.b;
|
||||
curr_src.w = src_slice.l;
|
||||
curr_dst.y = dst.y + dst_slice.b;
|
||||
curr_dst.h = dst.h - dst_slice.t - dst_slice.b;
|
||||
curr_dst.w = dst_slice.l;
|
||||
add_quad(&verts,curr_src,curr_dst);
|
||||
|
||||
// bottom bar
|
||||
curr_src = src;
|
||||
curr_dst = dst;
|
||||
curr_src.x = src.x + src_slice.l;
|
||||
curr_src.h = src_slice.b;
|
||||
curr_src.w = src.w - src_slice.l - src_slice.r;
|
||||
curr_dst.x = dst.x + dst_slice.l;
|
||||
curr_dst.h = dst_slice.b;
|
||||
curr_dst.w = dst.w - dst_slice.l - dst_slice.r;
|
||||
add_quad(&verts,curr_src,curr_dst);
|
||||
|
||||
// top bar
|
||||
curr_src = src;
|
||||
curr_dst = dst;
|
||||
curr_src.x = src.x + src_slice.l;
|
||||
curr_src.h = src_slice.t;
|
||||
curr_src.y = src.y + src.h - src_slice.t;
|
||||
curr_src.w = src.w - src_slice.l - src_slice.r;
|
||||
curr_dst.x = dst.x + dst_slice.l;
|
||||
curr_dst.h = dst_slice.t;
|
||||
curr_dst.y = dst.y + dst.h - dst_slice.t;
|
||||
curr_dst.w = dst.w - dst_slice.l - dst_slice.r;
|
||||
add_quad(&verts,curr_src,curr_dst);
|
||||
|
||||
// center
|
||||
curr_src = src;
|
||||
curr_dst = dst;
|
||||
curr_src.x = src.x + src_slice.l;
|
||||
curr_src.w = src.w - src_slice.l - src_slice.r;
|
||||
curr_src.y = src.y + src_slice.b;
|
||||
curr_src.h = src.h - src_slice.t - src_slice.b;
|
||||
curr_dst.x = dst.x + dst_slice.l;
|
||||
curr_dst.w = dst.w - dst_slice.l - dst_slice.r;
|
||||
curr_dst.y = dst.y + dst_slice.b;
|
||||
curr_dst.h = dst.h - dst_slice.t - dst_slice.b;
|
||||
add_quad(&verts, curr_src, curr_dst);
|
||||
|
||||
// bottom right
|
||||
curr_src = src;
|
||||
curr_dst = dst;
|
||||
curr_src.x = src.x + src.w - src_slice.r;
|
||||
curr_src.w = src_slice.r;
|
||||
curr_src.h = src_slice.b;
|
||||
curr_dst.x = dst.x + dst.w - dst_slice.r;
|
||||
curr_dst.w = dst_slice.r;
|
||||
curr_dst.h = dst_slice.b;
|
||||
add_quad(&verts, curr_src, curr_dst);
|
||||
|
||||
// top right
|
||||
curr_src = src;
|
||||
curr_dst = dst;
|
||||
curr_src.x = src.x + src.w - src_slice.r;
|
||||
curr_src.w = src_slice.r;
|
||||
curr_src.y = src.y + src.h - src_slice.t;
|
||||
curr_src.h = src_slice.t;
|
||||
curr_dst.x = dst.x + dst.w - dst_slice.r;
|
||||
curr_dst.w = dst_slice.r;
|
||||
curr_dst.y = dst.y + dst.h - dst_slice.t;
|
||||
curr_dst.h = dst_slice.t;
|
||||
add_quad(&verts, curr_src, curr_dst);
|
||||
|
||||
// right bar
|
||||
curr_src = src;
|
||||
curr_dst = dst;
|
||||
curr_src.x = src.x + src.w - src_slice.r;
|
||||
curr_src.w = src_slice.r;
|
||||
curr_src.y = src.y + src_slice.b;
|
||||
curr_src.h = src.h - src_slice.t - src_slice.b;
|
||||
curr_dst.x = dst.x + dst.w - dst_slice.r;
|
||||
curr_dst.w = dst_slice.r;
|
||||
curr_dst.y = dst.y + dst_slice.b;
|
||||
curr_dst.h = dst.h - dst_slice.t - dst_slice.b;
|
||||
add_quad(&verts, curr_src, curr_dst);
|
||||
|
||||
JSValue mesh = quads_to_mesh(js, verts);
|
||||
arrfree(verts);
|
||||
ret = mesh;
|
||||
)
|
||||
|
||||
JSC_CCALL(gpu_tile,
|
||||
HMM_Vec2 size;
|
||||
JSValue jstex = argv[0];
|
||||
JS_GETPROP(js,size.x,jstex,width,number)
|
||||
JS_GETPROP(js, size.y, jstex, height, number)
|
||||
|
||||
rect src_pixels = js2rect(js, argv[1]); // 'src' as pixel dimensions
|
||||
rect dst = js2rect(js, argv[2]); // 'dst' as screen coords
|
||||
|
||||
// Determine how many full tiles horizontally/vertically
|
||||
float fcols, frows;
|
||||
float remaining_w = modff(dst.w / src_pixels.w, &fcols);
|
||||
float remaining_h = modff(dst.h / src_pixels.h, &frows);
|
||||
|
||||
// The partial leftover in pixel dimensions
|
||||
float remain_src_w = remaining_w * src_pixels.w;
|
||||
float remain_src_h = remaining_h * src_pixels.h;
|
||||
|
||||
// The corresponding leftover area in screen coords (since src -> 1:1 draw)
|
||||
float remain_dst_w = remain_src_w;
|
||||
float remain_dst_h = remain_src_h;
|
||||
|
||||
int cols = (int)fcols;
|
||||
int rows = (int)frows;
|
||||
|
||||
// Convert the whole source rect from pixels into UV coords
|
||||
// so add_quad can draw the correct portion of the texture.
|
||||
rect src_full;
|
||||
src_full.x = src_pixels.x / size.x;
|
||||
src_full.y = src_pixels.y / size.y;
|
||||
src_full.w = src_pixels.w / size.x;
|
||||
src_full.h = src_pixels.h / size.y;
|
||||
|
||||
// For partial leftover in UV coords
|
||||
float remain_src_w_uv = remain_src_w / size.x;
|
||||
float remain_src_h_uv = remain_src_h / size.y;
|
||||
|
||||
// We'll set up some "partial" src rect variants:
|
||||
rect src_partial_x = src_full; // partial in the X dimension
|
||||
src_partial_x.w = remain_src_w_uv;
|
||||
|
||||
rect src_partial_y = src_full; // partial in the Y dimension
|
||||
src_partial_y.h = remain_src_h_uv;
|
||||
|
||||
rect src_partial_xy = src_full; // partial in both X and Y
|
||||
src_partial_xy.w = remain_src_w_uv;
|
||||
src_partial_xy.h = remain_src_h_uv;
|
||||
|
||||
// Now we tile in screen coords. Each tile is as wide/high as src_pixels (1:1).
|
||||
// The UV coords for a "full" tile use src_full;
|
||||
// for partial leftover tiles, we use the partial variants above.
|
||||
text_vert *verts = NULL;
|
||||
|
||||
float tile_w = src_pixels.w;
|
||||
float tile_h = src_pixels.h;
|
||||
|
||||
rect curr_dst;
|
||||
curr_dst.w = tile_w;
|
||||
curr_dst.h = tile_h;
|
||||
curr_dst.y = dst.y;
|
||||
|
||||
// Place the full rows & columns
|
||||
for (int y = 0; y < rows; y++) {
|
||||
curr_dst.x = dst.x;
|
||||
for (int x = 0; x < cols; x++) {
|
||||
add_quad(&verts, src_full, curr_dst);
|
||||
curr_dst.x += tile_w;
|
||||
}
|
||||
// Place the partial tile on the right edge, if any
|
||||
if (remain_dst_w > 0.0f) {
|
||||
rect partial_dst = { curr_dst.x, curr_dst.y, remain_dst_w, tile_h };
|
||||
add_quad(&verts, src_partial_x, partial_dst);
|
||||
}
|
||||
curr_dst.y += tile_h;
|
||||
}
|
||||
|
||||
// Now place the leftover row (if any)
|
||||
if (remain_dst_h > 0.0f) {
|
||||
rect partial_row_dst;
|
||||
partial_row_dst.y = curr_dst.y;
|
||||
partial_row_dst.w = tile_w;
|
||||
partial_row_dst.h = remain_dst_h;
|
||||
partial_row_dst.x = dst.x;
|
||||
|
||||
// Full columns in this leftover row
|
||||
for (int x = 0; x < cols; x++) {
|
||||
add_quad(&verts, src_partial_y, partial_row_dst);
|
||||
partial_row_dst.x += tile_w;
|
||||
}
|
||||
|
||||
// Partial corner tile: leftover on the right plus leftover row
|
||||
if (remain_dst_w > 0.0f) {
|
||||
rect partial_corner_dst = { partial_row_dst.x, partial_row_dst.y,
|
||||
remain_dst_w, remain_dst_h };
|
||||
add_quad(&verts, src_partial_xy, partial_corner_dst);
|
||||
}
|
||||
}
|
||||
|
||||
ret = quads_to_mesh(js,verts);
|
||||
arrfree(verts);
|
||||
)
|
||||
|
||||
static const JSCFunctionListEntry js_SDL_GPUDevice_funcs[] = {
|
||||
MIST_FUNC_DEF(gpu, claim_window, 1),
|
||||
MIST_FUNC_DEF(gpu, make_pipeline, 1), // loads pipeline state into an object
|
||||
@@ -4327,6 +4604,8 @@ static const JSCFunctionListEntry js_SDL_GPUDevice_funcs[] = {
|
||||
MIST_FUNC_DEF(gpu, wait_for_fences, 2),
|
||||
MIST_FUNC_DEF(gpu, query_fence, 1),
|
||||
MIST_FUNC_DEF(gpu, shader_format, 0),
|
||||
MIST_FUNC_DEF(gpu, slice9, 4),
|
||||
MIST_FUNC_DEF(gpu, tile, 3),
|
||||
};
|
||||
|
||||
JSC_CCALL(renderpass_bind_pipeline,
|
||||
|
||||
Reference in New Issue
Block a user