diff --git a/code/font/VEFontCache/VEFontCache.odin b/code/font/VEFontCache/VEFontCache.odin index 99bd736..126b4c8 100644 --- a/code/font/VEFontCache/VEFontCache.odin +++ b/code/font/VEFontCache/VEFontCache.odin @@ -116,13 +116,6 @@ font_key_from_label :: #force_inline proc( label : string ) -> u64 { return hash } -// ve_fontcache_configure_snap -configure_snap :: proc( ctx : ^Context, snap_width, snap_height : u32 ) { - assert( ctx != nil ) - ctx.snap_width = snap_width - ctx.snap_height = snap_height -} - // For a provided alpha value, // allows the function to calculate the position of a point along the curve at any given fraction of its total length // ve_fontcache_eval_bezier (quadratic) @@ -358,6 +351,13 @@ shutdown :: proc( ctx : ^Context ) shaper_shutdown( & shaper_ctx ) } +// ve_fontcache_configure_snap +configure_snap :: proc( ctx : ^Context, snap_width, snap_height : u32 ) { + assert( ctx != nil ) + ctx.snap_width = snap_width + ctx.snap_height = snap_height +} + // ve_fontcache_load load_font :: proc( ctx : ^Context, label : string, data : []byte, size_px : f32 ) -> FontID { diff --git a/code/font/VEFontCache/draw.odin b/code/font/VEFontCache/draw.odin index 64c4d37..edcf2ee 100644 --- a/code/font/VEFontCache/draw.odin +++ b/code/font/VEFontCache/draw.odin @@ -6,7 +6,7 @@ DrawCall :: struct { end_index : u32, clear_before_draw : b32, region : AtlasRegionKind, - colour : [4]f32, + colour : Colour, } DrawCall_Default :: DrawCall { @@ -25,11 +25,11 @@ DrawList :: struct { } FrameBufferPass :: enum u32 { - None = 0, - Glyph = 1, - Atlas = 2, - Target = 3, - Target_Unchanged = 4, + None = 0, + Glyph = 1, + Atlas = 2, + Target = 3, + Target_Uncached = 4, } GlyphDrawBuffer :: struct { @@ -127,7 +127,7 @@ directly_draw_massive_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph : Gly call : DrawCall { using call - pass = .Target_Unchanged + pass = .Target_Uncached colour = ctx.colour start_index = u32(ctx.draw_list.indices.num) blit_quad( & ctx.draw_list, dst, dst + { dst_width, dst_height }, glyph_position, glyph_position + glyph_size ) @@ -200,7 +200,7 @@ draw_cached_glyph :: proc( ctx : ^Context, entry : ^Entry, glyph_index : Glyph, call := DrawCall_Default { using call - pass = .Target_Unchanged + pass = .Target_Uncached colour = ctx.colour start_index = cast(u32) ctx.draw_list.indices.num diff --git a/code/font/VEFontCache/shaper.odin b/code/font/VEFontCache/shaper.odin index 8800c0c..230314f 100644 --- a/code/font/VEFontCache/shaper.odin +++ b/code/font/VEFontCache/shaper.odin @@ -88,7 +88,7 @@ shaper_shape_from_text :: proc( ctx : ^ShaperContext, info : ^ShaperInfo, output // script = HB_SCRIPT_LATIN harfbuzz.buffer_set_script( buffer, script ) harfbuzz.buffer_set_direction( buffer, harfbuzz.script_get_horizontal_direction( script )) - harfbuzz.set_language( buffer, harfbuzz.language_get_default() ) + harfbuzz.buffer_set_language( buffer, harfbuzz.language_get_default() ) // Perform the actual shaping of this run using HarfBuzz. harfbuzz.shape( font, buffer, nil, 0 ) diff --git a/code/sectr/engine/render.odin b/code/sectr/engine/.render.odin similarity index 100% rename from code/sectr/engine/render.odin rename to code/sectr/engine/.render.odin diff --git a/code/sectr/engine/client_api.odin b/code/sectr/engine/client_api.odin index 1509050..f42e623 100644 --- a/code/sectr/engine/client_api.odin +++ b/code/sectr/engine/client_api.odin @@ -177,8 +177,8 @@ startup :: proc( prof : ^SpallProfiler, persistent_mem, frame_mem, transient_mem sokol_app.client_init() window := & state.app_window - window.extent.x = sokol_app.widthf() - window.extent.y = sokol_app.heightf() + window.extent.x = cast(f32) i32(sokol_app.widthf() * 0.5) + window.extent.y = cast(f32) i32(sokol_app.heightf() * 0.5) // TODO(Ed): We don't need monitor tracking until we have multi-window support (which I don't think I'll do for this prototype) // Sokol doesn't provide it. diff --git a/code/sectr/engine/client_api_sokol_callbacks.odin b/code/sectr/engine/client_api_sokol_callbacks.odin index 3796850..3cb0d3d 100644 --- a/code/sectr/engine/client_api_sokol_callbacks.odin +++ b/code/sectr/engine/client_api_sokol_callbacks.odin @@ -27,11 +27,13 @@ sokol_app_frame_callback :: proc "c" () { window := & state.app_window // if int(window.extent.x) != int(sokol_width) || int(window.extent.y) != int(sokol_height) { window.resized = true - window.extent.x = sokol_width * 0.5 - window.extent.y = sokol_height * 0.5 + window.extent.x = cast(f32) i32(sokol_width * 0.5) + window.extent.y = cast(f32) i32(sokol_height * 0.5) // log("sokol_app: Event-based frame callback triggered (detected a resize") // } + font_provider_reload() + // sokol_app is the only good reference for a frame-time at this point. sokol_delta_ms := sokol_app.frame_delta() sokol_delta_ns := transmute(Duration) sokol_delta_ms * MS_To_NS diff --git a/code/sectr/engine/render_vefc.odin b/code/sectr/engine/render_vefc.odin new file mode 100644 index 0000000..2864a60 --- /dev/null +++ b/code/sectr/engine/render_vefc.odin @@ -0,0 +1,190 @@ +package sectr + +import ve "codebase:font/VEFontCache" +import sokol_gfx "thirdparty:sokol/gfx" +import sokol_glue "thirdparty:sokol/glue" + +PassActions :: struct { + bg_clear_black : sokol_gfx.Pass_Action, + +} + +RenderState :: struct { + pass_actions : PassActions, +} + +// TODO(Ed) : Review this and put into space.odin when ready +ortho :: proc(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32) -> [4][4]f32 { + result: [4][4]f32 + result[0][0] = 2.0 / (right - left) + result[1][1] = 2.0 / (top - bottom) + result[2][2] = -2.0 / (far - near) + result[3][0] = -(right + left) / (right - left) + result[3][1] = -(top + bottom) / (top - bottom) + result[3][2] = -(far + near) / (far - near) + result[3][3] = 1.0 + return result +} + +render :: proc() +{ + Bindings :: sokol_gfx.Bindings + Range :: sokol_gfx.Range + ShaderStage :: sokol_gfx.Shader_Stage + + state := get_state(); using state + using render_data + + do_nothing : bool + do_nothing = false + + // The below are most likely limited to a "depth layer" and so + // different depth layers need different draw pass combos (of the 3 constructive passes) + // Will need to profile how expensive it is for batching with the UI box rendering + // since the the text is correlated with the box rendering + + font_provider := & state.font_provider_data + using font_provider + // ve_ctx := & font_provider.ve_font_cache + + // "Draw text" using immediate mode api + { + // text_test_str := str_fmt("frametime: %v", frametime_avg_ms) + text_test_str := str_fmt("HELLO VE FONT CACHE!!!!!") + + // font_provider := & state.font_provider_data + fdef := hmap_chained_get( font_cache, default_font.key ) + + ve.draw_text( & ve_font_cache, fdef.ve_id, text_test_str, {30, 30}, Vec2{1, 1} ) + } + + // Process the draw calls for drawing text + { + draw_list := ve.get_draw_list( & ve_font_cache ) + + sokol_gfx.update_buffer( draw_list_vbuf, Range{ draw_list.vertices.data, draw_list.vertices.num }) + sokol_gfx.update_buffer( draw_list_ibuf, Range{ draw_list.indices.data, draw_list.indices.num }) + + for & draw_call in array_to_slice(draw_list.calls) + { + if (draw_call.end_index - draw_call.start_index) == 0 do continue + + switch draw_call.pass + { + // 1. Do the glyph rendering pass + // Glyphs are first rendered to an intermediate 2k x 512px R8 texture + case .Glyph: + width := ve_font_cache.atlas.buffer_width + height := ve_font_cache.atlas.buffer_height + + pass := glyph_pass + if draw_call.clear_before_draw { + pass.action.colors[0].load_action = .CLEAR + pass.action.colors[0].clear_value.a = 1.0 + } + sokol_gfx.begin_pass( pass ) + + sokol_gfx.apply_viewport( 0,0, width, height, origin_top_left = true ) + sokol_gfx.apply_scissor_rect( 0,0, width, height, origin_top_left = true ) + + sokol_gfx.apply_pipeline( glyph_pipeline ) + + bindings := Bindings { + vertex_buffers = { + 0 = draw_list_vbuf, + }, + vertex_buffer_offsets = { + 0 = 0, + }, + index_buffer = draw_list_ibuf, + index_buffer_offset = i32(draw_call.start_index), + fs = {}, + } + sokol_gfx.apply_bindings( bindings ) + + // 2. Do the atlas rendering pass + // A simple 16-tap box downsample shader is then used to blit from this intermediate texture to the final atlas location + case .Atlas: + width := ve_font_cache.atlas.width + height := ve_font_cache.atlas.height + + pass := atlas_pass + if draw_call.clear_before_draw { + pass.action.colors[0].load_action = .CLEAR + // pass.action.colors[0].clear_value.a = 0.0 + } + sokol_gfx.begin_pass( pass ) + + sokol_gfx.apply_viewport( 0, 0, width, height, origin_top_left = true ) + sokol_gfx.apply_scissor_rect( 0, 0, width, height, origin_top_left = true ) + + sokol_gfx.apply_pipeline( atlas_pipeline ) + + fs_uniform := Ve_Blit_Atlas_Fs_Params { region = cast(i32) draw_call.region } + sokol_gfx.apply_uniforms( ShaderStage.FS, SLOT_ve_blit_atlas_fs_params, Range { & fs_uniform, size_of(fs_uniform) }) + + sokol_gfx.apply_bindings(Bindings { + vertex_buffers = { + 0 = draw_list_vbuf, + }, + vertex_buffer_offsets = { + 0 = 0, + }, + index_buffer = draw_list_ibuf, + index_buffer_offset = i32(draw_call.start_index), + fs = { + images = { SLOT_ve_blit_atlas_src_texture = glyph_rt_color, }, + samplers = { SLOT_ve_blit_atlas_src_sampler = gfx_sampler, }, + }, + }) + + // 3. Use the atlas to then render the text. + case .None: fallthrough + case .Target: fallthrough + case .Target_Uncached: + width := u32(app_window.extent.x * 2) + height := u32(app_window.extent.y * 2) + + pass := atlas_pass + if ! draw_call.clear_before_draw { + pass.action.colors[0].load_action = .LOAD + // pass.action.colors[0].clear_value.a = 0.0 + } + pass.swapchain = sokol_glue.swapchain() + sokol_gfx.begin_pass( pass ) + + sokol_gfx.apply_viewport( 0, 0, width, height, origin_top_left = true ) + sokol_gfx.apply_scissor_rect( 0, 0, width, height, origin_top_left = true ) + + sokol_gfx.apply_pipeline( screen_pipeline ) + + fs_uniform := Ve_Draw_Text_Fs_Params { down_sample = 0, colour = {1, 1, 1, 1} } + sokol_gfx.apply_uniforms( ShaderStage.FS, SLOT_ve_blit_atlas_fs_params, Range { & fs_uniform, size_of(fs_uniform) }) + + src_rt := draw_call.pass == .Target_Uncached ? glyph_rt_color : atlas_rt_color + + sokol_gfx.apply_bindings(Bindings { + vertex_buffers = { + 0 = draw_list_vbuf, + }, + vertex_buffer_offsets = { + 0 = 0, + }, + index_buffer = draw_list_ibuf, + index_buffer_offset = i32(draw_call.start_index), + fs = { + images = { SLOT_ve_draw_text_src_texture = src_rt, }, + samplers = { SLOT_ve_draw_text_src_sampler = gfx_sampler, }, + }, + }) + } + + num_indices := draw_call.end_index - draw_call.start_index + sokol_gfx.draw( 0, num_indices, 1 ) + + sokol_gfx.end_pass() + } + + sokol_gfx.commit() + } +} diff --git a/code/sectr/font/provider_VEFontCache.odin b/code/sectr/font/provider_VEFontCache.odin index f6ba42a..d4a66cf 100644 --- a/code/sectr/font/provider_VEFontCache.odin +++ b/code/sectr/font/provider_VEFontCache.odin @@ -1,8 +1,9 @@ package sectr import "core:os" -import ve "codebase:font/VEFontCache" -import sokol_gfx "thirdparty:sokol/gfx" +import ve "codebase:font/VEFontCache" +import sokol_gfx "thirdparty:sokol/gfx" +import sokol_glue "thirdparty:sokol/glue" Font_Provider_Use_Freetype :: false @@ -30,11 +31,32 @@ FontProviderData :: struct ve_font_cache : ve.Context, font_cache : HMapChained(FontDef), - gfx_bindings : sokol_gfx.Bindings, - gfx_pipeline : sokol_gfx.Pipeline, - gfx_v_buffer : sokol_gfx.Buffer, - gfx_uv_buffer : sokol_gfx.Buffer, - gfx_sampler : sokol_gfx.Sampler, + gfx_sampler : sokol_gfx.Sampler, + + draw_list_vbuf : sokol_gfx.Buffer, + draw_list_ibuf : sokol_gfx.Buffer, + + glyph_shader : sokol_gfx.Shader, + atlas_shader : sokol_gfx.Shader, + screen_shader : sokol_gfx.Shader, + + // 2k x 512, R8 + glyph_rt_color : sokol_gfx.Image, + // glyph_rt_resolve : sokol_gfx.Image, + // glyph_rt_depth : sokol_gfx.Image, + + // 4k x 2k, R8 + atlas_rt_color : sokol_gfx.Image, + // atlas_rt_resolve : sokol_gfx.Image, + // atlas_rt_depth : sokol_gfx.Image, + + glyph_pipeline : sokol_gfx.Pipeline, + atlas_pipeline : sokol_gfx.Pipeline, + screen_pipeline : sokol_gfx.Pipeline, + + glyph_pass : sokol_gfx.Pass, + atlas_pass : sokol_gfx.Pass, + screen_pass : sokol_gfx.Pass, } font_provider_startup :: proc() @@ -51,7 +73,317 @@ font_provider_startup :: proc() ve.init( & provider_data.ve_font_cache, .STB_TrueType, allocator = persistent_slab_allocator() ) log("VEFontCached initialized") + ve.configure_snap( & provider_data.ve_font_cache, u32(state.app_window.extent.x * 2.0), u32(state.app_window.extent.y * 2.0) ) + // TODO(Ed): Setup sokol hookup for VEFontCache + { + AttachmentDesc :: sokol_gfx.Attachment_Desc + BlendFactor :: sokol_gfx.Blend_Factor + BlendOp :: sokol_gfx.Blend_Op + BlendState :: sokol_gfx.Blend_State + BorderColor :: sokol_gfx.Border_Color + BufferDesciption :: sokol_gfx.Buffer_Desc + BufferUsage :: sokol_gfx.Usage + BufferType :: sokol_gfx.Buffer_Type + ColorTargetState :: sokol_gfx.Color_Target_State + Filter :: sokol_gfx.Filter + ImageDesc :: sokol_gfx.Image_Desc + PassAction :: sokol_gfx.Pass_Action + Range :: sokol_gfx.Range + SamplerDescription :: sokol_gfx.Sampler_Desc + Wrap :: sokol_gfx.Wrap + VertexAttributeState :: sokol_gfx.Vertex_Attr_State + VertexBufferLayoutState :: sokol_gfx.Vertex_Buffer_Layout_State + VertexIndexType :: sokol_gfx.Index_Type + VertexFormat :: sokol_gfx.Vertex_Format + VertexLayoutState :: sokol_gfx.Vertex_Layout_State + VertexStep :: sokol_gfx.Vertex_Step + + using provider_data + backend := sokol_gfx.query_backend() + app_env := sokol_glue.environment() + + glyph_shader = sokol_gfx.make_shader(ve_render_glyph_shader_desc(backend) ) + atlas_shader = sokol_gfx.make_shader(ve_blit_atlas_shader_desc(backend) ) + screen_shader = sokol_gfx.make_shader(ve_draw_text_shader_desc(backend) ) + + draw_list_vbuf = sokol_gfx.make_buffer( BufferDesciption { + size = size_of([4]f32) * Kilo * 128, + usage = BufferUsage.STREAM, + type = BufferType.VERTEXBUFFER, + }) + + draw_list_ibuf = sokol_gfx.make_buffer( BufferDesciption { + size = size_of(u32) * Kilo * 32, + usage = BufferUsage.STREAM, + type = BufferType.INDEXBUFFER, + }) + + gfx_sampler = sokol_gfx.make_sampler( SamplerDescription { + min_filter = Filter.NEAREST, + mag_filter = Filter.NEAREST, + mipmap_filter = Filter.NONE, + wrap_u = Wrap.CLAMP_TO_EDGE, + wrap_v = Wrap.CLAMP_TO_EDGE, + border_color = BorderColor.OPAQUE_BLACK, + }) + + // glyph_pipeline + { + vs_layout : VertexLayoutState + { + using vs_layout + attrs[ATTR_ve_render_glyph_vs_v_position] = VertexAttributeState { + format = VertexFormat.FLOAT2, + offset = 0, + buffer_index = 0, + } + attrs[ATTR_ve_render_glyph_vs_v_texture] = VertexAttributeState { + format = VertexFormat.FLOAT2, + offset = size_of(Vec2), + buffer_index = 0, + } + buffers[0] = VertexBufferLayoutState { + stride = size_of(Vec2) * 2, + step_func = VertexStep.PER_VERTEX + } + } + + color_target := ColorTargetState { + pixel_format = .R8, + // write_mask = + blend = BlendState { + enabled = true, + src_factor_rgb = .ONE_MINUS_DST_COLOR, + dst_factor_rgb = .ONE_MINUS_SRC_COLOR, + op_rgb = BlendOp.ADD, + src_factor_alpha = BlendFactor.ONE, + dst_factor_alpha = BlendFactor.ZERO, + op_alpha = BlendOp.ADD, + }, + } + + glyph_pipeline = sokol_gfx.make_pipeline({ + shader = glyph_shader, + layout = vs_layout, + index_type = VertexIndexType.UINT32, + colors = { + 0 = color_target, + }, + color_count = 1, + // sample_count = 1, + // label = + }) + } + + // glyph_pass + { + glyph_rt_color = sokol_gfx.make_image( ImageDesc { + type = ._2D, + render_target = true, + width = i32(ve_font_cache.atlas.buffer_width), + height = i32(ve_font_cache.atlas.buffer_height), + num_slices = 1, + num_mipmaps = 1, + usage = .STREAM, + pixel_format = .R8, + sample_count = app_env.defaults.sample_count, + // TODO(Ed): Setup labels for debug tracing/logging + // label = + }) + + color_attach := AttachmentDesc { + image = glyph_rt_color, + // mip_level = 1, + } + + glyph_attachments := sokol_gfx.make_attachments({ + colors = { + 0 = color_attach, + }, + }) + + glyph_action := PassAction { + colors = { + 0 = { + load_action = .DONTCARE, + store_action = .STORE, + clear_value = {0,0,0,1}, + } + } + } + + glyph_pass = sokol_gfx.Pass { + action = glyph_action, + attachments = glyph_attachments, + // label = + } + } + + // atlas_pipeline + { + vs_layout : VertexLayoutState + { + using vs_layout + attrs[ATTR_ve_blit_atlas_vs_v_position] = VertexAttributeState { + format = VertexFormat.FLOAT2, + offset = 0, + buffer_index = 0, + } + attrs[ATTR_ve_blit_atlas_vs_v_texture] = VertexAttributeState { + format = VertexFormat.FLOAT2, + offset = size_of(Vec2), + buffer_index = 0, + } + buffers[0] = VertexBufferLayoutState { + stride = size_of(Vec2) * 2, + step_func = VertexStep.PER_VERTEX + } + } + + color_target := ColorTargetState { + pixel_format = .R8, + // write_mask = + blend = BlendState { + enabled = true, + src_factor_rgb = .SRC_ALPHA, + dst_factor_rgb = .ONE_MINUS_SRC_ALPHA, + op_rgb = BlendOp.ADD, + src_factor_alpha = BlendFactor.ONE, + dst_factor_alpha = BlendFactor.ZERO, + op_alpha = BlendOp.ADD, + }, + } + + atlas_pipeline = sokol_gfx.make_pipeline({ + shader = atlas_shader, + layout = vs_layout, + index_type = VertexIndexType.UINT32, + colors = { + 0 = color_target, + }, + color_count = 1, + sample_count = 1, + }) + } + + // atlas_pass + { + atlas_rt_color = sokol_gfx.make_image( ImageDesc { + type = ._2D, + render_target = true, + width = i32(ve_font_cache.atlas.buffer_width), + height = i32(ve_font_cache.atlas.buffer_height), + num_slices = 1, + num_mipmaps = 1, + usage = .STREAM, + pixel_format = .R8, + sample_count = app_env.defaults.sample_count, + // TODO(Ed): Setup labels for debug tracing/logging + // label = + }) + + color_attach := AttachmentDesc { + image = atlas_rt_color, + // mip_level = 1, + } + + atlas_attachments := sokol_gfx.make_attachments({ + colors = { + 0 = color_attach, + }, + }) + + atlas_action := PassAction { + colors = { + 0 = { + load_action = .LOAD, + store_action = .STORE, + clear_value = {0,0,0,1}, + } + } + } + + atlas_pass = sokol_gfx.Pass { + action = atlas_action, + attachments = atlas_attachments, + // label = + } + } + + // screen pipeline + { + vs_layout : VertexLayoutState + { + using vs_layout + attrs[ATTR_ve_draw_text_vs_v_position] = VertexAttributeState { + format = VertexFormat.FLOAT2, + offset = 0, + buffer_index = 0, + } + attrs[ATTR_ve_draw_text_vs_v_texture] = VertexAttributeState { + format = VertexFormat.FLOAT2, + offset = size_of(Vec2), + buffer_index = 0, + } + buffers[0] = VertexBufferLayoutState { + stride = size_of(Vec2) * 2, + step_func = VertexStep.PER_VERTEX + } + } + + color_target := ColorTargetState { + // pixel_format = .R8, + // write_mask = + blend = BlendState { + enabled = true, + src_factor_rgb = .SRC_ALPHA, + dst_factor_rgb = .ONE_MINUS_SRC_ALPHA, + op_rgb = BlendOp.ADD, + src_factor_alpha = BlendFactor.ONE, + dst_factor_alpha = BlendFactor.ZERO, + op_alpha = BlendOp.ADD, + }, + } + + screen_pipeline = sokol_gfx.make_pipeline({ + shader = screen_shader, + layout = vs_layout, + index_type = VertexIndexType.UINT32, + colors = { + 0 = color_target, + }, + color_count = 1, + sample_count = 1, + }) + } + + // screen_pass + { + screen_action := PassAction { + colors = { + 0 = { + load_action = .CLEAR, + store_action = .STORE, + clear_value = {0,0,0,0}, + } + } + } + + screen_pass = sokol_gfx.Pass { + action = screen_action, + // label = + } + } + } +} + +font_provider_reload :: proc() +{ + state := get_state() + provider_data := & state.font_provider_data + + ve.configure_snap( & provider_data.ve_font_cache, u32(state.app_window.extent.x * 2.0), u32(state.app_window.extent.y) ) } font_provider_shutdown :: proc() @@ -92,7 +424,7 @@ font_load :: proc(path_file : string, verify( set_error == AllocatorError.None, "Failed to add new font entry to cache" ) // TODO(Ed): Load even sizes from 8px to upper bound. - def.ve_id = ve.load_font( & provider_data.ve_font_cache, desired_id, font_data, default_size ) + def.ve_id = ve.load_font( & provider_data.ve_font_cache, desired_id, font_data, 36.0 ) fid := FontID { key, desired_id } return fid diff --git a/scripts/update_deps.ps1 b/scripts/update_deps.ps1 index 1d2795e..c544ba9 100644 --- a/scripts/update_deps.ps1 +++ b/scripts/update_deps.ps1 @@ -109,11 +109,18 @@ clone-gitrepo $path_sokol_tools $url_sokol_tools $path_vendor = join-path $path_odin 'vendor' $path_vendor_raylib = join-path $path_vendor 'raylib' -$path_sokol_dlls = join-path $path_thirdparty 'sokol' +$path_harfbuzz_dlls = join-path $path_harfbuzz 'lib/win64' $path_raylib_dlls = join-path $path_vendor_raylib 'windows' +$path_sokol_dlls = join-path $path_thirdparty 'sokol' if ( $binaries_dirty -or $true ) { + $third_party_dlls = Get-ChildItem -path $path_harfbuzz_dlls -Filter '*dll' + foreach ($dll in $third_party_dlls) { + $destination = join-path $path_build $dll.Name + Copy-Item $dll.FullName -Destination $destination -Force + } + $third_party_dlls = Get-ChildItem -Path $path_sokol_dlls -Filter '*.dll' foreach ($dll in $third_party_dlls) { $destination = join-path $path_build $dll.Name diff --git a/thirdparty/harfbuzz b/thirdparty/harfbuzz index 2427211..4c81e82 160000 --- a/thirdparty/harfbuzz +++ b/thirdparty/harfbuzz @@ -1 +1 @@ -Subproject commit 24272117e3da8cd91d0d1a67a67a494b5ab93e77 +Subproject commit 4c81e825e1b58632b9c4e5e4974172b8b6740cde diff --git a/toolchain/Odin b/toolchain/Odin index 66c85cb..8bfc2a0 160000 --- a/toolchain/Odin +++ b/toolchain/Odin @@ -1 +1 @@ -Subproject commit 66c85cb42c0b926b93d0e00891cef24883b7f68a +Subproject commit 8bfc2a0af0eff7b573eb8cd33de1c15a051dddb6