From 117b5eb51e7b57c043b6d837ea9b9b34462cf778 Mon Sep 17 00:00:00 2001 From: Matthew Date: Fri, 19 Jun 2026 17:52:52 +1000 Subject: [PATCH] update dependencies, fix some crashes, cleanup --- .gitmodules | 3 - assets/gui.frag.spv | Bin 18860 -> 17836 bytes assets/gui.vert.spv | Bin 20628 -> 20320 bytes build.sh | 2 - dub.json | 20 ++-- src/VulkanRenderer | 1 - src/dlib | 2 +- src/editor/editor.d | 1 - src/editor/main.d | 1 - src/editor/parsing.d | 3 +- src/editor/ui.d | 238 ++++---------------------------------- src/shaders/gui.frag.glsl | 24 ---- src/shaders/gui.layout | 2 - 13 files changed, 33 insertions(+), 264 deletions(-) delete mode 160000 src/VulkanRenderer diff --git a/.gitmodules b/.gitmodules index bad792b..ed62a37 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "src/VulkanRenderer"] - path = src/VulkanRenderer - url = https://git.sleepy.day/sleepy-day/VulkanRenderer.git [submodule "src/dlib"] path = src/dlib url = https://git.sleepy.day/sleepy-day/dlib.git diff --git a/assets/gui.frag.spv b/assets/gui.frag.spv index 4c7e572a95040e96afbf90a0df10dd893fe2c326..4ddc450df630669102e1b97997e5fbf04ca904d9 100644 GIT binary patch literal 17836 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 eTs(D4i|Dt#{|oUy6wzi2)I^E{0J literal 18860 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 diff --git a/assets/gui.vert.spv b/assets/gui.vert.spv index 45ce2e3610739106e01b3258e20e949ed381ac00..77ac490268a0645da6bff40a41704a447f1baa13 100644 GIT binary patch literal 20320 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 literal 20628 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 diff --git a/build.sh b/build.sh index a6981d5..ff3b5d0 100755 --- a/build.sh +++ b/build.sh @@ -15,6 +15,4 @@ for shader in src/shaders/*.glsl; do $shader_compiler $shader_flags $shader_out${base_name}.spv $shader done -/bin/bash src/VulkanRenderer/build.sh build - /bin/bash src/dlib/build.sh build diff --git a/dub.json b/dub.json index 5556082..987ce02 100644 --- a/dub.json +++ b/dub.json @@ -9,16 +9,16 @@ "targetPath": "build", "sourceFiles-linux": ["build/libvma.a", "build/libstb.a", "build/libm3d.a"], "sourceFiles-windows": [], - "importPaths": ["src/editor", "src/dlib", "src/dlib/external/xxhash", "src/VulkanRenderer"], - "sourcePaths": ["src/editor", "src/dlib", "src/dlib/external/xxhash", "src/VulkanRenderer"], + "importPaths": ["src/editor", "src/dlib/dlib", "src/dlib/vulkan"], + "sourcePaths": ["src/editor", "src/dlib/dlib", "src/dlib/vulkan"], "libs-linux": ["X11", "vulkan", "stdc++", "xfixes", "freetype"], "libs-windows": [], "versions": ["VULKAN_DEBUG", "ENABLE_RENDERER", "DLIB"], "preGenerateCommands-linux": ["./build.sh"], "preGenerateCommands-windows": [], - "dflags": ["-P-I/usr/include/freetype2", "-Jbuild", "-Jassets", "-P-DDLIB_INCLUDE_VULKAN"], - "dflags-ldc2": ["-link-debuglib"], - "dflags-dmd": [] + "dflags": ["-P-I/usr/include/freetype2", "-Jbuild", "-Jassets", "-P-DBUILD_VULKAN"], + "dflags-ldc2": ["-link-debuglib", "--Xcc=-DBUILD_VULKAN"], + "dflags-dmd": ["-Xcc=-DBUILD_VULKAN"] }, { "name": "editor-test", @@ -27,16 +27,16 @@ "targetPath": "build", "sourceFiles-linux": ["build/libvma.a", "build/libstb.a", "build/libm3d.a", "build/libcglm.a"], "sourceFiles-windows": [], - "importPaths": ["src/editor", "src/dlib", "src/dlib/external/xxhash", "src/VulkanRenderer"], - "sourcePaths": ["src/editor", "src/dlib", "src/dlib/external/xxhash", "src/VulkanRenderer"], + "importPaths": ["src/editor", "src/dlib/dlib", "src/dlib/vulkan"], + "sourcePaths": ["src/editor", "src/dlib/dlib", "src/dlib/vulkan"], "libs-linux": ["X11", "vulkan", "stdc++", "xfixes", "freetype"], "libs-windows": [], "versions": ["VULKAN_DEBUG"], "preGenerateCommands-linux": ["./build.sh"], "preGenerateCommands-windows": [], - "dflags": ["-P-I/usr/include/freetype2", "-Jbuild", "-Jassets", "-unittest"], - "dflags-ldc2": ["-link-debuglib"], - "dflags-dmd": [] + "dflags": ["-P-I/usr/include/freetype2", "-Jbuild", "-Jassets", "-unittest", "-P-DBUILD_VULKAN"], + "dflags-ldc2": ["-link-debuglib", "--Xcc=-DBUILD_VULKAN"], + "dflags-dmd": ["-Xcc=-DBUILD_VULKAN"] } ] } diff --git a/src/VulkanRenderer b/src/VulkanRenderer deleted file mode 160000 index 245db6e..0000000 --- a/src/VulkanRenderer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 245db6ea6fe787e91839dd78f92dda007e234f7c diff --git a/src/dlib b/src/dlib index 6ae59da..53eb211 160000 --- a/src/dlib +++ b/src/dlib @@ -1 +1 @@ -Subproject commit 6ae59dab5bca9d44fdf4a7f517654b1c0f8545f1 +Subproject commit 53eb211a1e227d1cf3d8036a0e8ecfb79f514eed diff --git a/src/editor/editor.d b/src/editor/editor.d index ae84e39..b805c4e 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -24,7 +24,6 @@ struct RenderCtx Descriptor[FS] font_descs; Descriptor default_tex; Descriptor sampler; - Descriptor msdf_texture; Pipeline pipeline; Pipeline slug_pipeline; DescSetLayout desc_set_layout; diff --git a/src/editor/main.d b/src/editor/main.d index 747bb47..824a928 100644 --- a/src/editor/main.d +++ b/src/editor/main.d @@ -48,7 +48,6 @@ void main(string[] argv) SetExtent(window.w, window.h); g_ctx.pc.resolution = current_res; Ortho(&g_ctx.pc.projection, 0.0, 0.0, current_res.x, current_res.y, -10.0, 10.0); - UpdateMSDFShaderInfo(&g_ctx.pc, g_ctx.pc.resolution); } if(inputs.first == null) diff --git a/src/editor/parsing.d b/src/editor/parsing.d index f2845eb..5e2c993 100644 --- a/src/editor/parsing.d +++ b/src/editor/parsing.d @@ -661,7 +661,8 @@ TokenizeD(FlatBuffer* fb) } } - t.end = tk.pos; + t.end = tk.pos; + tk.pos += 1; } break; } } diff --git a/src/editor/ui.d b/src/editor/ui.d index abf34c0..4b13d92 100644 --- a/src/editor/ui.d +++ b/src/editor/ui.d @@ -293,19 +293,6 @@ struct UIPanel alias item this; } -void -UpdateMSDFShaderInfo(PushConst* pc, Vec2 resolution) -{ - const f32 AA_PIXEL_SIZE = 1.0; - - f32 aa_in_em = AA_PIXEL_SIZE * resolution.x / MSDF_INFO.pixels_per_em; - - pc.antialias_per_em = 1.0 / aa_in_em; - pc.aem_range = MSDF_INFO.aem_range; - pc.threshold_em = 0.0; - pc.distance_range = MSDF_INFO.distance_field_range; -} - struct Window { Window* next, prev; @@ -396,184 +383,6 @@ struct UIKey */ -enum MSDFType -{ - None, - HardMask, - SoftMask, - SDF, - PSDF, - MSDF, - MTSDF, -} - -enum MSDFYOrigin -{ - None, - Left, - Bottom, - Right, - Top, -} - -struct MSDFInfo -{ - MSDFGlyph[] glyphs; - MSDFType type; - Vec2 aem_range; - u32 distance_field_range; - u32 distance_field_range_middle; - f32 pixels_per_em; - u32 texture_width; - u32 texture_height; - MSDFYOrigin y_origin; - f32 line_height; // EM - f32 ascender; // EM - f32 descender; // EM - f32 underline_y; // EM - f32 underline_thickness; // EM -} - -struct MSDFBounds -{ - f32 left = 0.0, bottom = 0.0, right = 0.0, top = 0.0; -} - -struct MSDFGlyph -{ - dchar glyph = 0; - f32 advance = 0.0; - MSDFBounds plane; // EM - MSDFBounds atlas; // Pixels -} - -const u8[] MSDF_ATLAS = cast(u8[])import("msdf-atlas.rgba"); - -const MSDFInfo MSDF_INFO = GenerateMSDF(); - -static MSDFInfo -GenerateMSDF() -{ - import std.json; - - string msdf_json = import("msdf.json"); - - JSONValue jsonv = parseJSON(msdf_json); - - static T GetJSONValue(T)(JSONValue jsonv, string name) - { - static if(is(T == string)) - { - T result = ""; - } - else - { - T result = cast(T)0; - } - - if(const(JSONValue)* value = name in jsonv) - { - switch(value.type()) - { - static if(is(T == u32) || is(T == u64) || is(T == f32)) - { - case JSONType.float_: result = cast(T)value.floating; break; - case JSONType.uinteger: result = cast(T)value.uinteger; break; - case JSONType.integer: result = cast(T)value.integer; break; - } - static if(is(T == string)) - { - case JSONType.string: result = cast(T)value.str; break; - } - default: assert(false, "Unable to retrieve value"); - } - } - - return result; - } - - MSDFInfo result = { - distance_field_range: GetJSONValue!(u32)(jsonv["atlas"], "distanceRange"), - distance_field_range_middle: GetJSONValue!(u32)(jsonv["atlas"], "distanceRangeMiddle"), - pixels_per_em: GetJSONValue!(f32)(jsonv["atlas"], "size"), - texture_width: GetJSONValue!(u32)(jsonv["atlas"], "width"), - texture_height: GetJSONValue!(u32)(jsonv["atlas"], "height"), - line_height: GetJSONValue!(f32)(jsonv["metrics"], "lineHeight"), - ascender: GetJSONValue!(f32)(jsonv["metrics"], "ascender"), - descender: GetJSONValue!(f32)(jsonv["metrics"], "descender"), - underline_y: GetJSONValue!(f32)(jsonv["metrics"], "underlineY"), - underline_thickness: GetJSONValue!(f32)(jsonv["metrics"], "underlineThickness"), - }; - - result.aem_range = Vec2( - (result.distance_field_range_middle - result.distance_field_range/2) / result.pixels_per_em, - (result.distance_field_range_middle + result.distance_field_range/2) / result.pixels_per_em - ); - - string type_string = GetJSONValue!(string)(jsonv["atlas"], "type"); - string y_origin_string = GetJSONValue!(string)(jsonv["atlas"], "yOrigin"); - - assert(type_string.length); - assert(y_origin_string.length); - - final switch(type_string) with(MSDFType) - { - case "hardmask": result.type = HardMask; break; - case "softmask": result.type = SoftMask; break; - case "sdf": result.type = SDF; break; - case "psdf": result.type = PSDF; break; - case "msdf": result.type = MSDF; break; - case "mtsdf": result.type = MTSDF; break; - } - - final switch(y_origin_string) with(MSDFYOrigin) - { - case "top": result.y_origin = Top; break; - case "left": result.y_origin = Left; break; - case "right": result.y_origin = Right; break; - case "bottom": result.y_origin = Bottom; break; - } - - MSDFGlyph[] glyphs = new MSDFGlyph[128]; - - JSONValue[] glyph_json = jsonv["glyphs"].array; - - foreach(i; 0 .. glyph_json.length) - { - u64 ch = cast(u64)glyph_json[i]["unicode"].integer; - MSDFGlyph glyph = { glyph: cast(dchar)ch }; - glyph.advance = GetJSONValue!(f32)(glyph_json[i], "advance"); - if("planeBounds" in glyph_json[i]) - { - glyph.plane.left = GetJSONValue!(f32)(glyph_json[i]["planeBounds"], "left"); - glyph.plane.right = GetJSONValue!(f32)(glyph_json[i]["planeBounds"], "right"); - glyph.plane.bottom = GetJSONValue!(f32)(glyph_json[i]["planeBounds"], "bottom"); - glyph.plane.top = GetJSONValue!(f32)(glyph_json[i]["planeBounds"], "top"); - - glyph.atlas.left = GetJSONValue!(f32)(glyph_json[i]["atlasBounds"], "left"); - glyph.atlas.right = GetJSONValue!(f32)(glyph_json[i]["atlasBounds"], "right"); - glyph.atlas.bottom = GetJSONValue!(f32)(glyph_json[i]["atlasBounds"], "bottom"); - glyph.atlas.top = GetJSONValue!(f32)(glyph_json[i]["atlasBounds"], "top"); - } - - glyphs[ch] = glyph; - } - - foreach(i; 0 .. glyphs.length) - { - if(glyphs[i].glyph == 0xFFFF) - { - glyphs[i].glyph = 0; - glyphs[i].plane = MSDFBounds(left: 0.0, right: 0.0, top: 0.0, bottom: 0.0); - glyphs[i].atlas = MSDFBounds(left: 0.0, right: 0.0, top: 0.0, bottom: 0.0); - } - } - - result.glyphs = glyphs; - - return result; -} - enum bool KeyType(T) = (StringType!(T) || is(T == UIKey) || is(T == const(UIKey))); enum bool ItemAndKeyType(T) = (KeyType!(T) || is(T == UIItem*)); @@ -611,12 +420,17 @@ InitUI(Ctx* ctx) version(ENABLE_RENDERER) { - InitRenderer(handles, MB(16), MB(8)); + VulkanBuildInfo build_info = { + platform_handles: handles, + application_name: "ScratchPad", + engine_name: "ScratchPad", + }; - DescLayoutBinding[3] layout_bindings = [ + InitRenderer(build_info, MB(16), MB(8)); + + DescLayoutBinding[2] layout_bindings = [ { binding: 0, descriptorType: DT.Image, descriptorCount: FONT_SIZES, stageFlags: SS.All }, { binding: 1, descriptorType: DT.Sampler, descriptorCount: 1, stageFlags: SS.All }, - { binding: 2, descriptorType: DT.Image, descriptorCount: 1, stageFlags: SS.All }, ]; ctx.desc_set_layout = CreateDescSetLayout(layout_bindings); @@ -655,20 +469,6 @@ InitUI(Ctx* ctx) CreateGraphicsPipeline(&ctx.pipeline, &ui_info); - CreateDescriptor( - &ctx.msdf_texture, - DescInfo( - type: DT.Image, - format: FMT.RGBA_UNORM, - usage: IU.Texture, - w: MSDF_INFO.texture_width, - h: MSDF_INFO.texture_height, - ch: 4, - binding: 2, - ), - cast(u8[])MSDF_ATLAS[12 .. $] - ); - for(u32 i = 0; i < ctx.font_descs.length; i += 1) { CreateDescriptor(&ctx.font_descs[i], DescInfo( @@ -704,7 +504,6 @@ InitUI(Ctx* ctx) { Write(ctx.desc_sets[i], ctx.font_descs); Write(ctx.desc_sets[i], &ctx.sampler); - Write(ctx.desc_sets[i], &ctx.msdf_texture); } SetClearColors([0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 0.0]); @@ -2204,6 +2003,8 @@ DrawText(T, U, V)(Ctx* ctx, T text_param, U col_param, V text_size_param, Rect r AnimateReady(ready, &col); DrawGlyph(rect, g, &x, rect.p0.y, fs.line_height, fs.size, col); + + if(x > rect.p1.x) break; } } else static if(is(U == Vec4)) @@ -2216,6 +2017,8 @@ DrawText(T, U, V)(Ctx* ctx, T text_param, U col_param, V text_size_param, Rect r u8 ch = text[j]; Glyph* g = ch < fs.glyphs.length ? fs.glyphs.ptr + ch : null; DrawGlyph(rect, g, &x, rect.p0.y, fs.line_height, fs.size, hl_char == j ? InvertCol(col) : col); + + if(x > rect.p1.x) break; } } else static assert(false, "invalid input parameter, U must be TokenStyle[] or Vec4"); @@ -2546,8 +2349,6 @@ DrawGlyph(Rect rect, Glyph* glyph, f32* x_pos, f32 y, f32 line_height, u32 size, { if(glyph) { - const(MSDFGlyph)* msdf_glyph = &MSDF_INFO.glyphs[glyph.ch]; - Ctx* ctx = GetCtx(); Vertex* v = null; f32 advance = glyph.advance; @@ -2562,19 +2363,20 @@ DrawGlyph(Rect rect, Glyph* glyph, f32* x_pos, f32 y, f32 line_height, u32 size, } else { - f32 w = glyph.plane_right-glyph.plane_left; - f32 h = glyph.plane_bottom-glyph.plane_top; + f32 w = glyph.plane.right-glyph.plane.left; + f32 h = glyph.plane.bottom-glyph.plane.top; + v = GetVertex(ctx); - f32 y_pos = y + glyph.plane_top; + f32 y_pos = y + glyph.plane.top; // Need to change how the quads are calculated, i had changed it so they were all same height and same top/bottom placement as it was easier to draw rasterized glyphs that way but doesn't work when the SDFs are not generated in a similar way - v.dst_start = Vec2(*x_pos+glyph.plane_left, y_pos); - v.dst_end = Vec2(*x_pos+glyph.plane_left+w, y_pos+h); + v.dst_start = Vec2(*x_pos+glyph.plane.left, y_pos); + v.dst_end = Vec2(*x_pos+glyph.plane.left+w, y_pos+h); v.cols = col; - v.src_start = Vec2(glyph.atlas_left, glyph.atlas_top); // Vec2(msdf_glyph.atlas.left, msdf_glyph.atlas.top); - v.src_end = Vec2(glyph.atlas_right, glyph.atlas_bottom); // Vec2(msdf_glyph.atlas.right, msdf_glyph.atlas.bottom); + v.src_start = Vec2(glyph.atlas.left, glyph.atlas.top); + v.src_end = Vec2(glyph.atlas.right, glyph.atlas.bottom); v.has_texture = true; f32 end_x = *x_pos + advance; diff --git a/src/shaders/gui.frag.glsl b/src/shaders/gui.frag.glsl index 5d6249a..248f36c 100644 --- a/src/shaders/gui.frag.glsl +++ b/src/shaders/gui.frag.glsl @@ -65,20 +65,6 @@ Median(vec3 v) return max(min(v.r, v.g), min(max(v.r, v.g), v.b)); } -float -GetMSDFTexel() -{ - vec2 dx = 0.25 * dFdx(FD.uv); - vec2 dy = 0.25 * dFdy(FD.uv); - float center = Median(texture(MSDFAtlas, FD.uv).rgb); - float s0 = Median(texture(MSDFAtlas, FD.uv - dx - dy).rgb); - float s1 = Median(texture(MSDFAtlas, FD.uv + dx - dy).rgb); - float s2 = Median(texture(MSDFAtlas, FD.uv - dx + dy).rgb); - float s3 = Median(texture(MSDFAtlas, FD.uv + dx + dy).rgb); - - return mix(center, 0.25 * (s0+s1+s2+s3), 0.0); -} - vec2 Square(vec2 x) { @@ -126,17 +112,7 @@ void main() vec4 tex_color = vec4(1.0); // ToLinear(FD.color); if(FDF.has_texture != 0) { - // old: tex_color = texture(SpriteAtlas, FD.uv); - - /* - float sd = Median(texture(MSDFAtlas, FD.uv).rgb); - float px_range = ScreenPxRange(); - float screen_px_dist = ScreenPxRange() * (sd-0.5); - float opacity = clamp(0.5 + screen_px_dist/fwidth(screen_px_dist), 0.0, 1.0); - - color.a *= opacity; - */ } vec4 color = FD.color * tex_color; diff --git a/src/shaders/gui.layout b/src/shaders/gui.layout index aaa3fbf..7fe78ff 100644 --- a/src/shaders/gui.layout +++ b/src/shaders/gui.layout @@ -4,7 +4,6 @@ layout(rgba16f, set = 0, binding = 0) uniform image2D DrawImage; layout(set = 1, binding = 0) uniform texture2D SpriteAtlasArray[24]; layout(set = 1, binding = 1) uniform sampler SamplerNearest; -layout(set = 1, binding = 2) uniform texture2D MSDFAtlasTexture; layout (push_constant) uniform Constants { mat4 projection; @@ -17,7 +16,6 @@ layout (push_constant) uniform Constants { } PC; #define SpriteAtlas sampler2D(SpriteAtlasArray[PC.atlas_index], SamplerNearest) -#define MSDFAtlas sampler2D(MSDFAtlasTexture, SamplerNearest) #ifdef VERT_SHADER # define FragData out struct FragDataOut