From 44fe2c32818c91352075099225f58ac465efef65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sat, 15 Jan 2022 17:50:52 +0100 Subject: [PATCH] Start of gamma correction --- GlitchyEngine/src/Renderer/Texture.bf | 4 +- Sandbox/BeefProj.toml | 2 +- Sandbox/content/GammaTest/SmallLines.png | Bin 0 -> 2296 bytes .../GammaTest/gamma_correction_brightness.png | Bin 0 -> 45566 bytes Sandbox/content/GammaTest/zeroPointFive.png | Bin 0 -> 153 bytes Sandbox/src/GammaTestLayer.bf | 169 ++++++++++++++++++ Sandbox/src/SandboxApp.bf | 4 +- 7 files changed, 176 insertions(+), 3 deletions(-) create mode 100644 Sandbox/content/GammaTest/SmallLines.png create mode 100644 Sandbox/content/GammaTest/gamma_correction_brightness.png create mode 100644 Sandbox/content/GammaTest/zeroPointFive.png create mode 100644 Sandbox/src/GammaTestLayer.bf diff --git a/GlitchyEngine/src/Renderer/Texture.bf b/GlitchyEngine/src/Renderer/Texture.bf index e7382c8..d18d9d8 100644 --- a/GlitchyEngine/src/Renderer/Texture.bf +++ b/GlitchyEngine/src/Renderer/Texture.bf @@ -127,7 +127,9 @@ namespace GlitchyEngine.Renderer Debug.Assert(errorCode == 0, "Failed to load png File"); - Texture2DDesc desc = .(width, height, .R8G8B8A8_UNorm_SRGB, 1, 1, .Immutable); + // TODO: load as SRGB because PNGs are usually not stored as linear + //Texture2DDesc desc = .(width, height, .R8G8B8A8_UNorm_SRGB, 1, 1, .Immutable); + Texture2DDesc desc = .(width, height, .R8G8B8A8_UNorm, 1, 1, .Immutable); PrepareTexturePlatform(desc, false); diff --git a/Sandbox/BeefProj.toml b/Sandbox/BeefProj.toml index b3e6da3..6ebf7a4 100644 --- a/Sandbox/BeefProj.toml +++ b/Sandbox/BeefProj.toml @@ -5,4 +5,4 @@ Dependencies = {GlitchyEngine = "*", corlib = "*", msdfgen-beef = "*", LodePng = Name = "Sandbox" TargetType = "BeefGUIApplication" StartupObject = "GlitchyEngine.Program" -ProcessorMacros = ["SANDBOX_2D"] +ProcessorMacros = ["GAMMA_TEST", "NOT_SANDBOX_2D"] diff --git a/Sandbox/content/GammaTest/SmallLines.png b/Sandbox/content/GammaTest/SmallLines.png new file mode 100644 index 0000000000000000000000000000000000000000..01146f6714a6ad941b9cbd39ecb0c386a744d127 GIT binary patch literal 2296 zcmeAS@N?(olHy`uVBq!ia0y~yVB7)3IvgxO5owdWTp-0+;1OBOz`%DHgc*qb`A*0$S=t+&d4uN@N{-oC@9KL%gjk-V5qp2oRBc@!HY*vPN^I?5D*X&^hEB7 zgruP4(gSt#8haaOHiCen;m#cg3>6NvgV_4^`coN24U7zGb{{)%;=q9e1(DY;9z8j= z(d59an1GN&K!JwF#)BHFTP=XPA96D@J6BbDI&v~IC-X2fH+uw?f!T~8cA3WnW1u)t zjj+FGmMc&Vb8~T>V`^Ypm0M@i!lg@>HYI!21+8)_NGQs=vWt+%m?J64+@o8ZdU3iXeipM4)se;BW`KzW1n zh0qUO0jn%?rM+51d(C+xeN)cKTUwbkpG*%r4Qti!9b*^}L6)lJh?#aY8E%~{J+`Ahv{^@a1L z<;(9U>}UD^r{ULuPDk(N^41uhTFG-FisG4~qJpu4#>Qp-cbZwYx!hf{;Yr&R)0O6z zEsb=Hj5j|^i$9Zke)IYD8aG0Itc%#KvbrSn=4`INrzWk6HSO6NR~r0U-t3j>Rg?L- zQ?s>m>~Cq_4ZTvkD}3wvjsM@d%=X-@{(r8N{o4;by)*xA-gn+}Ms?M`pG`}u?|s^qJKM)B|7O;v+~0hw=l(9={myc?e$M~qX3O?ExlDVt zx|*Y&uY;eTQA&co<>GcGwMKvcyn5aA{-Hf<-P~W7f1UsMzn+1Yf#2lUw2!gCjKh-d=~)xqguIfP#RlBdfRfuS>fo-Sc6Mj1=(y?Db^vv>%A~^Ty>k}UqQ>~_RsCgbL-QMu@fCb#0M5Epa~W$h(d?xVg*qUQCO^?hVPEewag4&%U|#2ZPWb% QEP)w3UHx3vIVCg!07^iCMF0Q* literal 0 HcmV?d00001 diff --git a/Sandbox/content/GammaTest/gamma_correction_brightness.png b/Sandbox/content/GammaTest/gamma_correction_brightness.png new file mode 100644 index 0000000000000000000000000000000000000000..52e33b490f24de7fcde0f15fd05d6a2e4903e691 GIT binary patch literal 45566 zcmeEv1yr5OvgXDK76|SH2@V@~cMldIxNO|rCAbH72@ry7g1Zv}1P>70Jy>v<%~9^T z=f2!K@6F7bwZdB2RJyCG|NgqVy1KgePv~=b31kF31ONblEF~$b1OPy)gK1rONbqN4 zCIcS$*CSg=4F>=K5&ixj1RymX2LM1&FcT4Z{@m2Y(Z<2l#+F1%M1;iF-p1I>5(EIa z&SWT?s3>n?@tw_|2+M@{#>?0!VZxIr35WY)#5|*U`Uq7zRDQ45cESJw*{cWR~tQbxFLf8oO|=~(vr5pwE!So#}MHGZE|UCK!V`A z$J@dwS`fYg5N(bzoHFpf7yv={DB*m7pg4qYM)EUdKsGc$Z@|!C1@N36phxMmJ_hj3 zI8X6_0BFWP#e~R?0g#}BLPPAT{5B!36jA_{MbzrEF-3J*oypmwvky_KwuR zVC8mgxY$+@09bPL9=WAstj6=@f%Ubz&7s(bHq}AQb~+0;u6iu^0g$~lqjqe2kB!)y z*Y(rWYpbhYq`QPQ^*^e4-I{dhwyE7%UU>6fpPeqYER*{&Yx_w+pD%WNI+1-#FdX|R zz~Jk8w8V8S;@vgj7-^T3LA^Q+#){$-yC~7rh-2orq@lvG)ZG-LcSg$#bXQRP3v7T2 zbAAYq82SQjL#XdEl&I>CZOdl>z)_=3`#2Rml&`7((y+_jfxwMKHU+@fSSr>I0MHR7 zXHfZAEzk=O0ElM$(NqZGpS0u9wZRg!!+dQ=yw+n65GL>H5JnY7F!Cj^*P||ZB}^4G zSV2gm$2cxX$l9i88Wd-X!qA~whr(z3_);G}vz@BR?-8_6A3VDL)0q$mgD`cnD0u9Y z!1Jf=lF(1W$w~S{Fce8;V%Q{^l)_XC9*-}A{msVbV$;Vn(flI4z_v{sIF>F;AVW{5 za3v?*qd3EXO41Uf;vT$;7bQ@Qp{It!l`hav{KVQGu|vBEljsu(Nvg}L%YTt9AR!=U zMVooV@dzqFv4fH{u0ZDfvj((_E*t}9reJkRI zDic>_QC=y0G@e+jT9om8M;Tw)q>!f|xX7fyMnxdcTjM4aR-;q4Q$Zw8F}qTCrKyJm z(Ga)VmF}qpa&eH8A6wV6%E4(*XPU<38^XqLzM{f6Tp}#eENazC$MMDja4X4n=jo2} zk2a{@B^`T*&0`!;FH_^^v&z;pfwU}&5|a|uizSN{izRlN*~|9cW#l)DHELY>p$PR# zQ)*F4m_!f3WNau;E6=?{c!wp&$9-DHP-O8I|4pN)ORM#}{p8FR9p6k@n|JeW%^Q~l zUW_*?H&&PLP9>1kVXKkIVP}zsaCp1f>}+@m8GC0B6-Bf=1x4QKC+H_F1;o^k@a9g4 zM~Xj=FzeA;Az!iTvFgcv2K(&kGa0#Ux&2fnx%zzSd>&aI+1|lVgE@nfDQszcOjFDo zX&Y%%X$!S_FI`{K)fCj!fuyQdU*>D<*ECrNzU0z)tFHP|yIQ<7qm*K@v9$3W+PixB zIQintNt4cs!aD8+;? z3B4WO+hcIQ;GRz%O5Ydo>OM)_Vl+`7MjigbvQmRSK;31Qp`11*VS;T^@8EwN5*{k^ zYJee$pCJvuXRfb#Rod~?PJ79H^fV)_I;~@`V77dpecx<9_-ocD)-38w4Hk#boqZyU zifbbRh*=3hi-i(z1rY^5lMfqYjE0OcYNb;ZwQpUD&h!tk`M>kqXRYwB@N&#E&ui#@ z;%KYws~u42w8_*BToCagyED3TzZ(I(^QC|=feQ5#^3#O8I(PSc+8QOmJq!9?HN7Vk zkzFr@DHQ#x^wnB>=~L6b-Pfg0&o+{WVus960-t+tPJV{dU)K-s^hTl#3=UKa5{R-5 zQO6r$N@8;v`6}YDAbKg9C_0~J!lb}ePA|jmfsjy0P;>2`I4Yw%a3FgfTk|$ZMvb0O zeZ9HFoU4l0&TST91rvrg=ml&EZ(Udojn#xg@t#^znRoLucR33`o%WBf+CM;8>>#Ql ztOa`Qe4X0UR#0cuSoolS8I*y~j~NZ|J-ez48Q)|9XD?+c5&>Wzkt zM~%1E=jk&wQ4))i){{`Ik*891TZgBxHDbGhBSto6V{5*f1PgFn?@w(17Z=G%9u%zQNPP zGo*D?=Xg{#yN0e-rS|rnBJILR~sNZ&fA{yW@w;s+J$nzv`L{!_e5|{Xj)`0ctSw)_Uo5} zuRi8&F4@N;UnS091O10@V@{(Vi@-#uL=OZZ2km5X@^f)53)tUmUB43^$cE`$fU z3y&36JxP41?o2N#PnAEvyNbh&i@Sq{NNz~<@ zlZe>ZgGksI*ys&`%uFO4TntQXY#bcSbR^6`CRRou6C)D~Jrfru6?UO>(bS-@wMnk&l%0zM(&Ue(RT&?H>(UJN$+n7)3@` zeOpE*1|Z|#2^kswA!F-gZ~4ok85uHyEJ0QvYexsL9Mj**fgzQX`$P0^o3pa|TS*5; zF=ucOenaGMB^^}UY(b1lAO{;Kdqa?zGx$l!{_f!&9F;(Sg8Of%0<-_EBHQ1$GJpSE ze^mcV7#+=w|HXsc*ZfN{kgM6h5WBDWRqPj=`gN#z!KibK*n{*PZR}NSY%KYIHP=5k zV&Hw)y?K&QshL?D*|<1R^D_QbrKk)ulkByO;vD?3;n9US$o4M9?({NMrxGczM@P6JM6b^`+rdSiAV zGd&kOD~O)cfQuPC(}6$^b|wQuW_F`r;E9h$i@(?{trXq zW@R^I0~#3_(t`|G^y!(HK&>c=x?QN_`^lfb|%?$PLT`8lpwb5_!;2$dxiK7k4gJtqp+#l%p zzi6dKAbYd_#KSyzO2gk_BKiNU&;MV>{%q}cZ!&7mqfLtAA_1*40+n>_+3+?@I2lPW>YE z*P6eT)c8}9i|wJ{gNok-e>Ii|DYjoc$*-m01Rgkd$oNO{@SmK_uXFo<`18*m{SPaC zsP1PY57GD`{S&SqLiCW~CtMHF_#yoht{+15kl`m>57GD`{S&SqLiCW~CtMHF_#yoh zt{+15kl`m>57GD`{S&SqLiCW~CtMHF_#yoht{+15kl`m>57GD`{S&SqLiCW~CtMHF z_#yoht{+15kl`m>57GD`{S&SqLiCW~CtMHF_#yoht{+15kl`m>57GD`{S&SqLiCW~ zCtMHF_#yoht{+15kl`m>57GD`{S&SqLiCW~CtMHF_#yoht{+15kl`m>57GD`{S&Sq zLiCW~CtMHF_#yoht{+15kl`m>57GD`{S&SqLiCW~CtMHF_#yoht{+15kl`m>57GD` z{S&SqLiCW~CtMHF_#ypY!iDhX>o`Ex;CFDifM2$;k1vu9eo+UBp`?-=0N_pm0QmX? z02g=Q-&+8H6A%E{)&l^zlK}v1n^@g$aRA`{+xJ2$t~0w{Zmud5b9ZOyjYFBT-}{9n z)ggl_g2l*%J{K`jO(@0Zm(tp3CUul2%uG(IT}|eAQHOolFa6+KI*D9ZK#~&@B2EG= zD%p`J%g!9vPv;`Aan>8CA1h1x#By);%FWZWqj|&oKx03B_`-T4yQ!(kmJV8tpS?4-oCd*8AU8KRu;=390%zq-Z3bvMGcz+P3MIHxQAH)sZ00lm(DC)*O0R#rp0%~L zj!tF{)rL{Y*}($iz)_vuijtC2kd8tkh%BaWf36WmD4EF+R@ihi!>oE5g_z%SvCS_% zJ>6_9zrTw2Bq%)Rd?}c?rlv+dm9;QCdr|AgdEWDQP@T>g?F|g#-ScJs9w&kKT7sH-V)M~QS}XS1 z&lhbghn`3Ml#H#{_CiAK(LUEJdO*&Tpm*=y-7P)#`BGyw+l{U3IVQ*Pp{54K3x*_Y zIhH~uidewAm(b-?I#+dZvBf6xLaoihRO{{O`1tq-iz#~oj+3EJ{rwuv?x$9@b1yVB z>Yevy98NPBb(&oFWrkhY~D@>AZQ$3NlYMW`G%zGD#)Gi4>omomEKZWODR- zMUqULSyomyIXU?T-I)%Hh1M7+XyL#_!+A5K9~hy*%9C@mEqm(&$@0g_x7m>0_UBk=6xWWo4GGvTEBGl1LXKCR#)p zDYA||Hh0&t;8*`;2nCRe0Zx!+Ud1}KZ}1Bb2gYk}D<+y$7-{nDi z;zlg9a0CzW{QMecl!ZPNm470&T_zP0!Z$NcaVH@6F~ zvpF?I#Y2U%8$T$xYwx@HW{;a70kCj*h!_wc!3{zDI;MbL z*kCI0c(EYgeq1^Ts$h5`-wEY#0|?q@8mZ`*Ow-!bV+x$ju&PRp0z*i|T^MovmoO7JA0@x{XHe&o5)9*v#DCj= z{}}?-^_6X_Ti0ijGZxky7_HM)+Ov4S%V4Af#(Ol2X_XmAuXk&vv%2YK(t?$;Wg zOE`A7@H$2XvhMwP0B53peJhdXrhc0~x-tTKm1tA~x`eBcu0HB)-@C3jP3{G&F+Q`J z)M>6HEUwq)rmH77#v$MKDSLft>U%)~QtJV)2D<%ow4J@%Bgd3Hd@N)Ul$^aQ4%#_1 zEkstEMl=MpfzHyf#IH~I^SU4LmIvy7J>QBWhJH*7G*g+}Q;U}!LM63d*hQRt#`&R) zZP@B=VyBcozIA)K>h8AZ+!KG60yk7v7R`C~LS1IeCiCjNKia=x@Nn-U&Zk8$0{=ac z)9dl?fm#myIu4j)R9uzn`2e%sF4w<{RA&gaD&XccvJ%>VP98 z>&F*Z^eGMpf66ZP!}b9-rgp^PFpb3=n(Q^%dBe%2|3CD15iMUG0xkE7LNo zDbCGZsq7_!^39cqPE1UEp{AC0M*x4Q!xsnfvc^(_6)zG|wnX(VP_c?bk0;a|-f9e^nAgB#w$^$HO;l6ME6HY->w;JC*l@yi91u_d`;XD;h{ z=2$%c4A$I6WFXZBPmFV6*9<}fzfj+NF+B-B(2|m<{BxA&OpfqAKd;C$;)oyy1W!mC zTwXzJ*)O3EyeFHs&&i&Ddzz^u%}?_R-cNKd0wJVE+=~&WX{)BqHEo{yZSy3xPP}(r zGKbNtxGl|bKQj~7<7P?eA`xy--d=Zyd_WD`7aeN}bkA)Z*r{3s1@RGN!&Q|CmDoC^ z?104;O3oCvd^cngJ-~Bc6_gWx@=pfxlSI>a7tec+#Y5Fc=PxrBGFho?&3Q zvZ1Ol6=IMotnx~7Lvd-4vvCMd4P%6b^pX(ip z;+Dia#%CS3Dt6#-2Ovm-3h@2-@#E;|D9=IDSh`?wQBe>wKD$8|yduVm@_ZF&V0|dV zf`9qc9bEIG^yLTd8~3r;7dkrDLlrvZF8g2WUFO~1aa9gw@-g&7K!WoF;UdH6=wwG&o4ou}0O?G_#n^%5X_WEV{@kHB#m6juugjaWg;uAX$^JM>wHGf^VLl1ujF@U`XH264 zfD2$0(2Gy%JCn`>lM|ST2{td2#Qi(Fk7TwgH*ybJ!SBVM-Ry3yl56BWnrvv1jwl^} z!JXlGDY_fy0s;8G_d)fpgWuUW@B5w(tn3`{>&5^~=Y_ulH_8E^&A>y`^+?se9iq3L zkfhEX9RgyAGP*(OFcO;H_aqNX#s8^Rt%Z3~!CFmIInnV z>LL`DTZa)+!o&F8RfC6?Qy}dOfvcsl90B zq+e9uQC@?+2mf}%_`N|Jd8l`3vGgU}Q^xKp+I}xoF2|Czh4G$G1endwbPWNju7L{^ zk8EnU!x5acg$_-CkQ&{DXvthk8u8`S+fp(XDxC;IL(nPmnN7!q*Fx}ji%+KBa?#}* zrBd3TNsNB?w3dH1xf-`F5b#>C&w^Nn9%U)Xf$%Lg4pfQ};=+~U?gT+u{_DsL=MHAl zP`<|cX4;9XljY?ql|<3z;w*uaRZXk0qhRbRN%q3mqpuM zT_H-~gYNC*vPLoE;2Q3XQl|4>*khmS!Pfnv9E|Y+w+5Fh%ClC&=9{Dibyc<}ZFNqs zN_U55Fm15zZg&Ee)OJ-&?41cNJBeL($L)0*?!ssXssIshm6c_Dnpf07ZjT4|1cY$s z2qVwt??ykK8NOnq4Mnz%iZB~{haA)bRS)rO;^Bk=4`&e?Ch^9IzdC2GcAB0}iRH@O|s8ums-dK~SyTv?Y- zHJVS*C=Y=h1vu6(6ixLc3(Ijk%TKd5x3(rCmmD1jy1Tm%HTirT7)VP?1HXZ|T<5*1 z;`Ic0&hfbHH(hQQTbP?$H}0{wE(rMCUY}Q|aoCg<6-k#k8@Lt~N(tPYjIpt?fhTTs z;|YL7z^CFgW@@K-Bh$m&+#I}q6KNz4s`d#&jc-hgg=1ZKwnz|rjhCo;c{S4wfaTUZ z-bP=m7QYD1sdGIvhztINLpnD3Qdv2!PZr!;Hhg>V)(^(Ny^98!*>hrIB2>3;^sS6s zpm+98{|o<2>Lj`*>%$xy^5wKCt=jXVQPKnKb6g|&bx|?C_iN*=Jn=z$<1C?ez#EL- z{$vZavsRDo4IjzrR=CG$5gK1-L;CUNk3&XD90_uolD;S_4hIV_LLWv@5M+y%qm7{E zQNOK~+$wQhWMhDgm-{}J&u#GasU`#2o2l!_>2!)PFE5TA@LNg{kEvh5|=&Xtpww19$xjcuDKflZB` zj0|K)XhNcc(x*g4kR|RV^OuygBhI~a`)-Yv%pmtX<(sRA`q)=1?)5lV7AFYH*@kL1 zeqN!^PO)85eQ2h;#$@bP#;H%KWj&C1__i;I+*!L|+4L04xfElkbCLQ#;AWFe3x@d_ zaKG@-1yYA}{I=OnjFpU;OAedc?*{d`SkCgPaWf<|ces%$ zT^cfR-l)q)lNgJ(NRYqOj5jv+KvY^Zl^jE#jbZ{cDbD6a5!~EtwWzCAe9*>YcRD)j zMM!fdwupSnG@nMG;BPfd7$)1e*hKr0S$L1~KWnk5XWt~pGG(!p^kqh`(S zq^1pwuhnc#N_8Gp*ldkeI4vALhc&eCBlKro#7MCI#cJhc#lzdK@&bmzcY+ zERU^CmTKbT;e~~VU!f;Rxl&M29MZ0f^W?9U*45ROl`-%ugEv;pI7q3fx*8f9c6N5) z3E?(%aJJyKk>T$;CHso0fBln}rCo~Gwi%5BcqM9_^r6S#XPob;XuG~^EFl2`m))#B^j*@fFL+$kn_c_?ChEF z**RAd{9q-g6S--qeflHe)SqsPYz?w*ngw7&C z=0Iagt3+((We=f5d5pd#C<^ll@>{&BZ9(UvQs^c`4&~6tc$l8n_R|sbH>b*N!uAOX zkli`$_U!eDueU5$APinT2|d(-vO8Qv4uk%jcBIg>H)<4#27u3x=y|J@7xohMDZ3wh z3<4=+r&umDCjbc052?g}>i{t-#7LUao_!FigO7r5!);D?q$+W6 z7I$K5kjDY!p>3}kAy*P|55M6@Ag(m@B#)oc6Qxy}h3+!#Zwi6+vqgH#6&li>KFJ1& zOJpzH4S{L*2>q!zYRJj$e~%y5B4(dU+bTM@iMu`R~{KUNC-__ z!|Yt|^J^qLmjospZYc5SG~69=;@$1~ub1^79bMv z@cJi_L!nAO;Z%lhm;3&{pI4q=n}@5xL}4~nvicTUbJjsAt zocu{QOkf$&>m8mP=i3t+xrEcE*z{tAfDPRu4{zP**4&+~scn8mUV+S*wKi7k#BLl2 zoZG}N-$u;j1C0D3RgnkTowcM5HNUA#K3NV2MhL!`)nKO|j0&N{hsRAtkS*)Ojp=(- zXyd@TdUK&rHru+rP22mnH)mULNN-DYmVcUynpWR?pg*&7tY^i~C(`WXa;H36!JM)A zB$g{YMS1v3rJ)?<^P@ybrMu~mDqEN5drHd6E4O*=8)slcy}Y~xN3>N{RbZMzCNU(( zbTk1sBL=)3doR7x6A9(ZvOr^I`|3g~nK2CU(7hR83*I;;qi_Kv6%-DRCBZqUz8Eq> z6p1@cJ7?ZT^W=i^az;i*jtmDWxPo#r9@LOC761ko7Nnqq!?EBIgdj%uF!Fq;DCuGA zU}Vx)>$44%h0D{O;^JajTH52|V+#w56`fChWt4uN*M(~f-sYQ$it`ZS@kOD^?;()j z3}^%`Y=&bAd%4|v2h9NN@jzM#3SZ0kmDf+iM4@&8*#IOQgo=~^G`}7|9Vgl=wAGm# zJ<0KP0`gaxq<*A}$dBZA%yA0jD>6tD-=3&QL&0pkh_tnK7MF+(m?O7c?( z)+BA?w#9M8FL>uE0uLc9$c7pbXZGYU8(khY2?5((+0Xjjk&?_lVP$O?3+9+QYtcQYZs4T~3vPq!yw zM)HlqFfjJa=Ct{6wzzM-4v=X=@j?=km&nE^ESn+6CjgICm85Ixy_ zD*21tH_jnNuLJc~h9m|3Uui{kolMmPpE+*|(9}*R>-fnsiDCQpzpvbuip*lh0g6=? zn7LX%fj7|-}5n7nrpN4Gac^&KUADn``U$0W+qIHU)SB3wx% z2IXi@n2*0`CnwP}A2b9XF?@s?T6sK2IsX{?S~!XhqRyjQas8VG3j|6fw{3U!=A~r+NKm`&va@yyP^~zpQcnOC6mcWdR?4+ z;nmpzc%PENVWR`itAdjWAPxES+fPXjm}>;E*0OdxCS2XUH61f!^2Wfr!{cscbuba6~{{_v{_r z%sAA75stOTZ@gQ$p?%x3z1EB4rs6*CVqO7!ZL5%&MKyRxUJa3~l{l?}u*=AtfbrEY@pC1H)+?!v|+@kPvaL9F||cDZuv;7@c2x zx4I1=@ic(rb?cUkb)m8|m=$iD%ZM0i&U}g<6lUia#S1rzA_KSw?e7 z0C54`N8RLMirzBc*Y?=sXD{uG2v~7EvY3%j5h7seAlYKbsBmr)0Ra%^fKFja=!{$| z_6nPJvZ#@DrOhq+ICG3bjP7?b(1HNe^e9|0L07#U4||2hecEPk%KT(JI)HFjyJ@_= zm(l?z5)+gofZuMt+t-7o##k^)jaK+`?jpk@h@5%W8_&mXjlo-^B*>@v=Fn(2jsZpW zM^BMX>=4oYrG2sDLns)=30Qr*LAl*2Sw(Ug?v~Ju2|^|iydxqCCTc1WPxm_rP|jD-=Ub@UHga#s`% z-kvw3W3Puj0b*m$HgebA?sxkiOMi4=c1H{DTVl{qcIrr9W{80Q#ybFfq{x;>8OG3b znPY-kXSJ8MGTAbi&uP<8wtEM&Wl=R0Zo-B64RRp(#FVa`tqt%tqHWm+8SR;vgajOb zd}exR8Ep*4v>~QR=OCq6)XB+dZEY<-g(>r!wYeG;Omwmfx>HqHSeU32JN1w%b2@G^ z%V*Ly<7x``m2~-yls;Da0x!!1e>xu7;I$MFJ_iQ}aEkp!iF(ZD@zoLV{2PVA+Q$TR zO8H%zMxxEj!i0*mS2kZA_e^W((_hndhfII(BWvZeUl)}$c-pl_#)J4qSwJx@?v=Rv z%w?Uhqu5`6U>}kMBToh=Q-q(DitS+CFLM`-es)5`qHQ3N&({3M?@9 z0#~q4tOMS5xrP-Mp7}W%E8qpxBtX?ykX!GO9rW@NMF^xFP&~Oxv7-tJA`GIy9LP&b zT_U|Dm4bsVCs(>-=Va&TutAkT8c-pM6q$GXK`wp!FuK$3Edo6>+ zE|=@FeqjvGEaYc2eb>Yp96=0UU*SSzl0MM{WB!LQursOigkon4$nqm~y2wbD%C7%4z*dRcU| zr(RuHNZaXItwLOS`h!{SVW-_1DP#GAcp zN0GWM&^(OCP+NtU%V2^^9;fR~K(FSw{m@8l@QG`}Uigvk>%^YP+91_ATZ0HBX*9>$ z9;K=yFO)Rvt{uNnBAzc%W!LLdAKxW5`^bL$IM8f~aC}qiB4+7kR#VNZ(Vdp4L@Jg> z_NY`<_=-X+bN?IxZOJg2kKJODjs@={nFy)0X|YY*%||%8()L%*U5Nw z+y60tox_Iwv4NSHnTg59#{}Ayq3)~w#`2aHep=dM1$YoKD;rx%`^`pPBY4LH&cZqG zeV8%^fl}sM!0pDyK2dgIYPJJs?mfV{fTH4J^js-8zpYb(RU>qb#PZhL%bc8?{QUf! z98zTueuvrhOg;~Ax-iS@y9NMQ%@66<27c0^*BBI1Gz<*vhPsalIKR~&5PF^`(rdC? zeyITGOV~L$6f$|IH;z*heZf)NPL!d-_2$gGt29Iiq!q;U4Pl^cHO`V zE|FqU$=4JfmCsN-&o}02=u3q@o$MSw$O-CDMQhRMLF32JIMVQd9BxQiRDY?6s@$jz zExfnL-Glhrsd+5UvTO)QazHJ#HUd!sU*Xr{*%?syh^$Ds`p=I^!~qb`k)Q!Af(8Yv zQ1N_0O}a?>xSS}gkCYnQa8U4IWtYgEa4_oKq=2K`tokK5>r^#{-?MkKvyCbngmD9? zpfCVClK4xzwosGsSg7rSn2V@5knG9)5s^;^#3njr(}I}y#({#_=VK&s`{T-PMP~4Z zdH_dh!jOwAevc%P<`1%1DkX;IQ^_JsNbG|HBD_z6aoVQsTF`CGCti`{RbaU0Id6IJ zYzCl3v}GsDYryJDBMY-AO?!&WP3dbT4o~9>bBPLHX5wJfRfNObV32Kc%MCuUr@A;% zA5UJkH)|M>cm5Eh*>TOr)nxfxP*M+#sX&?va#3Suo^S_&ISFfK6YxF<{iS+(N2{Z) zi{@_Cl39*WRreR-GnYzPbB!9D7e=4-GKCt1Kr!?f$;iDT5~L@*aQNdX7@|>dxmJ)# z9b{x9%#VQ9M((>8hF4^l-6@`u*y?YWCZZu%Xr8URb5iG3@D4yFsIJ=eMPHxk-gQNC zSGc!3#bE%1N@p*Z^|w0k!<1AA>#C0g^DyO!-rSv%-7y+xrUyXr;9K}z=}4`&`oe=W zh)kC?TfphiFpSS<2Ka@52cO z@CJsFF$v^$ygrB$Yc4b+a zno5?agR^$3stFpEu9bO%9Qxan{-&;ef_hVB+V|Nsk4A7vs&W8ZZhH;BSrUB~doc{2 z|CqEdy6C_7d*TBsj0aPB_Uk$cK7;d$U7@zGBjSaE%4=$z*FUA$h2N(rrW3(ai~?R{ zYN#EeZe-7XtUIbuCgPjFdp7!-mOj36(bSv|a|8NuNV|%f-;>QRZ=AFkK3&FCZn=o7 zbcjt&_nyZOMxQv_lY}AH>_F+H(nMEL>mE~|83W`xX8k?0XZLog3A!g!b8mZv{Gt?PS9$kwVX(kpfItUJq80EzK{nJ?0$O>HPL%x>abzj&|C>}(n zJSw~^H8i%@cj3MxDS)p2+AU(+nL=ndj*2iQKZ0vr-Q&4!e4hrAcVqvH;@2=_toVym zzGY;gkiqSXk!C49=n?@*QLn=t9L4o@dFZ^!M`*)U;KbfJY*X*Gf9fVXKbsFNy-com zYNB#1_L(QLaI&ktl(Fc_W6m+ zr(pYSbK84Zr!T7C>Ku!>b<_?!)a+Wdnkbt%o3%$Ey%<3<|C}ug47Z}o@r4#ng{s6- zB-p~U9b?vD2@}Vf=gePn@tM|MO!c(mKieK?^l6l6*`CQ+%0b(N&>nL~qWNaow|>12 z6X@gPdf>yic72l*d_ zOoI;VGz4rpOp&(f;UsB>$wM`D@T^i?f zsVMe8flo~@CB~2pHcAQ#`UVDMw%u86_U0OE6`Dkp%>0{j8X9KyoF5;BvDjJh-=443 z*Vl)pv-aU%El9ttD=D%3T4y&nIC#UB*A;f^#$HIJtj2@hyS>~U-fEikLPh0z8N2mM zy@N@Pl68LBL{8tf4wTQ8A3%(9p8H;-|^hfXlw0j{^Do{5O4ZvvR`vZB4N zqvH_zlZoqwvWl#)-;R4?0NU8Z(hs%y2VvtOAxm#H%xuc-Hr)7GSTbmsVwrhfD3yjo zL%@>t5PQ#0YAJAG6%v6)ODi#^>yOVoWuL9*TZlhimL^k9!s9D%IBSA!f&!=~BE$MG z*>X}+nw)=wO*kl+wrL>3DTGpmf_*yfpKzAXt_(Iw|LoTi(0mxq|-YP{s1b| z)y4vqY+^O=P?8`Yoh?-owmku&+M<{;P@J0Sp}vR^C$nj}c-Cvj#T%O$RMC}A8nI7D5PX-Xs3Pt~-1?=pgd2)S-YxJRQE=sxn(pz1i*Z}03Z zxUNK^k%@cW!3jJ!nDb*;3WU8)h6S_%9i88>GR{7CLRD{as$C&|Qg1C>@=2Zz>VT89 zWu)h$AR1u!Gh$dCA`7yZ1a;xO2{^dOjply|j)HP5$`Tr9&Chyo)ytigWs#Ph9Trm7 zlT-W*p-FQ1PhJ`+WY)Ro&kd5kn40pz(DqS}X2wC=wqr(o$GyG^(Z;WVhKEoM3Ps2LsY~cmhmZY>7@EUdYz0&_*@L= z>ezK-g0I(AkvmOTO*?~USkdESU)K2q`;FLeA8w9v9;3SMs4V)6S?P(ho{tyUCZS>D zH|JUN=UW!NWGVnlBwCvDh1rcEM*B?oV(?!&179(7y;w`SJ9#JIwZXH%B{zRHKhV5d zj+j-y^B6mmx#`1hs(pW!3!_f*veRBN7};oLOM*Z-JHMGo(Wl5m70AGmw1bE)N@-K zi$z3bR<6)}$(t5G)@@*TBE2#qBbRT`eIsU!_T`;srHgY+TVYA;x85U7xtH^%L7n0iBk(m8=)KQ} zf*NbNoe9U9xdI@bjdy*254i!zj#r&tpV}pa-U(P%=7ym&P8}w3kI=dp z9qUUb7j9%ONCI0({sj$2Zag!M7!pM7o+wObzC+Ns1tnX_b0@9sk(g}KkJ~p$b5%j3 zqw)9zmnK5_!J}HWimRltK}djv&&#}SEka|sAzP9XtJemFoRNG4BG6;PwV6BFikP@w zpwWsb$|UX}(BUaWkv{8C@5L?^xpDx6-KQq|UL&4PrJ@2AP;&XOtsHLI-p-r0oI`$w z*(i6T8A?H=sS_NFyYJU%Yla=Cb6xxECXu#WXpRE`l#-vMHJlR`hpJDhpsDs0^)1cj zqkC;N2*S3Y>c5(@<{WXk6(@4lPQg7EGZV7@_%)VQ?nN%_Yj`{+t8wklh*8!u8AU^A zh0^qIQ;IDv_y!r=NW*rz&tt_g`SM=J&kOs{U7jN{x;EC?cJAv@f{Y^=lQlNC5Tv*l z3)bsO);qKe1~$w{NQ)yjt`-^%dg6OZdsU;SoVMOCrI4m?D(WrvJ#W$5O?{Vi{_)9t z3is~(RSPB#(PIqB`X!0G(+}Y&O?FyXb7kGt5-5kk1Fr(BkNkBUN5s~L*mT)GW%6kz zuC>?75F&t2X&m|~lH!w+(%dQ2r2{=rC)7$Gcjj@9Uh3a*g$ALRznSlK`Rr?V4P|Ki zj)>$VmmtrlT2ELEDvR8v9iuMNToyv&3TVZ4xfEqMToNMFWGj!y`uIy${R$j{=|eaX zGq0cF!@q71;WlK6!=Mhxc=Ph{vT9F{DZNfTHPcLY`Xw?Qo@`bIB{hr=#2k!-67};o zyl?Bg5`IFT`68U3qZ;X!0Gh|Z22(7C}u*n7Ou|~`k$dye@Pt{ByFrdW7<1YLgAX;Rd$c6c6 zl&JK=+~Hl7-)k|#05l}@F@;7swS_&5Y~MY?20`VcDw@^GqCpA+)QyjDUVJu75`F|= zHucSx%>wcgx6x56jx%;cKmDxQj9*PA!~Cp54~G?FtPwd3%@hGsDLvfS<9+gcAu6n& zu%5cz40MpQsAD&P7f`JStt2|(s<2k_UIsUh%3V!#gjx@}3fj#O(Hn>x*szu@tuEWp zsowYL)*WIUt*;0zqKMnis1PNOHhZQDvDL$g3DAdD&xex>{}gDXoo;uSSKqgZ&}9It zk5s5_(kqWI0Ah!ngAd9ZA~O7Z4c}JwUWP$>$Ekn6`Q(TnB7)QA`U`$fRvK}sSb$0B zM6p_0T9o(1=aG?0@YQ2Rw&d#k{AVq1*iU8=zIN2Zt&l{J`4P5%;>c~;XfQ&t)1>${q4?W4{l#$>U7_cgakUm2z zYp{6Y^RW+>>?|=9fYk9F)z^EP2>!KYGPzvb1`rYl76HHcY!F%y9s@ItsquW=NlfHp zN=9-)fvBPa%XI&pGG5fE?Xo6Sf)R~Sd8`yPDL}eIkuAN=2;d7uoijaP2ed^fcf%V= zS;$eb=ux2Iq)twh3fZLK_&-TV%LM?8jfo+Pq@{z$8~OV$5@;&bEp{F2<0eGOG2qkM zCy|8nb-Bg~QBJAPRbSnsQmR>dTRmuPQc`-GDV~ z8k6z;Rdl^}B1zz11DWYju9?`-`kRB;(CzV|Of}P%VL3?6OF2}`NKgQR-s!#XPl-Mn z+Y2^T=1_4HM7^0BTe3~Y6oKc;7;<3V1b=q`L#%oUuxMXD)Zc3+jqlC@p7+NT`*eoj z#@~F3wllzKpwgat^pv3YkXImY#r%npbgU@69VY=nZw7iwz-wF12-G9@X81SYN5c`1 z&9mjCgBNypZ_rQo_c{T`Y0!|B>U7}aVK%nY^b#6ik9Vu?*!!mEG&w9SEy-dMp^gLEA*6=m8mdjsHh}mWO&qCGrX?87j9#N zFA(iHXYpQ*-+%1^{6&bzT}h4IsbG2tkD8hqe0l3q7;)B5uXgrqciQ3n+Y-19H5HX~ zbVTq0Fk{QPfrLbFM<8Nv6d^uJa4^;DjSD^C`DSkP5$|1G)^(S4?PKj}X*s#M7O$&R zHVbKKY47jVS>S6LZ#a0#$X3o;?{2`^rLy|jmvrpAMx9*?YzkqJ&reUu2&N0R_)`5kH*ZpC`ar1t~5Od1`pb@}tH~#zgRWGj3 z$G&RA^*6{_J18h9W+1?ivO+Brlj;QQ_4#ldx)A26J?HkPyL|}jr_BKnc>@9$nvar= ztt|p1#HdIq^Y5v9$PvTP=qNYw{-x*6Ncy!DU4H=-3Uxp2eKitd;5u*i@BQG%0-J{O zk_jNG={s~Hi+V)EC`yvItQ1(OD z`&T|a|5$_e2#Vky<7y}IVASqZGE#MQiQMt=I-VNOq6DmPNuYU+Clh=~QB+S>B|=4X z(Iao>9{y485ms7OMoLP$V~Rk59LNWamn~>(TNYIF4wJO3nOC@M0RAONqJK)*B@|b| zt*H(%s;#TbOf*b8IIwX_Qq*HToo=cL>0W0o%)~Jhim6fd`!4u@BM%%(8jsuW$pBhV zNhIZC_x=BsJ@9oU_1$K=V@Le2|Fw3(2M+IGfGoHhw{LL#C*?5Zk3m4OjvLZjc} zu~BZ*$NEEq^R(59A8A#4<_=qBBvU7q)uN$rr1diNtgZq(SZorMxa!>zS;{N?b@aJF-YY1G9}e%gFziwneN>mQ3ow zmR4pwl=AgT47@cI`V68fA?eVf;{uSfLP{|QVWrjJ}z<^^y8 zO%m z(t~J1e8H{3IL)D|}bS5}ADgpZ6~X zW8uYx1?+0AvL+AVXkuCxTa2x@6=WVl<@ipM&-)oevX;h%K1^S! zY}Mr;QE55tZ>mnphFP?K`38JEI@xV{x`7~-BT0ims;J1fHH9U(dpx4>04LD5vwga6$#q4O#y1@nX3>d|GzWdc8nRqkCZi4W)@siu;2W@}RE&+Xazna0KJ_&51k%1_lu}Cf zJUx+3OO*6-qBM?!i+8(%j`74HBjj+3q_=sLDO2Q-eV>JCA_=t|cHhRiZF4Q74#vvh ziMrPy+%dZ=s|ftLn|nfSU)w%mvkUo|Gmpb=mv&TLO+hG!zFY_ij9#Y}>hL*r|7gCD zzdF3G{{1>CiWI%5t#nJ1h5Y+roCEBi+0O|(Q+PpUTSaDvy#D$mW2w_YMmXL+Z(8D>y~mc^nvZ`W>n?ute7d}O#WpN|ut zG4!3XG8w`%<>(9ePXj=VdM`e+juiPPB&Ee%Wh-cv(Iu}v_|W+TO-F^TQ5uELH(?l+~NC3gFVzc{wA+qYy8%%kCcFrQ3?f%amDl5Ai3pte- zGw|5LOEejN$j;-@bnbV90o$ROB%K zg~-@)dCl#0%W-?U`)1|X4hMO#uSIA2<-hR*tO)?7w7vkU9upJO_lgR#R;kk!kcX95 zBOiH*6x8{qq7fD{oTdA}SrL+OpDbt55%aIEXDvs~Z+zdZ#08Y$R%*49-!Zx&HggS7 z8^H3qc10UA_pCg9COhci(_FC7vxuyd%f94MDnNd3zx_V2I@*mG>oa|Or|{uD&2(NZ z$)RluC&AwZrfAF06)2?9R$+W)QBR^|v}-~pydNliUYi+95K$5yzoo{&88A^#QXn<` zu&_+s?mRbIB<0JifbX&$Ej@;!7;{m*u8VFg{V?-W)%+f7HdN*8Qe~MIJ@4022;%He z^yoC3Q2WYM$Ut{H;$`BsnTj;Zbfv4x8K-xobHZmRs4zPS}RY|Xs)OFa0I)Uy&v zcp&z7b!GpKaX5->B$vxWnuxaa|ql8aZ?6@Qh|vdy&Fzt_R)7VV+`E3SljP=mSg>H zf<$KQwYbfK(L!;t?cYVniY%#K=WFt_7_hF#c-(rIoL9_{KWwHo=WTJko2%N86KN$q z`;KhxLTs>+xY(j3fyiE@+ewM(_STw)t+5ht%pwrtEAp2m4t; zD_xK8hs9voHIdV68$Gs`p6{(c?9NAGJ3i>fU7i10YJY?AY{AvB)aci9>-Fref(}o9 zcWIEaa{g(;WOj@NH}40TeN40rc}LYL@i*78TaB6D>BSy(qoJA)w(H9*?T@k}B=%>> z$v7^@dZ$y0Xc5==$Nm?!`_ViV9tQ&n&rMIWukZ(Ct~8fg&DZVqF0XY5o{6!HR2dE0 zTWf2lkFW2&+rj+0>i7Jp(_rVqOOl+N9FD85p`iinB?ANUS;mpH+5Jm&V(wwJUh}am zy$>G$ia-3Kr?Ss4;EurR~LthDjmQ`MyKKM zQn@~+fF(ybv~v!Au$igp5>R>dD|s-HZ@k-uQ`UvKO3TY17FVClxjjz*^v>#gegEK* z==)kJgFth1IK|x5^uHvQ^xLGgYohB9zILI&g8pYe3mR#-&s7;wOGmL@&)HgA1BxVa zex}Gfd#u5@_hk)V9HvZ-*Y%NmeggU~$Zr8hZv=Lme8RG}qGHqr8Io!bf`;Mh5glw5 z8&`Xw{~YhuRzcr4?Mg)dB>j6-$4%C)jpqse7#M#?n@nfJg2PsZrK&F%gCBpTc3LbZ zx%pKfwZMpqRB6jI{fI7Ae)Lny=-?A&(pJJz8EfFdXZ@kD=kdn^#z!^(tKKj->(8D- zsvMFkCiw{^uEfqy{L+Yu+(Q)BNJaJUQP0jWLi#7!s4_fz!@~R;zHtxS{=l;_bSjcc zm1Q%sAQ&McOG_@2!aX<{(0ug+gQV7nWV2#4riPdzinrIjsdHdtr(GzdkbMxk)?Q5T z+$QmC3hx&1s`t8J^8>Q$E_t2AjKX@C&1;&ey}~Xo-^V&v>KvzVZq}6EOj{v8z7hjR zm6e%%n_TGk)U3J!bzfJ_lK~HOa>S+vt5k@5O=l>%Yx|@P>ewHxwrq7=N*)uN`PF8j z11(3Ni3?Qbl7)7+%aTW#tJVvZo!JN!zJi|gU_u%x>PxZhNvi7tqZrxLFPzx%E+44d zP=is^#i{&!uPvcob3?OHzc@Idj5n*q1(C-q=Uweb0v1Ik>TG&0s6%A|^)kQji!~HI z4|GgyL;CPyyl+CX*g76B3YYb!cFe3DUz;NA@;`m!(djo3JoIB`QEf>MM4=Oz!E1hq z&2GP}`*X`zUPRzXo=Xuy_6qi8()thGP5ao{_VM+Hsl&ub8_v9}r!^bcSvAe)4sxi- z|njgc3~pQ3jFsKoRG_v}l@r2omrJaX0iKanNiz(ejW`j7JL!%VCH4d5C{ z^REJK74vcFcFptzsIN8l{ss3u+rDXhmp?$7;#LNEcYXbKqi)3W-vBbn28k813c6xe zd$IYOALpL=z!IExSWRQWQ!&R%c(Ex^%R?gWsO5Q05}$=mu}&hU}|w z0#>6wEQ|{dov~+YRFSGuaUg89AU8?jD5g=9eu#p&nB~;_CEaebD+&5Axn_D4X+z5r zMRQdlZ6a|jQaMC(zVAH}MEOxkn44m#3Vbe(R@b*=)KHF>VhM<-Z{hI?3u0qYrMzUn z!F1OUisc)T!oD;us=7sQrW2im7l|uVJutOz8n~)+CQ&P04C&IlJF+`zu1*h-j4>jd zUMQ2yc<>+$WF};jIv!7bf#8a2?ek^ZP=!3dMA4M$X^Qe(D9-NGN!IeaQk!e>`R&W3fO z_4qyuXzF?|6UfNiT$BaYtdCOXO0WGI8~S6Ss;OXwzLD^!b-i?=fk*-!pRRs@HL9ds z29K1j)?@Waz`*YN-QDJ!&_w~S+MYFh^!%}_hM^|HomcJ@L})TpMl()((}L=I4{Mgw zlo|DJ2#7At`Gg``OX~?mYZrO9WY0rw`+69^2%XLlz=<9f9~$3=h0`;tZ(1tA=B|A` zpAzO@TA(7-ZDkG36=;c^ku;;~&&0}EJH6?;b(5_S#hC{_VS0x}|mSM#C4 z!_jE>C7yujQX+cAaWnY(6nzzxJkWm8RRy&n1eQR5(yY`Mii-p+Xt-~Oh?3WT2cJ1C zl#IC&&`aij3j6h(f~Efz`@#1)S0WTpWFSdDTWMgRqM`!WQV=`2AqI<(&uM!YsBl*w zGB2J{5t~<#y2qZcBt)8^_`7n`OS<$&`HR^dKDXV=7L6s&?j`tn)$sQ6j8Xpm6^y)C zahbvb@qigVt(O2ICmfQ3E+&BCGI3UL&{< zj?1*TP*aY=m=ML6A`k3{Mu=fSXn#5)JB||-A;LOG2qPn;NX=7;6YwwAc92h8HxMcy z`t3{VvzDY-67|wxa!*QekMs>R!ytztqQ9cX`g1(t$Q-Gp^W?uyz!UG=&@?41xKVT( zqu$aI zi81}R^F!Yb`s3mI7h&;SRQFjQ>GbpuPLS}r`ZXca77aa11AyBoK4Au>ZN)-)FTqa9b7Dd&N z@#%^D#DLmbQO%S0ogR^Ij8YG?R3}c5s0>{Gsa>-Mer>mICMFx*7$Qp+#(!(>{LBg{8F$h~-cE4Lu$w;4#_zbi}%T{7(Ns6Q=0@ zFQ5r)oly<>pH9Uf_yu^_01)B2`CCv`Rn-w8GVYJAO6$Z^o`{Ma36mj6)ay)FTv(W9 z*DI{m;p+pGXEQT1UteEaTU+mV&hg6v-bSlS9ud!k1pP$Rt~upA1JTod63jHBw%3M+ zT82IC5ro@uG}r3C{Sk`B?8%8Cf|%Y5Tc4rIsHiX@S9oP6ISgA^q{G7!Fvu{kj--;4 zU|*LU*Q?=X{^$+}DqhyR(tLQR${5f>ig&hoXPKu2f#cPZ#D=Geh!b<+RSZVLh z2%{LH8CUdpg%e41nc0WHr;ztG)Sn?Zf?%ExH&&bm5(T4{AFcw0S0;ML)3(^e_DiIS zVkY-3LqI^DycyaO$-LYc4Sjr4}NV1l)>nU*s5ZW?R8Rrua0^s-5@d7MvvX zvD4im&>S9-GB`&qJ~A{kb)%=GSsq6U)=Y~M(|e7}>}WV)wsOckknYIq?*_o&Z#E|h zlRso6C@asPp;wnu6=&ZO(JM``D>;L$3WY-YAgOc_Mcm}aHrF3VGOf8oZ3W-Xv^%yX$a5SBVmPX2 zVgB+jw{Avvh*;&sn>_DOx4EBBC--YKyr?CiLmIyv1d!Z*R1Ez@-4w!x(yzo$c78&d z4)J)G-fn)|7n_A};vwbnmHb$Dk5AFWJRq1#&hNa7@|nE?$Z24pDtaG3qy&--LetYujrj4R*(+XKmFfdiW+$0!;(_69s|v|^qmhwhuxjaSUNynq~T zWal5hd>SuMZowt`L`qMw^syojl63WUJ0F6Z>Kl$Q2%qOm1cA*FO{7Jpf`y9Z6ZeEH zHeiaguHgojrWcZC#)yzPuT9Sd3KC*vl*`8vfYXIBe1cN~qnLSx!&}NZHXoC+&|_T+V}O3!y#~!sSF7Zek5#r;UB()FLikD6FQ%g)(2#;*(E!KALd{iyNlMSk z%y<;65AS~O5Ku-d2W4q&V!?`*Tz?I4Ec~7ZCqD z5O`bMe3v%Q6_lWlBJ&dYQeG;zEQa0JVevD|%F|@|u~1XVCz{!*8Nx&QGjkcx-wgkkr(hF^=dg7i}F02?>y%1|=roFAk#BdDIMK0-hixt?zYM2iKMtJ2Tn? zFmOt_guO&K|9_ehSw9;uI+@_^`K@#ei3j?iRZjUYAWtoVi1UPy`P+?%OFl^r4Ser- zJ!fE3f%Yc20RO>NFks)%6_kUfl;U>}4u9B(TFpX8mp=_L@vM5EQ_S8=IGEkBXSDh0 z_!CM;e%4-W9(6!6DC>jlP?3r9Gr>CJZ3+{=+?R~RYC+1CyxV}}sqNtuRGf#&CQU)N z1BeV4NC~5yVfK*QPgt^5|KS+UAE9Csm z&e5)sNgQen$kIg+;!;XF1O0!VRYJ*?xZ9YULFnGMA!Uo+Y0?ejvs5`eYC)N_UQLpH zKLW4Vyjav?h_=bs0%H1sO}m1RxS&Mmr>G!YrfOg+u0W_un@|yqbl9)BzGRDqkFoTJ zDr#S`Si;<6HasRtG_VSb)%43hPVZIovA%AOACKqfJxD}Zjw*AO~KV#rMEMiN&Q5vE9b zsZZx8p3-dm*OCWu1k$q`5kT5HYYTTc%`^5%scxTzoJ@kY5QC8<|1wwrmDz1OcvW}4 z@uX0qrCnfM6@$jQtyJkj3Ce(DEg_qa>px?L=J8(DMv$f)wIJ+(kneD#!+gncl^76F zn!KNS@~`!QZ}*D)NZP^&F=vs<{Bsgce9u-8k;=UDmlJ!@V2NoF=B7<-;Iyp{7h?3{ zPwMg@2O@83UL9lL|1I}C&sO-&$HPg`jH{+;4QUz$aoH?snY zHM!0fMI_w&bz!GU3s5ij_U#ae=qEJajq)jM-6+`1zR|46;B_?i+X9TfV^nI*=JkK3 zJl%Ev_e=dN&x^Je2h=pV%r@lxym}$dXYNQz2@)Ps$45@0Fl+_rYkjPOaqm0KHlaPg zUP!27*S&@B37LsAe^0;BsaBXI##_Fa0sSi;p>$hAAs$f39m6gCAp#dQi~I2?q_e+At%r@Ktd=C1PH*j#18$G8)>bW-W=7Ct5Wic z>aNe~Xp6I_o8)7E;v0+)@kct?@S(R}x(&tLEm&l&QgmjMouF5K`E$!FQ@@V7U=rRM z0dlgnNPOkigZkGLYf=lcC#p9acJRl@F8=Q+yqLyXK1-#KNSw%@Cj-A@U)Jc{e!qq3 zQKhd3h%X(utuus#?gc4TXX)vbE{>s9Jv+A@3c>%Kk2gU~?x6$!hyQM%C<+*rNl8gj zylOR%E{7J&I^MiUt0lHX_|26ckZK@9(Rxy22%U=%%Yh=C#r z!X-Z??FPH$W^m`f@|ibphAyta{FR)Pl-eA*7p+roGw(DeqzQUs2o(8|`=W`FAVDPC zR6}Q=>&`$;4QQ5X;0E?!1_plH^&`MdP}9&5zCWme7@GTl!4Kr;Gbrih6Tm}k`r65O z9oC#ybu={_z?m6{A4ufhtVfj0AkuJf!07}HMI){UcWiHOgVGuxvbwt}PVNtWN7o^1 zsqj@)jXpsk`7o{WjsA-RHN*7i>@Y&OvLKFBJ#oD6N<+O~j=?}|X5rxiBE&xw#e^=- zpOIYNrHp3<#ux06kJ~c0&wq}W_Lqu4%OzO9Pxi4^~={9u+(h4IE7-)j~Hy6 zzu`)JJRBo%_M|gJ(lsXUSuHo~@)sPVD&-`;qKAo&uCAIuzZ2kcdG_DF@gOxo|N&=`BYA%uRH=6Etw6&azhRIVV(<}P^W_=tkMcwCcnqp9Y1r60@V|88|~Sg zn6%6U+hQTgO^0)O)I(I9l@KCV@@35ZG(pdYD1}fZxuJmH9b_pHzs^yls0bb5{Bw&N znTg}?e*exVj=}S`s7){YOT38QHcz`GG)Zkt9g@mfY52aDTkaZdC@XuV*8F_^jdauN zd%*$ahKG#-5zo2fWYYpFAqAz;?vMihkR5NKbdSB|u`6FD`#%mW!Hd~Tck^sIS4+k+ zYOhmw&RYYq6SVV)BCFB%Tn)Znv})&tOcWJnMYuCR2=Ain!Z#9j~n6`62{n{cn={ty{0icvEDZ;lOhL9UWY04 zWay&LmWTH`{G{)O$>AgsyfyfBqqFv?|^de9+MW1WKF3dRL?4!603>f;UapO4WZ@n16*#&RPZr_8}9M z`fYchMT3he8l(|Gz{5wWiljsXth*)<$JsE-cBJ`=e=jH?dkz-;zb+e&aH=O835lTF zYj9=(9X3bc`9PZ#D3Vc&5XQcv`;!!FN5Wr5b zj$^%!B_Gj*&hq+nLc@jMuIKe^6LF`-ZToZ$BElf>37FYjZ=MbGCR6qy{dlfrKFyLhkFtC)WA<=%5nZ9EsEqQB>e8ZSMsW)TsSd8^TkMi)ZWHt`chs>1QOIB z2dk|8q88uQ+aA&~ZjSW(149R$Bm;gP+T_Vpw1uzD*;d@6ZyYnTJDc<#28GnwHhM42 zBxbRghZ=GnbY0*fMDY_<@$L4p$2X6W+0yTVBRwuh4wDHruy&_Oy%e_&$f$?R2(_xGcqMNPk| z26hAF%$xJY5gZm0zb)kAJi@4@8dtrc_=8&F*QU*??0)WtC2r(p1~(lOQXHQgPI|~! z`T0HX8uwqjw@|a=D~)uk&Cb=Dt&+6twa4N=eAVaRt1(;cv~ZKQZ#oP-Q{y(@tu8VV z@vRs7Xbl?dRJ$0koImYaYBmIoIaPgz!aSG#ow2P0Qi4ykPj%6-sIkxzyr0eF(jN@)Mg0wVkCDK+tH_n+7X`|b4$kcuQIP^C1u!7jW z~Ywrhn<^9vay6R9a((}`YnM;EXU(okJ;|n21HO2kv0rbw++=;~2_?C>yWK4zqWKC?VZ*&$2Z928=DDm|FQJ zGMkw@QBRQ=zXsHp@vqMt9V%0%#3>Um4H!w@_DU8}P)z4r9Pvci)KjCBxT?}g!lTl~ zuxjPY)ky}bYkVV{PnL=w+7cflDbVp)gf z$zDX0mq%Z&@>fy86{1*p<@^-$^5T#F;iacU)yC(k-pDg8#o{oT5QUX{1*gc}Ns`w# zIUhE9I2*1OC=a*rla3@;vuLxjhg74j+vuvv@Z|f<9z#r?&*U~^6>BN_UB}e--cL1E ziQ6*o+C{dXg$JIKzOoSW(v|5J#dIkSYofx5_{$Aj-_wYuh@x7t{cCbK%H-XVjmOka zjy}AHzg?|VNbodC#yseU`|ivXO2pZYSrtuZKCvqlg4KIBC^|8Of&v!u>xxdFoZN|0 ztmKUi7$UxYyR$*v~ZA{2if4SUu-N&|?nS>V~HJp&} z$`{maKCT!4_KP_9^T%GHC6{W<3~B_&hfNhog+=SMbo1p1`{;f@V7213c-!;1#bnzh zk%O8o`kYnXVrQ!Ii2O^k$Nf!hm^^N#ao4Miozt+WTnx+;QvyAeiT%si17yO4u zx2bQ^g&|b(&G`*iU7mhEV{S4+Ew>dNZHwYf_G$)a9jlq~bVMpI1SCCn(#b2;&f6Ua z8`nerLbHC{UN2>STWz^6%}?`4yIwgzB=@z&RmYtn7;lV~>h~}?Kf|thLzVe4ds+J# zZT8>7gSf3vV`Q88-E|y4-K9}qMb*-gHEs2!HA&oVQ8g?+e*V<`Ov{Rqqy@U(L@fC4 zbwPot>3Y}a(?^4L)sm8un_d>*(=CLmR2TtJ$rfcH-N*BFukyP#@5h4T;<0QIgA}u1 zRCIvnLRiBLA(v`Ol>CGm3tvt!mHnq~ub97l1l0Ha)nPiw^npBZGb~I@E{VT9Cc+w9 zA?_a}WeR6@<3!jsQy9J^SOf=Nl32krSow;JxU+KRVHy%LvSO-- zi*-g_fTBwA`>{s?YROWojnU!Zhkj6r0$dM;H1@61;w)?X<2Crc05R2YC9zF5I8JYC zYR+IRM2cYSm;Tl7d$f3r`5~~xV-QNLUP$mKC#Nqg26lFeE}$EeL}10HrW%$lkD-u& z4_p+8|mv{W$X>i@vAT)xmsb zK+fW*e_pS%q1FLzs;okCbRt^?qjVBxO#m(g#+Xo2wi1pGv}J;aI)ON_g@wiOLS1Ah zs+mJX7_M9*+8V;|zMP{HYh_VnOleep`T%89w-az`$57#5`PiJJ@d{UwPpdcu0trWC^ohaod)@&T$n{D*?O5#_2OX1rPX zW!UOy!ExQ|T7X(R9}{^l7J1wgSiK!>x;q5bMr1;s7m<>yjn8P_!RB{{K0c3{!3Y}_ z{h$lL7op`Nc+o!?F@8k;!mKtQA>x2py};@!RU6PW@R>2LWPwX!|0`z)7sMWZt9x;P z-vMb3hyBOs#D}JirSU)r=+!#)J(P)ri*r-SfW99}_~W5>64UARNiyd3FV%$oWw~ zZ!Ra_ognQ+Zf~lALFea5Wud!hiCTurFXP6izTfvnx$_N)s zVG`;cJw+6%BFZi@wJ1Sp88g<)Q$&>X01)ls$GB9ejvuoT|D#!PWB3D60cPIu2HF<*?7IE zi3EbyA7?8bRfG6I*y|6mwM57FpG@BL&Z!y6n2)fZ?~~+4X)Z2s5jRoTZU5A?4Od?% zyv-V{+1@~WGL98w8pkGN>mF-&AiG0b7pBOtcd*VYD$O9&zN?m2UF zalwc(;_I}yGIg^`7(BYStz57Akwbu90OlCz&>7!t1Q9VYj3Gz@?wF2P{IO|wI3M8o z$4UIVDg>ro!{XV0E)4Pc*;4BtW%7@qpsM|Mfr$S!88jGVy2XC>` lC|%8ef8`KBC{NFjf&rlkyYHmz;Nlz*IVmN{3UR~0{{;+?S_%LF literal 0 HcmV?d00001 diff --git a/Sandbox/content/GammaTest/zeroPointFive.png b/Sandbox/content/GammaTest/zeroPointFive.png new file mode 100644 index 0000000000000000000000000000000000000000..05af48ec70bec851b7fb4c793c1afc2f50e66b90 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?I3?vN&YJLDI#^NA%Cx&(BWL^R}Ea{HEjtmSN z`?>!lvI6*?y}vd$@?2>@>DCCC5( literal 0 HcmV?d00001 diff --git a/Sandbox/src/GammaTestLayer.bf b/Sandbox/src/GammaTestLayer.bf new file mode 100644 index 0000000..6b7e65b --- /dev/null +++ b/Sandbox/src/GammaTestLayer.bf @@ -0,0 +1,169 @@ +using GlitchyEngine; +using GlitchyEngine.Events; +using GlitchyEngine.ImGui; +using GlitchyEngine.Math; +using GlitchyEngine.Renderer; +using GlitchyEngine.Renderer.Text; +using ImGui; +using System; + +namespace Sandbox +{ + class GammaTestLayer : Layer + { + RasterizerState _rasterizerState ~ _?.ReleaseRef(); + + GraphicsContext _context ~ _?.ReleaseRef(); + DepthStencilTarget _depthTarget ~ _?.ReleaseRef(); + + Texture2D _checkerTexture ~ _?.ReleaseRef(); + + Texture2D _smallLines ~ _?.ReleaseRef(); + Texture2D _gammaCorrectionBrightness ~ _?.ReleaseRef(); + Texture2D _zeroPointFive ~ _?.ReleaseRef(); + + BlendState _alphaBlendState ~ _?.ReleaseRef(); + + DepthStencilState _depthStencilState ~ _.ReleaseRef(); + + Font _font ~ _.ReleaseRef(); + + FontRenderer.PreparedText _smallLinesInfo ~ _.ReleaseRef(); + FontRenderer.PreparedText _halfQuadInfo ~ _.ReleaseRef(); + FontRenderer.PreparedText _explanation ~ _.ReleaseRef(); + + [AllowAppend] + public this() : base("Example") + { + _context = Application.Get().Window.Context..AddRef(); + + // Create rasterizer state + GlitchyEngine.Renderer.RasterizerStateDescription rsDesc = .(.Solid, .Back, false, 0); + _rasterizerState = new RasterizerState(rsDesc); + + _depthTarget = new DepthStencilTarget(_context.SwapChain.Width, _context.SwapChain.Height); + + _checkerTexture = new Texture2D("content/Textures/Checkerboard.dds"); + _smallLines = new Texture2D("content/GammaTest/SmallLines.png"); + _gammaCorrectionBrightness = new Texture2D("content/GammaTest/gamma_correction_brightness.png"); + + _zeroPointFive = new Texture2D("content/GammaTest/zeroPointFive.png"); + + let sampler = SamplerStateManager.GetSampler( + SamplerStateDescription() + { + MagFilter = .Point, + AddressModeU = .Wrap, + AddressModeV = .Wrap, + }); + + _checkerTexture.SamplerState = sampler; + + _smallLines.SamplerState = SamplerStateManager.PointClamp; + + sampler.ReleaseRef(); + + BlendStateDescription blendDesc = .(); + blendDesc.RenderTarget[0] = .(true, .SourceAlpha, .InvertedSourceAlpha, .Add, .SourceAlpha, .InvertedSourceAlpha, .Add, .All); + _alphaBlendState = new BlendState(blendDesc); + + DepthStencilStateDescription dssDesc = .() + { + DepthEnabled = false + }; + _depthStencilState = new DepthStencilState(dssDesc); + + _font = new Font(@"C:\Windows\Fonts\arial.ttf", 24); + + _smallLinesInfo = FontRenderer.PrepareText(_font, "Is the bottom center quad the same color as the left and right columns?", 24); + + _halfQuadInfo = FontRenderer.PrepareText(_font, "Is this quad roughly the same color \nas the column next to it?\nIs it the same Color as the bottom quad to the left?", 24); + + _explanation = FontRenderer.PrepareText(_font, "If all these questions can be answered with \"yes\" then gamma correction is doing it's job!", 24); + + camera = new OrthographicCamera(); + camera.Width = _context.SwapChain.Width; + camera.Height = _context.SwapChain.Height; + camera.FarPlane = 10; + camera.NearPlane = -10; + camera.Position = .(_context.SwapChain.Width, _context.SwapChain.Height, 0) / 2; + camera.Update(); + } + + OrthographicCamera camera ~ delete _; + + public override void Update(GameTime gameTime) + { + RenderCommand.Clear(null, .(0f, 0f, 0f)); + RenderCommand.Clear(_depthTarget, .Depth, 1.0f, 0); + + // Draw test geometry + RenderCommand.SetRenderTarget(null); + RenderCommand.SetDepthStencilTarget(_depthTarget); + RenderCommand.BindRenderTargets(); + + RenderCommand.SetRasterizerState(_rasterizerState); + + RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport); + + Renderer2D.BeginScene(camera, .BackToFront); + + RenderCommand.SetBlendState(_alphaBlendState); + RenderCommand.SetDepthStencilState(_depthStencilState); + + //Renderer2D.DrawQuad(Vector3(0, 0, 1), Vector2(8), 0, _checkerTexture, .White, .(0, 0, 1, 1)); + //Renderer2D.DrawQuad(Vector3(0, 0, 0), Vector2(_smallLines.Width, _smallLines.Height), 0, _smallLines, .White, .(0, 0, 1, 1)); + + Renderer2D.DrawQuad(Vector3(_smallLines.Width / 2, _smallLines.Height / 2, 0), Vector2(_smallLines.Width, _smallLines.Height), 0, _smallLines, .White, .(0, 0, 1, 1)); + + FontRenderer.DrawText(_smallLinesInfo, 0, _smallLines.Height); + + float f = _smallLines.Height / 2; + + Renderer2D.DrawQuad(Vector3(_smallLines.Width * 2, f / 2, 0), Vector2(f, f), 0, .(0.5f, 0.5f, 0.5f)); + Renderer2D.DrawQuad(Vector3(_smallLines.Width * 2, 3 * f / 2 + 1, 0), Vector2(f, f), 0, _zeroPointFive); + //Renderer2D.DrawQuad(Vector3(_smallLines.Width + f / 2, 3 * f / 2, 0), Vector2(f, f), 0, .(0.25f, 0.25f, 0.25f)); + + //FontRenderer.DrawText(_halfQuadInfo, _smallLines.Width + f, f / 2); + + //Renderer2D.DrawQuad(Vector3(_gammaCorrectionBrightness.Width / 2, _smallLines.Height * 1.5f, 0), Vector2(_gammaCorrectionBrightness.Width, _gammaCorrectionBrightness.Height), 0, _gammaCorrectionBrightness, .White, .(0, 0, 1, 1)); + + //Renderer2D.DrawQuad(Vector3(_smallLines.Width + f / 2, 500, 0), Vector2(f, f), 0, .(0.1f, 0.1f, 0.1f)); + //Renderer2D.DrawQuad(Vector3(_gammaCorrectionBrightness.Width / 2, 0, 0), Vector2(_gammaCorrectionBrightness.Width, _gammaCorrectionBrightness.Height), 0, _gammaCorrectionBrightness, .White, .(0, 0, 1, 1)); + + //Renderer2D.DrawQuad(Vector3(0, -200, 0), Vector2(100, 100), 0, .(0.5f, 0.5f, 0.5f)); + //Renderer2D.DrawQuad(Vector3(0, -300, 0), Vector2(100, 100), 0, .(0.25f, 0.25f, 0.25f)); + + //Renderer2D.DrawQuad(Vector3(0, _gammaCorrectionBrightness.Height, 0), Vector2(_gammaCorrectionBrightness.Width, _gammaCorrectionBrightness.Height), 0, _gammaCorrectionBrightness, .(2, 2, 2), .(0, 0, 1, 1)); + + Renderer2D.EndScene(); + } + + public override void OnEvent(Event event) + { + EventDispatcher dispatcher = EventDispatcher(event); + + dispatcher.Dispatch(scope (e) => OnImGuiRender(e)); + + dispatcher.Dispatch(scope (e) => OnWindowResize(e)); + } + + private bool OnImGuiRender(ImGuiRenderEvent e) + { + return false; + } + + private bool OnWindowResize(WindowResizeEvent e) + { + _depthTarget.ReleaseRef(); + _depthTarget = new DepthStencilTarget(_context.SwapChain.Width, _context.SwapChain.Height); + + camera.Width = _context.SwapChain.Width; + camera.Height = _context.SwapChain.Height; + camera.Position = .(_context.SwapChain.Width, _context.SwapChain.Height, 0) / 2; + camera.Update(); + + return false; + } + } +} \ No newline at end of file diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index 4415bc1..dbfa922 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -529,7 +529,9 @@ namespace Sandbox { public this() { -#if SANDBOX_2D +#if GAMMA_TEST + PushLayer(new GammaTestLayer()); +#elif SANDBOX_2D PushLayer(new ExampleLayer2D()); #else PushLayer(new ExampleLayer());