From 2da7af7431f651928591dbcb075da4786811e711 Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 24 Aug 2025 16:28:45 +1000 Subject: [PATCH] start on gui --- assets/gui.frag.spv | Bin 1336 -> 3476 bytes assets/gui.vert.spv | Bin 4148 -> 5432 bytes dub.json | 1 + src/VulkanRenderer | 2 +- src/dlib | 2 +- src/editor/editor.d | 64 +++++++++++++++++++++++++++++++------- src/shaders/gui.frag.glsl | 37 ++++++++++++++++++++-- src/shaders/gui.layout | 2 +- src/shaders/gui.vert.glsl | 48 +++++++++++++++++++--------- 9 files changed, 123 insertions(+), 33 deletions(-) diff --git a/assets/gui.frag.spv b/assets/gui.frag.spv index 6568e895a26c3e79b62465136be2dc434b782bd0..95359538c376ca449c771f26534ad40b05fb942a 100644 GIT binary patch literal 3476 zcmZveX?GMw6o!jrW)jE(h-^V)5*9%)N@R~LA-hC~83e?oX{LLUhDrC>-4ixH=<)c~ zU*-?;iyq&nr;0Q=R?f}c-h1oTt=n~`x951DsqQiZX2|?vx@*7bF}o!0G5w~#`oO!h zwC2T0>}BDmALmiSi{fS?|A46#xW$$F%4C)YlNT<2PKE)+Jruv2#C01oITt?dtgog~ zoHxy|=>=BA?iIQs8QS!t82c&Fk0M``iC&1_i1sNCTwg&ob5H!_)>L!s?LQ+#uc|lZ zFCCzw`W9Eb`A7G?fbG3@cmIk`Ci~*Ody6acUZdUiviwym^jc9IdO?(ijXc^4iSIAr zqPWrO1Z6-~h;rRk<=v~j*OE>ggu$Bf)aMqaPH#1*rX4lUPn)W091yOZWRfdpP;w)T z^Ds4qJ|sPhUaNwxJ}jR4LDW$*s`{J2pEUD0%xF(xJ0ZT1`s;Ik?k}s0HCeH-8c8cr zYS}7R?g z@gT}_r(c)Q_EUe;`e%0NO8Jg|{vEw)mZfJw(`)*ToMv(lk7dilm!9h{Hs-djIm^SD zyybJhwPKFz{${%srguX>4XFxjBy7@AkL~?n<3hQ|*^-ULjmrU_-qnq zxxPqZxHoL9cA7k6h7-*Jv&OfxI%~|L`ogz03P=l`ddCZGTW7wQ5&XXOmv#Is{On!M zN3G?2=-c?-qDJOzNwKb8=4Q#BNn-JR@7rNJjzjB!zHZ{jbuMNU`H&>$YfN-ld6_A6 zd}Gp?r|z54)puJR%(y&z#F4={0&`Ze*hfSxa#II3zJpPH#V5qEx%`fUDHC;^l#Mvso&H( zEg}YTm@g%BC+vAcoSMNp|9#1vAOCmOM-Psg-R667>LaGSoKDOS)&Z72pfiW85moDn zgL{HO3mx1OabLtbrc*S;$>Hka+h8B3KafT>>zIh9sj-U6>>C80mUs<2oq0g0c;^%kh%O#yVf4oDFtUjYE&q)46bV|hhURTZC zneEzd=tR_iw&eR%GPXYy5B4(=HsE)bYR#gN2yDVZ)Fr0(FW8>U>D>p@)o9~V~h`A-g4xW2Jclg_q!CwSmp)4%k!1w z36Z;xJCf-ec86J!Ox&Q&|FvZL#vO1M#DH=4cULlf2FISv6gJn3Rmq&E+`Dh2V|SP} ziz)Z3E*o}-`PO21r(91TNX9;>uct@+k?5g_difp6KI8#M4DZTMBHkr*-k_%|ko*Z4o{G(_(&>3=TW{^37s%IdjR_@MYrY|ENP(M7&AlWPVtCM3;r@7au6e zgC%*$%DcsfMZ97A#M!S;e7}fTr@tqec;*HF0TGz4onM*8yf5O;DkA(Y_Ml|;bFqgc zgT)Sp+7FAU!+py~tPT5bcF&`diN)t|$0Re)5bq9kd?2EZ(;{NP3~Cql`A~%Kwg{Zt We^fI2yYJy6$zZYntKOi~>;C{RuQ4A0 literal 1336 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 literal 4148 zcmZXVX?Ijb5Qc9^CQ(paaY4l-h#QDIt}KCQM5BpDQE?f^$u*7+lQ?sO0XI-K7u;7| z|A~LVALJL$@p)#tIM=Z`FIDwcRabT2>dD}$jU!oQAX}52pZ$^b)Yyeex2Xaj| z+_k5s=cc!IiutW~-F=&pYqLQ`*LOj7aaSMW{{yu~OXEDS9&7+Nf}6p;U^kcq1vm&! zfYac2Fv!1E$iHY{C|jLPO;@L8W~Qbes@9j5s-5CcGp{xqt-LzlXy^5!aWFUToKjq) zRc|iOmjfz9l>4e=m2PkQ@^;av=N-zyRI9S$OYJ+bqhqWXHR`C4q^zMj3&s_M#H^SxN_B5|Ff*7hohtYluS zf%Uvq(w93p2J=~XfKtF7PE)jwS~!AQJYyVxP=}Eoz)kci~5H-gVLE==7XE(fg=wU zW~e(0^h8?kJjdWU=WO2Y9o4vD{>i)aEp{43W3dH0(&equ5bS#&mC_WUVw&tl8W!lCh8axSKTh{5h0&+h5PJI|Bt+S_{% z)D|45DdL@{G2jY&9NoUPeJlFQwtkm>XUUlGJ4f0s{m#Z3Ag}GW*YEkX{qEY{g|^?J zobP+o9_soByLW2rBb+Yo-Ths`*^8VqICJEz8=Sga?ENWv?5*zF*c08}yuYzNdpy~f zkZJB172H?-GPGgjD7c&|BS>w1>#)y3jsn-_WS@&}KUeerYNR=GquBOpzWf8p_BTz= zeC7Ed%Z~gR_S&Aka|`$7UKapkyUDu-LqVVv>*8^IpGyZ`!~M4!Zzp1RZp?)KmlEf9cq{pwu?^V%4$8Tw`TmYL zzw*}CE)u7I8QuNO(XZ_rmD9h1G+%$*?_u=tA5DJiIpZH8?bRMPpdCX-kNSlB9!I*b ze(P$VNSywY=?}cj{Z_haI+~qm`hN&Qp^)2|f-hQ>6!Rz~M{|=Y^+xqN@KHI;W<#_*QhV2YJ zm+T#M<8O%XcssRy7gvGx$@UFh3w%HO=y()428@xPPdOVCzd(#{`Z^#t4y@t%IAir$$N7?rI*+24>pX^S zo#=BK-5B|(^Ei5cohRUo)n^^&R?a%!>nteW>yy~tt9*)P`H{j%B?>ErRlaIVN(fjvq z!pTR>ffQ5jy9Fm7doQA!CqK*UUyWP>uK>?vZDaf{{%+~>e&0gA4Gse9tsoD90*nLW zwT&^}d3p!LJZ(aM7r3XqF(b(LfV}oPU+!xlzZOIv z-=Nz^`TKl}EgyY+hi)J8(Z~1b(MLJ=2Y7wa$B*dd%SRtSq08Hc-`nr_Gq68>XF&A0 Ug8mCQ0pgo#8~+b~k?#fn0%3_?YXATM diff --git a/dub.json b/dub.json index 118cea4..affcfd2 100644 --- a/dub.json +++ b/dub.json @@ -13,6 +13,7 @@ "sourcePaths": ["src/editor", "src/dlib", "src/dlib/external/xxhash", "src/VulkanRenderer"], "libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++", "xcb-xfixes", "freetype"], "libs-windows": [], + "versions": ["VK_DEBUG_PRINTF"], "preGenerateCommands-linux": ["./build.sh"], "preGenerateCommands-windows": [], "dflags": ["-Xcc=-mno-sse", "-P-I/usr/include/freetype2", "-Jbuild"], diff --git a/src/VulkanRenderer b/src/VulkanRenderer index f3b7536..b0d96f2 160000 --- a/src/VulkanRenderer +++ b/src/VulkanRenderer @@ -1 +1 @@ -Subproject commit f3b7536c8e4edea80d3b7ef3e4265e521a050c03 +Subproject commit b0d96f26fe727d297c441ce989f3fec45095e3c3 diff --git a/src/dlib b/src/dlib index 98701be..f8d1707 160000 --- a/src/dlib +++ b/src/dlib @@ -1 +1 @@ -Subproject commit 98701be20c223d1130a1f423c8ca3b520c9d4a95 +Subproject commit f8d1707450d92bd147a3283527043c86312b3872 diff --git a/src/editor/editor.d b/src/editor/editor.d index 43a8100..c80d801 100644 --- a/src/editor/editor.d +++ b/src/editor/editor.d @@ -41,20 +41,26 @@ struct Editor u8[] font_data; FontFace font; FontAtlasBuf atlas_buf; + + UVec2 res; } struct PushConst { - Vec2 res; + Mat4 projection; } struct Vertex { + Vec4 col; Vec2 dst_start; Vec2 dst_end; Vec2 src_start; Vec2 src_end; - Vec4 col; + f32 border_thickness; + f32 corner_radius; + f32 edge_softness; + f32 raised; } void @@ -68,11 +74,18 @@ Cycle(Editor* ed) f32 h = ed.atlas_buf.atlas.size; DrawBuffer(ed, 0.0, 0.0, h, ed.active_buffer); + //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)); + BeginFrame(&ed.rd); UVec2 ext = UVec2(GetExtent(&ed.rd)); - ed.pc.res.x = cast(f32)ext.x; - ed.pc.res.y = cast(f32)ext.y; + if (ext != ed.res) + { + ed.res = ext; + Ortho(&ed.pc.projection, 0.0, 0.0, cast(f32)(ext.x), cast(f32)(ext.y), 1000.0, 0.1); + } BeginRendering(&ed.rd); @@ -169,12 +182,16 @@ 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[5] attributes = [ - { binding: 0, location: 0, format: FMT.RG_F32, offset: Vertex.dst_start.offsetof }, - { binding: 0, location: 1, format: FMT.RG_F32, offset: Vertex.dst_end.offsetof }, - { binding: 0, location: 2, format: FMT.RG_F32, offset: Vertex.src_start.offsetof }, - { binding: 0, location: 3, format: FMT.RG_F32, offset: Vertex.src_end.offsetof }, - { binding: 0, location: 4, format: FMT.RGBA_F32, offset: Vertex.col.offsetof }, + 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 }, ]; GfxPipelineInfo ui_info = { @@ -184,6 +201,12 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name) input_rate_stride: Vertex.sizeof, layout: editor.pipeline_layout, vertex_attributes: attributes, + src_color: BF.SrcAlpha, + dst_color: BF.OneMinusSrcAlpha, + color_op: BO.Add, + src_alpha: BF.One, + dst_alpha: BF.Zero, + alpha_op: BO.Add, }; assert(CreateGraphicsPipeline(&editor.rd, &editor.pipeline, &ui_info), "Unable to build UI pipeline"); @@ -319,9 +342,9 @@ DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec f32 y_pos = glyph.plane_top * scale; v.dst_start.x = *x_pos + l; - v.dst_start.y = y + h - y_pos; + v.dst_start.y = y - y_pos; v.dst_end.x = *x_pos + w + l; - v.dst_end.y = y - y_pos; + v.dst_end.y = y + h - y_pos; v.src_start.x = glyph.atlas_left; v.src_start.y = glyph.atlas_top; @@ -336,6 +359,23 @@ DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec *x_pos += glyph.advance * scale; } +void +DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, Vec4 col) +{ + // Y reversed + Vertex* v = ed.vertices.ptr + ed.ui_count; + v.dst_start.x = p0_x; + v.dst_start.y = p0_y; + v.dst_end.x = p1_x; + v.dst_end.y = p1_y; + v.col = col; + v.border_thickness = border; + v.corner_radius = corner; + v.edge_softness = softness; + + AddUIIndices(ed); +} + void AddUIIndices(Editor* ed) { diff --git a/src/shaders/gui.frag.glsl b/src/shaders/gui.frag.glsl index 60666e9..49ef7bd 100644 --- a/src/shaders/gui.frag.glsl +++ b/src/shaders/gui.frag.glsl @@ -1,18 +1,49 @@ #version 460 #extension GL_GOOGLE_include_directive : require +#extension GL_EXT_debug_printf : require #include "gui.layout" layout (location = 0) in struct FragDataIn { vec4 color; vec2 uv; -} FragData; + vec2 dst_pos; + vec2 dst_center; + vec2 dst_half_size; + float corner_radius; + float softness; + float raised; + float border_thickness; +} FD; layout (location = 0) out vec4 FragColor; +float RoundedRectSDF(vec2 pos, vec2 center, vec2 half_size, float radius) +{ + vec2 dist = (abs(center - pos) - half_size + vec2(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) +{ + return length(max(abs(pos - center) - size + radius, 0.0)) - radius; +} + void main() { - vec4 tex_color = texture(sampler2D(SpriteAtlas, SamplerNearest), FragData.uv); - FragColor = FragData.color * tex_color; + 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 sdf_factor = 1.0 - smoothstep(0, 2*softness, dist); + + debugPrintfEXT("%v2f %v2f %v2f", FD.dst_pos, FD.dst_center, FD.dst_half_size); + + vec4 tex_color = texture(sampler2D(SpriteAtlas, SamplerNearest), FD.uv); + vec4 out_color = FD.color * tex_color * sdf_factor; + + FragColor = out_color; } diff --git a/src/shaders/gui.layout b/src/shaders/gui.layout index 543f030..cb24155 100644 --- a/src/shaders/gui.layout +++ b/src/shaders/gui.layout @@ -5,5 +5,5 @@ layout (set = 0, binding = 1) uniform sampler SamplerNearest; layout (set = 1, binding = 0) uniform texture2D SpriteAtlas; layout (push_constant) uniform Constants { - vec2 res; + mat4 projection; } PC; diff --git a/src/shaders/gui.vert.glsl b/src/shaders/gui.vert.glsl index ea2b1bc..dfb7c43 100644 --- a/src/shaders/gui.vert.glsl +++ b/src/shaders/gui.vert.glsl @@ -4,22 +4,33 @@ #include "gui.layout" -layout (location = 0) in vec2 in_dst_start; -layout (location = 1) in vec2 in_dst_end; -layout (location = 2) in vec2 in_src_start; -layout (location = 3) in vec2 in_src_end; -layout (location = 4) in vec4 in_col; +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) out struct FragDataOut { vec4 color; vec2 uv; + vec2 dst_pos; + vec2 dst_center; + vec2 dst_half_size; + float corner_radius; + float softness; + float raised; + float border_thickness; } FragData; vec2 Vertices[4] = vec2[4]( - vec2(-1.0, +1.0), vec2(-1.0, -1.0), - vec2(+1.0, +1.0), - vec2(+1.0, -1.0) + vec2(-1.0, +1.0), + vec2(+1.0, -1.0), + vec2(+1.0, +1.0) ); vec2 rotate(vec2 coords, float theta) @@ -31,9 +42,12 @@ void main() { ivec2 tex_size = textureSize(sampler2D(SpriteAtlas, SamplerNearest), 0); - vec2 dst_half_size = (in_dst_end - in_dst_start) / 2; - vec2 dst_center = (in_dst_end + in_dst_start) / 2; - vec2 dst_pos = (Vertices[gl_VertexIndex] * dst_half_size + dst_center); + 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); + + vec2 half_size = ((pos_end.xy - pos_start.xy) / 2); + vec2 center = ((pos_end.xy + pos_start.xy) / 2); + vec2 pos = (Vertices[gl_VertexIndex] * half_size + center); vec2 src_half_size = (in_src_end - in_src_start) / 2; vec2 src_center = (in_src_end + in_src_start) / 2; @@ -48,9 +62,13 @@ void main() FragData.color = in_col; FragData.uv = uvs[gl_VertexIndex] / tex_size; + FragData.dst_pos = pos; + FragData.dst_center = center; + FragData.dst_half_size = half_size; + FragData.corner_radius = corner_radius; + FragData.softness = edge_softness; + FragData.raised = raised; + FragData.border_thickness = border_thickness; - gl_Position = vec4(2 * dst_pos.x / PC.res.x - 1, - 2 * dst_pos.y / PC.res.y - 1, - 0, - 1); + gl_Position = vec4(pos.x, pos.y, 0, 1); }