From 01c4abaf1da4288426b5d28beaff9b4b232e69b1 Mon Sep 17 00:00:00 2001 From: matthew Date: Mon, 11 Aug 2025 07:36:25 +1000 Subject: [PATCH] gui shader fixes, start work on text rendering --- assets/fonts/NuberNextCondensed-DemiBold.otf | Bin 0 -> 15180 bytes assets/shaders/gui.frag.spv | Bin 1336 -> 1300 bytes assets/shaders/gui.vert.spv | Bin 3844 -> 3844 bytes assets/textures/FontAtlas.png | Bin 0 -> 2612 bytes assets/textures/atlas.png | Bin 0 -> 15594 bytes build.sh | 17 +- dub.json | 12 +- external/stb/{stb_image.c => stb.c} | 1 - src/codegen/fonts.d | 825 +++++++++++++++++++ src/gears/game.d | 80 +- src/gears/main.d | 10 +- src/gears/vulkan.d | 158 ++-- src/packer/packer.d | 120 ++- src/shaders/gui.frag.glsl | 2 +- src/shaders/gui.vert.glsl | 6 +- src/shared/assets.d | 53 ++ src/shared/includes.c | 1 - src/shared/util.d | 42 + 18 files changed, 1221 insertions(+), 106 deletions(-) create mode 100644 assets/fonts/NuberNextCondensed-DemiBold.otf create mode 100644 assets/textures/FontAtlas.png create mode 100644 assets/textures/atlas.png rename external/stb/{stb_image.c => stb.c} (98%) create mode 100644 src/codegen/fonts.d diff --git a/assets/fonts/NuberNextCondensed-DemiBold.otf b/assets/fonts/NuberNextCondensed-DemiBold.otf new file mode 100644 index 0000000000000000000000000000000000000000..3ab6ad4c5003fb27c2175f8ebd8bee6d59659656 GIT binary patch literal 15180 zcmb_@2YeL8`}geK?QXIgPRMZq6ZS3?1(9B)_ufO3UJ?idNFxaeP1JxILJ|F`ARq+k zh*aqaHa+_E=|TL+ zd&EjwwrSr!_|BDOuM$Ge6XI&yp>4bN!b~BRkSdE&)~iEEkKQxg3$7vmkdRk4b?Du< z^`E1kWDwFYjS$QF9=&VU8JL;6nvh@}?T3$u3XQe;SPRe|Su!~yJalA0`I`zM?y|_g z6@db2k>zu=$9SYtL{!4Wg*E&JqCSKWVMbKw#8?svkdV^|Qgmok_^H&JWe6$XAK5jr zG4Tn;PErT>r=mWX5VQ?NPhztWK@iGypAZ%v*FAh6|6Fo9KIzD_P zuYW@?Mf3)O-q4~qvN3~2|JnY}MWRNC+Ub=;NSs;zJTtx&aRVPwND1Ok%8)>!k=IEL z@)l`HI+0#vAQ?%bNfLONLgtZ$WI0(+z9aj|ags^$$aNt|Xdtv0QzJ5FL}Z^{T}BNX zg}-5Acob=-k(0yYVrq}a+nL{RK4orw1 zQ>#|1ww|O`o0!;1aeVmT!Bs{Kej~U}t=e^i!zKlHj)@LUhzN}i?l>kgGPp)?E5v5I z_~5wk`0%*I@R2p13n{orNWssgR8&IdaRD?WO-N7Dhx8+J$b9lGIYf?SiZuXsp2 zE`Beb7jwm1;*a73@pn;|Y*GoSj8smlC{>ecNe!iTQWq&i8YqQIvC7S< zmru%B@-_J<`B$0BPkpRDK0Xc~mro_1>OODzH1lcW)5)isPj4sPD*b2nXP*VqPH$gi zWm(yt%~&VaDWe(HsO8k&$8%k8YD2UYLzrcrn+=kv<>OVmvVzoL#qJ!Vu;x9Pjis`W zk1~Nab6y`SqO8Ug_Hho0 zTy^Z^#w>n9!2Zi-?sjq>Q;KK5i^zveLiM~;oB7PNV+MYTrG~g5tM(G^%+ZEH~MW9$`;I zXqZH+d751IDPaF^OF`8|c!z1Ey#cti&# zPtY9qTWkAQ$MX7q+Bt5EDXLv0kiwdW*-$cdpv8%B?P* zl|w(xrU^Oz$L`Snw>#fEY%eR}V(l@N;SwrK$ zWvQFl>E~#ey*0XFi*cjdxNFh`w0Ky!+xa^E^bhI#-BH!6g+?@U+w_4 zR2q?%sCUjvPV(QIPn+h`Ci#vl`e*tl&YlCu4~%hdn=)p7$Dkg=#}AEjJNBMvI07s= zwQ1LpuCe1^pjYgXkw#k;6 z41K4VTUfFM{Z?iN3wMew^lG`XI(%AMx|?plajrgf)%#FUyL~DSn>T6ow!l4WmhV?P zYP~wN|9+gNu5GOdTkq2Ox2-fS**Q&d57ZiHF8dpboi?Sn#fn%XYz-?x*8rqV*gdSy zLh+GAU!^-}Alo6T&Yr{KLSxX1`YRWx&3}KsW8(g3t=`io@tR|2MypKT5PFU&8Nd(-p_g;hH0F6o#s%T}`;ktS-Crb%~W{S6DE;BEBZ6nf*1j zC9UlIZt=vhuqjEQp_7(u+q!t^cC4>)anq+xc0ZzT9b^;O2Pfq%ixzF$zGOnDj*}-0 zaycFkoxE_jyPMQ(P595(w{4^rm*f7enB7fW_BD$ZuiY7VcHDQhn-Be5SvSe0UXRXW z<)E4kj?r4@)LyWd0cvfD38`UWjf2z?$$15SNkZCP+Uc&94o@Dg)RaC}Tz0vOraq#P z&a-NUJYwaxgd;(e9KJw9XvcoJjJV?qdpmm!+j+`OYs=?$Y(1L2vM)EqvAx>4)QkGD zJe4ki)^{H|epswq?H;M+>nZglwJ?RR7Bx{%Nm55B`jUFGdc461O&zS*quAg~`bHLg zh{dBGlSeA*;ns=@rPbT0*Yp(Gp6TG)?)#qHCmRI zQKPllPiu5i=$pCD_q3&o>I~P^u8RNi8?A1rPHN9Mb^Djz8{7QH4KDN;qp63JCu-{D z0f}@|CS8{YvO1sWmZct~$1&E~kTbuXaooFwex!vcQn=gmQ;22fi5twwA7`ubhq2_SRI!(NmC1KwVsBk9l}O*b=fP>c^8BebdL1| zo#&);F0eV0eeR^Gv!?_#=pV+_zx~ufExJdqx#Uv!Py2T4VwdW_@>a*IYC$i)jz2jj zEm2g~5!R*6#pI-wNosC^EeUg1(?)9Q`j#wA&7jTF?;QY>sCaU~aTv3v>dBrbsdBQ{ z3ALvps8{x_KLVTBZsz!L-GbDipK8ZwLs4Z7#dJx1vP)*eGMx8l3z4;u?M!hw@|aJ% zeynn;`?jRgrI2N>Vew&Dv!6j`7lm(c(-~ONzMHEZ$hWHWbD)2FSZqJ2N^%}e zPP})X*1RC7!V1l*VzK8JgvjcQbXqZ8h1pqt7jrL>q`DoC3J=&CMr^u=@o9#zjK*4* zL9iX>gCXHeW^z=hIwYG_W`3;)sCubfwnMf%ThOm$RaioQvZ}J5XO8E+N9OM-OXP5*D#7=}|0tw~rStU{#E?Q&KlyruRHW{AqVzPv! z!57{`_Q8X{KyrneLQ7$k5FsQA%Y~i7IpM1Cv&GL+&C=M?*Ai~|$THJ1%QD}x-m<}R z#B$Pd+H%%%)pFh1)H>W6W}Rl8Yu#ZzZM|mw+4_g=HCu1nhqe@3s_lU7npjRu7QYh< zL?#7DiBh_BT)HORfrC|1t}D-w=g1pn!^hXBA{?eZK8Zdb`CRn5>8tt<_Kot5@lE#q z%=Zi51-^@xt4Hq_zO_!hl77Fil9XAv%Bc^h3krur1D4y{EB^?W2C+Un_HiIV1_9V?80$hBjUAAMl{tkUoTXXEKsyKFktT`q(%9ib6N{lv0TQgVV z7}Nl2lh{PPev%^E2hEzPB`Eez+ErBEq>FA^b(q<9+E{IwhE1rV*24t#>GXGJo4+}E zOTU^ucadu^bAG>KAPo?6cdz+_whLrQY=iT)G1+t!9sW(;@4wB`Sm}40j~(G2N_{)V z?O_fvb$W7Ya*%yl+H7uQ=F8e&%-b!fqc|c$v<+bJ=|sJHlCV^dvg+>#unyE{ui1Ca z)#$jpR(*Cs$N**htXzF(?naH4$Ze_F>na~=a6=rsX)KnQV|!)IvAc@mm^>Ox@26GK z?1{-)VTpRDY}z}?|3E$+lJD62x#pPqG~~MM*gI6SFV=*$H)+2cRvMpNU7L_RUg197 z-o}b!YPaiHmX5uw_tR3%HG6ln;h>vV>Pr)XH9PC~zVcC$|IK`ufOiZ0ou7Y^x=d-K zT|d|0n4G?F#ZH&Kp4LNQyVDja!rpxAp7GjH<@}EvJfQD$Uiq=Hl=3vFlhRcima5U% zBms7U<_7#Gv5xd?A{1hYHb=2H(Rym#6akLrNL0rqJIia0lmylxk@n8kRqlnM3UlH< z=mpaUwb%on*V&=?TDpkIgy(x7FMpPSLR29 zDmWVaD$&Y%ifEsr_%A6Sj{f>~-e|#F(22fEr&LXtua~vzl>(SXKW(en*YJW0R(eiP zsj7Xce5+Ca>?Vr+l2;tGN512}{s|-!rMMkevNmYbwM2NK0OFKu=NdvfU#{5YveT7m zgA_ETjq@G3A8C&7vt&oE+0=yM6x!HyDDT$e4kcZcYBp|^@3>2!=^0L-fMli%|6^&k=Aryv^9)9O^4A@ zt4?3Lwz4xD#fFXV+|X@j{jmvN_)05i>a5B=O-Y1!&Qbq|V&R3`vV9~Lz@~*7t>;W% zyz9(T*Y|1S!?oWXqCy}o-!bDe?e>}tXV0t~SFc@SM7K$Yx0dY zVR|l|n?n=M`_qfJn%so)-lDqG@$ksT{oq3b5^g;4$4^_ zTdz@EOfz@SmPaJVy=!Y?t5u5`+o1WF)mOP^P;vJ9MzjIWi>D6Iiun@`by?}Qzl)XJ zIfrKd&NstvZof}O)qRBwxsh}=bN>WBSCfZH=)2}ZuTIl{kKD}mj&c(G_{bplVT{I7=^6YILX^kKnaPAQ8Ov{hB!d`XT zYbiCsx`(;KBKp|6sG#Y3jfEFJ6mLs3Y?1a(@_D-O0*#rePy>gxgDckUyA=3voyJPG zS>E?ptjqDJLu7oH27#<%<^WoT*4}ZR+V71$+CNznwhnJ zbIvO5=DHpESHBIbRXcLTTWQqVq4VJ%s}=K8es={?K0t#-54A4Rll z9^|;+dzwb$M^cG3b`{!fts}SoPOWQq=UrXfi}`=-Zu{ZzL2ZNVtmBOTC^LpAY)M+8 z@ZhYKHqvW2+eu>;mVXvISKnEawO^|#tosKUG&qC$Md7qa6X-Zhsy@I;%8f0XuY3Rt z)pQoE-#5dbb~xo2PPfteqZCJ4@G03b{68A&G9!bwdk2SA+K8_1tFf*h%+~1F&e1W` z5+}NU{P?T&+kzbWy04~0xKBza#(vkd;jsR!5er`1`8W9Hx!blpx;B1)Gxt;$=Ny)} z;!=ux``qQrz6;v=RZ_REQ{qFR#N*OdYkKv`3hTHWwi<5R98Ts0INXl=Zv*U&vHKwH zu3+qU6}_&rMd-*%4OjNRxN-G@v?cE9A59t?3XVliTC@S@!EWorE?wKPpEknqG&t(? zYpyvg-WfJ&>4}qzmT%vl7T0vHdw5Fxgb|#5bn|}{x|uVOo=K$na}{`FjS6}>+kLG( zXCmD>S<}mLHqtGekFiO#2{^fnCg>kK9Xa6SMGq%kj$I}*=}yi~+TtSDX|S|E-KGx! zOBZmKMsSwW&ChwNpW-~FTV`we(f^-JrDs-a1wA=e>1OUPjtA8q-tM9k^m*6;!P{Nn zZ4P*Qk@J>rc~>du_y3Q%3un;);mEJnBLTnCfXb3RTKPoLC8wDwOtEG2C>Pf3pjKFIsJ(i#|kzO($)Tm??BpI`nw zzY=#T$TOj=@Rrb3m?f+ib_siNPgu{=(=x;oW*KdH z-;#n`!>g9N7Q_0QwV}1SwX3xcoX=6#XzM4|1=g>utF7y;o2*-{2d&>*&s%@A5nE|n zSz9GrJzFzdS2(4^Y$I(Ewj^6JoYNh)y|#2)rtO;T578p}igwW@RuZd{iz;%EH_@; z;>nTitG2J?=euiid7M87$V`mtShGoJI(4}80W}Nz%B*olby`pTSz>R)SF3;ouG`Pj zHrhm_Q4$+;-ib5gT>42a`-H~P#kq_=4bcT$uh{NOnnr+zGkRhgPl6 z$j2Vl5;qJk){#5Thi*!TzMj%~p?e>T!^Hx7w?K4eZ5vmkZdgPccP%Ej6=eI`au)<$ASZ-PG43vS~OC{U+~^H*r+2WNyA0+1MrgH{76MKXkYbTeeW| z=IlHuE-c1PTYda(){hQss1Rb{gX4hAEzCU(%^Gycyc>My=!ftsC5h9tgpW*){*KJR&D@atp?@>U+q55 z%1a7D>S`)&dXx(EV>QwAMzeJFWY=u3hka$f(!;zLaoj)N0H<3zOCG&qYtrE$DjYsf zd%`Q@cPzoKIP;2S$7%D5W&74+pD8qp-$~8tj9WiCnd)LT%WXsBWcD7@#WwV(Y+0QR zKMYRTotyB%JhyeG$BjF{I~_Ggj@S3ndjU^j^A@z}Q`?;a8*L(~kqV8=Ra<=_4*X>F zvg?7l8@A-Ccj&X*?3rk%eyfgU9^W>!tBaMD)#PEAU20EiW6e}ril&Oyq`GWST{=jt zifb}lt(Rk;VmaKWLw{yNMK!D23B7ZYdN{3vf^&M4^Yqz+SxIW)%E6l58K&7QP3 z-8>M%-e;2r46W@}4f6GSB-0>YyhqNeqmw_vwMV9H@T9Z@dloO-vtw!EzyVVd2D$Cg z=0z*cEjSv`c5wgG^iMhfCrfA3Y5JEM&7;#<-d%omkk(&O>6Ek12!+Yp$6Z!uDcd4{ z`01N%7Y|HYKlUq^I(Z6iVH)-eQ}gxGKNOY*@ic&Y+|-qmO+!@Ludu4fcHgCYWP4&k zNRrx1>!;{x{G?C=x33vga^vc#&AAL}i&>zlcM3vkNviYbZ!%~dS}pp>8`Z}3Wwltf zH9hXTXCHD7nYxLpR9U!j*RF-5nZo?0jvfMkV0WsfM&V}!C-phApH_71^J^B)muG<0 zw&VM$eXhH{G*44c!g0*YrRn_Uhfc?tFR&maM6qw%`}wMM?#=7J+;=2U<)^D*VA|52 zSX4vkoaPd%$mWQBX)RgpdYwL$)m9qYDXR^YHj3K1t=LJXfeBWFZC$*GC zDto?>(Ew~!-^dFT8GdU##5FB>il%0FJ&6+*KQ^wtsp5LM2kwOv3v9VxD9ser8V9?LEy9@?JhDwV)gMmhh7O6zxlMUy#I(w$I^`=6D1bTj)?RK1h-N?a89N6 zUMH(AP)GIM)D+sziD&+dif1HRl2S24w$qNY?zKtOOH&_UKbCcD`_L}x{>umbm!0T+ zlKP!csp~=}tutFaa4(%U%kW=zd;q@~mAk?KJ%^>y2PEre@HrZob5w;+|A9%Kq+QNQ>-Dt!6 z9z$9c`FW(Q@EUOlJ4rQRIq|c63V1Q`6ILR;OB|N!8249%hroXo;W|P#sUQTBSA-p; z9L9f@(~7ye0ap}~NlD?H36}%@0DM&tAZQ4c5Z)qXgvv-?N01RvZ^Hkw9e!DFj8MHO z6(*48JaFD~+1YwN%Y;}SKt>a+TTE%1^6^HY#3~%M^oQJRmQ78~lo^x~&a_twGq#C8({ZP&1g|2WdRQW6NG7!Df#D!H!h0`JyBi z!2|Q3v17fk1=pu*ys(vYCELBQ?S(cXX)IX0D(NVM!uCIBNZ>5h1!IbK^pQNY$3 zV??4=ut`-kpm2=D`;Wxe9O0mE0_sE2w>B`E@DX4X(tH5oFxIY7-27PQVB?{s)=10@g@S6^#)&zk|X1 zaEuX!m{T|gqXmOzt_hrSkBrBdbn;%K(0c;fMxz~_}7pdgD7D&L!S10VT2M8;o&c(3|(-G;wTP7kh)w7!!X4sfK*GsePPN zk$@A-arvC$OV~~$E zYe%9#pS`CIr;_uB%Z_t#q)8ck#d92m5)T$Wf6f^Xz6j*_dJP69 zzA`w)d@PTy@Eq5oP-re+rM%}P@P@DN1kl%*)Wn-)zBNp&TvmV8t1$HQXjKi9z8aX% zxc`D-tVw^db>P%--qkSY`m&xL8UMR6YnnXay2fV|hq$^qC(aj-eW;G|A|7z=a$f#( zo&DVwyv)vUJI1BVR~DZS=V>p~y8XR0^rfZYFD)JY($Yz0DYu~i95o*M68BvA4p*96 zY%{e%gLt0Xd>i`JAdO)627=p@@q6C4hJo5(XjUyqxE1Ih>nSyEpxlpCFfxoi#$F@c z@a(((DE;d*hztd`=liO$4R-Ej52wb@TVWw8D3w5=59ku`C0+pHvUml2kr#}(0(lK_ zW%4HC8nE30_LaJb>*Gs3fi%Dj_)IxY1-5J`v9@jBwGSyhVp1G<6B(KijT!OXo?w2w zRWXbY3ZIu_FCG^j7fnjP7^BvM8x&gXfPD}Y_+1vI5AUlCC7*$I6}TVZr5xLfkMRr7 z8Na_+hWxKaE@Eon3reHFDD>1CM~w@{Ph4 z`TCkP-#2IaL@0?Cp!UB!7C!1f9@+Q<6#NcK3yjC0&|*9*Ze#pu{8^mikiobf8F-4y zjhjR?E*npb{dk{%g8%hn{7S6G&;PC4UufVLgH1_0wDs`A7c=)UxgvlsBFec>uaIVV zE$}OwgF`Lx3h)}*pk+I}3bc42S`Wf2lEHXwWC&gv+BMAV?}OM+y5@7ASj4lOw_=`D zk~m34;J1NSM~z3u_mJm4%=|Y)H-3byZ9F#ejax)A^1(&JcxG~m>*PNk&SPkZfuI`? z0RQG`f)YT+A9yL3OVNYeQ;yB^JTLW13L`x;bWf@Aw5S$y;17?vmg9kRUiN@i)D_9o zido<>+e7vM;g>$IHT(ZH=Rs-QM(P>M!pAdb#}Q>ZiLnDUuohS$Tz6L^ey+o4Vm0&3)bs~fM_fZ5K-W0L z$9@Kg(cq>t2M{lNQm47Uq1+wwR%}_HXnUXRx1e zT140*u9eLA!MFmuat6|Wi1`#k6AH0D&Vx%o7`WX)`Wvi~0q*?<+hnd9XbFY2Bd~t_ zf=7bx^0jX@U#@k(VBFuKt+&u7 z-?$DLaa;EcG;!VaYMt5lc?2%r`^$`e0uT3qZ~H*cC2;tTaU1b@sjHBNzsLgSi& z6STh$|qiV7{Kz>CJh{c^N;!d+@$$ z;w^*!KkzeOUtrcqFkb#Y2^uMn*N?am%EK@E>v$gdnKCSz*#AXZf|SFo-Ix=+F<~O# z(S&4y`!+7{?l^R8HP+z+gr8uQ?tq)v_aU9z#$8C}XUP2_Y99eMSEjjgv6_o0!9Ga1 zl%RtQb+G4v0U<7KW9mCv{KD7CbBPq8Kw7ke759R+{(zj<-guhA(r|lv5BRCE6ZUf_ z^pJZn1;`h0OU7ep&_le}5I9|bV%$q;ch|UEG$7XdMFG3NCv-rq6%AE9l(W4@Q6 zjgQg8+=Ebl(#XZSFg+C0#{Xr$z{4%uKjzEli1MQOa@`vU|AOlt_daZ#H9$hQH;Yxqi?ruDM*#N_chGjq+Q$8IxjWN*OFG;?@6@g6sGn9K3wC-X29M?^kU70ADGp0bd?N z8h@IW;|_-695lUx;vO&TO3$_ErIeT}{e{-g_cc%JVjV2*UA$Km_w%;)?kL{2=5B19 zGi|9^WNP(&P|0_2lP=8Z1zUsC=lf;x4(rA3Jqx@zlBuzOLetDu;~mvA((}E|%zFK5 zXzQP*ro&$<@|jGX^x}STw*OpFFXDdz#(gNTok7GsI0VRo=kOGzo?LMZ8a(^-ztWT9 zHSEy`&La<>xa>VxP0pILz#hg=Ieb6nJN6|$PjKjRk@ldb$j)<5lka#u&*3Ln^W4Ls zSivvVUwBCzv-y~OLvPdPE|O(YrKiPTDarLxa`6SNevuOMw+7zPGq&0KuliJso!f(Q zINfr4P!4+m-+2gj3T_3g$l(ix=WCqT@m+(j>=Gz1-Xko?$!6eK+5&c%R$j$^`N7h*lJ)q+_<*s)hC#=?9ysrFbV0?3h;3JKOVnF^I+ho zJ%8+NJjbo6in*2rKRtOHI93`Kv%EJiV(w1Z&kEkW1d0P-O)GlyGIski;AAE88voZm z^25K6N5zGXAb0+K964rmDEZ}o5#v7*$z%Tih~!Tm3&e~iGxp>E-6#0}`xpWcpe=mW zcr;G{_jnnX4fl?C%pZ>|xmI$R--htp8_!#fOoJSzkuS(@vo*iv;cYw`P|1snm+`wC zAB@1IQ4ZX%g5OH4kV+-oQSr12Zh9<88zZh{-uYB9v6M&5$K^OmL(;`L3HjpN0KTSq hD}EQ|k5JXja~Ya(wrs~Q6XgXYFeaYjb9$&HM{s_H<#bADcNNn&0} zF_6v1z`_6$1A(H{Vg^Ee3n_+Q5C941xQ;1HG=pc%^)BLG#+G~2oNg(JZWgz~`z{p?$!~lGw7#IKm delta 263 zcmbQjwS$Y7nMs+Qft8Vgn}L@>XCiMns|EuDgZ9QuaYjas$&HM{s+vH)bADcNNn&0} zF_6v1z`_6$1A(H{Vg^Ge3n_+Q5~vC4Mjm>ev~$fP7&f2AK&m1EdF}MwEeN^KRBk4o1GorhM%{axb4Wki5yK4FEP_42%E( delta 158 zcmZpXYmwVv!&j?jpKQw44kY*TNdw87eA)mhFbt9a diff --git a/assets/textures/FontAtlas.png b/assets/textures/FontAtlas.png new file mode 100644 index 0000000000000000000000000000000000000000..6fe02e2ffa150478c90b7856fdde13bb20ab9802 GIT binary patch literal 2612 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&w3=!$sk4H3kOG-<~dxAr*1S60D0A4WyVx ziP10^O$VddV6-S0EeS_U!qJj&v?Ls+C1HaI69bbC1LL$eZ33X?pr@;!%Q~loCIGHy BDtrI{ literal 0 HcmV?d00001 diff --git a/assets/textures/atlas.png b/assets/textures/atlas.png new file mode 100644 index 0000000000000000000000000000000000000000..6d8a7f397d28e2f464285491202d7428351a18c5 GIT binary patch literal 15594 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 H7=QR5l(}ph literal 0 HcmV?d00001 diff --git a/build.sh b/build.sh index e11c140..99fa38e 100755 --- a/build.sh +++ b/build.sh @@ -60,12 +60,12 @@ if ! [ -f build/libxxhash.a ]; then fi # STB_IMAGE -src="external/stb/stb_image.c" +src="external/stb/stb.c" flags="-std=c99 -Wno-everything -Iexternal/stb -c -static" -obj="build/stb_image.o" -lib="build/libstb_image.a" +obj="build/stb.o" +lib="build/libstb.a" -if ! [ -f build/libstb_image.a ]; then +if ! [ -f build/libstb.a ]; then $c_compiler $flags $src $out $obj ar rcs $lib $obj rm $obj @@ -95,3 +95,12 @@ if ! [ -f build/libcglm.a ]; then rm $obj fi +if ! [ -f build/atlas.png ]; then + msdf-atlas-gen -font assets/fonts/NuberNextCondensed-DemiBold.otf -dimensions 256 256 -type softmask -imageout build/atlas.png -json build/atlas.json +fi + +if ! [ -f assets/textures/atlas.png ]; then + cp build/atlas.png assets/textures/atlas.png + mkdir -p assets/data + cp build/atlas.json assets/data/atlas.json +fi diff --git a/dub.json b/dub.json index 467e59a..7ba2a01 100644 --- a/dub.json +++ b/dub.json @@ -9,9 +9,9 @@ "targetPath": "build", "sourceFiles-linux": ["build/libvma.a", "build/libstb_image.a", "build/libm3d.a", "build/libcglm.a"], "sourceFiles-windows": [], - "importPaths": ["src/gears", "src/shared", "src/generated", "external/xxhash", "external/inteli"], - "sourcePaths": ["src/gears", "src/shared", "src/generated", "external/xxhash", "external/inteli"], - "libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++", "xcb-xfixes", "freetype2"], + "importPaths": ["src/gears", "src/codegen", "src/shared", "external/xxhash", "external/inteli"], + "sourcePaths": ["src/gears", "src/codegen", "src/shared", "external/xxhash", "external/inteli"], + "libs-linux": ["xcb", "X11", "X11-xcb", "vulkan", "stdc++", "xcb-xfixes"], "libs-windows": [], "preGenerateCommands-linux": ["./build.sh", "build/Packer"], "preGenerateCommands-windows": [], @@ -23,9 +23,9 @@ "targetType": "executable", "targetPath": "build", "targetName": "Packer", - "importPaths": ["src/packer", "src/shared", "src/generated", "external/xxhash", "external/inteli"], - "sourcePaths": ["src/packer", "src/shared", "src/generated", "external/xxhash", "external/inteli"], - "sourceFiles-linux": ["build/libstb_image.a", "build/libm3d.a", "build/libcglm"], + "importPaths": ["src/packer", "src/shared", "external/xxhash", "external/inteli"], + "sourcePaths": ["src/packer", "src/shared", "external/xxhash", "external/inteli"], + "sourceFiles-linux": ["build/libstb.a", "build/libm3d.a", "build/libcglm.a"], "preGenerateCommands-linux": ["./build.sh"], "postGenerateCommands-linux": [], "preGenerateCommands-windows": [], diff --git a/external/stb/stb_image.c b/external/stb/stb.c similarity index 98% rename from external/stb/stb_image.c rename to external/stb/stb.c index 5b04e48..8ddfd1f 100644 --- a/external/stb/stb_image.c +++ b/external/stb/stb.c @@ -1,3 +1,2 @@ #define STB_IMAGE_IMPLEMENTATION - #include "stb_image.h" diff --git a/src/codegen/fonts.d b/src/codegen/fonts.d new file mode 100644 index 0000000..334aafd --- /dev/null +++ b/src/codegen/fonts.d @@ -0,0 +1,825 @@ +import util; + +static immutable FontAtlas FONT_ATLAS = { + type: AtlasType.SoftMask, + size: 58.531250, + width: 256, + height: 256, + y_origin: YOrigin.Bottom, + em_size: 1.000000, + line_height: 1.408000, + ascender: 1.105000, + descender: -0.303000, + underline_y: -0.100000, + underline_thickness: 0.050000, + glyphs: [ + { + ch: ' ', + advance: 0.207000, + }, + { + ch: ',', + advance: 0.216000, + plane_left: 0.033160, + plane_bottom: -0.179391, + plane_right: 0.169840, + plane_top: 0.145222, + atlas_left: 0.033160, + atlas_bottom: -0.179391, + atlas_right: 0.169840, + atlas_top: 0.145222, + }, + { + ch: '-', + advance: 0.373000, + plane_left: 0.049821, + plane_bottom: 0.230646, + plane_right: 0.323179, + plane_top: 0.350240, + atlas_left: 0.049821, + atlas_bottom: 0.230646, + atlas_right: 0.323179, + atlas_top: 0.350240, + }, + { + ch: '.', + advance: 0.216000, + plane_left: 0.048203, + plane_bottom: -0.008542, + plane_right: 0.167797, + plane_top: 0.145222, + atlas_left: 0.048203, + atlas_bottom: -0.008542, + atlas_right: 0.167797, + atlas_top: 0.145222, + }, + { + ch: '0', + advance: 0.467000, + plane_left: 0.019939, + plane_bottom: -0.025627, + plane_right: 0.447061, + plane_top: 0.709023, + atlas_left: 0.019939, + atlas_bottom: -0.025627, + atlas_right: 0.447061, + atlas_top: 0.709023, + }, + { + ch: '1', + advance: 0.282000, + plane_left: 0.003406, + plane_bottom: -0.008542, + plane_right: 0.242594, + plane_top: 0.691938, + atlas_left: 0.003406, + atlas_bottom: -0.008542, + atlas_right: 0.242594, + atlas_top: 0.691938, + }, + { + ch: '2', + advance: 0.439000, + plane_left: 0.014481, + plane_bottom: -0.008542, + plane_right: 0.424519, + plane_top: 0.709023, + atlas_left: 0.014481, + atlas_bottom: -0.008542, + atlas_right: 0.424519, + atlas_top: 0.709023, + }, + { + ch: '3', + advance: 0.456000, + plane_left: 0.009939, + plane_bottom: -0.025627, + plane_right: 0.437061, + plane_top: 0.709023, + atlas_left: 0.009939, + atlas_bottom: -0.025627, + atlas_right: 0.437061, + atlas_top: 0.709023, + }, + { + ch: '4', + advance: 0.466000, + plane_left: 0.011396, + plane_bottom: -0.008542, + plane_right: 0.455604, + plane_top: 0.691938, + atlas_left: 0.011396, + atlas_bottom: -0.008542, + atlas_right: 0.455604, + atlas_top: 0.691938, + }, + { + ch: '5', + advance: 0.454000, + plane_left: 0.015439, + plane_bottom: -0.025627, + plane_right: 0.442561, + plane_top: 0.691938, + atlas_left: 0.015439, + atlas_bottom: -0.025627, + atlas_right: 0.442561, + atlas_top: 0.691938, + }, + { + ch: '6', + advance: 0.456000, + plane_left: 0.017939, + plane_bottom: -0.025627, + plane_right: 0.445061, + plane_top: 0.709023, + atlas_left: 0.017939, + atlas_bottom: -0.025627, + atlas_right: 0.445061, + atlas_top: 0.709023, + }, + { + ch: '7', + advance: 0.386000, + plane_left: 0.004066, + plane_bottom: -0.008542, + plane_right: 0.379934, + plane_top: 0.691938, + atlas_left: 0.004066, + atlas_bottom: -0.008542, + atlas_right: 0.379934, + atlas_top: 0.691938, + }, + { + ch: '8', + advance: 0.464000, + plane_left: 0.018439, + plane_bottom: -0.025627, + plane_right: 0.445561, + plane_top: 0.709023, + atlas_left: 0.018439, + atlas_bottom: -0.025627, + atlas_right: 0.445561, + atlas_top: 0.709023, + }, + { + ch: '9', + advance: 0.456000, + plane_left: 0.010939, + plane_bottom: -0.025627, + plane_right: 0.438061, + plane_top: 0.709023, + atlas_left: 0.010939, + atlas_bottom: -0.025627, + atlas_right: 0.438061, + atlas_top: 0.709023, + }, + { + ch: ':', + advance: 0.216000, + plane_left: 0.048203, + plane_bottom: -0.008542, + plane_right: 0.167797, + plane_top: 0.521089, + atlas_left: 0.048203, + atlas_bottom: -0.008542, + atlas_right: 0.167797, + atlas_top: 0.521089, + }, + { + ch: ';', + advance: 0.216000, + plane_left: 0.033160, + plane_bottom: -0.179391, + plane_right: 0.169840, + plane_top: 0.521089, + atlas_left: 0.033160, + atlas_bottom: -0.179391, + atlas_right: 0.169840, + atlas_top: 0.521089, + }, + { + ch: 'A', + advance: 0.535000, + plane_left: 0.011227, + plane_bottom: -0.008542, + plane_right: 0.523773, + plane_top: 0.709023, + atlas_left: 0.011227, + atlas_bottom: -0.008542, + atlas_right: 0.523773, + atlas_top: 0.709023, + }, + { + ch: 'B', + advance: 0.495000, + plane_left: 0.047439, + plane_bottom: -0.008542, + plane_right: 0.474561, + plane_top: 0.709023, + atlas_left: 0.047439, + atlas_bottom: -0.008542, + atlas_right: 0.474561, + atlas_top: 0.709023, + }, + { + ch: 'C', + advance: 0.508000, + plane_left: 0.030354, + plane_bottom: -0.025627, + plane_right: 0.491646, + plane_top: 0.726108, + atlas_left: 0.030354, + atlas_bottom: -0.025627, + atlas_right: 0.491646, + atlas_top: 0.726108, + }, + { + ch: 'D', + advance: 0.535000, + plane_left: 0.046854, + plane_bottom: -0.008542, + plane_right: 0.508146, + plane_top: 0.709023, + atlas_left: 0.046854, + atlas_bottom: -0.008542, + atlas_right: 0.508146, + atlas_top: 0.709023, + }, + { + ch: 'E', + advance: 0.454000, + plane_left: 0.047024, + plane_bottom: -0.008542, + plane_right: 0.439976, + plane_top: 0.709023, + atlas_left: 0.047024, + atlas_bottom: -0.008542, + atlas_right: 0.439976, + atlas_top: 0.709023, + }, + { + ch: 'F', + advance: 0.431000, + plane_left: 0.044066, + plane_bottom: -0.008542, + plane_right: 0.419934, + plane_top: 0.709023, + atlas_left: 0.044066, + atlas_bottom: -0.008542, + atlas_right: 0.419934, + atlas_top: 0.709023, + }, + { + ch: 'G', + advance: 0.535000, + plane_left: 0.025312, + plane_bottom: -0.025627, + plane_right: 0.503688, + plane_top: 0.726108, + atlas_left: 0.025312, + atlas_bottom: -0.025627, + atlas_right: 0.503688, + atlas_top: 0.726108, + }, + { + ch: 'H', + advance: 0.541000, + plane_left: 0.048896, + plane_bottom: -0.008542, + plane_right: 0.493104, + plane_top: 0.709023, + atlas_left: 0.048896, + atlas_bottom: -0.008542, + atlas_right: 0.493104, + atlas_top: 0.709023, + }, + { + ch: 'I', + advance: 0.211000, + plane_left: 0.045703, + plane_bottom: -0.008542, + plane_right: 0.165297, + plane_top: 0.709023, + atlas_left: 0.045703, + atlas_bottom: -0.008542, + atlas_right: 0.165297, + atlas_top: 0.709023, + }, + { + ch: 'J', + advance: 0.438000, + plane_left: 0.007024, + plane_bottom: -0.025627, + plane_right: 0.399976, + plane_top: 0.709023, + atlas_left: 0.007024, + atlas_bottom: -0.025627, + atlas_right: 0.399976, + atlas_top: 0.709023, + }, + { + ch: 'K', + advance: 0.507000, + plane_left: 0.051396, + plane_bottom: -0.008542, + plane_right: 0.495604, + plane_top: 0.709023, + atlas_left: 0.051396, + atlas_bottom: -0.008542, + atlas_right: 0.495604, + atlas_top: 0.709023, + }, + { + ch: 'L', + advance: 0.430000, + plane_left: 0.047566, + plane_bottom: -0.008542, + plane_right: 0.423434, + plane_top: 0.709023, + atlas_left: 0.047566, + atlas_bottom: -0.008542, + atlas_right: 0.423434, + atlas_top: 0.709023, + }, + { + ch: 'M', + advance: 0.682000, + plane_left: 0.050557, + plane_bottom: -0.008542, + plane_right: 0.631443, + plane_top: 0.709023, + atlas_left: 0.050557, + atlas_bottom: -0.008542, + atlas_right: 0.631443, + atlas_top: 0.709023, + }, + { + ch: 'N', + advance: 0.560000, + plane_left: 0.048854, + plane_bottom: -0.008542, + plane_right: 0.510146, + plane_top: 0.709023, + atlas_left: 0.048854, + atlas_bottom: -0.008542, + atlas_right: 0.510146, + atlas_top: 0.709023, + }, + { + ch: 'O', + advance: 0.535000, + plane_left: 0.028312, + plane_bottom: -0.025627, + plane_right: 0.506688, + plane_top: 0.726108, + atlas_left: 0.028312, + atlas_bottom: -0.025627, + atlas_right: 0.506688, + atlas_top: 0.726108, + }, + { + ch: 'P', + advance: 0.475000, + plane_left: 0.047481, + plane_bottom: -0.008542, + plane_right: 0.457519, + plane_top: 0.709023, + atlas_left: 0.047481, + atlas_bottom: -0.008542, + atlas_right: 0.457519, + atlas_top: 0.709023, + }, + { + ch: 'Q', + advance: 0.535000, + plane_left: 0.028312, + plane_bottom: -0.145222, + plane_right: 0.506688, + plane_top: 0.726108, + atlas_left: 0.028312, + atlas_bottom: -0.145222, + atlas_right: 0.506688, + atlas_top: 0.726108, + }, + { + ch: 'R', + advance: 0.500000, + plane_left: 0.046396, + plane_bottom: -0.008542, + plane_right: 0.490604, + plane_top: 0.709023, + atlas_left: 0.046396, + atlas_bottom: -0.008542, + atlas_right: 0.490604, + atlas_top: 0.709023, + }, + { + ch: 'S', + advance: 0.475000, + plane_left: 0.012396, + plane_bottom: -0.025627, + plane_right: 0.456604, + plane_top: 0.726108, + atlas_left: 0.012396, + atlas_bottom: -0.025627, + atlas_right: 0.456604, + atlas_top: 0.726108, + }, + { + ch: 'T', + advance: 0.466000, + plane_left: 0.010896, + plane_bottom: -0.008542, + plane_right: 0.455104, + plane_top: 0.709023, + atlas_left: 0.010896, + atlas_bottom: -0.008542, + atlas_right: 0.455104, + atlas_top: 0.709023, + }, + { + ch: 'U', + advance: 0.528000, + plane_left: 0.043396, + plane_bottom: -0.025627, + plane_right: 0.487604, + plane_top: 0.709023, + atlas_left: 0.043396, + atlas_bottom: -0.025627, + atlas_right: 0.487604, + atlas_top: 0.709023, + }, + { + ch: 'V', + advance: 0.522000, + plane_left: 0.004727, + plane_bottom: -0.008542, + plane_right: 0.517273, + plane_top: 0.709023, + atlas_left: 0.004727, + atlas_bottom: -0.008542, + atlas_right: 0.517273, + atlas_top: 0.709023, + }, + { + ch: 'W', + advance: 0.768000, + plane_left: 0.008132, + plane_bottom: -0.008542, + plane_right: 0.759868, + plane_top: 0.709023, + atlas_left: 0.008132, + atlas_bottom: -0.008542, + atlas_right: 0.759868, + atlas_top: 0.709023, + }, + { + ch: 'X', + advance: 0.513000, + plane_left: 0.008769, + plane_bottom: -0.008542, + plane_right: 0.504231, + plane_top: 0.709023, + atlas_left: 0.008769, + atlas_bottom: -0.008542, + atlas_right: 0.504231, + atlas_top: 0.709023, + }, + { + ch: 'Y', + advance: 0.524000, + plane_left: 0.005727, + plane_bottom: -0.008542, + plane_right: 0.518273, + plane_top: 0.709023, + atlas_left: 0.005727, + atlas_bottom: -0.008542, + atlas_right: 0.518273, + atlas_top: 0.709023, + }, + { + ch: 'Z', + advance: 0.452000, + plane_left: 0.011439, + plane_bottom: -0.008542, + plane_right: 0.438561, + plane_top: 0.709023, + atlas_left: 0.011439, + atlas_bottom: -0.008542, + atlas_right: 0.438561, + atlas_top: 0.709023, + }, + { + ch: 'a', + advance: 0.427000, + plane_left: 0.009024, + plane_bottom: -0.025627, + plane_right: 0.401976, + plane_top: 0.521089, + atlas_left: 0.009024, + atlas_bottom: -0.025627, + atlas_right: 0.401976, + atlas_top: 0.521089, + }, + { + ch: 'b', + advance: 0.457000, + plane_left: 0.043024, + plane_bottom: -0.025627, + plane_right: 0.435976, + plane_top: 0.709023, + atlas_left: 0.043024, + atlas_bottom: -0.025627, + atlas_right: 0.435976, + atlas_top: 0.709023, + }, + { + ch: 'c', + advance: 0.423000, + plane_left: 0.018024, + plane_bottom: -0.025627, + plane_right: 0.410976, + plane_top: 0.521089, + atlas_left: 0.018024, + atlas_bottom: -0.025627, + atlas_right: 0.410976, + atlas_top: 0.521089, + }, + { + ch: 'd', + advance: 0.456000, + plane_left: 0.021024, + plane_bottom: -0.025627, + plane_right: 0.413976, + plane_top: 0.709023, + atlas_left: 0.021024, + atlas_bottom: -0.025627, + atlas_right: 0.413976, + atlas_top: 0.709023, + }, + { + ch: 'e', + advance: 0.430000, + plane_left: 0.021024, + plane_bottom: -0.025627, + plane_right: 0.413976, + plane_top: 0.521089, + atlas_left: 0.021024, + atlas_bottom: -0.025627, + atlas_right: 0.413976, + atlas_top: 0.521089, + }, + { + ch: 'f', + advance: 0.283000, + plane_left: 0.009321, + plane_bottom: -0.008542, + plane_right: 0.282679, + plane_top: 0.726108, + atlas_left: 0.009321, + atlas_bottom: -0.008542, + atlas_right: 0.282679, + atlas_top: 0.726108, + }, + { + ch: 'g', + advance: 0.448000, + plane_left: 0.020524, + plane_bottom: -0.213561, + plane_right: 0.413476, + plane_top: 0.521089, + atlas_left: 0.020524, + atlas_bottom: -0.213561, + atlas_right: 0.413476, + atlas_top: 0.521089, + }, + { + ch: 'h', + advance: 0.449000, + plane_left: 0.039566, + plane_bottom: -0.008542, + plane_right: 0.415434, + plane_top: 0.709023, + atlas_left: 0.039566, + atlas_bottom: -0.008542, + atlas_right: 0.415434, + atlas_top: 0.709023, + }, + { + ch: 'i', + advance: 0.184000, + plane_left: 0.032203, + plane_bottom: -0.008542, + plane_right: 0.151797, + plane_top: 0.674853, + atlas_left: 0.032203, + atlas_bottom: -0.008542, + atlas_right: 0.151797, + atlas_top: 0.674853, + }, + { + ch: 'j', + advance: 0.187000, + plane_left: -0.051009, + plane_bottom: -0.213561, + plane_right: 0.154009, + plane_top: 0.674853, + atlas_left: -0.051009, + atlas_bottom: -0.213561, + atlas_right: 0.154009, + atlas_top: 0.674853, + }, + { + ch: 'k', + advance: 0.434000, + plane_left: 0.042024, + plane_bottom: -0.008542, + plane_right: 0.434976, + plane_top: 0.709023, + atlas_left: 0.042024, + atlas_bottom: -0.008542, + atlas_right: 0.434976, + atlas_top: 0.709023, + }, + { + ch: 'l', + advance: 0.190000, + plane_left: 0.035703, + plane_bottom: -0.008542, + plane_right: 0.155297, + plane_top: 0.709023, + atlas_left: 0.035703, + atlas_bottom: -0.008542, + atlas_right: 0.155297, + atlas_top: 0.709023, + }, + { + ch: 'm', + advance: 0.690000, + plane_left: 0.039472, + plane_bottom: -0.008542, + plane_right: 0.654528, + plane_top: 0.521089, + atlas_left: 0.039472, + atlas_bottom: -0.008542, + atlas_right: 0.654528, + atlas_top: 0.521089, + }, + { + ch: 'n', + advance: 0.446000, + plane_left: 0.036566, + plane_bottom: -0.008542, + plane_right: 0.412434, + plane_top: 0.521089, + atlas_left: 0.036566, + atlas_bottom: -0.008542, + atlas_right: 0.412434, + atlas_top: 0.521089, + }, + { + ch: 'o', + advance: 0.442000, + plane_left: 0.015981, + plane_bottom: -0.025627, + plane_right: 0.426019, + plane_top: 0.521089, + atlas_left: 0.015981, + atlas_bottom: -0.025627, + atlas_right: 0.426019, + atlas_top: 0.521089, + }, + { + ch: 'p', + advance: 0.457000, + plane_left: 0.043024, + plane_bottom: -0.213561, + plane_right: 0.435976, + plane_top: 0.521089, + atlas_left: 0.043024, + atlas_bottom: -0.213561, + atlas_right: 0.435976, + atlas_top: 0.521089, + }, + { + ch: 'q', + advance: 0.455000, + plane_left: 0.021024, + plane_bottom: -0.213561, + plane_right: 0.413976, + plane_top: 0.521089, + atlas_left: 0.021024, + atlas_bottom: -0.213561, + atlas_right: 0.413976, + atlas_top: 0.521089, + }, + { + ch: 'r', + advance: 0.298000, + plane_left: 0.038363, + plane_bottom: -0.008542, + plane_right: 0.294637, + plane_top: 0.521089, + atlas_left: 0.038363, + atlas_bottom: -0.008542, + atlas_right: 0.294637, + atlas_top: 0.521089, + }, + { + ch: 's', + advance: 0.400000, + plane_left: 0.011066, + plane_bottom: -0.025627, + plane_right: 0.386934, + plane_top: 0.521089, + atlas_left: 0.011066, + atlas_bottom: -0.025627, + atlas_right: 0.386934, + atlas_top: 0.521089, + }, + { + ch: 't', + advance: 0.293000, + plane_left: 0.004321, + plane_bottom: -0.025627, + plane_right: 0.277679, + plane_top: 0.657768, + atlas_left: 0.004321, + atlas_bottom: -0.025627, + atlas_right: 0.277679, + atlas_top: 0.657768, + }, + { + ch: 'u', + advance: 0.440000, + plane_left: 0.029566, + plane_bottom: -0.025627, + plane_right: 0.405434, + plane_top: 0.521089, + atlas_left: 0.029566, + atlas_bottom: -0.025627, + atlas_right: 0.405434, + atlas_top: 0.521089, + }, + { + ch: 'v', + advance: 0.419000, + plane_left: -0.004061, + plane_bottom: -0.008542, + plane_right: 0.423061, + plane_top: 0.521089, + atlas_left: -0.004061, + atlas_bottom: -0.008542, + atlas_right: 0.423061, + atlas_top: 0.521089, + }, + { + ch: 'w', + advance: 0.658000, + plane_left: 0.004387, + plane_bottom: -0.008542, + plane_right: 0.653613, + plane_top: 0.521089, + atlas_left: 0.004387, + atlas_bottom: -0.008542, + atlas_right: 0.653613, + atlas_top: 0.521089, + }, + { + ch: 'x', + advance: 0.412000, + plane_left: 0.000981, + plane_bottom: -0.008542, + plane_right: 0.411019, + plane_top: 0.521089, + atlas_left: 0.000981, + atlas_bottom: -0.008542, + atlas_right: 0.411019, + atlas_top: 0.521089, + }, + { + ch: 'y', + advance: 0.421000, + plane_left: -0.002561, + plane_bottom: -0.213561, + plane_right: 0.424561, + plane_top: 0.521089, + atlas_left: -0.002561, + atlas_bottom: -0.213561, + atlas_right: 0.424561, + atlas_top: 0.521089, + }, + { + ch: 'z', + advance: 0.383000, + plane_left: 0.002066, + plane_bottom: -0.008542, + plane_right: 0.377934, + plane_top: 0.521089, + atlas_left: 0.002066, + atlas_bottom: -0.008542, + atlas_right: 0.377934, + atlas_top: 0.521089, + }, + ], +}; diff --git a/src/gears/game.d b/src/gears/game.d index adfaf40..a73bb12 100644 --- a/src/gears/game.d +++ b/src/gears/game.d @@ -9,6 +9,7 @@ import platform; import math; import core.stdc.math : cosf, sinf; import std.algorithm.sorting; +import fonts; f32 g_DELTA; @@ -77,6 +78,7 @@ struct Game u32 ui_count; ImageView default_tex; + ImageView font_tex; UIPushConst ui_pc; @@ -107,8 +109,16 @@ InitGame(PlatformWindow* window) u8[16*16*4] white_tex; white_tex[] = u8.max; + u8[] atlas = LoadAssetData(&g.frame_arena, "textures/atlas.png"); + int width, height, has_ch; + auto img = stbi_load_from_memory(atlas.ptr, cast(int)atlas.length, &width, &height, &has_ch, 4); + assert(width == FONT_ATLAS.width && height == FONT_ATLAS.height && has_ch == 1, "atlas height and width do not match"); + u8[] img_slice = img[0 .. width * height]; + + CreateImageView(&g.rd, &g.font_tex, FONT_ATLAS.width, FONT_ATLAS.height, 1, img_slice); CreateImageView(&g.rd, &g.default_tex, 16, 16, 4, white_tex); - WriteGUI(&g.rd, g.ui_desc_set, &g.default_tex); + + WriteGUI(&g.rd, g.ui_desc_set, &g.font_tex); GfxPipelineInfo ui_info = { vertex_shader: "shaders/gui.vert.spv", @@ -165,7 +175,8 @@ Cycle(Game* g) Reset(&g.frame_arena); - DrawRect(g, 200.0, 200.0, 800.0, 400.0, Vec4(0.2, 0.3, 0.7, 1.0)); + DrawRect(g, 500.0, 500.0, 800.0, 800.0, Vec4(0.2, 0.3, 0.7, 1.0)); + DrawText(g, 200.0, 200.0, 32.0, "Test"); BeginFrame(&g.rd); @@ -308,31 +319,66 @@ Sort(Game* g, Vec3 pos, Model* model) } void -DrawRect(Game* g, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col) +DrawText(Game* g, f32 x, f32 y, f32 px, string str) { - g.ui_vertex_buf[g.ui_count].dst_start.x = p0_x; - g.ui_vertex_buf[g.ui_count].dst_start.y = p0_y; - g.ui_vertex_buf[g.ui_count].dst_end.x = p1_x; - g.ui_vertex_buf[g.ui_count].dst_end.y = p1_y; - g.ui_vertex_buf[g.ui_count].col = col; + f32 x_pos = x; + foreach(ch; str) + { + foreach(glyph; FONT_ATLAS.glyphs) + { + if (ch == glyph.ch) + { + UIVertex* v = g.ui_vertex_buf.ptr + g.ui_count; - u32 index_count = g.ui_count * 6; + f32 w = px * (glyph.plane_right - glyph.plane_left); + f32 h = px * (glyph.plane_bottom - glyph.plane_top); + f32 y_pos = px * glyph.plane_top; - g.ui_index_buf[index_count+0] = index_count+0; - g.ui_index_buf[index_count+1] = index_count+1; - g.ui_index_buf[index_count+2] = index_count+2; - g.ui_index_buf[index_count+3] = index_count+2; - g.ui_index_buf[index_count+4] = index_count+1; - g.ui_index_buf[index_count+5] = index_count+3; + v.dst_start.x = x_pos; + v.dst_start.y = y + y_pos; + v.dst_end.x = x_pos + w; + v.dst_end.y = y + h; + v.col = Vec4(1.0, 1.0, 1.0, 1.0); + + x_pos += px * glyph.advance; + + AddUIIndices(g); + } + } + } +} + +void +AddUIIndices(Game* g) +{ + g.ui_index_buf[0] = 0; + g.ui_index_buf[1] = 1; + g.ui_index_buf[2] = 2; + g.ui_index_buf[3] = 2; + g.ui_index_buf[4] = 1; + g.ui_index_buf[5] = 3; g.ui_count += 1; } +void +DrawRect(Game* g, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, Vec4 col) +{ + // Y reversed + g.ui_vertex_buf[g.ui_count].dst_start.x = p0_x; + g.ui_vertex_buf[g.ui_count].dst_start.y = p1_y; + g.ui_vertex_buf[g.ui_count].dst_end.x = p1_x; + g.ui_vertex_buf[g.ui_count].dst_end.y = p0_y; + g.ui_vertex_buf[g.ui_count].col = col; + + AddUIIndices(g); +} + // TODO: integrate this with vulkan again Model LoadModel(Game* g, string name) { - AssetInfo info = GetAssetInfo(name); + AssetInfo info; // = GetAssetInfo(name); u8[] data = LoadAssetData(&g.frame_arena, name); Model model = { @@ -590,7 +636,7 @@ CopyVertex(Vec3* dst, m3dv_t* src) void ReadModel(Game* g, string name) { - AssetInfo info = GetAssetInfo(name); + AssetInfo info; // = GetAssetInfo(name); u8[] data = LoadAssetData(&g.frame_arena, name); diff --git a/src/gears/main.d b/src/gears/main.d index aaa3db9..56f785e 100644 --- a/src/gears/main.d +++ b/src/gears/main.d @@ -10,13 +10,9 @@ import math; import core.stdc.string : memcpy; // TODO: -// 1. Remove bindless (informed to be perf death) -// 2. Set up VK_AMD_shader_info -// 3. Determine how to better handle inputs -// 4. Make assets loaded from the disk in debug mode -// 5. Set up multisampling -// 6. Remove renderer.d and just move the interface into vulkan.d -// 7. Remove dynamic rendering +// 1. Determine how to better handle inputs +// 2. Set up multisampling +// 3. Replace standard library calls with nogc replacements void main(string[] argv) { diff --git a/src/gears/vulkan.d b/src/gears/vulkan.d index a55ee67..3697c92 100644 --- a/src/gears/vulkan.d +++ b/src/gears/vulkan.d @@ -21,12 +21,17 @@ alias Pipeline = u32; alias Attribute = VkVertexInputAttributeDescription; alias SpecEntry = VkSpecializationMapEntry; alias RenderPass = VkRenderPass; -alias DescSet = VkDescriptorSet; alias DescSetLayout = VkDescriptorSetLayout; alias PipelineLayout = VkPipelineLayout; alias DescLayoutBinding = VkDescriptorSetLayoutBinding; alias DescWrite = VkWriteDescriptorSet; +struct DescSet +{ + VkDescriptorSet handle; + u32 dynamic_count; +} + bool g_VLAYER_SUPPORT = false; bool g_DEBUG_PRINTF = false; @@ -352,7 +357,7 @@ struct Vulkan Pipeline r_to_rgba_pipeline; Pipeline rg_to_rgba_pipeline; Pipeline rgb_to_rgba_pipeline; - VkDescriptorSet conv_desc_set; + DescSet conv_desc_set; VkDescriptorSetLayout conv_desc_layout; VkPipelineLayout conv_pipeline_layout; @@ -454,7 +459,7 @@ CreateDescSetLayout(Vulkan* vk, DescLayoutBinding[] bindings) } DescSet -AllocDescSet(Vulkan* vk, DescSetLayout layout) +AllocDescSet(Vulkan* vk, DescSetLayout layout, u32 dynamic_count = 0) { VkDescriptorSetAllocateInfo alloc_info = { sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, @@ -463,15 +468,17 @@ AllocDescSet(Vulkan* vk, DescSetLayout layout) descriptorPool: vk.active_pool, }; - DescSet set; - VkResult result = vkAllocateDescriptorSets(vk.device, &alloc_info, &set); + DescSet set = { + dynamic_count: dynamic_count, + }; + VkResult result = vkAllocateDescriptorSets(vk.device, &alloc_info, &set.handle); if (result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL) { PushDescriptorPool(vk); alloc_info.descriptorPool = vk.active_pool; - result = vkAllocateDescriptorSets(vk.device, &alloc_info, &set); + result = vkAllocateDescriptorSets(vk.device, &alloc_info, &set.handle); VkCheckA("vkAllocateDescriptorSets failure", result); // TODO: look more into how to handle this } @@ -530,7 +537,7 @@ InitConversionPipeline(Vulkan* vk) VkDescriptorSetLayoutBinding[] layout_bindings = [ { binding: 0, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT }, - { binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT }, + { binding: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 1, stageFlags: VK_SHADER_STAGE_COMPUTE_BIT }, ]; vk.conv_desc_layout = CreateDescSetLayout(vk, layout_bindings); @@ -989,7 +996,7 @@ CreateImageView(Vulkan* vk, ImageView* view, u32 w, u32 h, u32 ch, u8[] data) ch == 2 ? vk.rg_to_rgba_pipeline : vk.rgb_to_rgba_pipeline; - Bind(vk, pipeline, vk.conv_desc_set); + Bind(vk, pipeline, vk.conv_desc_set, true); ConvPushConst pc = { x: w, @@ -1375,32 +1382,54 @@ Copy(VkCommandBuffer cmd, VkImage src, VkImage dst, VkImageLayout src_layout, Vk } void -Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet[] sets) +Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet[] sets, bool compute = false) { assert(pipeline_handle > 0, "Bind failure: pipeline is 0"); + + VkCommandBuffer cmd = (compute ? vk.comp_cmd : vk.cmds[vk.frame_index]); PipelineHandles* pipeline = vk.pipeline_handles.ptr + pipeline_handle; - BindPipeline(vk, pipeline); + BindPipeline(vk, cmd, pipeline); + + u32[] offsets; + if (vk.global_set.dynamic_count > 0) + { + offsets = AllocArray!(u32)(&vk.frame_arenas[vk.frame_index], vk.global_set.dynamic_count); + } vkCmdBindDescriptorSets( - vk.cmds[vk.frame_index], + cmd, pipeline.type, pipeline.layout, 0, 1, - &vk.global_set, - 0, - null + &vk.global_set.handle, + cast(u32)offsets.length, + offsets.ptr ); + u32 offset_count; + VkDescriptorSet[] handles = AllocArray!(VkDescriptorSet)(&vk.frame_arenas[vk.frame_index], sets.length); + + foreach(i, set; sets) + { + handles[i] = set.handle; + offset_count += set.dynamic_count; + } + + if (offset_count > 0) + { + offsets = AllocArray!(u32)(&vk.frame_arenas[vk.frame_index], offset_count); + } + vkCmdBindDescriptorSets( - vk.cmds[vk.frame_index], + cmd, pipeline.type, pipeline.layout, 1, - cast(u32)sets.length, - sets.ptr, - 0, - null + cast(u32)handles.length, + handles.ptr, + cast(u32)offsets.length, + offsets.ptr ); } @@ -1415,68 +1444,73 @@ NewPipeline(Vulkan* vk) } void -Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet set) +Bind(Vulkan* vk, Pipeline pipeline_handle, DescSet set, bool compute = false) { assert(pipeline_handle > 0, "Bind failure: pipeline is 0"); + + VkCommandBuffer cmd = (compute ? vk.comp_cmd : vk.cmds[vk.frame_index]); PipelineHandles* pipeline = vk.pipeline_handles.ptr + pipeline_handle; - BindPipeline(vk, pipeline); + BindPipeline(vk, cmd, pipeline); + + u32[] offsets; + if (vk.global_set.dynamic_count > 0) + { + offsets = AllocArray!(u32)(&vk.frame_arenas[vk.frame_index], vk.global_set.dynamic_count); + } vkCmdBindDescriptorSets( - vk.cmds[vk.frame_index], + cmd, pipeline.type, pipeline.layout, 0, 1, - &vk.global_set, - 0, - null + &vk.global_set.handle, + cast(u32)offsets.length, + offsets.ptr ); + + if (set.dynamic_count > 0) + { + offsets = AllocArray!(u32)(&vk.frame_arenas[vk.frame_index], set.dynamic_count); + } vkCmdBindDescriptorSets( - vk.cmds[vk.frame_index], + cmd, pipeline.type, pipeline.layout, 1, 1, - &set, - 0, - null + &set.handle, + cast(u32)offsets.length, + offsets.ptr ); } pragma(inline): void -BindPipeline(Vulkan* vk, PipelineHandles* pipeline) +BindPipeline(Vulkan* vk, VkCommandBuffer cmd, PipelineHandles* pipeline) { - if - ( - vk.last_pipeline[vk.frame_index] == null || - vk.last_pipeline[vk.frame_index] == VK_NULL_HANDLE || - vk.last_pipeline[vk.frame_index] != pipeline.handle - ) - { - vkCmdBindPipeline(vk.cmds[vk.frame_index], pipeline.type, pipeline.handle); - vk.last_pipeline[vk.frame_index] = pipeline.handle; + vkCmdBindPipeline(cmd, pipeline.type, pipeline.handle); + vk.last_pipeline[vk.frame_index] = pipeline.handle; - VkViewport viewport = { - x: 0.0, - y: 0.0, - width: cast(f32)vk.swapchain_extent.width, - height: cast(f32)vk.swapchain_extent.height, - minDepth: 0.0, - maxDepth: 1.0, - }; + VkViewport viewport = { + x: 0.0, + y: 0.0, + width: cast(f32)vk.swapchain_extent.width, + height: cast(f32)vk.swapchain_extent.height, + minDepth: 0.0, + maxDepth: 1.0, + }; - vkCmdSetViewport(vk.cmds[vk.frame_index], 0, 1, &viewport); + vkCmdSetViewport(cmd, 0, 1, &viewport); - VkRect2D scissor = { - extent: { - width: vk.swapchain_extent.width, - height: vk.swapchain_extent.height, - }, - }; + VkRect2D scissor = { + extent: { + width: vk.swapchain_extent.width, + height: vk.swapchain_extent.height, + }, + }; - vkCmdSetScissor(vk.cmds[vk.frame_index], 0, 1, &scissor); - } + vkCmdSetScissor(cmd, 0, 1, &scissor); } pragma(inline): void @@ -2010,6 +2044,7 @@ PushDescriptorPool(Vulkan* vk) { type: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, descriptorCount: 4096 }, { type: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, descriptorCount: 4096 }, { type: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, descriptorCount: 4096 }, + { type: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, descriptorCount: 4096 }, { type: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, descriptorCount: 4096 }, { type: VK_DESCRIPTOR_TYPE_SAMPLER, descriptorCount: 4096 }, { type: VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, descriptorCount: 4096 }, @@ -2078,7 +2113,7 @@ InitGlobalDescSet(Vulkan* vk) VkWriteDescriptorSet write = { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: vk.global_set, + dstSet: vk.global_set.handle, dstBinding: 1, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLER, @@ -2103,7 +2138,7 @@ WriteGUI(Vulkan* vk, DescSet set, ImageView* atlas) VkWriteDescriptorSet[] writes = [ { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: set, + dstSet: set.handle, dstBinding: 0, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, @@ -2124,7 +2159,7 @@ WriteDrawImageDesc(Vulkan* vk) VkWriteDescriptorSet write = { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: vk.global_set, + dstSet: vk.global_set.handle, dstBinding: 0, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, @@ -2140,11 +2175,12 @@ WriteConvDescriptor(Vulkan* vk, Buffer* buf) VkDescriptorBufferInfo buf_info = { buffer: buf.buffer, range: buf.size, + offset: 0, }; VkWriteDescriptorSet write = { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: vk.conv_desc_set, + dstSet: vk.conv_desc_set.handle, dstBinding: 1, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -2164,7 +2200,7 @@ WriteConvDescriptor(Vulkan* vk, ImageView* view) VkWriteDescriptorSet write = { sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - dstSet: vk.conv_desc_set, + dstSet: vk.conv_desc_set.handle, dstBinding: 0, descriptorCount: 1, descriptorType: VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, diff --git a/src/packer/packer.d b/src/packer/packer.d index b2d893f..5c3ea92 100644 --- a/src/packer/packer.d +++ b/src/packer/packer.d @@ -6,9 +6,10 @@ import std.file; import util; import std.path; import assets; -import assets_codegen; import std.traits; import std.algorithm.comparison; +import core.memory; +import std.json; AssetType[string] Lookup = [ ".m3d": AT.ModelM3D, @@ -24,7 +25,7 @@ string[] FILE_NAMES = []; ****** UPDATE FILE_VERSION AFTER CHANGES !! ****** **************************************************/ -void main() +void main(string[] argv) { Log("running"); if (isDir("build")) @@ -32,8 +33,117 @@ void main() chdir("build"); } - PackFile(); - TestFile(); + bool pack = false; + + foreach(arg; argv) + { + if (arg == "pack") + { + pack = true; + } + } + + if (pack) + { + PackFile(); + TestFile(); + } + + CodegenFontLookup(); +} + +void +CodegenFontLookup() +{ + mkdirRecurse("../src/codegen"); + auto f = File("../src/codegen/fonts.d", "w"); + string font_json = readText("atlas.json"); + + JSONValue j = parseJSON(font_json); + + assert("atlas" in j, "atlas key not in json"); + + FontAtlas atlas = { + type: (j["atlas"]["type"].str == "softmask" ? AtlasType.SoftMask : AtlasType.None), + size: j["atlas"]["size"].floating, + width: cast(u32)j["atlas"]["width"].integer, + height: cast(u32)j["atlas"]["height"].integer, + y_origin: (j["atlas"]["yOrigin"].str == "bottom" ? YOrigin.Bottom : YOrigin.None), + em_size: cast(f32)j["metrics"]["emSize"].integer, + line_height: j["metrics"]["lineHeight"].floating, + ascender: j["metrics"]["ascender"].floating, + descender: j["metrics"]["descender"].floating, + underline_y: j["metrics"]["underlineY"].floating, + underline_thickness: j["metrics"]["underlineThickness"].floating, + }; + + foreach(val; j["glyphs"].array) + { + Glyph glyph = { + ch: cast(dchar)val["unicode"].integer, + advance: val["advance"].floating, + }; + + if ("planeBounds" in val) + { + glyph.plane_left = val["planeBounds"]["left"].floating; + glyph.plane_bottom = val["planeBounds"]["bottom"].floating; + glyph.plane_right = val["planeBounds"]["right"].floating; + glyph.plane_top = val["planeBounds"]["top"].floating; + + glyph.atlas_left = val["planeBounds"]["left"].floating; + glyph.atlas_bottom = val["planeBounds"]["bottom"].floating; + glyph.atlas_right = val["planeBounds"]["right"].floating; + glyph.atlas_top = val["planeBounds"]["top"].floating; + } + + atlas.glyphs ~= glyph; + } + + + f.writeln("import util;\n"); + f.writeln("static immutable FontAtlas FONT_ATLAS = {"); + + f.writefln("\ttype: AtlasType.%s,", atlas.type); + f.writefln("\tsize: %f,", atlas.size); + f.writefln("\twidth: %d,", atlas.width); + f.writefln("\theight: %d,", atlas.height); + f.writefln("\ty_origin: YOrigin.%s,", atlas.y_origin); + f.writefln("\tem_size: %f,", atlas.em_size); + f.writefln("\tline_height: %f,", atlas.line_height); + f.writefln("\tascender: %f,", atlas.ascender); + f.writefln("\tdescender: %f,", atlas.descender); + f.writefln("\tunderline_y: %f,", atlas.underline_y); + f.writefln("\tunderline_thickness: %f,", atlas.underline_thickness); + + f.writeln("\tglyphs: ["); + + foreach(g; atlas.glyphs) + { + f.writeln("\t\t{"); + + f.writefln("\t\t\tch: '%s',", g.ch); + f.writefln("\t\t\tadvance: %f,", g.advance); + + if (g.plane_left > 0.0 || g.plane_right > 0.0) + { + f.writefln("\t\t\tplane_left: %f,", g.plane_left); + f.writefln("\t\t\tplane_bottom: %f,", g.plane_bottom); + f.writefln("\t\t\tplane_right: %f,", g.plane_right); + f.writefln("\t\t\tplane_top: %f,", g.plane_top); + + f.writefln("\t\t\tatlas_left: %f,", g.atlas_left); + f.writefln("\t\t\tatlas_bottom: %f,", g.atlas_bottom); + f.writefln("\t\t\tatlas_right: %f,", g.atlas_right); + f.writefln("\t\t\tatlas_top: %f,", g.atlas_top); + } + + f.writeln("\t\t},"); + } + + f.writeln("\t],"); + + f.writeln("};"); } void @@ -206,7 +316,7 @@ InitModelHeader() ModelData ConvertModel(u8[] data) { - assert(data.size > 4, "Model data too small for a magic number"); + assert(data.length > 4, "Model data too small for a magic number"); u32 magic = *cast(u32*)(data.ptr); diff --git a/src/shaders/gui.frag.glsl b/src/shaders/gui.frag.glsl index 93b5149..335fc23 100644 --- a/src/shaders/gui.frag.glsl +++ b/src/shaders/gui.frag.glsl @@ -15,5 +15,5 @@ layout (location = 0) out vec4 FragColor; void main() { vec4 tex_color = texture(sampler2D(SpriteAtlas, SamplerNearest), FragData.uv); - FragColor = FragData.color * tex_color; + FragColor = FragData.color;// * tex_color; } diff --git a/src/shaders/gui.vert.glsl b/src/shaders/gui.vert.glsl index eac1cc1..062a7b3 100644 --- a/src/shaders/gui.vert.glsl +++ b/src/shaders/gui.vert.glsl @@ -17,10 +17,10 @@ layout (location = 0) out struct FragDataOut { } 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) diff --git a/src/shared/assets.d b/src/shared/assets.d index 0148607..bf68e9d 100644 --- a/src/shared/assets.d +++ b/src/shared/assets.d @@ -123,6 +123,56 @@ struct AssetInfo bool Asset_Pack_Opened = false; +debug +{ + +bool g_DIR_SET = false; + +void +SetDir() +{ + if (exists("assets")) + { + chdir("./assets"); + } + else if (exists("Gears") || exists("Gears.exe")) + { + chdir("../assets"); + } + else + { + assert(false, "Unable to set directory"); + } + + g_DIR_SET = true; +} + +u8[] +LoadAssetData(Arena* arena, string name) +{ + if (!g_DIR_SET) + { + SetDir(); + } + + File f; + try + { + f = File(name, "rb"); + } + catch (ErrnoException e) + { + assert(false, "Unable to open file"); + } + + u8[] mem = AllocArray!(u8)(arena, f.size()); + return f.rawRead(mem); +} + +} +else +{ + void OpenAssetPack() { @@ -260,5 +310,8 @@ UnloadAssetData(string name) } } +} + + diff --git a/src/shared/includes.c b/src/shared/includes.c index b4662be..5350278 100644 --- a/src/shared/includes.c +++ b/src/shared/includes.c @@ -6,7 +6,6 @@ # include # include # include -# include #endif #include diff --git a/src/shared/util.d b/src/shared/util.d index e6e8377..243852c 100644 --- a/src/shared/util.d +++ b/src/shared/util.d @@ -8,6 +8,48 @@ import core.simd; import std.conv; import std.string; +enum AtlasType +{ + None = 0, + SoftMask, +} + +enum YOrigin +{ + None = 0, + Bottom, +} + +struct FontAtlas +{ + AtlasType type; + f32 size; + u32 width; + u32 height; + YOrigin y_origin; + f32 em_size; + f32 line_height; + f32 ascender; + f32 descender; + f32 underline_y; + f32 underline_thickness; + Glyph[] glyphs; +} + +struct Glyph +{ + dchar ch; + f32 advance; + f32 plane_left; + f32 plane_bottom; + f32 plane_right; + f32 plane_top; + f32 atlas_left; + f32 atlas_bottom; + f32 atlas_right; + f32 atlas_top; +} + struct TrackedSlice(T) { T[] slice;