From 8e337db1e5fa2716eb99bb395c3082926779e328 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Tue, 23 Apr 2024 15:58:08 -0500 Subject: [PATCH] Sprite rendered quad --- scripts/engine.js | 12 ++++ source/engine/3d/model.c | 21 +++--- source/engine/HandmadeMath.h | 1 + source/engine/debug/debugdraw.c | 4 +- source/engine/font.c | 64 +++++++----------- source/engine/jsffi.c | 11 ++- source/engine/particle.c | 33 +++++---- source/engine/particle.h | 2 +- source/engine/render.c | 21 +++++- source/engine/render.h | 3 + source/engine/sprite.c | 116 +++++++++++++++----------------- source/engine/sprite.h | 17 +++-- source/engine/transform.c | 9 +++ source/engine/transform.h | 2 + source/shaders/sprite.sglsl | 27 ++++++-- source/shaders/text.sglsl | 1 + source/shaders/unlit.sglsl | 12 ++-- 17 files changed, 203 insertions(+), 153 deletions(-) diff --git a/scripts/engine.js b/scripts/engine.js index 2273f54..abf01f3 100644 --- a/scripts/engine.js +++ b/scripts/engine.js @@ -301,9 +301,11 @@ game.engine_start = function(s) { } game.startengine = 0; +var frames = []; function process() { + var startframe = profile.now(); var dt = profile.secs(profile.now()) - frame_t; frame_t = profile.secs(profile.now()); @@ -357,6 +359,16 @@ function process() render.end_pass(); profile.addreport(profcache, "render frame", st); + frames.push(profile.secs(profile.now()-startframe)); + if (frames.length > 20) frames.shift(); +} + +globalThis.fps = function() +{ + var sum = 0; + for (var i = 0; i < frames.length; i++) + sum += frames[i]; + return frames.length/sum; } game.timescale = 1; diff --git a/source/engine/3d/model.c b/source/engine/3d/model.c index c62eced..986621c 100644 --- a/source/engine/3d/model.c +++ b/source/engine/3d/model.c @@ -57,6 +57,8 @@ void model_init() { [0].format = SG_VERTEXFORMAT_FLOAT3, [1].format = SG_VERTEXFORMAT_USHORT2N, [1].buffer_index = 1, + [2].format = SG_VERTEXFORMAT_FLOAT3, + [2].buffer_index = 2 }, }, .index_type = SG_INDEXTYPE_UINT16, @@ -112,14 +114,8 @@ void mesh_add_material(mesh *mesh, cgltf_material *mat) mesh->bind.fs.images[0] = texture_from_file(img->uri)->id; } else mesh->bind.fs.images[0] = texture_from_file("icons/moon.gif")->id; - - mesh->bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){}); -/* - cgltf_texture *tex; - if (tex = mat->normal_texture.texture) - mesh->bind.fs.images[1] = texture_from_file(tex->image->uri)->id; - else - mesh->bind.fs.images[1] = texture_from_file("k")->id;*/ + + mesh->bind.fs.samplers[0] = std_sampler; } sg_buffer texcoord_floats(float *f, int verts, int comp) @@ -187,6 +183,7 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim) } free(idxs); + printf("adding material\n"); mesh_add_material(mesh, prim->material); int has_norm = 0; @@ -209,8 +206,8 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim) break; case cgltf_attribute_type_normal: -// has_norm = 1; -// mesh->bind.vertex_buffers[2] = normal_floats(vs, verts, comp); + has_norm = 1; + mesh->bind.vertex_buffers[2] = normal_floats(vs, verts, comp); break; case cgltf_attribute_type_tangent: @@ -238,7 +235,7 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim) break; } } -/* + if (!has_norm) { cgltf_attribute *pa = get_attr_type(prim, cgltf_attribute_type_position); int n = cgltf_accessor_unpack_floats(pa->data, NULL,0); @@ -260,7 +257,7 @@ void mesh_add_primitive(mesh *mesh, cgltf_primitive *prim) mesh->bind.vertex_buffers[2] = sg_make_buffer(&(sg_buffer_desc){ .data.ptr = face_norms, .data.size = sizeof(uint32_t) * verts}); - }*/ + } } void model_add_cgltf_mesh(model *model, cgltf_mesh *gltf_mesh) diff --git a/source/engine/HandmadeMath.h b/source/engine/HandmadeMath.h index 588bc37..07cddfa 100644 --- a/source/engine/HandmadeMath.h +++ b/source/engine/HandmadeMath.h @@ -221,6 +221,7 @@ typedef union HMM_Vec2 { } HMM_Vec2; static const HMM_Vec2 v2zero = {0,0}; +static const HMM_Vec2 v2one = {1,1}; typedef union HMM_Vec3 { struct diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index a1032e5..271b043 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -285,7 +285,7 @@ void debugdraw_init() .label = "circle vert buffer", }); - float circleverts[8] = { + float circleverts[] = { -1,-1, -1,1, 1,-1, @@ -293,7 +293,7 @@ void debugdraw_init() }; circle_bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){ - .data = (sg_range){.ptr = circleverts, .size = sizeof(float)*8}, + .data = (sg_range){.ptr = circleverts, .size = sizeof(circleverts)}, .usage = SG_USAGE_IMMUTABLE, .label = "circle quarter buffer", }); diff --git a/source/engine/font.c b/source/engine/font.c index 802226e..3670973 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -22,8 +22,6 @@ struct sFont *use_font; -#define max_chars 100000 - static sg_shader fontshader; static sg_bindings bind_text; static sg_pipeline pipe_text; @@ -38,19 +36,18 @@ struct text_vert { static struct text_vert *text_buffer; void font_init() { - text_buffer = malloc(sizeof(*text_buffer)*max_chars); fontshader = sg_make_shader(text_shader_desc(sg_query_backend())); pipe_text = sg_make_pipeline(&(sg_pipeline_desc){ .shader = fontshader, .layout = { .attrs = { - [0].format = SG_VERTEXFORMAT_FLOAT2, /* verts */ - [0].buffer_index = 1, - [1].format = SG_VERTEXFORMAT_FLOAT2, /* pos */ - [2].format = SG_VERTEXFORMAT_FLOAT2, /* width and height */ - [3].format = SG_VERTEXFORMAT_USHORT2N, /* uv pos */ - [4].format = SG_VERTEXFORMAT_USHORT2N, /* uv width and height */ - [5].format = SG_VERTEXFORMAT_UBYTE4N, /* color */ + [ATTR_vs_vert].format = SG_VERTEXFORMAT_FLOAT2, + [ATTR_vs_vert].buffer_index = 1, + [ATTR_vs_pos].format = SG_VERTEXFORMAT_FLOAT2, + [ATTR_vs_wh].format = SG_VERTEXFORMAT_FLOAT2, + [ATTR_vs_uv].format = SG_VERTEXFORMAT_USHORT2N, + [ATTR_vs_st].format = SG_VERTEXFORMAT_USHORT2N, + [ATTR_vs_vColor].format = SG_VERTEXFORMAT_UBYTE4N, }, .buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE }, @@ -59,27 +56,16 @@ void font_init() { .label = "text", }); - float text_verts[8] = { - 0,0, - 0,1, - 1,0, - 1,1 - }; - - bind_text.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){ - .data = SG_RANGE(text_verts), - .usage = SG_USAGE_IMMUTABLE, - .label = "text rectangle buffer", - }); - + bind_text.vertex_buffers[1] = sprite_quad; + bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ - .size = sizeof(struct text_vert)*max_chars, + .size = sizeof(struct text_vert), .type = SG_BUFFERTYPE_VERTEXBUFFER, .usage = SG_USAGE_STREAM, .label = "text buffer" }); - bind_text.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){}); + bind_text.fs.samplers[0] = std_sampler; } void font_free(font *f) @@ -192,8 +178,6 @@ struct sFont *MakeFont(const char *fontfile, int height) { return newfont; } -static int curchar = 0; - void draw_underline_cursor(HMM_Vec2 pos, float scale, struct rgba color) { pos.Y -= 2; @@ -218,24 +202,29 @@ void draw_char_box(struct Character c, HMM_Vec2 cursor, float scale, struct rgba } void text_flush(HMM_Mat4 *proj) { - if (curchar == 0) return; + if (arrlen(text_buffer) == 0) return; + sg_range verts; verts.ptr = text_buffer; - verts.size = sizeof(struct text_vert) * curchar; - int offset = sg_append_buffer(bind_text.vertex_buffers[0], &verts); + verts.size = sizeof(struct text_vert) * arrlen(text_buffer); + if (sg_query_buffer_will_overflow(bind_text.vertex_buffers[0], verts.size)) + bind_text.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ + .size = verts.size, + .type = SG_BUFFERTYPE_VERTEXBUFFER, + .usage = SG_USAGE_STREAM, + .label = "text buffer" + }); + + sg_append_buffer(bind_text.vertex_buffers[0], &verts); - bind_text.vertex_buffer_offsets[0] = offset; sg_apply_pipeline(pipe_text); sg_apply_bindings(&bind_text); sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(*proj)); - sg_draw(0, 4, curchar); - curchar = 0; + sg_draw(0, 4, arrlen(text_buffer)); + arrsetlen(text_buffer, 0); } void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgba color) { - if (curchar-10 >= max_chars) - return; - struct rgba colorbox = {0,0,0,255}; struct text_vert vert; @@ -255,8 +244,7 @@ void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgb vert.st.v = c.rect.h*USHRT_MAX; vert.color = color; - memcpy(text_buffer + curchar, &vert, sizeof(struct text_vert)); - curchar++; + arrput(text_buffer, vert); } const char *esc_color(const char *c, struct rgba *color, struct rgba defc) diff --git a/source/engine/jsffi.c b/source/engine/jsffi.c index e120969..e6d3f8d 100644 --- a/source/engine/jsffi.c +++ b/source/engine/jsffi.c @@ -569,7 +569,6 @@ JSC_GETSET(emitter, grow_for, number) JSC_GETSET(emitter, shrink_for, number) JSC_GETSET(emitter, max, number) JSC_GETSET(emitter, explosiveness, number) -JSC_GETSET(emitter, go, gameobject) JSC_GETSET(emitter, bounce, number) JSC_GETSET(emitter, collision_mask, bitmask) JSC_GETSET(emitter, die_after_collision, boolean) @@ -611,7 +610,6 @@ JSC_CCALL(render_end_pass, sg_end_pass(); sg_commit(); debug_newframe(); - sprite_newframe(); ) JSC_SCALL(render_text_size, ret = bb2js(text_bb(str, js2number(argv[1]), js2number(argv[2]), 1))) JSC_CCALL(render_set_camera, useproj = projection) @@ -1055,7 +1053,6 @@ static const JSCFunctionListEntry js_emitter_funcs[] = { CGETSET_ADD(emitter, shrink_for), CGETSET_ADD(emitter, max), CGETSET_ADD(emitter, explosiveness), - CGETSET_ADD(emitter, go), CGETSET_ADD(emitter, bounce), CGETSET_ADD(emitter, collision_mask), CGETSET_ADD(emitter, die_after_collision), @@ -1320,11 +1317,11 @@ static const JSCFunctionListEntry js_pshape_funcs[] = { JSC_GETSET(sprite, color, color) JSC_GETSET(sprite, emissive, color) -JSC_GETSET(sprite, parallax, number) JSC_GETSET(sprite, pos, vec2) JSC_GETSET(sprite, scale, vec2) JSC_GETSET(sprite, angle, number) -JSC_GETSET(sprite, frame, rect) +JSC_GETSET(sprite, spriteoffset, vec2) +JSC_GETSET(sprite, spritesize, vec2) JSC_CCALL(sprite_draw, sprite_draw(js2sprite(this), js2gameobject(argv[0]))) static const JSCFunctionListEntry js_sprite_funcs[] = { @@ -1333,8 +1330,8 @@ static const JSCFunctionListEntry js_sprite_funcs[] = { CGETSET_ADD(sprite,angle), CGETSET_ADD(sprite,color), CGETSET_ADD(sprite,emissive), - CGETSET_ADD(sprite,parallax), - CGETSET_ADD(sprite,frame), + CGETSET_ADD(sprite, spriteoffset), + CGETSET_ADD(sprite, spritesize), MIST_FUNC_DEF(sprite, draw, 1) }; diff --git a/source/engine/particle.c b/source/engine/particle.c index fdf380c..b87b7ea 100644 --- a/source/engine/particle.c +++ b/source/engine/particle.c @@ -46,11 +46,11 @@ void particle_init() .layout = { .attrs = { [1].format = SG_VERTEXFORMAT_FLOAT2, - [2].format = SG_VERTEXFORMAT_FLOAT, - [3].format = SG_VERTEXFORMAT_FLOAT2, - [4].format = SG_VERTEXFORMAT_UBYTE4N, - [0].format = SG_VERTEXFORMAT_FLOAT2, - [0].buffer_index = 1 + [2].format = SG_VERTEXFORMAT_FLOAT, + [3].format = SG_VERTEXFORMAT_FLOAT2, + [4].format = SG_VERTEXFORMAT_UBYTE4N, + [0].format = SG_VERTEXFORMAT_FLOAT2, + [0].buffer_index = 1 }, .buffers[0].step_func = SG_VERTEXSTEP_PER_INSTANCE, }, @@ -78,13 +78,8 @@ void particle_init() 1,1, }; - par_bind.vertex_buffers[1] = sg_make_buffer(&(sg_buffer_desc){ - .data = (sg_range){.ptr = circleverts, .size = sizeof(float)*8}, - .usage = SG_USAGE_IMMUTABLE, - .label = "particle quater buffer" - }); - - par_bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){}); + par_bind.vertex_buffers[1] = sprite_quad; + par_bind.fs.samplers[0] = std_sampler; } emitter *make_emitter() { @@ -172,6 +167,20 @@ void parallel_pv(emitter *e, struct scheduler *sched, struct sched_task_partitio } } +void emitter_draw(emitter *e, gameobject *go) +{ + sg_apply_pipeline(par_pipe); + sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(useproj)); + sg_apply_bindings(&par_bind); + par_bind.fs.images[0] = e->texture->id; + struct sched_task task; + scheduler_add(&sched, &task, parallel_pv, e, arrlen(e->particles), arrlen(e->particles)/sched.threads_num); + scheduler_join(&sched, &task); + sg_append_buffer(par_bind.vertex_buffers[0], &(sg_range){.ptr=&pv, .size=sizeof(struct par_vert)*arrlen(e->particles)}); + draw_count += arrlen(e->particles); + sg_draw(0,4,draw_count); +} + void emitters_draw(HMM_Mat4 *proj) { if (arrlen(emitters) == 0) return; diff --git a/source/engine/particle.h b/source/engine/particle.h index fbc000f..55ebfa1 100644 --- a/source/engine/particle.h +++ b/source/engine/particle.h @@ -26,7 +26,6 @@ typedef struct particle { typedef struct emitter { struct particle *particles; transform3d t; - gameobject *go; HMM_Vec3 *mesh; /* list of points to optionally spawn from */ HMM_Vec3 *norm; /* norm at each point */ int type; /* spray, cloud, or mesh */ @@ -70,6 +69,7 @@ void stop_emitter(emitter *e); void emitter_emit(emitter *e, int count); void emitters_step(double dt); +void emitter_draw(emitter *e, gameobject *go); void emitters_draw(HMM_Mat4 *proj); void emitter_step(emitter *e, double dt); diff --git a/source/engine/render.c b/source/engine/render.c index e01e4c8..2556897 100644 --- a/source/engine/render.c +++ b/source/engine/render.c @@ -31,6 +31,9 @@ HMM_Vec2 campos = {0,0}; float camzoom = 1; +sg_buffer sprite_quad; +sg_sampler std_sampler; + static struct { sg_swapchain swap; sg_pipeline pipe; @@ -223,6 +226,22 @@ void render_init() { .logger = { .func = sg_logging }, .buffer_pool_size = 1024 }); + + float quad[] = { + 0,0, + 1,0, + 0,1, + 1,1 + }; + + sprite_quad = sg_make_buffer(&(sg_buffer_desc){ + .data = quad, + .size = sizeof(quad), + .usage = SG_USAGE_IMMUTABLE, + .label = "sprite quad" + }); + + std_sampler = sg_make_sampler(&(sg_sampler_desc){}); #ifndef NDEBUG sg_trace_hooks hh = sg_install_trace_hooks(&hooks); @@ -276,7 +295,7 @@ void render_init() { .data = gif_quad, .label = "gif vert buffer", }); - sg_gif.bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){}); + sg_gif.bind.fs.samplers[0] = std_sampler; sg_crt.shader = sg_make_shader(crt_shader_desc(sg_query_backend())); sg_crt.pipe = sg_make_pipeline(&(sg_pipeline_desc){ diff --git a/source/engine/render.h b/source/engine/render.h index fe577b4..84e7c82 100644 --- a/source/engine/render.h +++ b/source/engine/render.h @@ -32,6 +32,9 @@ extern HMM_Mat4 hudproj; extern HMM_Mat4 useproj; extern sg_pass_action pass_action; +extern sg_buffer sprite_quad; +extern sg_sampler std_sampler; + struct draw_p { float x; float y; diff --git a/source/engine/sprite.c b/source/engine/sprite.c index 2953b82..91e2c5e 100644 --- a/source/engine/sprite.c +++ b/source/engine/sprite.c @@ -14,24 +14,10 @@ static sg_shader shader_sprite; static sg_pipeline pip_sprite; sg_bindings bind_sprite; -struct sprite_vert { - HMM_Vec2 pos; - HMM_Vec2 uv; - struct rgba color; - struct rgba emissive; -}; - -static int num_spriteverts = 5000; - static sg_shader slice9_shader; static sg_pipeline slice9_pipe; static sg_bindings slice9_bind; -static float slice9_points[8] = { - 0.0, 0.0, - 0.0, 1.0, - 1.0, 0.0, - 1.0, 1.0 -}; + struct slice9_vert { HMM_Vec2 pos; struct uv_n uv; @@ -43,31 +29,45 @@ struct slice9_vert { sprite *sprite_make() { sprite *sp = calloc(sizeof(*sp), 1); - sp->pos = (HMM_Vec2){0,0}; - sp->scale = (HMM_Vec2){1,1}; + sp->pos = v2zero; + sp->scale = v2one; sp->angle = 0; sp->color = color_white; sp->emissive = color_clear; - sp->frame = ST_UNIT; - sp->parallax = 1; - + sp->spritesize = v2one; + sp->spriteoffset = v2zero; return sp; } void sprite_free(sprite *sprite) { free(sprite); } -static int sprite_draws = 0; -static int sprite_count = 0; static texture *loadedtex; +static int sprite_count = 0; void sprite_flush() { +return; if (!loadedtex) return; +/* + int flushed = arrlen(spverts)/4; sg_apply_bindings(&bind_sprite); - sg_draw(sprite_count * 4, 4, sprite_draws); - sprite_count += sprite_draws; - sprite_draws = 0; + sg_range data = (sg_range){ + .ptr = spverts, + .size = sizeof(sprite_vert)*arrlen(spverts) + }; + if (sg_query_buffer_will_overflow(bind_sprite.vertex_buffers[0], data.size)) + bind_sprite.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ + .size = data.size, + .type = SG_BUFFERTYPE_VERTEXBUFFER, + .usage = SG_USAGE_STREAM, + .label = "sprite vertex buffer" + }); + + sg_update_buffer(bind_sprite.vertex_buffers[0], &data); + + sg_draw(sprite_count * 4, 4, flushed); + sprite_count += flushed; + */ } -void sprite_newframe() { sprite_count = 0; sprite_draws = 0;} void sprite_initialize() { shader_sprite = sg_make_shader(sprite_shader_desc(sg_query_backend())); @@ -76,22 +76,17 @@ void sprite_initialize() { .shader = shader_sprite, .layout = { .attrs = { - [0].format = SG_VERTEXFORMAT_FLOAT2, - [1].format = SG_VERTEXFORMAT_FLOAT2, - [2].format = SG_VERTEXFORMAT_UBYTE4N, - [3].format = SG_VERTEXFORMAT_UBYTE4N}}, + [0].format = SG_VERTEXFORMAT_FLOAT2 + }, + .buffers[1].step_func = SG_VERTEXSTEP_PER_INSTANCE + }, .primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP, .label = "sprite pipeline", .colors[0].blend = blend_trans, }); - bind_sprite.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ - .size = sizeof(struct sprite_vert) * num_spriteverts, - .type = SG_BUFFERTYPE_VERTEXBUFFER, - .usage = SG_USAGE_STREAM, - .label = "sprite vertex buffer", - }); - bind_sprite.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){}); + bind_sprite.vertex_buffers[0] = sprite_quad; + bind_sprite.fs.samplers[0] = std_sampler; slice9_shader = sg_make_shader(slice9_shader_desc(sg_query_backend())); @@ -108,21 +103,17 @@ void sprite_initialize() { .primitive_type = SG_PRIMITIVETYPE_TRIANGLE_STRIP, }); - slice9_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ - .size = sizeof(struct slice9_vert) * 100, - .type = SG_BUFFERTYPE_VERTEXBUFFER, - .usage = SG_USAGE_STREAM, - .label = "slice9 buffer" - }); + slice9_bind.vertex_buffers[0] = sprite_quad; } void sprite_pipe() { sg_apply_pipeline(pip_sprite); - sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(useproj)); + sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vp, SG_RANGE_REF(useproj)); } -void tex_draw(HMM_Mat3 m, struct rect r, struct rgba color, int wrap, HMM_Vec2 wrapoffset, HMM_Vec2 wrapscale, struct rgba emissive, float parallax) { +void tex_draw(HMM_Mat3 m, struct rect r, struct rgba color, int wrap, HMM_Vec2 wrapoffset, HMM_Vec2 wrapscale, struct rgba emissive) { + /* struct sprite_vert verts[4]; float w = loadedtex->width*r.w; float h = loadedtex->height*r.h; @@ -134,11 +125,8 @@ void tex_draw(HMM_Mat3 m, struct rect r, struct rgba color, int wrap, HMM_Vec2 w {w,h} }; - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 4; i++) verts[i].pos = mat_t_pos(m, sposes[i]); - verts[i].color = color; - verts[i].emissive = emissive; - } if (wrap) { r.w *= wrapscale.x; @@ -154,15 +142,16 @@ void tex_draw(HMM_Mat3 m, struct rect r, struct rgba color, int wrap, HMM_Vec2 w verts[3].uv.X = r.x+r.w; verts[3].uv.Y = r.y; - sg_append_buffer(bind_sprite.vertex_buffers[0], SG_RANGE_REF(verts)); - sprite_draws++; + for (int i = 0; i < 4; i++) + arrput(spverts, verts[i]); + */ } transform2d sprite2t(sprite *s) { return (transform2d){ .pos = s->pos, - .scale = s->scale, + .scale = HMM_MulV2(s->scale, (HMM_Vec2){loadedtex->width, loadedtex->height}), .angle = HMM_TurnToRad*s->angle }; } @@ -174,19 +163,26 @@ void sprite_tex(texture *t) } void sprite_draw(struct sprite *sprite, gameobject *go) { - transform2d t = go2t(go); - t.pos.x += (campos.x - (campos.x/sprite->parallax)); - t.pos.y += (campos.y - (campos.y/sprite->parallax)); - HMM_Mat3 m = transform2d2mat(t); - HMM_Mat3 sm = transform2d2mat(sprite2t(sprite)); - tex_draw(HMM_MulM3(m,sm), sprite->frame, sprite->color, 0, (HMM_Vec2){0,0}, sprite->scale, sprite->emissive, sprite->parallax); + HMM_Mat4 m = transform2d2mat4(go2t(go)); + HMM_Mat4 sm = transform2d2mat4(sprite2t(sprite)); + struct spriteuni spv; + rgba2floats(&spv.color.e, sprite->color); + rgba2floats(spv.emissive.e, sprite->emissive); + spv.size = sprite->spritesize; + spv.offset = sprite->spriteoffset; + spv.model = HMM_MulM4(m,sm); + sg_apply_pipeline(pip_sprite); + sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_sprite, SG_RANGE_REF(spv)); + sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vp, SG_RANGE_REF(useproj)); + sg_apply_bindings(&bind_sprite); + sg_draw(0,4,1); } void gui_draw_img(texture *tex, transform2d t, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba color) { sg_apply_pipeline(pip_sprite); - sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(useproj)); + sg_apply_uniforms(SG_SHADERSTAGE_VS, SLOT_vp, SG_RANGE_REF(useproj)); sprite_tex(tex); - tex_draw(transform2d2mat(t), ST_UNIT, color, wrap, wrapoffset, (HMM_Vec2){wrapscale,wrapscale}, (struct rgba){0,0,0,0}, 0); + tex_draw(transform2d2mat(t), ST_UNIT, color, wrap, wrapoffset, (HMM_Vec2){wrapscale,wrapscale}, (struct rgba){0,0,0,0}); } void slice9_draw(texture *tex, transform2d *t, HMM_Vec4 border, struct rgba color) diff --git a/source/engine/sprite.h b/source/engine/sprite.h index 41bdc33..cb264b0 100644 --- a/source/engine/sprite.h +++ b/source/engine/sprite.h @@ -7,18 +7,22 @@ #include "transform.h" #include "gameobject.h" -#define DRAW_SIMPLE 0 -#define DRAW_TILE 1 - struct sprite { HMM_Vec2 pos; HMM_Vec2 scale; float angle; struct rgba color; struct rgba emissive; - struct rect frame; - int drawmode; - float parallax; + HMM_Vec2 spritesize; + HMM_Vec2 spriteoffset; +}; + +struct spriteuni { + HMM_Vec4 color; + HMM_Vec4 emissive; + HMM_Vec2 size; + HMM_Vec2 offset; + HMM_Mat4 model; }; typedef struct sprite sprite; @@ -33,7 +37,6 @@ void sprite_draw(struct sprite *sprite, gameobject *go); void sprite_pipe(); void sprite_draw_all(); void sprite_flush(); -void sprite_newframe(); void gui_draw_img(texture *tex, transform2d t, int wrap, HMM_Vec2 wrapoffset, float wrapscale, struct rgba color); diff --git a/source/engine/transform.c b/source/engine/transform.c index 8a082ec..8f3eacc 100644 --- a/source/engine/transform.c +++ b/source/engine/transform.c @@ -40,6 +40,15 @@ HMM_Mat3 transform2d2mat(transform2d trn) { return HMM_MulM3(HMM_Translate2D(trn.pos), HMM_MulM3(HMM_RotateM3(trn.angle), HMM_ScaleM3(trn.scale))); } +HMM_Mat4 transform2d2mat4(transform2d trn) +{ + transform3d t3d; + t3d.pos.xy = trn.pos; + t3d.scale.xy = trn.scale; + t3d.rotation = HMM_QFromAxisAngle_RH((HMM_Vec3){0,0,-1}, trn.angle); + return transform3d2mat(t3d); +} + transform2d mat2transform2d(HMM_Mat3 m) { transform2d t; diff --git a/source/engine/transform.h b/source/engine/transform.h index cb009b7..8f6c29d 100644 --- a/source/engine/transform.h +++ b/source/engine/transform.h @@ -27,6 +27,8 @@ HMM_Vec3 trans_down(const transform3d *trans); HMM_Vec3 trans_right(const transform3d *trans); HMM_Vec3 trans_left(const transform3d *trans); +HMM_Mat4 transform2d2mat4(transform2d trn); + /* Transform a position via the matrix */ HMM_Vec2 mat_t_pos(HMM_Mat3 m, HMM_Vec2 pos); /* Transform a direction via the matrix - does not take into account translation of matrix */ diff --git a/source/shaders/sprite.sglsl b/source/shaders/sprite.sglsl index 3bc696b..6278523 100644 --- a/source/shaders/sprite.sglsl +++ b/source/shaders/sprite.sglsl @@ -1,20 +1,30 @@ @vs vs in vec2 vertex; -in vec2 uv; -in vec4 vc; -in vec4 emissive; out vec2 texcoords; out vec4 fcolor; out vec4 femissive; -uniform vs_p { mat4 proj; }; +uniform app { + float time; + vec2 window; +}; + +uniform vp { + mat4 proj; +}; + +uniform sprite { + vec4 vcolor; + vec4 vemissive; + vec2 spritesize; + vec2 spriteoff; + mat4 model; +}; void main() { - fcolor = vc; - femissive = emissive; - texcoords = uv; + texcoords = spriteoff + spritesize*vertex; gl_Position = proj * vec4(vertex, 0, 1.0); } @end @@ -23,6 +33,7 @@ void main() in vec2 texcoords; in vec4 fcolor; in vec4 femissive; + out vec4 color; uniform texture2D image; @@ -33,6 +44,8 @@ void main() color = texture(sampler2D(image,smp), texcoords); color *= fcolor; color.xyz = mix(color.xyz, femissive.xyz, femissive.a); + color.a = 1.0; + } @end diff --git a/source/shaders/text.sglsl b/source/shaders/text.sglsl index 9894038..5bf3fc6 100644 --- a/source/shaders/text.sglsl +++ b/source/shaders/text.sglsl @@ -1,5 +1,6 @@ @vs vs in vec2 vert; + in vec2 pos; in vec2 wh; in vec2 uv; diff --git a/source/shaders/unlit.sglsl b/source/shaders/unlit.sglsl index d925ccd..5662904 100644 --- a/source/shaders/unlit.sglsl +++ b/source/shaders/unlit.sglsl @@ -1,10 +1,10 @@ @vs vs in vec3 a_pos; in vec2 a_tex_coords; -//in vec3 a_norm; +in vec3 a_norm; out vec2 tex_coords; -//out vec3 normal; +out vec3 normal; uniform vs_p { uniform mat4 vp; @@ -14,21 +14,21 @@ uniform mat4 model; void main() { gl_Position = vp * vec4(vec3(model * vec4(a_pos,1.0)), 1.0); tex_coords = a_tex_coords; - //normal = a_norm; + normal = a_norm; } @end @fs fs in vec2 tex_coords; -//in vec3 normal; +in vec3 normal; out vec4 color; uniform texture2D diffuse; uniform sampler smp; void main() { - //vec3 lightDir = normalize(vec3(0.5f, 0.5f, 1.0f)); - //float diff = max(dot(normal, lightDir), 0.0f); + vec3 lightDir = normalize(vec3(0.5f, 0.5f, 1.0f)); + float diff = max(dot(normal, lightDir), 0.0f); color = texture(sampler2D(diffuse,smp),tex_coords); } @end