Particles now work with ssbos

This commit is contained in:
John Alanbrook 2024-05-10 07:55:53 -05:00
parent 011d1d99d5
commit 36505ebf51
3 changed files with 44 additions and 23 deletions

View file

@ -608,6 +608,11 @@ sg_bindings js2bind(JSValue v)
bind.fs.samplers[i] = std_sampler; 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; return bind;
} }
@ -630,7 +635,10 @@ JSC_GETSET(emitter, persist_var, number)
JSC_GETSET(emitter, warp_mask, bitmask) JSC_GETSET(emitter, warp_mask, bitmask)
JSC_CCALL(emitter_emit, emitter_emit(js2emitter(this), js2number(argv[0]), js2transform2d(argv[1]))) 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_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()) JSC_CCALL(render_flushtext, text_flush())
@ -742,6 +750,13 @@ sg_shader js2shader(JSValue v)
desc.fs.image_sampler_pairs[0].sampler_slot = 0; 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); sg_shader sh = sg_make_shader(&desc);
jsfreestr(vsf); jsfreestr(vsf);
@ -841,7 +856,8 @@ JSC_CCALL(render_spdraw,
sg_bindings bind = js2bind(argv[0]); sg_bindings bind = js2bind(argv[0]);
sg_apply_bindings(&bind); sg_apply_bindings(&bind);
int p = js2number(js_getpropstr(argv[0], "count")); 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, JSC_CCALL(render_setpipeline,
@ -1812,7 +1828,11 @@ JSC_CCALL(os_make_transform2d,
JSC_SCALL(os_system, return number2js(system(str)); ) JSC_SCALL(os_system, return number2js(system(str)); )
JSC_SCALL(os_make_model, ret = model2js(model_make(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, JSC_CCALL(os_make_buffer,
int type = js2number(argv[1]); int type = js2number(argv[1]);

View file

@ -19,7 +19,7 @@ emitter *make_emitter() {
e->speed = 20; e->speed = 20;
e->buffer = sg_make_buffer(&(sg_buffer_desc){ e->buffer = sg_make_buffer(&(sg_buffer_desc){
.size = sizeof(struct par_vert), .size = sizeof(struct par_vert),
.type = SG_BUFFERTYPE_VERTEXBUFFER, .type = SG_BUFFERTYPE_STORAGEBUFFER,
.usage = SG_USAGE_STREAM .usage = SG_USAGE_STREAM
}); });
return e; return e;
@ -41,13 +41,14 @@ float variate(float val, float variance)
int emitter_spawn(emitter *e, transform2d *t) 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.life = e->life;
p.pos = (HMM_Vec4){t->pos.x,t->pos.y,0,0}; 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); 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.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); p.scale = variate(e->scale*t->scale.x, e->scale_var);
arrput(e->particles,p); arrput(e->particles,p);
return 1; return 1;
@ -59,7 +60,7 @@ void emitter_emit(emitter *e, int count, transform2d *t)
emitter_spawn(e, t); emitter_spawn(e, t);
} }
void emitter_draw(emitter *e, sg_bindings bind) void emitter_draw(emitter *e)
{ {
if (arrlen(e->particles) == 0) return; if (arrlen(e->particles) == 0) return;
arrsetlen(e->verts, arrlen(e->particles)); 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); e->verts[i].scale = lerp(p->time/e->grow_for, 0, p->scale);
else if (p->time > (p->life - e->shrink_for)) 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].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; sg_range verts;
verts.ptr = e->verts; verts.ptr = e->verts;
verts.size = sizeof(*e->verts)*arrlen(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){ e->buffer = sg_make_buffer(&(sg_buffer_desc){
.size = verts.size, .size = verts.size,
.type = SG_BUFFERTYPE_VERTEXBUFFER, .type = SG_BUFFERTYPE_STORAGEBUFFER,
.usage = SG_USAGE_STREAM .usage = SG_USAGE_STREAM
}); });
}
sg_append_buffer(e->buffer, &verts); 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) { 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); 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++) { 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) if (e->particles[i].time >= e->particles[i].life)
arrdelswap(e->particles, i); arrdelswap(e->particles, i);
else if (query_point(e->particles[i].pos.xy)) // else if (query_point(e->particles[i].pos.xy))
arrdelswap(e->particles,i); // arrdelswap(e->particles,i);
} }
e->tte-=dt; e->tte-=dt;
if (e->tte <= 0) { float step = lerp(e->explosiveness, e->life/e->max,0);
emitter_spawn(e, t); while (e->tte <= 0) {
e->tte = lerp(e->explosiveness, e->life/e->max,0); e->tte += step;
if (!emitter_spawn(e, t)) break;
} }
} }

View file

@ -28,7 +28,7 @@ typedef struct par_vert {
HMM_Vec2 pos; HMM_Vec2 pos;
float angle; float angle;
float scale; float scale;
struct rgba color; HMM_Vec4 color;
} par_vert; } par_vert;
typedef struct emitter { typedef struct emitter {
@ -70,6 +70,6 @@ void emitter_free(emitter *e);
void emitter_emit(emitter *e, int count, transform2d *t); void emitter_emit(emitter *e, int count, transform2d *t);
void emitter_step(emitter *e, double dt, 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 #endif