From 36505ebf513d03061c1f382b45f3c4975f34b218 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Fri, 10 May 2024 07:55:53 -0500 Subject: [PATCH] Particles now work with ssbos --- source/engine/jsffi.c | 28 ++++++++++++++++++++++++---- source/engine/particle.c | 35 ++++++++++++++++++----------------- source/engine/particle.h | 4 ++-- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index 7d6b446..b8ee301 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -608,6 +608,11 @@ sg_bindings js2bind(JSValue v) bind.fs.samplers[i] = std_sampler; } + JSValue ssbo = js_getpropstr(v, "ssbo"); + for (int i = 0; i < js_arrlen(ssbo); i++) { + bind.vs.storage_buffers[i] = *js2sg_buffer(js_getpropidx(ssbo,i)); + } + return bind; } @@ -630,7 +635,10 @@ JSC_GETSET(emitter, persist_var, number) JSC_GETSET(emitter, warp_mask, bitmask) JSC_CCALL(emitter_emit, emitter_emit(js2emitter(this), js2number(argv[0]), js2transform2d(argv[1]))) JSC_CCALL(emitter_step, emitter_step(js2emitter(this), js2number(argv[0]), js2transform2d(argv[1]))) -JSC_CCALL(emitter_draw, emitter_draw(js2emitter(this), js2bind(argv[0]))) +JSC_CCALL(emitter_draw, + emitter_draw(js2emitter(this)); + return number2js(arrlen(js2emitter(this)->verts)); +) JSC_CCALL(render_flushtext, text_flush()) @@ -742,6 +750,13 @@ sg_shader js2shader(JSValue v) desc.fs.image_sampler_pairs[0].sampler_slot = 0; } + JSValue ssbos = js_getpropstr(vs, "storage_buffers"); + unin = js_arrlen(ssbos); + for (int i = 0; i < unin; i++) { + desc.vs.storage_buffers[i].used = true; + desc.vs.storage_buffers[i].readonly = true; + } + sg_shader sh = sg_make_shader(&desc); jsfreestr(vsf); @@ -841,7 +856,8 @@ JSC_CCALL(render_spdraw, sg_bindings bind = js2bind(argv[0]); sg_apply_bindings(&bind); int p = js2number(js_getpropstr(argv[0], "count")); - sg_draw(0,p,1); + int n = js2number(js_getpropstr(argv[0], "inst")); + sg_draw(0,p,n); ) JSC_CCALL(render_setpipeline, @@ -1311,7 +1327,7 @@ static const JSCFunctionListEntry js_emitter_funcs[] = { CGETSET_ADD(emitter, die_after_collision), CGETSET_ADD(emitter, persist), CGETSET_ADD(emitter, persist_var), - CGETSET_ADD(emitter, warp_mask), + CGETSET_ADD(emitter, warp_mask), MIST_FUNC_DEF(emitter, emit, 1), MIST_FUNC_DEF(emitter, step, 1), MIST_FUNC_DEF(emitter, draw, 1) @@ -1812,7 +1828,11 @@ JSC_CCALL(os_make_transform2d, JSC_SCALL(os_system, return number2js(system(str)); ) JSC_SCALL(os_make_model, ret = model2js(model_make(str))) -JSC_CCALL(os_make_emitter, ret = emitter2js(make_emitter())) +JSC_CCALL(os_make_emitter, + emitter *e = make_emitter(); + ret = emitter2js(e); + js_setpropstr(ret, "buffer", sg_buffer2js(&e->buffer)); +) JSC_CCALL(os_make_buffer, int type = js2number(argv[1]); diff --git a/source/engine/particle.c b/source/engine/particle.c index ca7dceb..34f64b6 100644 --- a/source/engine/particle.c +++ b/source/engine/particle.c @@ -19,7 +19,7 @@ emitter *make_emitter() { e->speed = 20; e->buffer = sg_make_buffer(&(sg_buffer_desc){ .size = sizeof(struct par_vert), - .type = SG_BUFFERTYPE_VERTEXBUFFER, + .type = SG_BUFFERTYPE_STORAGEBUFFER, .usage = SG_USAGE_STREAM }); return e; @@ -41,13 +41,14 @@ float variate(float val, float variance) int emitter_spawn(emitter *e, transform2d *t) { - particle p; + if (arrlen(e->particles) == e->max) return 0; + particle p = {0}; p.life = e->life; p.pos = (HMM_Vec4){t->pos.x,t->pos.y,0,0}; - float newan = t->angle * HMM_TurnToRad*(frand(e->divergence)-(e->divergence/2)); + float newan = t->angle + (frand(e->divergence)-(e->divergence/2))*HMM_TurnToRad; HMM_Vec2 norm = HMM_V2Rotate((HMM_Vec2){0,1}, newan); p.v = HMM_MulV4F((HMM_Vec4){norm.x,norm.y,0,0}, variate(e->speed, e->variation)); - p.angle = newan; + p.angle = 0.25; p.scale = variate(e->scale*t->scale.x, e->scale_var); arrput(e->particles,p); return 1; @@ -59,7 +60,7 @@ void emitter_emit(emitter *e, int count, transform2d *t) emitter_spawn(e, t); } -void emitter_draw(emitter *e, sg_bindings bind) +void emitter_draw(emitter *e) { if (arrlen(e->particles) == 0) return; arrsetlen(e->verts, arrlen(e->particles)); @@ -73,27 +74,26 @@ void emitter_draw(emitter *e, sg_bindings bind) e->verts[i].scale = lerp(p->time/e->grow_for, 0, p->scale); else if (p->time > (p->life - e->shrink_for)) e->verts[i].scale = lerp((p->time-(p->life-e->shrink_for))/e->shrink_for, p->scale, 0);*/ - e->verts[i].color = vec2rgba(p->color); + e->verts[i].color = p->color; } sg_range verts; verts.ptr = e->verts; verts.size = sizeof(*e->verts)*arrlen(e->verts); - if (sg_query_buffer_will_overflow(e->buffer, verts.size)) + if (sg_query_buffer_will_overflow(e->buffer, verts.size)) { + sg_destroy_buffer(e->buffer); e->buffer = sg_make_buffer(&(sg_buffer_desc){ .size = verts.size, - .type = SG_BUFFERTYPE_VERTEXBUFFER, + .type = SG_BUFFERTYPE_STORAGEBUFFER, .usage = SG_USAGE_STREAM }); + } sg_append_buffer(e->buffer, &verts); - - bind.vertex_buffers[0] = e->buffer; - sg_apply_bindings(&bind); - sg_draw(0,4,arrlen(e->verts)); } void emitter_step(emitter *e, double dt, transform2d *t) { + HMM_Vec4 g_accel = HMM_MulV4F((HMM_Vec4){cpSpaceGetGravity(space).x, cpSpaceGetGravity(space).y, 0, 0}, dt); for (int i = 0; i < arrlen(e->particles); i++) { @@ -110,13 +110,14 @@ void emitter_step(emitter *e, double dt, transform2d *t) { if (e->particles[i].time >= e->particles[i].life) arrdelswap(e->particles, i); - else if (query_point(e->particles[i].pos.xy)) - arrdelswap(e->particles,i); +// else if (query_point(e->particles[i].pos.xy)) +// arrdelswap(e->particles,i); } e->tte-=dt; - if (e->tte <= 0) { - emitter_spawn(e, t); - e->tte = lerp(e->explosiveness, e->life/e->max,0); + float step = lerp(e->explosiveness, e->life/e->max,0); + while (e->tte <= 0) { + e->tte += step; + if (!emitter_spawn(e, t)) break; } } diff --git a/source/engine/particle.h b/source/engine/particle.h index ce6227a..7bea7c5 100644 --- a/source/engine/particle.h +++ b/source/engine/particle.h @@ -28,7 +28,7 @@ typedef struct par_vert { HMM_Vec2 pos; float angle; float scale; - struct rgba color; + HMM_Vec4 color; } par_vert; typedef struct emitter { @@ -70,6 +70,6 @@ void emitter_free(emitter *e); void emitter_emit(emitter *e, int count, transform2d *t); void emitter_step(emitter *e, double dt, transform2d *t); -void emitter_draw(emitter *e, sg_bindings bind); +void emitter_draw(emitter *e); #endif