custom ssbo buffers

This commit is contained in:
John Alanbrook 2024-07-18 17:09:35 -05:00
parent 066b213fbe
commit cf6feffda2
9 changed files with 56 additions and 47 deletions

View file

@ -438,6 +438,7 @@ render.init = function() {
circleshader = render.make_shader("shaders/circle.cg"); circleshader = render.make_shader("shaders/circle.cg");
polyshader = render.make_shader("shaders/poly.cg"); polyshader = render.make_shader("shaders/poly.cg");
parshader = render.make_shader("shaders/baseparticle.cg"); parshader = render.make_shader("shaders/baseparticle.cg");
textssbo = render.make_textssbo();
render.textshader = textshader; render.textshader = textshader;
@ -637,22 +638,28 @@ render.slice9 = function(tex, pos, bb, scale = [tex.width,tex.height], color = C
render.draw(shape.quad); render.draw(shape.quad);
} }
var textssbo = render.text_ssbo(); render.emitter = function(emit)
render.emitter(emit)
{ {
var ssbo = emit.draw(); var amt = emit.draw();
render.use_shader(particleshader); if (amt === 0) return;
render.draw(shape.quad, ssbo, render.use_shader(parshader);
render.use_mat({});
render.draw(shape.quad, emit.buffer, amt);
} }
var textssbo;
render.flush_text = function() render.flush_text = function()
{ {
if (!render.textshader) return; if (!render.textshader) return;
var amt = render.flushtext(textssbo);
render.use_shader(render.textshader); render.use_shader(render.textshader);
render.use_mat({text:render.font.texture}); 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 = {}; render.fontcache = {};

View file

@ -46,6 +46,8 @@ sampler smp;
void main() void main()
{ {
color = color0; color = color0;
color.r = 1;
color.a = 1;
} }
@end @end

View file

@ -20,8 +20,6 @@
struct sFont *use_font; struct sFont *use_font;
sg_buffer text_ssbo;
struct text_vert { struct text_vert {
HMM_Vec2 pos; HMM_Vec2 pos;
HMM_Vec2 wh; HMM_Vec2 wh;
@ -32,15 +30,6 @@ struct text_vert {
static struct text_vert *text_buffer; 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) void font_free(font *f)
{ {
sg_destroy_image(f->texID); 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; b.y = cursor.Y + wh.y/2;
} }
int text_flush() { int text_flush(sg_buffer *buf) {
if (arrlen(text_buffer) == 0) return 0; if (arrlen(text_buffer) == 0) return 0;
sg_range verts; sg_range verts;
verts.ptr = text_buffer; verts.ptr = text_buffer;
verts.size = sizeof(struct text_vert) * arrlen(text_buffer); verts.size = sizeof(struct text_vert) * arrlen(text_buffer);
if (sg_query_buffer_will_overflow(text_ssbo, verts.size)) { if (sg_query_buffer_will_overflow(*buf, verts.size)) {
sg_destroy_buffer(text_ssbo); sg_destroy_buffer(*buf);
text_ssbo = sg_make_buffer(&(sg_buffer_desc){ *buf = sg_make_buffer(&(sg_buffer_desc){
.size = verts.size, .size = verts.size,
.type = SG_BUFFERTYPE_STORAGEBUFFER, .type = SG_BUFFERTYPE_STORAGEBUFFER,
.usage = SG_USAGE_STREAM, .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); int n = arrlen(text_buffer);
arrsetlen(text_buffer, 0); arrsetlen(text_buffer, 0);
return n; return n;

View file

@ -34,7 +34,6 @@ typedef struct sFont font;
void font_free(font *f); void font_free(font *f);
void font_init();
struct sFont *MakeFont(const char *fontfile, int height); struct sFont *MakeFont(const char *fontfile, int height);
void font_set(font *f); void font_set(font *f);
void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color); 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); 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 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 #endif

View file

@ -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_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_step, emitter_step(js2emitter(self), js2number(argv[0]), js2transform(argv[1])))
JSC_CCALL(emitter_draw, 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)); return number2js(arrlen(js2emitter(self)->verts));
) )
JSC_CCALL(render_flushtext, 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, JSC_CCALL(render_glue_pass,
@ -982,7 +995,6 @@ JSC_CCALL(render_setpipeline,
sg_apply_pipeline(p); sg_apply_pipeline(p);
) )
JSC_CCALL(render_text_ssbo, return sg_buffer2js(&text_ssbo))
JSC_CCALL(render_screencolor, JSC_CCALL(render_screencolor,
texture *t = calloc(sizeof(*t), 1); texture *t = calloc(sizeof(*t), 1);
t->id = screencolor; t->id = screencolor;
@ -996,14 +1008,14 @@ JSC_CCALL(render_imgui_end, gui_endframe())
JSC_CCALL(render_imgui_init, return gui_init(js)) JSC_CCALL(render_imgui_init, return gui_init(js))
static const JSCFunctionListEntry js_render_funcs[] = { 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, camera_screen2world, 2),
MIST_FUNC_DEF(render, make_textssbo, 0),
MIST_FUNC_DEF(render, viewport, 4), MIST_FUNC_DEF(render, viewport, 4),
MIST_FUNC_DEF(render, end_pass, 0), MIST_FUNC_DEF(render, end_pass, 0),
MIST_FUNC_DEF(render, commit, 0), MIST_FUNC_DEF(render, commit, 0),
MIST_FUNC_DEF(render, glue_pass, 0), MIST_FUNC_DEF(render, glue_pass, 0),
MIST_FUNC_DEF(render, text_size, 3), 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, set_camera, 1),
MIST_FUNC_DEF(render, pipeline, 1), MIST_FUNC_DEF(render, pipeline, 1),
MIST_FUNC_DEF(render, setuniv3, 2), MIST_FUNC_DEF(render, setuniv3, 2),
@ -2380,10 +2392,17 @@ JSC_SCALL(os_make_model,
js_setpropstr(v, "material", material2js(me->primitives[0].mat)); js_setpropstr(v, "material", material2js(me->primitives[0].mat));
return v; return v;
) )
JSC_CCALL(os_make_emitter, JSC_CCALL(os_make_emitter,
emitter *e = make_emitter(); emitter *e = make_emitter();
ret = emitter2js(e); 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, JSC_CCALL(os_make_buffer,

View file

@ -99,6 +99,7 @@ static JSClassDef js_##TYPE##_class = {\
.finalizer = js_##TYPE##_finalizer,\ .finalizer = js_##TYPE##_finalizer,\
};\ };\
TYPE *js2##TYPE (JSValue val) { \ TYPE *js2##TYPE (JSValue val) { \
if (JS_IsUndefined(val)) return NULL; \
assert(JS_GetClassID(val) == js_##TYPE##_id); \ assert(JS_GetClassID(val) == js_##TYPE##_id); \
return JS_GetOpaque(val,js_##TYPE##_id); \ return JS_GetOpaque(val,js_##TYPE##_id); \
}\ }\

View file

@ -17,11 +17,7 @@ emitter *make_emitter() {
e->tte = lerp(e->explosiveness, e->life/e->max, 0); e->tte = lerp(e->explosiveness, e->life/e->max, 0);
e->scale = 1; e->scale = 1;
e->speed = 20; 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; return e;
} }
@ -62,10 +58,9 @@ void emitter_emit(emitter *e, int count, transform *t)
emitter_spawn(e, 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 0;
if (arrlen(e->particles) == 0) return;
arrsetlen(e->verts, arrlen(e->particles)); arrsetlen(e->verts, arrlen(e->particles));
for (int i = 0; i < arrlen(e->particles); i++) { for (int i = 0; i < arrlen(e->particles); i++) {
if (e->particles[i].time >= e->particles[i].life) continue; if (e->particles[i].time >= e->particles[i].life) continue;
@ -83,16 +78,16 @@ void emitter_draw(emitter *e)
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(*b, verts.size)) {
sg_destroy_buffer(e->buffer); sg_destroy_buffer(*b);
e->buffer = sg_make_buffer(&(sg_buffer_desc){ *b = sg_make_buffer(&(sg_buffer_desc){
.size = verts.size, .size = verts.size,
.type = SG_BUFFERTYPE_STORAGEBUFFER, .type = SG_BUFFERTYPE_STORAGEBUFFER,
.usage = SG_USAGE_STREAM .usage = SG_USAGE_STREAM
}); });
} }
sg_append_buffer(e->buffer, &verts); sg_append_buffer(*b, &verts);
} }
void emitter_step(emitter *e, double dt, transform *t) { void emitter_step(emitter *e, double dt, transform *t) {

View file

@ -62,7 +62,6 @@ typedef struct emitter {
/* TRAILS */ /* TRAILS */
warpmask warp_mask; warpmask warp_mask;
double tte; /* time to emit */ double tte; /* time to emit */
sg_buffer buffer;
} emitter; } emitter;
emitter *make_emitter(); emitter *make_emitter();
@ -70,6 +69,6 @@ void emitter_free(emitter *e);
void emitter_emit(emitter *e, int count, transform *t); void emitter_emit(emitter *e, int count, transform *t);
void emitter_step(emitter *e, double dt, 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 #endif

View file

@ -149,8 +149,6 @@ void render_init() {
sg_trace_hooks hh = sg_install_trace_hooks(&hooks); sg_trace_hooks hh = sg_install_trace_hooks(&hooks);
#endif #endif
font_init();
sg_features feat = sg_query_features(); sg_features feat = sg_query_features();
TOPLEFT = feat.origin_top_left; TOPLEFT = feat.origin_top_left;