From 19c28de4fdb27f23ce346fef8e999c844ffd4c31 Mon Sep 17 00:00:00 2001 From: Matthew Date: Mon, 25 Aug 2025 06:07:55 +1000 Subject: [PATCH] gui shader set up --- .ignore | 1 + assets/gui.frag.spv | Bin 3500 -> 5084 bytes assets/gui.vert.spv | Bin 5432 -> 5932 bytes dub.json | 2 +- src/VulkanRenderer | 2 +- src/dlib | 2 +- src/editor/editor.d | 53 ++++++++++++++++++++++++-------------- src/shaders/gui.frag.glsl | 36 +++++++++++++++++++++----- src/shaders/gui.vert.glsl | 37 ++++++++++++++++---------- 9 files changed, 91 insertions(+), 42 deletions(-) diff --git a/.ignore b/.ignore index a6ae5ac..578b033 100644 --- a/.ignore +++ b/.ignore @@ -2,3 +2,4 @@ src/VulkanRenderer/vma src/DLibs/external build +assets diff --git a/assets/gui.frag.spv b/assets/gui.frag.spv index 2c93105a3ff1967779ceb25ce64e55dcfe1ae00d..7bf5ca360217fcff7ec5fe9a1c32339ee0862be9 100644 GIT binary patch literal 5084 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 jF>nU73hTTt!N|bz_&+)uY|i>$;Vm<9 diff --git a/assets/gui.vert.spv b/assets/gui.vert.spv index b52986e2e600f122f3498f161d81efdd45ca095b..a8a2e3551a985f65a1b215ee8820e59a80c52e30 100644 GIT binary patch literal 5932 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 PFU&!%|3CZ+Uk&~XA?rZI literal 5432 zcmZvd`@2+S6~{MlW{v?$CJ0`l!y%-?C`pVW5#n;7j-FGept2f=nayEvn3?v>L9iQU zmR%Kz?50_kC7G0zcJtEJe&`SCm!7B3XU|@`o2PxA?^$bo*Y|zj^ul4>4LP0vkl?hl%qZ`}HJm6s(;G`cQg8;G1?Ry9a1lHQo(C_3CHyVM{)>XflBLPibZu&8W@>tGtD#>c> zAU#>@x9+yooO3>Ny{t7zcMaP0K3p}Q-(3B8ubpPMrS&ZB4~E)}XnWm0Rn{}8y#1T8 zySp8z&cK1H{K@(CvhFeG&}H>1%-c1a-K}5E*RIv6HT#2Cx`Q7}w%d*|(oQq)-}NnY zQaQH|?r6PzBqn0J8MsE;8Kl{8tV6?o^0C~X`F73aNKYQN!7 z$(W{!F{}CB7Fdn?d z?3?{nLBD%s&`JCGxrwpI;j?v~{@#(%Iy@T};M3-OS}PS|`-|{VLxp*Ium1n|)#Q)l*z?&m8*V!xJr8+(bKQO` zKb)?Mde=MWTb;pNaYrKO+LPPeZuR!GJnfB?-iGbm19J=Q_A5E}-8=8+dU*HuWc9la z9IwxN`KFkUcW)i=i+B>>I*fg1%$H;HepB@CJ+rR;XyeYgxBD3{V)yN}BiwpoKgaM5 zbDS8%`(|vv=Dj=1z*~yAfi>^>GVffBT?1qH-Pq6gEVdlG=f<8h^X|2=bsD?J#-1%> z_t@BZIcN82IOj_46Xx}4opH*XN9DIMf+?M*OZ}PbRST z;d)rpB=ED&4Or`N5A5qYtaZw-A%0Wgn_o*`-Xl4+-U0VY&iafu6`c9&3qSO4BVGjT zU%j#SO)k#E4fuYx--0z~eUaZ^I7ns=_w>0uE0NAbaf4+6){IkTq8PVRi&%AHNAFz()d030*JLlZx%n8@+Pgv_R zZ$HNV4#}B+0c#Dm^IrbF@Exc8xlVDH|4}5=+Nbf$1$PrGq|SBobDV#}#Jc$otOhaf z>+m;@#M?{pUi^I{@ytkkXe2&75+56hd!^Vjd#Z?cP_6H)Z`{qyU=8*f;G1LY`|<|h z+j5W@O<>mnHS*1(&H93$N8@|AuKCo$tXPt@CC$ z`KaL*eBYpQojZx;L$eECO}WnZ=J{9a+)ca_$dA^!2hMTTSf}S@$PM4~DPp-9=IlA! z59EZOXWR90&IiCo5Zd<@oV=gfds!d*c|Wi(HM0eGE52{4xWC|T!&ht0`aHjKG3G3O zxxNn&%L%`7eIFz)*EdHjC;ZgjQ;ho|eEU)p^?ewBw7!FIYRy@n_eswBR$@N}{2g$= zZpVHcEC=#xT#HWt`G`M>?>z4-YN_F?kq^xs_>L9z*74Qd0j$G&EEoDFexnp0!B0W# z$2`6o`Izrf{L%Tg;MAIPoWoeT80Sv>@;Gf`$B8;<8zWZSFZigXPb?qt0N;9JT^I1x$cN?xzGFqbcj2p(w~iiG&i&kiy&E{c@*Vwj z!H4EEg=Q<(ajMwQ0{K{j&*9rnKH7aAf3)w@aPpzK2jBHB_x%N8`RMyz{L?@_+I<)iQW@ogs`?Y@FP+V@xCu~bX_c!ouC-0lP z6#Gr!S~(}jR^z^$!kTk^H(RkmV!s38JnhB*F0fDeI2+$9 zc;i+0-v_Hfmv|iegMy2<>k(qx$Xmyw*dGGxcoX|2e+;CxCimHR`L_Ux4#K{ZrUq0`*S<^~P#K|110p zAoRb+SN}9nZ>%Qtzrnu{Gx0F{{<^9{y6{u diff --git a/dub.json b/dub.json index affcfd2..32ef420 100644 --- a/dub.json +++ b/dub.json @@ -16,7 +16,7 @@ "versions": ["VK_DEBUG_PRINTF"], "preGenerateCommands-linux": ["./build.sh"], "preGenerateCommands-windows": [], - "dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-Jbuild"], + "dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-Jbuild", "-Jassets"], "dflags-dmd": ["-P=-DSTBI_NO_SIMD"] }, ] diff --git a/src/VulkanRenderer b/src/VulkanRenderer index e5f4777..5c2a3ab 160000 --- a/src/VulkanRenderer +++ b/src/VulkanRenderer @@ -1 +1 @@ -Subproject commit e5f47772a5d879f3cd5848108761271876bbef0e +Subproject commit 5c2a3ab5efa1aaa15ca6f3144655550dd024823a diff --git a/src/dlib b/src/dlib index f8d1707..f211a29 160000 --- a/src/dlib +++ b/src/dlib @@ -1 +1 @@ -Subproject commit f8d1707450d92bd147a3283527043c86312b3872 +Subproject commit f211a29857111a6be26b9cb0e9799ffcb7631df6 diff --git a/src/editor/editor.d b/src/editor/editor.d index c80d801..130a45f 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -10,6 +10,10 @@ import buffer; import std.stdio; import std.exception; +const u8[] FONT_BYTES = import("pc-9800.ttf"); +const u8[] VERTEX_BYTES = import("gui.vert.spv"); +const u8[] FRAGMENT_BYTES = import("gui.frag.spv"); + const UI_COUNT = 50000; struct Editor @@ -52,7 +56,7 @@ struct PushConst struct Vertex { - Vec4 col; + Vec4[4] cols; Vec2 dst_start; Vec2 dst_end; Vec2 src_start; @@ -76,7 +80,8 @@ Cycle(Editor* ed) //DrawRect(ed, 200.0, 200.0, 300.0, 300.0, 0.0, 0.0, 0.0, Vec4(0.2, 0.4, 0.8, 1.0)); //DrawRect(ed, 330.0, 330.0, 430.0, 430.0, 0.0, 0.0, 0.0, Vec4(0.2, 0.4, 0.8, 1.0)); - DrawRect(ed, 450.0, 450.0, 550.0, 550.0, 0.0, 1.0, 0.0, Vec4(1.0)); + DrawRect(ed, 450.0, 450.0, 550.0, 550.0, 0.0, 5.0, 1.0, 20.0, [Vec4(0.2, 0.5, 0.9, 1.0), Vec4(Vec3(0.8), 1.0), Vec4(Vec3(0.8), 1.0), Vec4(Vec3(0.6), 1.0)]); + DrawRect(ed, 450.0, 450.0, 550.0, 550.0, 2.0, 5.0, 1.0, 20.0, [Vec4(Vec3(0.0), 1.0), Vec4(Vec3(0.0), 1.0), Vec4(Vec3(0.0), 1.0), Vec4(Vec3(0.0), 1.0)]); BeginFrame(&ed.rd); @@ -142,8 +147,7 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name) Arena arena = CreateArena(MB(32)); - u8[] font_data = LoadFile(&arena, "assets/pc-9800.ttf"); - FontFace font = OpenFont(font_data); + FontFace font = OpenFont(cast(u8[])FONT_BYTES); FontAtlasBuf atlas_buf = CreateAtlas(&arena, font, 14.0, 256); Editor editor = { @@ -151,7 +155,7 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name) arena: arena, temp_arena: CreateArena(MB(8)), rd: InitRenderer(handles, MB(32), MB(16)), - font_data: font_data, + font_data: cast(u8[])FONT_BYTES, font: font, atlas_buf: atlas_buf, buffers: MAllocArray!(FlatBuffer)(32), @@ -182,21 +186,24 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name) editor.desc_set = AllocDescSet(&editor.rd, editor.desc_set_layout); editor.pipeline_layout = CreatePipelineLayout(&editor.rd, editor.desc_set_layout, PushConst.sizeof); - Attribute[9] attributes = [ - { binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.col.offsetof }, - { binding: 0, location: 1, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, - { binding: 0, location: 2, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, - { binding: 0, location: 3, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, - { binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, - { binding: 0, location: 5, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof }, - { binding: 0, location: 6, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof }, - { binding: 0, location: 7, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof }, - { binding: 0, location: 8, format: FMT.R_F32, offset: Vertex.raised.offsetof }, + Attribute[12] attributes = [ + { binding: 0, location: 0, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 0}, + { binding: 0, location: 1, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 1}, + { binding: 0, location: 2, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 2}, + { binding: 0, location: 3, format: FMT.RGBA_F32, offset: Vertex.cols.offsetof + Vec4.sizeof * 3}, + { binding: 0, location: 4, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, + { binding: 0, location: 5, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, + { binding: 0, location: 6, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, + { binding: 0, location: 7, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, + { binding: 0, location: 8, format: FMT.R_F32, offset: Vertex.border_thickness.offsetof }, + { binding: 0, location: 9, format: FMT.R_F32, offset: Vertex.corner_radius.offsetof }, + { binding: 0, location: 10, format: FMT.R_F32, offset: Vertex.edge_softness.offsetof }, + { binding: 0, location: 11, format: FMT.R_F32, offset: Vertex.raised.offsetof }, ]; GfxPipelineInfo ui_info = { - vertex_shader: LoadFile(&editor.temp_arena, "assets/gui.vert.spv"), - frag_shader: LoadFile(&editor.temp_arena, "assets/gui.frag.spv"), + vertex_shader: cast(u8[])VERTEX_BYTES, + frag_shader: cast(u8[])FRAGMENT_BYTES, input_rate: IR.Instance, input_rate_stride: Vertex.sizeof, layout: editor.pipeline_layout, @@ -220,6 +227,8 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name) Write(&editor.rd, editor.desc_set, &editor.font_atlas, 0, DT.Image); + SetClearColors(&editor.rd, [0.149, 0.607, 0.768, 1.0], [0.0, 0.0, 0.0, 0.0]); + Reset(&editor.temp_arena); return editor; @@ -351,7 +360,10 @@ DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec v.src_end.x = glyph.atlas_right; v.src_end.y = glyph.atlas_bottom; - v.col = col; + v.cols[0] = col; + v.cols[1] = col; + v.cols[2] = col; + v.cols[3] = col; AddUIIndices(ed); } @@ -360,7 +372,7 @@ DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec } void -DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, Vec4 col) +DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, f32 raised, Vec4[4] cols) { // Y reversed Vertex* v = ed.vertices.ptr + ed.ui_count; @@ -368,10 +380,11 @@ DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 cor v.dst_start.y = p0_y; v.dst_end.x = p1_x; v.dst_end.y = p1_y; - v.col = col; + v.cols = cols; v.border_thickness = border; v.corner_radius = corner; v.edge_softness = softness; + v.raised = raised; AddUIIndices(ed); } diff --git a/src/shaders/gui.frag.glsl b/src/shaders/gui.frag.glsl index 1637234..d86d166 100644 --- a/src/shaders/gui.frag.glsl +++ b/src/shaders/gui.frag.glsl @@ -25,9 +25,19 @@ float RoundedRectSDF(vec2 pos, vec2 center, vec2 half_size, float radius) return min(max(dist.x, dist.y), 0.0) + length(max(dist, 0.0)) - radius; } -float RoundedRectSDF2(vec2 pos, vec2 center, vec2 size, float radius) +float ToSRGB(float col) { - return length(max(abs(pos - center) - size + radius, 0.0)) - radius; + return pow(col, 1.0/2.2); +} + +vec4 ToSRGB(vec4 col) +{ + return vec4(ToSRGB(col.r), ToSRGB(col.g), ToSRGB(col.b), col.a); +} + +vec4 ToLinear(vec4 col) +{ + return pow(col, vec4(vec3(2.2), 1.0)); } void main() @@ -35,15 +45,29 @@ void main() float softness = FD.softness; vec2 softness_padding = vec2(max(0, softness*2-1), max(0, softness*2-1)); - //float dist = RoundedRectSDF(FD.dst_pos, FD.dst_center, FD.dst_half_size-softness_padding, FD.corner_radius); - float dist = RoundedRectSDF2(FD.dst_pos, FD.dst_center, vec2(1.0), FD.corner_radius); + float dist = RoundedRectSDF(FD.dst_pos, FD.dst_center, FD.dst_half_size-softness_padding, FD.corner_radius); + //float dist = RoundedRectSDF2(FD.dst_pos, FD.dst_center, vec2(1.0), FD.corner_radius); float sdf_factor = 1.0 - smoothstep(0, 2*softness, dist); - debugPrintfEXT("%v2f %v2f %v2f %f", FD.dst_pos, FD.dst_center, FD.dst_half_size, sdf_factor); + float border_factor = 1.0; + if (FD.border_thickness != 0.0) + { + vec2 interior_half_size = FD.dst_half_size - vec2(FD.border_thickness); + + float interior_radius_reduce_f = min(interior_half_size.x/FD.dst_half_size.x, interior_half_size.y/FD.dst_half_size.y); + + float interior_corner_radius = FD.corner_radius * interior_radius_reduce_f * interior_radius_reduce_f; + + float inside_d = RoundedRectSDF(FD.dst_pos, FD.dst_center, interior_half_size-softness_padding, interior_corner_radius); + + float inside_f = smoothstep(0, 2*softness, inside_d); + border_factor = inside_f; + } vec4 tex_color = texture(sampler2D(SpriteAtlas, SamplerNearest), FD.uv); - vec4 out_color = FD.color * tex_color * sdf_factor; + debugPrintfEXT("tex_color %v4f", tex_color); + vec4 out_color = FD.color * tex_color * sdf_factor * border_factor; FragColor = out_color; } diff --git a/src/shaders/gui.vert.glsl b/src/shaders/gui.vert.glsl index dfb7c43..5d76729 100644 --- a/src/shaders/gui.vert.glsl +++ b/src/shaders/gui.vert.glsl @@ -4,15 +4,18 @@ #include "gui.layout" -layout (location = 0) in vec4 in_col; -layout (location = 1) in vec2 in_dst_start; -layout (location = 2) in vec2 in_dst_end; -layout (location = 3) in vec2 in_src_start; -layout (location = 4) in vec2 in_src_end; -layout (location = 5) in float border_thickness; -layout (location = 6) in float corner_radius; -layout (location = 7) in float edge_softness; -layout (location = 8) in float raised; +layout (location = 0) in vec4 in_col_1; +layout (location = 1) in vec4 in_col_2; +layout (location = 2) in vec4 in_col_3; +layout (location = 3) in vec4 in_col_4; +layout (location = 4) in vec2 in_dst_start; +layout (location = 5) in vec2 in_dst_end; +layout (location = 6) in vec2 in_src_start; +layout (location = 7) in vec2 in_src_end; +layout (location = 8) in float border_thickness; +layout (location = 9) in float corner_radius; +layout (location = 10) in float edge_softness; +layout (location = 11) in float raised; layout (location = 0) out struct FragDataOut { vec4 color; @@ -42,8 +45,8 @@ void main() { ivec2 tex_size = textureSize(sampler2D(SpriteAtlas, SamplerNearest), 0); - vec4 pos_start = PC.projection * vec4(in_dst_start.x, in_dst_start.y, 0.0, 1.0); - vec4 pos_end = PC.projection * vec4(in_dst_end.x, in_dst_end.y, 0.0, 1.0); + vec4 pos_start = vec4(in_dst_start.x, in_dst_start.y - raised, 0.0, 1.0); + vec4 pos_end = vec4(in_dst_end.x, in_dst_end.y, 0.0, 1.0); vec2 half_size = ((pos_end.xy - pos_start.xy) / 2); vec2 center = ((pos_end.xy + pos_start.xy) / 2); @@ -60,7 +63,14 @@ void main() vec2(in_src_end.x, in_src_end.y) ); - FragData.color = in_col; + vec4 cols[4] = vec4[4]( + in_col_1, + in_col_2, + in_col_3, + in_col_4 + ); + + FragData.color = cols[gl_VertexIndex]; FragData.uv = uvs[gl_VertexIndex] / tex_size; FragData.dst_pos = pos; FragData.dst_center = center; @@ -70,5 +80,6 @@ void main() FragData.raised = raised; FragData.border_thickness = border_thickness; - gl_Position = vec4(pos.x, pos.y, 0, 1); + vec4 v_pos = PC.projection * vec4(pos.x, pos.y, 0, 1); + gl_Position = vec4(v_pos.x, v_pos.y, 0, 1); }