refactor out duplicate and dead code
This commit is contained in:
@@ -473,117 +473,6 @@ static HMM_Vec3 base_quad[4] = {
|
||||
{1.0,1.0,1.0}
|
||||
};
|
||||
|
||||
JSC_CCALL(gpu_make_sprite_mesh,
|
||||
size_t quads = JS_ArrayLength(js, argv[0]);
|
||||
size_t verts = quads*4;
|
||||
size_t count = quads*6;
|
||||
|
||||
// Prepare arrays on CPU
|
||||
HMM_Vec2 *posdata = malloc(sizeof(*posdata)*verts);
|
||||
HMM_Vec2 *uvdata = malloc(sizeof(*uvdata)*verts);
|
||||
HMM_Vec4 *colordata = malloc(sizeof(*colordata)*verts);
|
||||
|
||||
for (int i = 0; i < quads; i++) {
|
||||
JSValue sub = JS_GetPropertyUint32(js,argv[0],i);
|
||||
|
||||
transform *tr;
|
||||
rect src;
|
||||
HMM_Vec4 color;
|
||||
JS_GETATOM(js,src,sub,src,rect)
|
||||
JS_GETATOM(js,color,sub,color,color)
|
||||
JS_GETATOM(js,tr,sub,transform,transform)
|
||||
JS_FreeValue(js,sub);
|
||||
|
||||
size_t base = i*4;
|
||||
if (tr) {
|
||||
HMM_Mat3 trmat = transform2mat3(tr);
|
||||
for (int j = 0; j < 4; j++)
|
||||
posdata[base+j] = HMM_MulM3V3(trmat, base_quad[j]).xy;
|
||||
} else {
|
||||
rect dst;
|
||||
JS_GETATOM(js,dst,sub,rect,rect);
|
||||
posdata[base+0] = (HMM_Vec2){dst.x,dst.y};
|
||||
posdata[base + 1] = (HMM_Vec2){ dst.x+dst.w, dst.y };
|
||||
posdata[base + 2] = (HMM_Vec2){ dst.x, dst.y+dst.h };
|
||||
posdata[base + 3] = (HMM_Vec2){ dst.x+dst.w, dst.y+dst.h };
|
||||
}
|
||||
|
||||
uvdata[base+0] = (HMM_Vec2){src.x, src.y+src.h};
|
||||
uvdata[base+1] = (HMM_Vec2){src.x+src.w, src.y+src.h};
|
||||
uvdata[base+2] = (HMM_Vec2){src.x, src.y};
|
||||
uvdata[base+3] = (HMM_Vec2){src.x+src.w, src.y};
|
||||
|
||||
colordata[base+0] = color;
|
||||
colordata[base+1] = color;
|
||||
colordata[base+2] = color;
|
||||
colordata[base+3] = color;
|
||||
}
|
||||
|
||||
// Check old mesh
|
||||
JSValue old_mesh = JS_NULL;
|
||||
if (argc > 1)
|
||||
old_mesh = argv[1];
|
||||
|
||||
// Needed sizes
|
||||
size_t pos_size = sizeof(*posdata)*verts;
|
||||
size_t uv_size = sizeof(*uvdata)*verts;
|
||||
size_t color_size = sizeof(*colordata)*verts;
|
||||
|
||||
BufferCheckResult pos_chk = get_or_extend_buffer(js, old_mesh, "pos", pos_size, 0, 2, 1, 0);
|
||||
BufferCheckResult uv_chk = get_or_extend_buffer(js, old_mesh, "uv", uv_size, 0, 2, 1, 0);
|
||||
BufferCheckResult color_chk = get_or_extend_buffer(js, old_mesh, "color", color_size, 0, 4, 1, 0);
|
||||
|
||||
int need_new_all = pos_chk.need_new || uv_chk.need_new || color_chk.need_new;
|
||||
|
||||
ret = JS_NewObject(js);
|
||||
|
||||
if (need_new_all) {
|
||||
// Create all new buffers
|
||||
JSValue new_pos = make_gpu_buffer(js, posdata, pos_size, 0, 2, 1,0);
|
||||
JSValue new_uv = make_gpu_buffer(js, uvdata, uv_size, 0, 2, 1,0);
|
||||
JSValue new_color = make_gpu_buffer(js, colordata, color_size, 0, 0, 1,0);
|
||||
|
||||
JS_SetPropertyStr(js, ret, "pos", new_pos);
|
||||
JS_SetPropertyStr(js, ret, "uv", new_uv);
|
||||
JS_SetPropertyStr(js, ret, "color", new_color);
|
||||
|
||||
// Indices
|
||||
JSValue indices = make_quad_indices_buffer(js, quads);
|
||||
JS_SetPropertyStr(js, ret, "indices", indices);
|
||||
} else {
|
||||
// Reuse the old buffers
|
||||
// Just copy data into existing buffers via their pointers
|
||||
memcpy(pos_chk.ptr, posdata, pos_size);
|
||||
memcpy(uv_chk.ptr, uvdata, uv_size);
|
||||
memcpy(color_chk.ptr, colordata, color_size);
|
||||
|
||||
// Duplicate old references since we're returning a new object
|
||||
JS_SetPropertyStr(js, ret, "pos", JS_DupValue(js, pos_chk.val));
|
||||
JS_SetPropertyStr(js, ret, "uv", JS_DupValue(js, uv_chk.val));
|
||||
JS_SetPropertyStr(js, ret, "color", JS_DupValue(js, color_chk.val));
|
||||
|
||||
// Indices can remain the same if they were also large enough. If using a shared global index buffer:
|
||||
JSValue indices = make_quad_indices_buffer(js, quads);
|
||||
JS_SetPropertyStr(js, ret, "indices", indices);
|
||||
}
|
||||
|
||||
JS_SetPropertyStr(js, ret, "vertices", number2js(js, verts));
|
||||
JS_SetPropertyStr(js, ret, "count", number2js(js, count));
|
||||
JS_SetPropertyStr(js,ret,"num_indices", number2js(js,count));
|
||||
|
||||
// Free temporary CPU arrays
|
||||
free(posdata);
|
||||
free(uvdata);
|
||||
free(colordata);
|
||||
|
||||
// Free old buffer values if they were fetched
|
||||
if (!JS_IsNull(pos_chk.val)) JS_FreeValue(js, pos_chk.val);
|
||||
if (!JS_IsNull(uv_chk.val)) JS_FreeValue(js, uv_chk.val);
|
||||
if (!JS_IsNull(color_chk.val)) JS_FreeValue(js, color_chk.val);
|
||||
|
||||
return ret;
|
||||
)
|
||||
|
||||
struct quad_buffers {
|
||||
HMM_Vec2 *pos;
|
||||
HMM_Vec2 *uv;
|
||||
@@ -601,27 +490,6 @@ struct quad_buffers quad_buffers_new(int verts)
|
||||
return b;
|
||||
}
|
||||
|
||||
JSValue quadbuffers_to_mesh(JSContext *js, struct quad_buffers buffers)
|
||||
{
|
||||
JSValue jspos = make_gpu_buffer(js, buffers.pos, sizeof(HMM_Vec2)*buffers.verts, 0, 2, 0, 0);
|
||||
JSValue jsuv = make_gpu_buffer(js, buffers.uv, sizeof(HMM_Vec2)*buffers.verts, 0, 2,0,0);
|
||||
JSValue jscolor = make_gpu_buffer(js, buffers.color, sizeof(HMM_Vec4)*buffers.verts, 0, 4,0,0);
|
||||
|
||||
size_t quads = buffers.verts/4;
|
||||
size_t count = buffers.verts/2*3;
|
||||
JSValue jsidx = make_quad_indices_buffer(js, quads);
|
||||
|
||||
JSValue ret = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, ret, "pos", jspos);
|
||||
JS_SetPropertyStr(js, ret, "uv", jsuv);
|
||||
JS_SetPropertyStr(js, ret, "color", jscolor);
|
||||
JS_SetPropertyStr(js, ret, "indices", jsidx);
|
||||
JS_SetPropertyStr(js, ret, "vertices", number2js(js, buffers.verts));
|
||||
JS_SetPropertyStr(js,ret,"num_indices", number2js(js,count));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sort_sprite(const sprite *a, const sprite *b)
|
||||
{
|
||||
if (a->layer != b->layer) return a->layer - b->layer;
|
||||
@@ -634,142 +502,6 @@ int sort_sprite(const sprite *a, const sprite *b)
|
||||
return 0;
|
||||
}
|
||||
|
||||
JSC_CCALL(gpu_make_sprite_queue,
|
||||
sprite *sprites = NULL;
|
||||
size_t quads = 0;
|
||||
int needfree = 1;
|
||||
|
||||
if (js_is_blob(js, argv[0])) {
|
||||
// test for fastest
|
||||
size_t size;
|
||||
sprite *sprites = js_get_blob_data(js, &size, argv[0]);
|
||||
quads = size/sizeof(*sprites);
|
||||
needfree = 0;
|
||||
for (int i = 0; i < quads; i++)
|
||||
JS_DupValue(js,sprites[i].image);
|
||||
} else {
|
||||
quads = JS_ArrayLength(js, argv[0]);
|
||||
if (quads == 0)
|
||||
return JS_ThrowReferenceError(js, "Expected an array of sprites with length > 0.");
|
||||
|
||||
arrsetcap(sprites, quads);
|
||||
|
||||
for (int i = 0; i < quads; i++) {
|
||||
JSValue sub = JS_GetPropertyUint32(js, argv[0], i);
|
||||
sprite *jsp = js2sprite(js, sub);
|
||||
if (jsp) {
|
||||
arrput(sprites, *jsp);
|
||||
JS_DupValue(js,jsp->image);
|
||||
}
|
||||
else {
|
||||
sprite sp = {0};
|
||||
JS_GETATOM(js, sp.pos, sub, pos, vec2)
|
||||
JS_GETATOM(js, sp.center, sub, center, vec2)
|
||||
JS_GETATOM(js, sp.skew, sub, skew, vec2)
|
||||
JS_GETATOM(js, sp.scale, sub, scale, vec2)
|
||||
JS_GETATOM(js, sp.color,sub,color,color)
|
||||
JS_GETATOM(js, sp.layer,sub,layer,number)
|
||||
sp.image = JS_GetPropertyStr(js,sub,"image");
|
||||
sprite_apply(&sp);
|
||||
arrput(sprites,sp);
|
||||
}
|
||||
JS_FreeValue(js, sub);
|
||||
}
|
||||
}
|
||||
|
||||
qsort(sprites, quads, sizeof(sprite), sort_sprite);
|
||||
|
||||
struct quad_buffers buffers = quad_buffers_new(quads*4);
|
||||
|
||||
const HMM_Vec2 local[4] = { {0,0}, {1,0}, {0,1}, {1,1} };
|
||||
|
||||
rect uv;
|
||||
rect uv_px;
|
||||
JSValue cur_img = JS_NULL;
|
||||
|
||||
for (size_t i = 0; i < quads; i++) {
|
||||
sprite *s = &sprites[i];
|
||||
if (JS_IsNull(cur_img) || !JS_StrictEq(js, s->image, cur_img)) {
|
||||
cur_img = s->image;
|
||||
JS_GETATOM(js, uv, cur_img, rect, rect)
|
||||
JS_GETATOM(js, uv_px, cur_img, rect_px, rect)
|
||||
}
|
||||
|
||||
HMM_Vec2 px_size = {
|
||||
uv_px.w * s->scale.X,
|
||||
uv_px.h * s->scale.Y
|
||||
};
|
||||
|
||||
HMM_Vec2 anchor = {
|
||||
px_size.X * s->center.X,
|
||||
px_size.Y * s->center.Y
|
||||
};
|
||||
|
||||
size_t base = i * 4;
|
||||
|
||||
for (int v = 0; v < 4; v++) {
|
||||
HMM_Vec2 lp = {
|
||||
local[v].X * px_size.X - anchor.X,
|
||||
local[v].Y * px_size.Y - anchor.Y
|
||||
};
|
||||
|
||||
HMM_Vec2 world = HMM_AddV2(s->pos, HMM_MulM2V2(s->affine, lp));
|
||||
|
||||
buffers.pos[base + v] = world;
|
||||
buffers.color[base + v] = s->color;
|
||||
}
|
||||
|
||||
/* UVs are still top-left-origin pixel coords, so keep previous packing */
|
||||
buffers.uv[base + 0] = (HMM_Vec2){ uv.x, uv.y + uv.h };
|
||||
buffers.uv[base + 1] = (HMM_Vec2){ uv.x + uv.w, uv.y + uv.h };
|
||||
buffers.uv[base + 2] = (HMM_Vec2){ uv.x, uv.y };
|
||||
buffers.uv[base + 3] = (HMM_Vec2){ uv.x + uv.w, uv.y };
|
||||
}
|
||||
|
||||
JSValue mesh = quadbuffers_to_mesh(js, buffers);
|
||||
|
||||
ret = JS_NewArray(js);
|
||||
int first_index = 0;
|
||||
int count = 0;
|
||||
int n = 0;
|
||||
JSValue img = JS_NULL;
|
||||
|
||||
for (int i = 0; i < quads; i++) {
|
||||
if (!JS_SameValue(js, sprites[i].image, img)) {
|
||||
if (count > 0) {
|
||||
JSValue q = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, q, "type", JS_NewString(js, "geometry"));
|
||||
JS_SetPropertyStr(js, q, "mesh", JS_DupValue(js, mesh));
|
||||
JS_SetPropertyStr(js, q, "pipeline", JS_DupValue(js, argv[2]));
|
||||
JS_SetPropertyStr(js, q, "image", img);
|
||||
JS_SetPropertyStr(js, q, "first_index", number2js(js, first_index));
|
||||
JS_SetPropertyStr(js, q, "num_indices", number2js(js, count * 6));
|
||||
JS_SetPropertyUint32(js, ret, n++, q);
|
||||
}
|
||||
first_index = i*6;
|
||||
count = 1;
|
||||
img = JS_DupValue(js, sprites[i].image);
|
||||
} else count++;
|
||||
JS_FreeValue(js,sprites[i].image);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
JSValue q = JS_NewObject(js);
|
||||
JS_SetPropertyStr(js, q, "type", JS_NewString(js, "geometry"));
|
||||
JS_SetPropertyStr(js, q, "mesh", JS_DupValue(js, mesh));
|
||||
JS_SetPropertyStr(js, q, "pipeline", JS_DupValue(js, argv[2]));
|
||||
JS_SetPropertyStr(js, q, "image", img);
|
||||
JS_SetPropertyStr(js, q, "first_index", number2js(js, first_index));
|
||||
JS_SetPropertyStr(js, q, "num_indices", number2js(js, count * 6));
|
||||
JS_SetPropertyUint32(js, ret, n++, q);
|
||||
}
|
||||
|
||||
if (needfree)
|
||||
arrfree(sprites);
|
||||
|
||||
JS_FreeValue(js, mesh);
|
||||
)
|
||||
|
||||
JSC_CCALL(geometry_rect_transform,
|
||||
// argv[0] = world‐space rect
|
||||
rect r = js2rect(js, argv[0]);
|
||||
@@ -899,14 +631,11 @@ JSC_CCALL(geometry_tilemap_to_data,
|
||||
xy_data[base + 7] = world_y + size_y;
|
||||
|
||||
// Set UVs (normalized 0-1 for now)
|
||||
uv_data[base + 0] = 0.0f;
|
||||
uv_data[base + 1] = 0.0f;
|
||||
uv_data[base + 2] = 1.0f;
|
||||
uv_data[base + 3] = 0.0f;
|
||||
uv_data[base + 4] = 0.0f;
|
||||
uv_data[base + 5] = 1.0f;
|
||||
uv_data[base + 6] = 1.0f;
|
||||
uv_data[base + 7] = 1.0f;
|
||||
uv_data[base + 0] = 0; uv_data[base + 1] = 1.0f; // now samples the TOP of the image
|
||||
uv_data[base + 2] = 1.0f; uv_data[base + 3] = 1.0f;
|
||||
uv_data[base + 4] = 0; uv_data[base + 5] = 0;
|
||||
uv_data[base + 6] = 1.0f; uv_data[base + 7] = 0;
|
||||
|
||||
|
||||
// Set colors (check if tile has color property)
|
||||
SDL_FColor default_color = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
@@ -1270,82 +999,6 @@ JSC_CCALL(geometry_transform_xy_blob,
|
||||
ret = transformed_blob;
|
||||
)
|
||||
|
||||
// RENDERITEM SYSTEM
|
||||
typedef struct {
|
||||
int layer;
|
||||
float y;
|
||||
JSValue val;
|
||||
} RenderItem;
|
||||
|
||||
#define MAX_RENDER_ITEMS 64000
|
||||
static RenderItem render_items[MAX_RENDER_ITEMS];
|
||||
static int render_item_count = 0;
|
||||
|
||||
JSC_CCALL(geometry_renderitem_push,
|
||||
if (argc < 3) {
|
||||
return JS_ThrowTypeError(js, "renderitem_push requires 3 arguments: layer, y, val");
|
||||
}
|
||||
|
||||
if (render_item_count >= MAX_RENDER_ITEMS) {
|
||||
return JS_ThrowTypeError(js, "Maximum render items exceeded");
|
||||
}
|
||||
|
||||
int layer;
|
||||
double y;
|
||||
|
||||
if (JS_ToInt32(js, &layer, argv[0]) < 0) {
|
||||
return JS_ThrowTypeError(js, "layer must be a number");
|
||||
}
|
||||
|
||||
if (JS_ToFloat64(js, &y, argv[1]) < 0) {
|
||||
return JS_ThrowTypeError(js, "y must be a number");
|
||||
}
|
||||
|
||||
render_items[render_item_count].layer = layer;
|
||||
render_items[render_item_count].y = (float)y;
|
||||
render_items[render_item_count].val = JS_DupValue(js, argv[2]);
|
||||
render_item_count++;
|
||||
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
static int compare_render_items(const void *a, const void *b)
|
||||
{
|
||||
const RenderItem *item_a = (const RenderItem *)a;
|
||||
const RenderItem *item_b = (const RenderItem *)b;
|
||||
|
||||
if (item_a->layer != item_b->layer) {
|
||||
return item_a->layer - item_b->layer;
|
||||
}
|
||||
|
||||
// if (item_a->y != item_b->y) {
|
||||
// return (item_b->y > item_a->y) ? 1 : -1;
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
JSC_CCALL(geometry_renderitem_sort,
|
||||
qsort(render_items, render_item_count, sizeof(RenderItem), compare_render_items);
|
||||
|
||||
JSValue result = JS_NewArray(js);
|
||||
|
||||
for (int i = 0; i < render_item_count; i++) {
|
||||
JS_SetPropertyUint32(js, result, i, JS_DupValue(js, render_items[i].val));
|
||||
}
|
||||
|
||||
return result;
|
||||
)
|
||||
|
||||
JSC_CCALL(geometry_renderitem_clear,
|
||||
for (int i = 0; i < render_item_count; i++) {
|
||||
JS_FreeValue(js, render_items[i].val);
|
||||
}
|
||||
render_item_count = 0;
|
||||
|
||||
return JS_NULL;
|
||||
)
|
||||
|
||||
JSC_CCALL(geometry_array_blob,
|
||||
JSValue arr = argv[0];
|
||||
size_t len = JS_ArrayLength(js,arr);
|
||||
@@ -1463,11 +1116,6 @@ static const JSCFunctionListEntry js_geometry_funcs[] = {
|
||||
MIST_FUNC_DEF(geometry, transform_xy_blob, 2),
|
||||
MIST_FUNC_DEF(gpu, tile, 4),
|
||||
MIST_FUNC_DEF(gpu, slice9, 4),
|
||||
MIST_FUNC_DEF(gpu, make_sprite_mesh, 2),
|
||||
MIST_FUNC_DEF(gpu, make_sprite_queue, 4),
|
||||
MIST_FUNC_DEF(geometry, renderitem_push, 3),
|
||||
MIST_FUNC_DEF(geometry, renderitem_sort, 0),
|
||||
MIST_FUNC_DEF(geometry, renderitem_clear, 0),
|
||||
MIST_FUNC_DEF(geometry, array_blob, 2),
|
||||
MIST_FUNC_DEF(geometry, make_quad_indices, 1),
|
||||
MIST_FUNC_DEF(geometry, make_rect_quad, 3),
|
||||
|
||||
Reference in New Issue
Block a user