From cf6feffda2b284fe16c034c1795c9298f0d71e2c Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Thu, 18 Jul 2024 17:09:35 -0500 Subject: [PATCH] custom ssbo buffers --- scripts/render.js | 21 ++++++++++++++------- shaders/baseparticle.cg | 2 ++ source/engine/font.c | 21 +++++---------------- source/engine/font.h | 3 +-- source/engine/jsffi.c | 31 +++++++++++++++++++++++++------ source/engine/jsffi.h | 1 + source/engine/particle.c | 19 +++++++------------ source/engine/particle.h | 3 +-- source/engine/render.c | 2 -- 9 files changed, 56 insertions(+), 47 deletions(-) diff --git a/scripts/render.js b/scripts/render.js index 311e952..3bfc855 100644 --- a/scripts/render.js +++ b/scripts/render.js @@ -438,6 +438,7 @@ render.init = function() { circleshader = render.make_shader("shaders/circle.cg"); polyshader = render.make_shader("shaders/poly.cg"); parshader = render.make_shader("shaders/baseparticle.cg"); + textssbo = render.make_textssbo(); render.textshader = textshader; @@ -637,22 +638,28 @@ render.slice9 = function(tex, pos, bb, scale = [tex.width,tex.height], color = C render.draw(shape.quad); } -var textssbo = render.text_ssbo(); - -render.emitter(emit) +render.emitter = function(emit) { - var ssbo = emit.draw(); - render.use_shader(particleshader); - render.draw(shape.quad, ssbo, + var amt = emit.draw(); + if (amt === 0) return; + render.use_shader(parshader); + render.use_mat({}); + render.draw(shape.quad, emit.buffer, amt); } +var textssbo; + render.flush_text = function() { if (!render.textshader) return; + var amt = render.flushtext(textssbo); + render.use_shader(render.textshader); render.use_mat({text:render.font.texture}); - render.draw(shape.quad, textssbo, render.flushtext()); + if (amt === 0) return; + + render.draw(shape.quad, textssbo, amt); } render.fontcache = {}; diff --git a/shaders/baseparticle.cg b/shaders/baseparticle.cg index 36c1205..1ff1a2c 100644 --- a/shaders/baseparticle.cg +++ b/shaders/baseparticle.cg @@ -46,6 +46,8 @@ sampler smp; void main() { color = color0; + color.r = 1; + color.a = 1; } @end diff --git a/source/engine/font.c b/source/engine/font.c index 0c8344f..bc05183 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -20,8 +20,6 @@ struct sFont *use_font; -sg_buffer text_ssbo; - struct text_vert { HMM_Vec2 pos; HMM_Vec2 wh; @@ -32,15 +30,6 @@ struct text_vert { static struct text_vert *text_buffer; -void font_init() { - text_ssbo = sg_make_buffer(&(sg_buffer_desc){ - .size = sizeof(struct text_vert), - .type = SG_BUFFERTYPE_STORAGEBUFFER, - .usage = SG_USAGE_STREAM, - .label = "text buffer" - }); -} - void font_free(font *f) { sg_destroy_image(f->texID); @@ -177,15 +166,15 @@ void draw_char_box(struct Character c, HMM_Vec2 cursor, float scale, struct rgba b.y = cursor.Y + wh.y/2; } -int text_flush() { +int text_flush(sg_buffer *buf) { if (arrlen(text_buffer) == 0) return 0; sg_range verts; verts.ptr = text_buffer; verts.size = sizeof(struct text_vert) * arrlen(text_buffer); - if (sg_query_buffer_will_overflow(text_ssbo, verts.size)) { - sg_destroy_buffer(text_ssbo); - text_ssbo = sg_make_buffer(&(sg_buffer_desc){ + if (sg_query_buffer_will_overflow(*buf, verts.size)) { + sg_destroy_buffer(*buf); + *buf = sg_make_buffer(&(sg_buffer_desc){ .size = verts.size, .type = SG_BUFFERTYPE_STORAGEBUFFER, .usage = SG_USAGE_STREAM, @@ -193,7 +182,7 @@ int text_flush() { }); } - sg_append_buffer(text_ssbo, &verts); + sg_append_buffer(*buf, &verts); int n = arrlen(text_buffer); arrsetlen(text_buffer, 0); return n; diff --git a/source/engine/font.h b/source/engine/font.h index db61988..46c390a 100644 --- a/source/engine/font.h +++ b/source/engine/font.h @@ -34,7 +34,6 @@ typedef struct sFont font; void font_free(font *f); -void font_init(); struct sFont *MakeFont(const char *fontfile, int height); void font_set(font *f); void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color); @@ -42,6 +41,6 @@ void text_settype(struct sFont *font); struct boundingbox text_bb(const char *text, float scale, float lw, float tracking); int renderText(const char *text, HMM_Vec2 pos, float scale, struct rgba color, float lw, int caret, float tracking); -int text_flush(); +int text_flush(sg_buffer *buf); #endif diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index 38a5961..46ba1e9 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -681,12 +681,25 @@ JSC_GETSET(emitter, warp_mask, bitmask) JSC_CCALL(emitter_emit, emitter_emit(js2emitter(self), js2number(argv[0]), js2transform(argv[1]))) JSC_CCALL(emitter_step, emitter_step(js2emitter(self), js2number(argv[0]), js2transform(argv[1]))) JSC_CCALL(emitter_draw, - emitter_draw(js2emitter(self)); + sg_buffer *b = js2sg_buffer(js_getpropstr(self, "buffer")); + emitter_draw(js2emitter(self), b); return number2js(arrlen(js2emitter(self)->verts)); ) JSC_CCALL(render_flushtext, - return number2js(text_flush()); + sg_buffer *buf = js2sg_buffer(argv[0]); + int amt = text_flush(buf); + return number2js(amt); +) + +JSC_CCALL(render_make_textssbo, + sg_buffer *b = malloc(sizeof(*b)); + *b = sg_make_buffer(&(sg_buffer_desc){ + .type = SG_BUFFERTYPE_STORAGEBUFFER, + .size = 4, + .usage = SG_USAGE_STREAM + }); + return sg_buffer2js(b); ) JSC_CCALL(render_glue_pass, @@ -982,7 +995,6 @@ JSC_CCALL(render_setpipeline, sg_apply_pipeline(p); ) -JSC_CCALL(render_text_ssbo, return sg_buffer2js(&text_ssbo)) JSC_CCALL(render_screencolor, texture *t = calloc(sizeof(*t), 1); t->id = screencolor; @@ -996,14 +1008,14 @@ JSC_CCALL(render_imgui_end, gui_endframe()) JSC_CCALL(render_imgui_init, return gui_init(js)) static const JSCFunctionListEntry js_render_funcs[] = { - MIST_FUNC_DEF(render, flushtext, 0), + MIST_FUNC_DEF(render, flushtext, 1), MIST_FUNC_DEF(render, camera_screen2world, 2), + MIST_FUNC_DEF(render, make_textssbo, 0), MIST_FUNC_DEF(render, viewport, 4), MIST_FUNC_DEF(render, end_pass, 0), MIST_FUNC_DEF(render, commit, 0), MIST_FUNC_DEF(render, glue_pass, 0), MIST_FUNC_DEF(render, text_size, 3), - MIST_FUNC_DEF(render, text_ssbo, 0), MIST_FUNC_DEF(render, set_camera, 1), MIST_FUNC_DEF(render, pipeline, 1), MIST_FUNC_DEF(render, setuniv3, 2), @@ -2380,10 +2392,17 @@ JSC_SCALL(os_make_model, js_setpropstr(v, "material", material2js(me->primitives[0].mat)); return v; ) + JSC_CCALL(os_make_emitter, emitter *e = make_emitter(); ret = emitter2js(e); - js_setpropstr(ret, "buffer", sg_buffer2js(&e->buffer)); + sg_buffer *b = malloc(sizeof(*b)); + *b = sg_make_buffer(&(sg_buffer_desc) { + .type = SG_BUFFERTYPE_STORAGEBUFFER, + .size = 4, + .usage = SG_USAGE_STREAM + }); + js_setpropstr(ret, "buffer", sg_buffer2js(b)); ) JSC_CCALL(os_make_buffer, diff --git a/source/engine/jsffi.h b/source/engine/jsffi.h index bac1dff..c36aafa 100644 --- a/source/engine/jsffi.h +++ b/source/engine/jsffi.h @@ -99,6 +99,7 @@ static JSClassDef js_##TYPE##_class = {\ .finalizer = js_##TYPE##_finalizer,\ };\ TYPE *js2##TYPE (JSValue val) { \ + if (JS_IsUndefined(val)) return NULL; \ assert(JS_GetClassID(val) == js_##TYPE##_id); \ return JS_GetOpaque(val,js_##TYPE##_id); \ }\ diff --git a/source/engine/particle.c b/source/engine/particle.c index 6ec8f89..7807f3d 100644 --- a/source/engine/particle.c +++ b/source/engine/particle.c @@ -17,11 +17,7 @@ emitter *make_emitter() { e->tte = lerp(e->explosiveness, e->life/e->max, 0); e->scale = 1; e->speed = 20; - e->buffer = sg_make_buffer(&(sg_buffer_desc){ - .size = sizeof(struct par_vert), - .type = SG_BUFFERTYPE_STORAGEBUFFER, - .usage = SG_USAGE_STREAM - }); + return e; } @@ -62,10 +58,9 @@ void emitter_emit(emitter *e, int count, transform *t) emitter_spawn(e, t); } -void emitter_draw(emitter *e) +int emitter_draw(emitter *e, sg_buffer *b) { - printf("drawing %d particles\n", arrlen(e->particles)); - if (arrlen(e->particles) == 0) return; + if (arrlen(e->particles) == 0) return 0; arrsetlen(e->verts, arrlen(e->particles)); for (int i = 0; i < arrlen(e->particles); i++) { if (e->particles[i].time >= e->particles[i].life) continue; @@ -83,16 +78,16 @@ void emitter_draw(emitter *e) 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)) { - sg_destroy_buffer(e->buffer); - e->buffer = sg_make_buffer(&(sg_buffer_desc){ + if (sg_query_buffer_will_overflow(*b, verts.size)) { + sg_destroy_buffer(*b); + *b = sg_make_buffer(&(sg_buffer_desc){ .size = verts.size, .type = SG_BUFFERTYPE_STORAGEBUFFER, .usage = SG_USAGE_STREAM }); } - sg_append_buffer(e->buffer, &verts); + sg_append_buffer(*b, &verts); } void emitter_step(emitter *e, double dt, transform *t) { diff --git a/source/engine/particle.h b/source/engine/particle.h index 20c0f2c..6a846a0 100644 --- a/source/engine/particle.h +++ b/source/engine/particle.h @@ -62,7 +62,6 @@ typedef struct emitter { /* TRAILS */ warpmask warp_mask; double tte; /* time to emit */ - sg_buffer buffer; } emitter; emitter *make_emitter(); @@ -70,6 +69,6 @@ void emitter_free(emitter *e); void emitter_emit(emitter *e, int count, transform *t); void emitter_step(emitter *e, double dt, transform *t); -void emitter_draw(emitter *e); +int emitter_draw(emitter *e, sg_buffer *b); #endif diff --git a/source/engine/render.c b/source/engine/render.c index 1f1666d..3dfc076 100644 --- a/source/engine/render.c +++ b/source/engine/render.c @@ -149,8 +149,6 @@ void render_init() { sg_trace_hooks hh = sg_install_trace_hooks(&hooks); #endif - font_init(); - sg_features feat = sg_query_features(); TOPLEFT = feat.origin_top_left;