diff --git a/source/engine/debug/debugdraw.c b/source/engine/debug/debugdraw.c index 92007c78..33c7922e 100644 --- a/source/engine/debug/debugdraw.c +++ b/source/engine/debug/debugdraw.c @@ -30,6 +30,7 @@ struct point_vertex { float radius; }; static int point_c = 0; +static int point_sc = 0; static struct point_vertex point_b[v_amt]; static sg_shader line_shader; @@ -44,6 +45,8 @@ struct line_vert { }; static int line_c = 0; static int line_v = 0; +static int line_sc = 0; +static int line_sv = 0; static struct line_vert line_b[v_amt]; static uint16_t line_bi[v_amt]; @@ -57,6 +60,8 @@ static sg_bindings poly_bind; static sg_shader poly_shader; static int poly_c = 0; static int poly_v = 0; +static int poly_sc = 0; +static int poly_sv = 0; struct poly_vertex { cpVect pos; float uv[2]; @@ -69,6 +74,7 @@ static sg_pipeline circle_pipe; static sg_bindings circle_bind; static sg_shader csg; static int circle_count = 0; +static int circle_sc = 0; struct circle_vertex { cpVect pos; float radius; @@ -79,64 +85,88 @@ struct circle_vertex { static struct circle_vertex circle_b[v_amt]; -void debug_flush() + + +void debug_flush(HMM_Mat4 *view) { if (poly_c != 0) { - sg_apply_pipeline(poly_pipe); - sg_apply_bindings(&poly_bind); - sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection)); - sg_update_buffer(poly_bind.vertex_buffers[0], &(sg_range){ - .ptr = poly_b, .size = sizeof(struct poly_vertex)*poly_v}); - sg_update_buffer(poly_bind.index_buffer, &(sg_range){ - .ptr = poly_bi, .size = sizeof(uint32_t)*poly_c}); - sg_draw(0,poly_c,1); - poly_c = 0; - poly_v = 0; + sg_apply_pipeline(poly_pipe); + sg_apply_bindings(&poly_bind); + sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(*view)); + sg_append_buffer(poly_bind.vertex_buffers[0], &(sg_range){ + .ptr = poly_b, .size = sizeof(struct poly_vertex)*poly_v}); + sg_append_buffer(poly_bind.index_buffer, &(sg_range){ + .ptr = poly_bi, .size = sizeof(uint32_t)*poly_c}); + sg_draw(poly_sc,poly_c,1); } if (point_c != 0) { - sg_apply_pipeline(point_pipe); - sg_apply_bindings(&point_bind); - sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection)); - sg_update_buffer(point_bind.vertex_buffers[0], &(sg_range){ - .ptr = point_b, - .size = sizeof(struct point_vertex)*point_c}); - sg_draw(0,point_c,1); - point_c = 0; + sg_apply_pipeline(point_pipe); + sg_apply_bindings(&point_bind); + sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(*view)); + sg_append_buffer(point_bind.vertex_buffers[0], &(sg_range){ + .ptr = point_b, + .size = sizeof(struct point_vertex)*point_c}); + sg_draw(point_sc,point_c,1); } if (line_c != 0) { - sg_apply_pipeline(line_pipe); - sg_apply_bindings(&line_bind); - sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(projection)); - float time = lastTick; - sg_range tr = { - .ptr = &time, - .size = sizeof(float) - }; - sg_apply_uniforms(SG_SHADERSTAGE_FS,0,&tr); - sg_update_buffer(line_bind.vertex_buffers[0], &(sg_range){ - .ptr = line_b, .size = sizeof(struct line_vert)*line_v}); - sg_update_buffer(line_bind.index_buffer, &(sg_range){ - .ptr = line_bi, .size = sizeof(uint16_t)*line_c}); - sg_draw(0,line_c,1); - line_c = 0; - line_v = 0; + sg_apply_pipeline(line_pipe); + sg_apply_bindings(&line_bind); + sg_apply_uniforms(SG_SHADERSTAGE_VS,0,SG_RANGE_REF(*view)); + float time = lastTick; + sg_range tr = { + .ptr = &time, + .size = sizeof(float) + }; + sg_apply_uniforms(SG_SHADERSTAGE_FS,0,&tr); + sg_append_buffer(line_bind.vertex_buffers[0], &(sg_range){ + .ptr = line_b, .size = sizeof(struct line_vert)*line_v}); + sg_append_buffer(line_bind.index_buffer, &(sg_range){ + .ptr = line_bi, .size = sizeof(uint16_t)*line_c}); + sg_draw(line_sc,line_c,1); } if (circle_count != 0) { - sg_apply_pipeline(circle_pipe); - sg_apply_bindings(&circle_bind); - sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(projection)); - sg_update_buffer(circle_bind.vertex_buffers[0], &(sg_range){ - .ptr = circle_b, - .size = sizeof(struct circle_vertex)*circle_count - }); - sg_draw(0,4,circle_count); - circle_count = 0; + sg_apply_pipeline(circle_pipe); + sg_apply_bindings(&circle_bind); + sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(*view)); + sg_append_buffer(circle_bind.vertex_buffers[0], &(sg_range){ + .ptr = circle_b, + .size = sizeof(struct circle_vertex)*circle_count + }); + sg_draw(circle_sc,4,circle_count); } } +void debug_nextpass() +{ + point_sc = point_c; + point_c = 0; + + circle_sc = circle_count; + circle_count = 0; + + line_sv = line_v; + line_v = 0; + line_sc = line_c; + line_c = 0; + + poly_sc = poly_c; + poly_c = 0; + + poly_sv = poly_v; + poly_v = 0; +} + +void debug_newframe() +{ + point_sc = 0; + point_c = 0; + circle_sc = circle_count = line_sv = line_v = line_sc = line_c = poly_sc = poly_c = 0; + poly_sv = poly_v = 0; +} + static sg_shader_uniform_block_desc projection_ubo = { .size = sizeof(projection), .uniforms = { @@ -171,7 +201,7 @@ void debugdraw_init() }); point_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ - .size = sizeof(struct point_vertex)*5000, + .size = sizeof(struct point_vertex)*v_amt, .usage = SG_USAGE_STREAM }); @@ -197,12 +227,12 @@ void debugdraw_init() }); line_bind.vertex_buffers[0] = sg_make_buffer(&(sg_buffer_desc){ - .size = sizeof(struct line_vert)*5000, + .size = sizeof(struct line_vert)*v_amt, .usage = SG_USAGE_STREAM }); line_bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){ - .size = sizeof(uint16_t)*5000, + .size = sizeof(uint16_t)*v_amt, .usage = SG_USAGE_STREAM, .type = SG_BUFFERTYPE_INDEXBUFFER }); @@ -343,8 +373,8 @@ void draw_line(cpVect *a_points, int a_n, struct rgba color, float seg_len, int uint16_t idxs[i_c]; for (int i = 0, d = 0; i < n-1; i++, d+=2) { - idxs[d] = i + line_v; - idxs[d+1] = i+1 + line_v; + idxs[d] = i + line_v + line_sv; + idxs[d+1] = i+1 + line_v + line_sv; } sg_range vr = { @@ -467,7 +497,7 @@ void draw_edge(cpVect *points, int n, struct rgba color, int thickness, int clos }); for (int i = 0; i < mesh->num_triangles*3; i++) - mesh->triangle_indices[i] += poly_v; + mesh->triangle_indices[i] += (poly_v+poly_sv); struct poly_vertex vertices[mesh->num_vertices]; @@ -595,7 +625,7 @@ void draw_poly(cpVect *points, int n, struct rgba color) } for (int i = 0; i < tric*3; i++) - tridxs[i] += poly_v; + tridxs[i] += poly_v+poly_sv; sg_range trip = { .ptr = tridxs, @@ -622,8 +652,3 @@ void draw_poly(cpVect *points, int n, struct rgba color) poly_c += tric*3; poly_v += n; } - -void debugdraw_flush() -{ - -} diff --git a/source/engine/debug/debugdraw.h b/source/engine/debug/debugdraw.h index ddcc23fb..1b32e0e2 100644 --- a/source/engine/debug/debugdraw.h +++ b/source/engine/debug/debugdraw.h @@ -2,6 +2,7 @@ #define DEBUGDRAW_H #include +#include "HandmadeMath.h" struct rgba; void debugdraw_init(); @@ -19,9 +20,8 @@ void draw_poly(cpVect *points, int n, struct rgba color); void draw_grid(int width, int span, struct rgba color); -void debug_flush(); - -void debugdraw_flush(); /* This is called once per frame to draw all queued elements */ +void debug_flush(HMM_Mat4 *view); +void debug_newframe(); cpVect inflatepoint(cpVect a, cpVect b, cpVect c, float d); void inflatepoints(cpVect *r, cpVect *p, float d, int n); diff --git a/source/engine/ffi.c b/source/engine/ffi.c index 5cf0b910..079a012e 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -1564,6 +1564,25 @@ JSValue duk_make_timer(JSContext *js, JSValueConst this, int argc, JSValueConst return JS_NewInt64(js, id); } +JSValue duk_cmd_points(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) +{ + int n = js_arrlen(argv[1]); + cpVect points[n]; + + for (int i = 0; i < n; i++) + points[i] = js2vec2(js_arridx(argv[1], i)); + + int cmd = js2int(argv[0]); + + switch(cmd) { + case 0: + draw_poly(points, n, js2color(argv[2])); + break; + } + + return JS_NULL; +} + #define DUK_FUNC(NAME, ARGS) JS_SetPropertyStr(js, globalThis, #NAME, JS_NewCFunction(js, duk_##NAME, #NAME, ARGS)); void ffi_load() { @@ -1592,6 +1611,8 @@ void ffi_load() { DUK_FUNC(cmd_edge2d, 6) DUK_FUNC(make_timer, 3) + DUK_FUNC(cmd_points, 5); + DUK_FUNC(cmd, 6) DUK_FUNC(register, 3) DUK_FUNC(register_collide, 6) diff --git a/source/engine/font.c b/source/engine/font.c index 2c9f8c1f..e6082a47 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -190,8 +190,10 @@ struct sFont *MakeFont(const char *fontfile, int height) { } stbtt_GetFontVMetrics(&fontinfo, &newfont->ascent, &newfont->descent, &newfont->linegap); - float emscale = stbtt_ScaleForMappingEmToPixels(&fontinfo, 16); - newfont->linegap = (newfont->ascent - newfont->descent)* 2 * emscale; + newfont->emscale = stbtt_ScaleForMappingEmToPixels(&fontinfo, 16); + newfont->linegap = (newfont->ascent - newfont->descent)* 2 * newfont->emscale; + + YughWarn("Font ascent descent is %g", (newfont->ascent-newfont->descent)*newfont->emscale); newfont->texID = sg_make_image(&(sg_image_desc){ .type = SG_IMAGETYPE_2D, @@ -218,8 +220,8 @@ struct sFont *MakeFont(const char *fontfile, int height) { r.t1 = (glyph.y1) / (float)packsize; stbtt_GetCodepointHMetrics(&fontinfo, c, &newfont->Characters[c].Advance, &newfont->Characters[c].leftbearing); - newfont->Characters[c].Advance *= emscale; - newfont->Characters[c].leftbearing *= emscale; + newfont->Characters[c].Advance *= newfont->emscale; + newfont->Characters[c].leftbearing *= newfont->emscale; // newfont->Characters[c].Advance = glyph.xadvance; /* x distance from this char to the next */ newfont->Characters[c].Size[0] = glyph.x1 - glyph.x0; @@ -268,7 +270,7 @@ void sdrawCharacter(struct Character c, HMM_Vec2 cursor, float scale, struct rgb float lsize = 1.0 / 1024.0; - float oline = 1.0; + float oline = 0.0; vert.pos.x = cursor.X + c.Bearing[0] * scale + oline; vert.pos.y = cursor.Y - c.Bearing[1] * scale - oline; @@ -348,9 +350,16 @@ struct boundingbox text_bb(const char *text, float scale, float lw, float tracki } } - float height = cursor.Y + (font->linegap*scale); + float height = cursor.Y + (font->height*scale); float width = lw > 0 ? lw : cursor.X; + struct boundingbox bb = {}; + bb.l = 0; + bb.t = font->ascent * font->emscale * scale; + bb.b = font->descent * font->emscale * scale; + bb.r = cursor.X; + return bb; + return cwh2bb((HMM_Vec2){0,0}, (HMM_Vec2){width,height}); } diff --git a/source/engine/font.h b/source/engine/font.h index a9d9a2be..31c0e9d1 100644 --- a/source/engine/font.h +++ b/source/engine/font.h @@ -24,6 +24,7 @@ struct sFont { int ascent; int descent; int linegap; + float emscale; struct Character Characters[127]; sg_image texID; }; diff --git a/source/engine/openglrender.c b/source/engine/openglrender.c index f0489650..8592d8a2 100644 --- a/source/engine/openglrender.c +++ b/source/engine/openglrender.c @@ -329,23 +329,23 @@ void openglRender(struct window *window) { sprite_draw_all(); sprite_flush(); - call_draw(); -// debug_flush(); //// DEBUG if (debugDrawPhysics) { gameobject_draw_debugs(); call_debugs(); } + + debug_flush(&projection); - debug_flush(); - ////// TEXT && GUI + + debug_nextpass(); call_gui(); text_flush(); - + debug_flush(&hudproj); nuke_start(); call_nk_gui(); nuke_end(); @@ -358,8 +358,9 @@ void openglRender(struct window *window) { sg_draw(0,6,1); sg_end_pass(); - sg_commit(); + + debug_newframe(); } sg_shader sg_compile_shader(const char *v, const char *f, sg_shader_desc *d) diff --git a/source/engine/sprite.c b/source/engine/sprite.c index 37a68c45..80432d92 100644 --- a/source/engine/sprite.c +++ b/source/engine/sprite.c @@ -19,6 +19,7 @@ struct TextureOptions TEX_SPRITE = {1, 0, 0}; static struct sprite *sprites; static int first = -1; +static sg_shader shader_sprite; static sg_pipeline pip_sprite; static sg_bindings bind_sprite; @@ -28,6 +29,23 @@ struct sprite_vert { struct rgba color; }; +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; + unsigned short border[4]; + HMM_Vec2 scale; + struct rgba color; +}; + int make_sprite(int go) { struct sprite sprite = { .color = color_white, @@ -118,7 +136,7 @@ void sprite_settex(struct sprite *sprite, struct Texture *tex) { sprite_setframe(sprite, &ST_UNIT); } -sg_shader shader_sprite; + void sprite_initialize() { shader_sprite = sg_compile_shader("shaders/spritevert.glsl", "shaders/spritefrag.glsl", &(sg_shader_desc){ @@ -134,8 +152,7 @@ void sprite_initialize() { .image_type = SG_IMAGETYPE_2D, .sampler_type = SG_SAMPLERTYPE_FLOAT, }, - - .fs.uniform_blocks[0] = {.size = 12, .uniforms = {[0] = {.name = "spriteColor", .type = SG_UNIFORMTYPE_FLOAT3}}}}); + }); pip_sprite = sg_make_pipeline(&(sg_pipeline_desc){ .shader = shader_sprite, @@ -159,6 +176,40 @@ void sprite_initialize() { .usage = SG_USAGE_STREAM, .label = "sprite vertex buffer", }); + + slice9_shader = sg_compile_shader("shaders/slice9_v.glsl", "shaders/slice9_f.glsl", &(sg_shader_desc) { + .vs.uniform_blocks[0] = { + .size = 64, + .layout = SG_UNIFORMLAYOUT_STD140, + .uniforms = { [0] = {.name = "projection", .type = SG_UNIFORMTYPE_MAT4}, + }}, + + .fs.images[0] = { + .name = "image", + .image_type = SG_IMAGETYPE_2D, + .sampler_type = SG_SAMPLERTYPE_FLOAT + }, + }); + + slice9_pipe = sg_make_pipeline(&(sg_pipeline_desc){ + .shader = slice9_shader, + .layout = { + .attrs = { + [0].format = SG_VERTEXFORMAT_FLOAT2, + [1].format = SG_VERTEXFORMAT_USHORT4N, + [2].format = SG_VERTEXFORMAT_FLOAT2, + [3].format = SG_VERTEXFORMAT_UBYTE4N + }}, + .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, + }); + + } /* offset given in texture offset, so -0.5,-0.5 results in it being centered */ @@ -178,7 +229,6 @@ void tex_draw(struct Texture *tex, HMM_Vec2 pos, float angle, HMM_Vec2 size, HMM tex->width * st_s_w(r) * size.X, tex->height * st_s_h(r) * size.Y }; - for (int i = 0; i < 4; i++) { sposes[i] = HMM_AddV2(sposes[i], offset); @@ -217,6 +267,8 @@ void sprite_draw(struct sprite *sprite) { } } + + void sprite_setanim(struct sprite *sprite, struct TexAnim *anim, int frame) { if (!sprite) return; sprite->tex = anim->tex; @@ -232,6 +284,47 @@ void gui_draw_img(const char *img, HMM_Vec2 pos, float scale, float angle) { tex_draw(tex, pos, 0.f, size, offset, tex_get_rect(tex), color_white); } +void slice9_draw(const char *img, HMM_Vec2 pos, HMM_Vec2 dimensions, struct rgba color) +{ + sg_apply_pipeline(slice9_pipe); + sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(hudproj)); + struct Texture *tex = texture_loadfromfile(img); + + struct glrect r = tex_get_rect(tex); + + struct slice9_vert verts[4]; + + HMM_Vec2 sposes[4] = { + {0.0,0.0}, + {1.0,0.0}, + {0.0,1.0}, + {1.0,1.0}, + }; + + for (int i = 0; i < 4; i++) { + verts[i].pos = HMM_MulV2(sposes[i], dimensions); + //verts[i].uv =z sposes[i]; + verts[i].color = color; + } + + verts[0].uv.u = r.s0 * USHRT_MAX; + verts[0].uv.v = r.t1 * USHRT_MAX; + verts[1].uv.u = r.s1 * USHRT_MAX; + verts[1].uv.v = r.t1 * USHRT_MAX; + verts[2].uv.u = r.s0 * USHRT_MAX; + verts[2].uv.v = r.t0 * USHRT_MAX; + verts[3].uv.u = r.s1 * USHRT_MAX; + verts[3].uv.v = r.t0 * USHRT_MAX; + + bind_sprite.fs_images[0] = tex->id; + sg_append_buffer(bind_sprite.vertex_buffers[0], SG_RANGE_REF(verts)); + sg_apply_bindings(&bind_sprite); + + sg_draw(sprite_count * 4, 4, 1); + sprite_count++; + +} + void sprite_setframe(struct sprite *sprite, struct glrect *frame) { sprite->frame = *frame; } diff --git a/source/scripts/base.js b/source/scripts/base.js index 622a2a8c..832aef46 100644 --- a/source/scripts/base.js +++ b/source/scripts/base.js @@ -1,18 +1,3 @@ - -var fns = [ -() => { -var ttt = {}; -Object.defineProperty(ttt, 'a', {}); -ttt.a = 5; -}, -() => { Log.warn("did it"); } -]; - -//fns.forEach(x => x()); - - - - /* Prototypes out an object and extends with values */ function clone(proto, binds) { var c = Object.create(proto); @@ -539,6 +524,15 @@ function points2bb(points) { return b; }; +function bb2points(bb) +{ + return [ + [bb.l,bb.t], + [bb.r,bb.t], + [bb.r,bb.b], + [bb.l,bb.b] + ]; +} function bb2cwh(bb) { if (!bb) return undefined; @@ -552,6 +546,23 @@ function bb2cwh(bb) { return cwh; }; +function pointinbb(bb, p) +{ + if (bb.t < p.y || bb.b > p.y || bb.l > p.x || bb.r < p.x) + return false; + + return true; +} + +function movebb(bb, pos) { + var newbb = Object.assign({}, bb); + newbb.t += pos.y; + newbb.b += pos.y; + newbb.l += pos.x; + newbb.r += pos.x; + return newbb; +}; + function bb_expand(oldbb, x) { if (!oldbb || !x) return; var bb = {}; diff --git a/source/scripts/debug.js b/source/scripts/debug.js index a681767f..b489c2e8 100644 --- a/source/scripts/debug.js +++ b/source/scripts/debug.js @@ -8,7 +8,6 @@ var Gizmos = { var Shape = { circle(pos, radius, color) { - cmd(115, pos, radius, color); }, }; @@ -30,6 +29,10 @@ var Debug = { capsize = 4; cmd(81, start, end, color, capsize); }, + + poly(points, color) { + cmd_points(0,points,color); + }, box(pos, wh, color) { color = color ? color : Color.white; diff --git a/source/scripts/engine.js b/source/scripts/engine.js index 0737647a..1846dfd5 100644 --- a/source/scripts/engine.js +++ b/source/scripts/engine.js @@ -162,30 +162,32 @@ var GUI = { return cwh2bb([0,0], wh); }, - nodrawbb: { - draw() { return cwh2bb([0,0],[0,0]); } - }, - image_fn(defn) { var def = Object.create(this.defaults); Object.assign(def,defn); - if (!def.path) { Log.warn("GUI image needs a path."); - return GUI.nodrawbb; + def.draw = function(){}; + return def; } - return { - draw(pos) { - var wh = cmd(64,def.path); - gui_img(def.path, pos, def.scale, def.angle); - this.bb = cwh2bb([0,0],wh); - } + def.draw = function(pos) { + def.calc_bb(pos); + var wh = cmd(64,def.path); + gui_img(def.path, pos.sub(def.anchor.scale(wh)), def.scale, def.angle, def.color); }; + + def.calc_bb = function(cursor) { + var wh = cmd(64,def.path).scale(def.scale); + def.bb = cwh2bb(wh.scale([0.5,0.5]), wh); + def.bb = movebb(def.bb, cursor.sub(wh.scale(def.anchor))); + }; + + return def; }, defaults: { - padding:[0,0], + padding:[2,2], /* Each element inset with this padding on all sides */ font: "fonts/LessPerfectDOSVGA.ttf", font_size: 1, text_align: "left", @@ -198,7 +200,7 @@ var GUI = { }, text_outline: 1, /* outline in pixels */ color: [255,255,255,255], - margin: [5,5], + margin: [5,5], /* Distance between elements for things like columns */ width: 0, height: 0, }, @@ -207,20 +209,33 @@ var GUI = { { var def = Object.create(this.defaults); Object.assign(def,defn); - - return { - draw: function(cursor) { - var wh = bb2wh(cmd(118,str,def.font_size,def.width)); - var pos = cursor.sub(wh.scale(def.anchor)); - ui_text(str, pos, def.font_size, def.color, def.width); - this.bb = cwh2bb(pos,wh); - return cwh2bb(pos,wh); - } - }; - }, - - button_fn(str, cb, defn) { + def.draw = function(cursor) { + def.calc_bb(cursor); + + var old = def; + def = Object.create(def); + + if (def.hovered && pointinbb(def.bb, Mouse.screenpos) || def.selected) { + Object.assign(def, def.hovered); + def.calc_bb(cursor); + } + + var pos = cursor.sub(bb2wh(def.bb).scale(def.anchor)); + + ui_text(str, pos, def.font_size, def.color, def.width); + + def = old; + }; + + def.calc_bb = function(cursor) { + var bb = cmd(118, str, def.font_size, def.width); + var wh = bb2wh(bb); + var pos = cursor.sub(wh.scale(def.anchor)); + def.bb = movebb(bb,pos); + }; + + return def; }, column(defn) { @@ -229,12 +244,20 @@ var GUI = { if (!def.items) { Log.warn("Columns needs items."); - return GUI.nodrawbb; + def.draw = function(){}; + return def; }; + def.items.forEach(function(item,idx) { + Object.setPrototypeOf(def.items[idx], def); + }); + def.draw = function(pos) { + var c = Color.red.slice(); + c.a = 100; def.items.forEach(function(item) { - item.draw(pos); + item.draw.call(this,pos); + Debug.poly(bb2points(item.bb), c); var wh = bb2wh(item.bb); pos.y -= wh.y; pos.y -= def.padding.x*2; @@ -457,6 +480,12 @@ var Mouse = { return cmd(45); }, + get screenpos() { + var p = this.pos; + p.y = Window.dimensions.y - p.y; + return p; + }, + get worldpos() { return screen2world(cmd(45)); }, diff --git a/source/shaders/slice9_f.glsl b/source/shaders/slice9_f.glsl new file mode 100644 index 00000000..eb638086 --- /dev/null +++ b/source/shaders/slice9_f.glsl @@ -0,0 +1,37 @@ +#version 330 + +in vec2 uv; /* image uv */ +in vec4 border; /* uv length of border, normalized to image dimensions; left, bottom, right, top */ +in vec2 scale; /* polygon dimensions / texture dimensions */ +in vec4 fcolor; + +out vec4 color; + +uniform sampler2d image; + +float map(float value, float min1, float max1, float min2, float max2) +{ + return min2 + (value - min1) * (max2 - min2) / (max1 - min1); +} + +float processAxis(float coord, float texBorder, float winBorder) +{ + if (coord < winBorder) + return map(coord, 0, winBorder, 0, texBorder); + if (coord < 1 - winBorder) + return map(coord, winBorder, 1 - winBorder, texBorder, 1 - texBorder); + + return map(coord, 1 - winBorder, 1, 1 - texBorder, 1); +} + +uv9slice(vec2 uv, vec2 s, vec4 b) +{ + vec2 t = clamp((s * uv - b.xy) / (s - b.xy - b.zw), 0.0, 1.0); + return mix(uv * s, 1.0 - s * (1.0 - uv), t); +} + +void main() +{ + uv = uv9slice(uv, scale, border); + color = fcolor * texture(image, uv); +} diff --git a/source/shaders/slice9_v.glsl b/source/shaders/slice9_v.glsl new file mode 100644 index 00000000..3ce5ca3e --- /dev/null +++ b/source/shaders/slice9_v.glsl @@ -0,0 +1,24 @@ +#version 330 core + +layout (location = 0) in vec2 vert; +layout (location = 1) in vec2 uv; +layout (location = 2) in vec4 vborder; +layout (location = 3) in vec2 vscale; +layout (location = 4) in vec4 vcolor; + +out vec2 uv; +out vec4 border; +out vec2 scale; +out vec4 fcolor; + +uniform mat4 projection; + +void main() +{ + gl_Position = projection * vec4(vert, 0.0, 1.0); + + uv = vert; + border = vborder; + scale = vscale; + fcolor = vcolor; +}