From f49651384ccb974ef1604f55fb27d15dccfef9e0 Mon Sep 17 00:00:00 2001 From: SamratGhale Date: Fri, 27 Mar 2026 20:40:35 +0545 Subject: [PATCH] Recalculate Font on window resize --- draw/draw.odin | 18 ++-- edit2d.odin | 204 +++++++++++++++++++++--------------------- glyph/glyph.odin | 18 +++- handle_input.odin | 6 +- interface.odin | 32 +++---- interface_entity.odin | 17 ++-- interface_joints.odin | 41 +++++++-- 7 files changed, 188 insertions(+), 148 deletions(-) diff --git a/draw/draw.odin b/draw/draw.odin index 841ea5c..aaa5cc3 100644 --- a/draw/draw.odin +++ b/draw/draw.odin @@ -114,7 +114,8 @@ camera_convert_screen_to_world :: proc { camera_convert_world_to_screen :: proc( cam : ^Camera, pw : [2]f32, - ) -> [2]f32 { + ) -> [2]f32 +{ cam := cam pw := pw @@ -1353,6 +1354,7 @@ Draw :: struct //There should be option to draw without glyph? maybe glyph : e2_glyph.GlyphState, + font_path : string, texts : [dynamic]TextItem, } @@ -1413,20 +1415,20 @@ DrawStringVec :: proc(draw : ^Draw, p : [2]f32, cstr: cstring) str = strings.trim_right_space(str) str = strings.trim_null(str) - append(&draw.texts, TextItem{str, {f32(ps.x), f32(ps.y)}, {200,200,200,255}}) } -text_flush :: proc(draw: ^Draw) + +text_flush :: proc(draw: ^Draw, flush_glyph := false) { for &t in &draw.texts{ - e2_glyph.glyph_draw_font(&draw.glyph, t.str, t.pos, t.color) + e2_glyph.glyph_draw_font(&draw.glyph, t.str, t.pos, t.color, flush_glyph) } clear(&draw.texts) } -draw_flush :: proc(draw : ^Draw) { +draw_flush :: proc(draw : ^Draw, flush_glyph := false) { //background_draw(&draw.background, &draw.cam) @@ -1437,7 +1439,7 @@ draw_flush :: proc(draw : ^Draw) { points_flush(&draw.points, &draw.cam) circle_flush(&draw.circles, &draw.cam) textures_flush(draw) - text_flush(draw) + text_flush(draw, flush_glyph) check_opengl() } @@ -1596,7 +1598,9 @@ draw_create :: proc(draw : ^Draw, camera : ^Camera, font_path : string = "") draw.glyph.width = draw.cam.width draw.glyph.height = draw.cam.height - e2_glyph.glyph_init(&draw.glyph, font_path) + draw.font_path = font_path + + e2_glyph.glyph_init(&draw.glyph, draw.font_path) } check_opengl() diff --git a/edit2d.odin b/edit2d.odin index 599d11f..be00465 100644 --- a/edit2d.odin +++ b/edit2d.odin @@ -1,20 +1,30 @@ package edit2d -import "core:fmt" import "base:intrinsics" import "core:encoding/cbor" import b2 "vendor:box2d" import "base:runtime" + +/* import im "shared:odin-imgui" import "shared:odin-imgui/imgui_impl_glfw" import "shared:odin-imgui/imgui_impl_opengl3" +**/ + import gl "vendor:OpenGL" import "vendor:glfw" -import e2_draw "shared:Edit2D/draw" +import e2_draw "shared:Edit2D/draw" +import e2_glyph "shared:Edit2D/glyph" import "core:reflect" import mu "vendor:microui" +//Only to be used inside the libarary +__e2d_interal : struct +{ + viewport_changed : bool +} + engine_state :: struct @@ -98,6 +108,12 @@ engine_check_types :: proc($Game: typeid) } + +size_callback :: proc "c" (window: glfw.WindowHandle, width, height : i32) +{ + __e2d_interal.viewport_changed = true +} + /* This will only be called once to initilize the engine initilize graphics library, glfw, callbacks @@ -126,32 +142,8 @@ engine_init :: proc($GameType : typeid, state: ^engine_state, font_path : strin glfw.MakeContextCurrent(state.window) glfw.SwapInterval(1) gl.load_up_to(4, 5, glfw.gl_set_proc_address) - - im.CHECKVERSION() - im.CreateContext() - - io := im.GetIO() - - io.ConfigFlags += { - .NavEnableKeyboard, - .NavEnableGamepad, - .DpiEnableScaleFonts, - } - - - im.StyleColorsClassic() - - style := im.GetStyle() - style.ChildBorderSize = 0. - style.ChildRounding = 6 - style.TabRounding = 6 - style.FrameRounding = 6 - style.GrabRounding = 6 - style.WindowRounding = 6 - style.PopupRounding = 6 - - imgui_impl_glfw.InitForOpenGL(state.window, true) - imgui_impl_opengl3.Init("#version 150") + + glfw.SetWindowSizeCallback(state.window, size_callback) state.draw.cam = e2_draw.camera_init() @@ -175,33 +167,26 @@ engine_init :: proc($GameType : typeid, state: ^engine_state, font_path : strin }, 201, rawptr) - //Glyph and microui + + mu.init(&state.mu_ctx) + state.mu_ctx.style.font = cast(mu.Font)&state.draw.glyph + state.mu_ctx.text_width = mui_text_width + state.mu_ctx.text_height = mui_text_height + + texture_data := make([]u8, mu.DEFAULT_ATLAS_WIDTH* mu.DEFAULT_ATLAS_HEIGHT * 4) + idx :i32 = 0 + for y in 0.. e2_draw.Rect @@ -251,78 +236,84 @@ update_frame :: proc(state: ^engine_state) state.width , state.height = glfw.GetFramebufferSize(state.window) gl.Viewport(0, 0, state.width, state.height) + /* imgui_impl_opengl3.NewFrame() imgui_impl_glfw.NewFrame() im.NewFrame() + */ } end_frame :: proc(state: ^engine_state) { + /* im.Render() imgui_impl_opengl3.RenderDrawData(im.GetDrawData()) + */ //Microui + + fb_x, fb_y := glfw.GetFramebufferSize(state.window) + state.draw.glyph.atlas_width = fb_x + state.draw.glyph.atlas_height = fb_y + + cmd: ^mu.Command + + draw := &state.draw + for mu.next_command(&state.mu_ctx, &cmd) { - - cmd: ^mu.Command - - draw := &state.draw - for mu.next_command(&state.mu_ctx, &cmd) - { - #partial switch c in cmd.variant{ - case ^mu.Command_Text: - { - color := c.color - append(&draw.texts, e2_draw.TextItem{c.str, {f32(c.pos.x), f32(c.pos.y)}, {c.color.r, color.g, color.b, color.a}}) - } - case ^mu.Command_Rect: - { - rect := c.rect - pos :[2]f32= {f32(rect.x), f32(rect.y)} - wh :[2]f32= {f32(rect.w), f32(rect.h)} - w, h := wh.x, wh.y - - - points : [4][2]f32 = { - {pos.x + w, pos.y}, - {pos.x, pos.y}, - {pos.x, pos.y + h}, - {pos.x + w, pos.y + h}, - } - - for &p, i in &points do points[i] = e2_draw.camera_convert_screen_to_world(&draw.cam, p) - color := c.color - //hex_color := e2_draw.make_hex_color({color.r, color.g, color.b, color.a}) - e2_draw.solid_polygon_add(&draw.polygons, {q = e2_draw.Rot{c = 1}}, &points[0], 4, 0.01, transmute([4]u8)color) - } - case ^mu.Command_Clip: - { - rect := c.rect - gl.Scissor(rect.x, state.height - (rect.y + rect.h), rect.w, rect.h) - } - case ^mu.Command_Icon:{ - rect := mu.default_atlas[c.id] - - append(&draw.textures.textures, e2_draw.TextureData{ - texture_id = state.mu_tex, - src_rect = normalize_rect(rect, mu.DEFAULT_ATLAS_WIDTH), - dst_rect = e2_draw.Rect{f32(c.rect.x), f32(c.rect.y), f32(rect.w), f32(rect.h)}, - }) - - } + #partial switch c in cmd.variant{ + case ^mu.Command_Text: + { + color := c.color + append(&draw.texts, e2_draw.TextItem{c.str, {f32(c.pos.x), f32(c.pos.y)}, {c.color.r, color.g, color.b, color.a}}) } + case ^mu.Command_Rect: + { + rect := c.rect + pos :[2]f32= {f32(rect.x), f32(rect.y)} + wh :[2]f32= {f32(rect.w), f32(rect.h)} + w, h := wh.x, wh.y + + points : [4][2]f32 = { + {pos.x + w, pos.y}, + {pos.x, pos.y}, + {pos.x, pos.y + h}, + {pos.x + w, pos.y + h}, + } + + for &p, i in &points do points[i] = e2_draw.camera_convert_screen_to_world(&draw.cam, p) + color := c.color + e2_draw.solid_polygon_add(&draw.polygons, {q = e2_draw.Rot{c = 1}}, &points[0], 4, 0.01, transmute([4]u8)color) + } + case ^mu.Command_Clip: + { + rect := c.rect + gl.Scissor(rect.x, state.height - (rect.y + rect.h), rect.w, rect.h) + } + case ^mu.Command_Icon:{ + rect := mu.default_atlas[c.id] + + append(&draw.textures.textures, e2_draw.TextureData{ + texture_id = state.mu_tex, + src_rect = normalize_rect(rect, mu.DEFAULT_ATLAS_WIDTH), + dst_rect = e2_draw.Rect{f32(c.rect.x), f32(c.rect.y), f32(rect.w), f32(rect.h)}, + }) + + } } } + glfw.SwapBuffers(state.window) + __e2d_interal.viewport_changed = false } cleanup :: proc(state: ^engine_state) { - imgui_impl_opengl3.Shutdown() - imgui_impl_glfw.Shutdown() + //imgui_impl_opengl3.Shutdown() + //imgui_impl_glfw.Shutdown() } engine_should_close :: proc(state : ^engine_state) -> b32 @@ -367,6 +358,17 @@ is_key_released :: #force_inline proc(state: ^engine_state, key : i32) -> bool{ draw_flush :: proc(d: ^e2_draw.Draw) { - e2_draw.draw_flush(d) + if __e2d_interal.viewport_changed + { + d.glyph.atlas_width = d.cam.width + d.glyph.atlas_height = d.cam.height + d.glyph.font_size_pt = 9 + d.glyph.width = d.cam.width + d.glyph.height = d.cam.height + + e2_glyph.glyph_init(&d.glyph, d.font_path) + + } + e2_draw.draw_flush(d, __e2d_interal.viewport_changed) } diff --git a/glyph/glyph.odin b/glyph/glyph.odin index 7ddde9d..54a9b71 100644 --- a/glyph/glyph.odin +++ b/glyph/glyph.odin @@ -52,8 +52,20 @@ GlyphState :: struct { width, height : i32, } +glyph_delete :: proc(glyph : ^GlyphState) +{ + //Delete the textures -glyph_init :: proc(glyph: ^GlyphState, font_path : string = "") { + gl.DeleteProgram(glyph.program_id) + gl.DeleteBuffers(1, &glyph.rect_instances_vbo) + gl.DeleteVertexArrays(1, &glyph.vao) + gl.DeleteTextures(1, &glyph.atlas_texture) + +} + + +glyph_init :: proc(glyph: ^GlyphState, font_path : string = "") +{ ok : bool glyph.program_id, ok = gl.load_shaders_source(#load("./shaders/font_vert.glsl"), #load("./shaders/font_frag.glsl"), ) @@ -102,7 +114,7 @@ glyph_init :: proc(glyph: ^GlyphState, font_path : string = "") { } -glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, color : [4]u8) { +glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, color : [4]u8, flush : bool = false) { //using app //text := get_string(&gap_buf) @@ -162,7 +174,7 @@ glyph_draw_font :: proc(glyph_state: ^GlyphState, text: string, pos : [2]f32, co assert(codepoint < 127) glyph_atlas := glyph_state.atlas_items[codepoint] - if !glyph_atlas.filled + if !glyph_atlas.filled || flush { glyph_index := stbtt.FindGlyphIndex(&glyph_state.font_info, c) diff --git a/handle_input.odin b/handle_input.odin index c976335..610e671 100644 --- a/handle_input.odin +++ b/handle_input.odin @@ -1,7 +1,7 @@ package edit2d import b2 "vendor:box2d" -import im "shared:odin-imgui" +//import im "shared:odin-imgui" import "vendor:glfw" import "base:runtime" import draw "./draw" @@ -175,8 +175,8 @@ handle_input :: proc( level_save_to_file(level, state) } - if im.GetIO().WantCaptureMouse do return false - if im.GetIO().WantCaptureKeyboard do return false + //if im.GetIO().WantCaptureMouse do return false + //if im.GetIO().WantCaptureKeyboard do return false diff --git a/interface.odin b/interface.odin index 820b018..6810896 100644 --- a/interface.odin +++ b/interface.odin @@ -1,7 +1,7 @@ #+feature dynamic-literals package edit2d -import im "shared:odin-imgui" +//import im "shared:odin-imgui" import mu "vendor:microui" import e2_glyph "./glyph" import "core:fmt" @@ -184,31 +184,21 @@ interface_all :: proc(interface: ^interface_state) -> bool mu_interface_draw_options(interface.state) mu_interface_game_mode(state, interface) - if im.Begin("Box2d interface") + + if mu.begin_window(&state.mu_ctx, "B2d Interface", {1630, 170, 250, 450}) { - if im.BeginTabBar("Tabs") + if .ACTIVE in mu.header(&state.mu_ctx, "Entity", {.AUTO_SIZE}) { - - if mu.begin_window(&state.mu_ctx, "B2d Interface", {1630, 170, 250, 450}) - { - if .ACTIVE in mu.header(&state.mu_ctx, "Entity", {.AUTO_SIZE}) - { - if interface_entity(interface) do ret = true - } - mu.end_window(&state.mu_ctx) - } - - if im.BeginTabItem("Joints", nil, {}) - { - if interface_joints(interface) do ret = true - im.EndTabItem() - } - - im.EndTabBar() + if interface_entity(interface) do ret = true } + mu.end_window(&state.mu_ctx) } + + //if interface_joints(interface) do ret = true + + mu.end(&state.mu_ctx) - im.End() + //im.End() return ret } diff --git a/interface_entity.odin b/interface_entity.odin index 4c132b3..18eb6ce 100644 --- a/interface_entity.odin +++ b/interface_entity.odin @@ -1,7 +1,7 @@ package edit2d import b2 "vendor:box2d" -import im "shared:odin-imgui" +//import im "shared:odin-imgui" import mu "vendor:microui" import "core:slice" import draw "./draw" @@ -107,6 +107,7 @@ mu_interface_body_def_editor :: proc(interface: ^interface_state, def : ^engine_ } +/* interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_entity_def) -> bool { curr_index := &interface.curr_static_index @@ -167,6 +168,7 @@ interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_ent } return false } +*/ mu_interface_edit_static_index :: proc(interface: ^interface_state, def : ^engine_entity_def) -> bool { @@ -184,6 +186,7 @@ mu_interface_edit_static_index :: proc(interface: ^interface_state, def : ^engin indexes := &level.relations[entity.index] //if mu.slider() + return true } @@ -383,12 +386,10 @@ interface_entity :: proc(interface: ^interface_state) -> bool //Flags for flag in engine_entity_flags_enum { - contains := flag in def.entity_flags - if im.Checkbox(fmt.ctprint(flag), &contains) do def.entity_flags ~= {flag} + //contains := flag in def.entity_flags + //if mu.checkbox(fmt.tprint(flag), &contains) do def.entity_flags ~= {flag} } - im.Separator() - if .ACTIVE in mu.begin_treenode(&interface.state.mu_ctx, "Body Def") { @@ -402,14 +403,13 @@ interface_entity :: proc(interface: ^interface_state) -> bool mu.end_treenode(&interface.state.mu_ctx) } - im.Separator() - if .ACTIVE in mu.begin_treenode(&interface.state.mu_ctx, "Static Index") { - ret |= interface_edit_static_index(interface, def) + //ret |= interface_edit_static_index(interface, def) } + /* if .CHAIN in def.entity_flags { im.InputInt("Body Count", &def.body_count) @@ -420,6 +420,7 @@ interface_entity :: proc(interface: ^interface_state) -> bool interface_edit_rev_joint_minimal(&def.rev_joint) } } + */ return !compare_engine_entity_def(def^, def_old) || ret } diff --git a/interface_joints.odin b/interface_joints.odin index e071d10..b2948bd 100644 --- a/interface_joints.odin +++ b/interface_joints.odin @@ -2,7 +2,7 @@ package edit2d import "core:fmt" import b2 "vendor:box2d" -import im "shared:odin-imgui" +//import im "shared:odin-imgui" import draw "./draw" /* @@ -36,6 +36,7 @@ distance_joint_def :: struct using def : b2.DistanceJointDef, } +/* interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^interface_state) -> bool { level := interface.world @@ -91,6 +92,30 @@ interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^inter return ret } +mu_interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^interface_state) -> bool +{ + level := interface.world + + { + if joint_def.entity_a in level.static_indexes{ + entity_a := interface.entity_defs[level.static_indexes[joint_def.entity_a]] + draw.points_add(&interface.state.draw.points, entity_a.body_def.position, 20.0, {200, 240, 200, 200}) + + } + if joint_def.entity_b in level.static_indexes{ + entity_b := interface.entity_defs[level.static_indexes[joint_def.entity_b]] + draw.points_add(&interface.state.draw.points, entity_b.body_def.position, 20.0, {200, 240, 200, 200}) + } + } + + + ret := false + + + + +} + interface_edit_distance_joint :: proc( interface : ^interface_state ) -> bool { @@ -271,13 +296,19 @@ interface_joints :: proc(interface: ^interface_state) -> bool ret := false //interface.edit_mode = .JOINT - if im.BeginCombo("Joint type", fmt.ctprint(interface.curr_joint_type)) + ctx := &interface.state.mu_ctx + + if .ACTIVE in mu.begin_treenode(ctx, "Joint Type") { for type in b2.JointType { - if im.Selectable(fmt.ctprint(type), type == interface.curr_joint_type) do interface.curr_joint_type = type + state := interface.curr_joint_type == type + if .CHANGE in mu.checkbox(ctx, fmt.tprint(type), &state) + { + interface.curr_joint_type = type + } } - im.EndCombo() + mu.end_treenode(ctx) } @@ -291,4 +322,4 @@ interface_joints :: proc(interface: ^interface_state) -> bool } return ret } - +*/ \ No newline at end of file