Recalculate Font on window resize

This commit is contained in:
SamratGhale
2026-03-27 20:40:35 +05:45
parent 00ae6cbc4e
commit f49651384c
7 changed files with 188 additions and 148 deletions
+11 -7
View File
@@ -114,7 +114,8 @@ camera_convert_screen_to_world :: proc {
camera_convert_world_to_screen :: proc( camera_convert_world_to_screen :: proc(
cam : ^Camera, cam : ^Camera,
pw : [2]f32, pw : [2]f32,
) -> [2]f32 { ) -> [2]f32
{
cam := cam cam := cam
pw := pw pw := pw
@@ -1353,6 +1354,7 @@ Draw :: struct
//There should be option to draw without glyph? maybe //There should be option to draw without glyph? maybe
glyph : e2_glyph.GlyphState, glyph : e2_glyph.GlyphState,
font_path : string,
texts : [dynamic]TextItem, 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_right_space(str)
str = strings.trim_null(str) str = strings.trim_null(str)
append(&draw.texts, TextItem{str, {f32(ps.x), f32(ps.y)}, {200,200,200,255}}) 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{ 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) clear(&draw.texts)
} }
draw_flush :: proc(draw : ^Draw) { draw_flush :: proc(draw : ^Draw, flush_glyph := false) {
//background_draw(&draw.background, &draw.cam) //background_draw(&draw.background, &draw.cam)
@@ -1437,7 +1439,7 @@ draw_flush :: proc(draw : ^Draw) {
points_flush(&draw.points, &draw.cam) points_flush(&draw.points, &draw.cam)
circle_flush(&draw.circles, &draw.cam) circle_flush(&draw.circles, &draw.cam)
textures_flush(draw) textures_flush(draw)
text_flush(draw) text_flush(draw, flush_glyph)
check_opengl() check_opengl()
} }
@@ -1596,7 +1598,9 @@ draw_create :: proc(draw : ^Draw, camera : ^Camera, font_path : string = "")
draw.glyph.width = draw.cam.width draw.glyph.width = draw.cam.width
draw.glyph.height = draw.cam.height 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() check_opengl()
+41 -39
View File
@@ -1,20 +1,30 @@
package edit2d package edit2d
import "core:fmt"
import "base:intrinsics" import "base:intrinsics"
import "core:encoding/cbor" import "core:encoding/cbor"
import b2 "vendor:box2d" import b2 "vendor:box2d"
import "base:runtime" import "base:runtime"
/*
import im "shared:odin-imgui" import im "shared:odin-imgui"
import "shared:odin-imgui/imgui_impl_glfw" import "shared:odin-imgui/imgui_impl_glfw"
import "shared:odin-imgui/imgui_impl_opengl3" import "shared:odin-imgui/imgui_impl_opengl3"
**/
import gl "vendor:OpenGL" import gl "vendor:OpenGL"
import "vendor:glfw" 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 "core:reflect"
import mu "vendor:microui" import mu "vendor:microui"
//Only to be used inside the libarary
__e2d_interal : struct
{
viewport_changed : bool
}
engine_state :: struct 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 This will only be called once to initilize the engine
initilize graphics library, glfw, callbacks initilize graphics library, glfw, callbacks
@@ -127,31 +143,7 @@ engine_init :: proc($GameType : typeid, state: ^engine_state, font_path : strin
glfw.SwapInterval(1) glfw.SwapInterval(1)
gl.load_up_to(4, 5, glfw.gl_set_proc_address) gl.load_up_to(4, 5, glfw.gl_set_proc_address)
im.CHECKVERSION() glfw.SetWindowSizeCallback(state.window, size_callback)
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")
state.draw.cam = e2_draw.camera_init() state.draw.cam = e2_draw.camera_init()
@@ -175,10 +167,7 @@ engine_init :: proc($GameType : typeid, state: ^engine_state, font_path : strin
}, 201, rawptr) }, 201, rawptr)
//Glyph and microui
{
//Create index
mu.init(&state.mu_ctx) mu.init(&state.mu_ctx)
state.mu_ctx.style.font = cast(mu.Font)&state.draw.glyph state.mu_ctx.style.font = cast(mu.Font)&state.draw.glyph
state.mu_ctx.text_width = mui_text_width state.mu_ctx.text_width = mui_text_width
@@ -198,10 +187,6 @@ engine_init :: proc($GameType : typeid, state: ^engine_state, font_path : strin
} }
} }
state.mu_tex = e2_draw.create_texture(texture_data, mu.DEFAULT_ATLAS_WIDTH, mu.DEFAULT_ATLAS_HEIGHT) state.mu_tex = e2_draw.create_texture(texture_data, mu.DEFAULT_ATLAS_WIDTH, mu.DEFAULT_ATLAS_HEIGHT)
}
} }
normalize_rect :: proc(rect : mu.Rect, size : i32) -> e2_draw.Rect normalize_rect :: proc(rect : mu.Rect, size : i32) -> e2_draw.Rect
@@ -251,19 +236,26 @@ update_frame :: proc(state: ^engine_state)
state.width , state.height = glfw.GetFramebufferSize(state.window) state.width , state.height = glfw.GetFramebufferSize(state.window)
gl.Viewport(0, 0, state.width, state.height) gl.Viewport(0, 0, state.width, state.height)
/*
imgui_impl_opengl3.NewFrame() imgui_impl_opengl3.NewFrame()
imgui_impl_glfw.NewFrame() imgui_impl_glfw.NewFrame()
im.NewFrame() im.NewFrame()
*/
} }
end_frame :: proc(state: ^engine_state) end_frame :: proc(state: ^engine_state)
{ {
/*
im.Render() im.Render()
imgui_impl_opengl3.RenderDrawData(im.GetDrawData()) imgui_impl_opengl3.RenderDrawData(im.GetDrawData())
*/
//Microui //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 cmd: ^mu.Command
@@ -293,7 +285,6 @@ end_frame :: proc(state: ^engine_state)
for &p, i in &points do points[i] = e2_draw.camera_convert_screen_to_world(&draw.cam, p) for &p, i in &points do points[i] = e2_draw.camera_convert_screen_to_world(&draw.cam, p)
color := c.color 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) 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: case ^mu.Command_Clip:
@@ -315,14 +306,14 @@ end_frame :: proc(state: ^engine_state)
} }
}
glfw.SwapBuffers(state.window) glfw.SwapBuffers(state.window)
__e2d_interal.viewport_changed = false
} }
cleanup :: proc(state: ^engine_state) cleanup :: proc(state: ^engine_state)
{ {
imgui_impl_opengl3.Shutdown() //imgui_impl_opengl3.Shutdown()
imgui_impl_glfw.Shutdown() //imgui_impl_glfw.Shutdown()
} }
engine_should_close :: proc(state : ^engine_state) -> b32 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) 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)
} }
+15 -3
View File
@@ -52,8 +52,20 @@ GlyphState :: struct {
width, height : i32, 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 ok : bool
glyph.program_id, ok = gl.load_shaders_source(#load("./shaders/font_vert.glsl"), #load("./shaders/font_frag.glsl"), ) 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 //using app
//text := get_string(&gap_buf) //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) assert(codepoint < 127)
glyph_atlas := glyph_state.atlas_items[codepoint] 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) glyph_index := stbtt.FindGlyphIndex(&glyph_state.font_info, c)
+3 -3
View File
@@ -1,7 +1,7 @@
package edit2d package edit2d
import b2 "vendor:box2d" import b2 "vendor:box2d"
import im "shared:odin-imgui" //import im "shared:odin-imgui"
import "vendor:glfw" import "vendor:glfw"
import "base:runtime" import "base:runtime"
import draw "./draw" import draw "./draw"
@@ -175,8 +175,8 @@ handle_input :: proc(
level_save_to_file(level, state) level_save_to_file(level, state)
} }
if im.GetIO().WantCaptureMouse do return false //if im.GetIO().WantCaptureMouse do return false
if im.GetIO().WantCaptureKeyboard do return false //if im.GetIO().WantCaptureKeyboard do return false
+4 -14
View File
@@ -1,7 +1,7 @@
#+feature dynamic-literals #+feature dynamic-literals
package edit2d package edit2d
//import im "shared:odin-imgui" //import im "shared:odin-imgui"
import mu "vendor:microui" import mu "vendor:microui"
import e2_glyph "./glyph" import e2_glyph "./glyph"
import "core:fmt" import "core:fmt"
import "vendor:glfw" import "vendor:glfw"
@@ -184,10 +184,6 @@ interface_all :: proc(interface: ^interface_state) -> bool
mu_interface_game_mode(state, interface) mu_interface_game_mode(state, interface)
{
if im.BeginTabBar("Tabs")
{
if mu.begin_window(&state.mu_ctx, "B2d Interface", {1630, 170, 250, 450}) 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 .ACTIVE in mu.header(&state.mu_ctx, "Entity", {.AUTO_SIZE})
@@ -198,17 +194,11 @@ interface_all :: proc(interface: ^interface_state) -> bool
} }
//if interface_joints(interface) do ret = true //if interface_joints(interface) do ret = true
{
if interface_joints(interface) do ret = true
im.EndTabItem()
}
mu.end(&state.mu_ctx) mu.end(&state.mu_ctx)
}
}
mu.end(&state.mu_ctx)
//im.End() //im.End()
return ret return ret
} }
+9 -8
View File
@@ -1,7 +1,7 @@
package edit2d package edit2d
import b2 "vendor:box2d" import b2 "vendor:box2d"
import im "shared:odin-imgui" //import im "shared:odin-imgui"
import mu "vendor:microui" import mu "vendor:microui"
import "core:slice" import "core:slice"
import draw "./draw" 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 interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_entity_def) -> bool
{ {
curr_index := &interface.curr_static_index curr_index := &interface.curr_static_index
@@ -167,6 +168,7 @@ interface_edit_static_index :: proc(interface:^interface_state, def: ^engine_ent
} }
return false return false
} }
*/
mu_interface_edit_static_index :: proc(interface: ^interface_state, def : ^engine_entity_def) -> bool 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] indexes := &level.relations[entity.index]
//if mu.slider() //if mu.slider()
return true
} }
@@ -383,12 +386,10 @@ interface_entity :: proc(interface: ^interface_state) -> bool
//Flags //Flags
for flag in engine_entity_flags_enum for flag in engine_entity_flags_enum
{ {
contains := flag in def.entity_flags //contains := flag in def.entity_flags
if im.Checkbox(fmt.ctprint(flag), &contains) do def.entity_flags ~= {flag} //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") 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) mu.end_treenode(&interface.state.mu_ctx)
} }
im.Separator()
if .ACTIVE in mu.begin_treenode(&interface.state.mu_ctx, "Static Index") 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 if .CHAIN in def.entity_flags
{ {
im.InputInt("Body Count", &def.body_count) 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) interface_edit_rev_joint_minimal(&def.rev_joint)
} }
} }
*/
return !compare_engine_entity_def(def^, def_old) || ret return !compare_engine_entity_def(def^, def_old) || ret
} }
+36 -5
View File
@@ -2,7 +2,7 @@ package edit2d
import "core:fmt" import "core:fmt"
import b2 "vendor:box2d" import b2 "vendor:box2d"
import im "shared:odin-imgui" //import im "shared:odin-imgui"
import draw "./draw" import draw "./draw"
/* /*
@@ -36,6 +36,7 @@ distance_joint_def :: struct
using def : b2.DistanceJointDef, using def : b2.DistanceJointDef,
} }
/*
interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^interface_state) -> bool interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^interface_state) -> bool
{ {
level := interface.world level := interface.world
@@ -91,6 +92,30 @@ interface_edit_joint_common :: proc(joint_def : ^joint_common, interface: ^inter
return ret 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 interface_edit_distance_joint :: proc( interface : ^interface_state ) -> bool
{ {
@@ -271,13 +296,19 @@ interface_joints :: proc(interface: ^interface_state) -> bool
ret := false ret := false
//interface.edit_mode = .JOINT //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 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 return ret
} }
*/