From e070c2b0f55c6466581e30566025bf4f6dcf0697 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Sun, 17 Nov 2024 23:49:07 -0500 Subject: [PATCH 01/16] Bump --- dependencies.gradle | 20 ++++++++++---------- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43504 bytes gradlew | 7 +++++-- gradlew.bat | 2 ++ settings.gradle | 2 +- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index c34c5b6c4..b9814139a 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -49,7 +49,7 @@ configurations { } dependencies { - compileOnly("com.github.GTNewHorizons:Hodgepodge:2.5.71") + compileOnly("com.github.GTNewHorizons:Hodgepodge:2.5.78") compileOnly("com.gtnewhorizons.retrofuturabootstrap:RetroFuturaBootstrap:0.4.0") { transitive = false } @@ -57,11 +57,11 @@ dependencies { annotationProcessor("org.projectlombok:lombok:1.18.22") // Use modern models+textures to inject QuadProviders - devOnlyNonPublishable('com.github.GTNewHorizons:TX-Loader:1.7.1:dev') + devOnlyNonPublishable('com.github.GTNewHorizons:TX-Loader:1.7.2:dev') // Iris Shaders compileOnly('org.jetbrains:annotations:24.0.1') - api("com.github.GTNewHorizons:GTNHLib:0.5.12:dev") + api("com.github.GTNewHorizons:GTNHLib:0.5.20:dev") shadowImplementation("org.anarres:jcpp:1.4.14") // Apache 2.0 shadowImplementation("org.taumc:glsl-transformation-lib:0.2.0-4.g6b42bca") { exclude module: "antlr4" // we only want to shadow the runtime module @@ -70,18 +70,18 @@ dependencies { compileOnly "org.apache.ant:ant:1.8.2" // Because who doesn't want NEI - devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.6.39-GTNH:dev') - devOnlyNonPublishable('com.github.GTNewHorizons:CodeChickenCore:1.3.7:dev') + devOnlyNonPublishable('com.github.GTNewHorizons:NotEnoughItems:2.6.45-GTNH:dev') + devOnlyNonPublishable('com.github.GTNewHorizons:CodeChickenCore:1.3.10:dev') // Notfine Deps compileOnly("thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev") devOnlyNonPublishable("com.github.GTNewHorizons:Baubles:1.0.4:dev") - compileOnly("com.github.GTNewHorizons:twilightforest:2.6.34:dev") { transitive = false } + compileOnly("com.github.GTNewHorizons:twilightforest:2.6.35:dev") { transitive = false } compileOnly(rfg.deobf('curse.maven:witchery-69673:2234410')) - compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.12.10-GTNH:dev") { transitive = false } - compileOnly("com.github.GTNewHorizons:Natura:2.7.3:dev") + compileOnly("com.github.GTNewHorizons:TinkersConstruct:1.12.14-GTNH:dev") { transitive = false } + compileOnly("com.github.GTNewHorizons:Natura:2.7.5:dev") - compileOnly("com.github.GTNewHorizons:ThaumicHorizons:1.6.3:dev") + compileOnly("com.github.GTNewHorizons:ThaumicHorizons:1.6.4:dev") compileOnly("com.github.GTNewHorizons:Battlegear2:1.4.1:dev") { transitive = false } compileOnly(rfg.deobf('maven.modrinth:backhand:1.4.1')) { transitive = false } @@ -100,7 +100,7 @@ dependencies { compileOnly(rfg.deobf("curse.maven:campfirebackport-387444:4611675")) compileOnly(rfg.deobf("curse.maven:xaeros-minimap-263420:5060684")) - compileOnly("com.github.GTNewHorizons:HoloInventory:2.4.12-GTNH:dev") + compileOnly("com.github.GTNewHorizons:HoloInventory:2.4.13-GTNH:dev") runtimeOnlyNonPublishable(rfg.deobf("CoreTweaks:CoreTweaks:0.3.3.2")) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..2c3521197d7c4586c843d1d3e9090525f1898cde 100644 GIT binary patch delta 8703 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 Ojj7^59?Sdh$^Qpp*~F>< delta 8662 zcmYM1RaBhK(uL9BL4pT&ch}$qcL*As0R|^HFD`?-26qkaNwC3nu;A|Q0Yd)oJ7=x) z_f6HatE;=#>YLq{FoYf$!na@pfNwSyI%>|UMk5`vO(z@Ao)eZR(~D#FF?U$)+q)1q z9OVG^Ib0v?R8wYfQ*1H;5Oyixqnyt6cXR#u=LM~V7_GUu}N(b}1+x^JUL#_8Xj zB*(FInWvSPGo;K=k3}p&4`*)~)p`nX#}W&EpfKCcOf^7t zPUS81ov(mXS;$9To6q84I!tlP&+Z?lkctuIZ(SHN#^=JGZe^hr^(3d*40pYsjikBWME6IFf!!+kC*TBc!T)^&aJ#z0#4?OCUbNoa}pwh=_SFfMf|x$`-5~ zP%%u%QdWp#zY6PZUR8Mz1n$f44EpTEvKLTL;yiZrPCV=XEL09@qmQV#*Uu*$#-WMN zZ?rc(7}93z4iC~XHcatJev=ey*hnEzajfb|22BpwJ4jDi;m>Av|B?TqzdRm-YT(EV zCgl${%#nvi?ayAFYV7D_s#07}v&FI43BZz@`dRogK!k7Y!y6r=fvm~=F9QP{QTj>x z#Y)*j%`OZ~;rqP0L5@qYhR`qzh^)4JtE;*faTsB;dNHyGMT+fpyz~LDaMOO?c|6FD z{DYA+kzI4`aD;Ms|~h49UAvOfhMEFip&@&Tz>3O+MpC0s>`fl!T(;ZP*;Ux zr<2S-wo(Kq&wfD_Xn7XXQJ0E4u7GcC6pqe`3$fYZ5Eq4`H67T6lex_QP>Ca##n2zx z!tc=_Ukzf{p1%zUUkEO(0r~B=o5IoP1@#0A=uP{g6WnPnX&!1Z$UWjkc^~o^y^Kkn z%zCrr^*BPjcTA58ZR}?%q7A_<=d&<*mXpFSQU%eiOR`=78@}+8*X##KFb)r^zyfOTxvA@cbo65VbwoK0lAj3x8X)U5*w3(}5 z(Qfv5jl{^hk~j-n&J;kaK;fNhy9ZBYxrKQNCY4oevotO-|7X}r{fvYN+{sCFn2(40 zvCF7f_OdX*L`GrSf0U$C+I@>%+|wQv*}n2yT&ky;-`(%#^vF79p1 z>y`59E$f7!vGT}d)g)n}%T#-Wfm-DlGU6CX`>!y8#tm-Nc}uH50tG)dab*IVrt-TTEM8!)gIILu*PG_-fbnFjRA+LLd|_U3yas12Lro%>NEeG%IwN z{FWomsT{DqMjq{7l6ZECb1Hm@GQ`h=dcyApkoJ6CpK3n83o-YJnXxT9b2%TmBfKZ* zi~%`pvZ*;(I%lJEt9Bphs+j#)ws}IaxQYV6 zWBgVu#Kna>sJe;dBQ1?AO#AHecU~3cMCVD&G})JMkbkF80a?(~1HF_wv6X!p z6uXt_8u)`+*%^c@#)K27b&Aa%m>rXOcGQg8o^OB4t0}@-WWy38&)3vXd_4_t%F1|( z{z(S)>S!9eUCFA$fQ^127DonBeq@5FF|IR7(tZ?Nrx0(^{w#a$-(fbjhN$$(fQA(~|$wMG4 z?UjfpyON`6n#lVwcKQ+#CuAQm^nmQ!sSk>=Mdxk9e@SgE(L2&v`gCXv&8ezHHn*@% zi6qeD|I%Q@gb(?CYus&VD3EE#xfELUvni89Opq-6fQmY-9Di3jxF?i#O)R4t66ekw z)OW*IN7#{_qhrb?qlVwmM@)50jEGbjTiDB;nX{}%IC~pw{ev#!1`i6@xr$mgXX>j} zqgxKRY$fi?B7|GHArqvLWu;`?pvPr!m&N=F1<@i-kzAmZ69Sqp;$)kKg7`76GVBo{ zk+r?sgl{1)i6Hg2Hj!ehsDF3tp(@n2+l%ihOc7D~`vzgx=iVU0{tQ&qaV#PgmalfG zPj_JimuEvo^1X)dGYNrTHBXwTe@2XH-bcnfpDh$i?Il9r%l$Ob2!dqEL-To>;3O>` z@8%M*(1#g3_ITfp`z4~Z7G7ZG>~F0W^byMvwzfEf*59oM*g1H)8@2zL&da+$ms$Dp zrPZ&Uq?X)yKm7{YA;mX|rMEK@;W zA-SADGLvgp+)f01=S-d$Z8XfvEZk$amHe}B(gQX-g>(Y?IA6YJfZM(lWrf);5L zEjq1_5qO6U7oPSb>3|&z>OZ13;mVT zWCZ=CeIEK~6PUv_wqjl)pXMy3_46hB?AtR7_74~bUS=I}2O2CjdFDA*{749vOj2hJ z{kYM4fd`;NHTYQ_1Rk2dc;J&F2ex^}^%0kleFbM!yhwO|J^~w*CygBbkvHnzz@a~D z|60RVTr$AEa-5Z->qEMEfau=__2RanCTKQ{XzbhD{c!e5hz&$ZvhBX0(l84W%eW17 zQ!H)JKxP$wTOyq83^qmx1Qs;VuWuxclIp!BegkNYiwyMVBay@XWlTpPCzNn>&4)f* zm&*aS?T?;6?2>T~+!=Gq4fjP1Z!)+S<xiG>XqzY@WKKMzx?0|GTS4{ z+z&e0Uysciw#Hg%)mQ3C#WQkMcm{1yt(*)y|yao2R_FRX$WPvg-*NPoj%(k*{BA8Xx&0HEqT zI0Swyc#QyEeUc)0CC}x{p+J{WN>Z|+VZWDpzW`bZ2d7^Yc4ev~9u-K&nR zl#B0^5%-V4c~)1_xrH=dGbbYf*7)D&yy-}^V|Np|>V@#GOm($1=El5zV?Z`Z__tD5 zcLUi?-0^jKbZrbEny&VD!zA0Nk3L|~Kt4z;B43v@k~ zFwNisc~D*ZROFH;!f{&~&Pof-x8VG8{gSm9-Yg$G(Q@O5!A!{iQH0j z80Rs>Ket|`cbw>z$P@Gfxp#wwu;I6vi5~7GqtE4t7$Hz zPD=W|mg%;0+r~6)dC>MJ&!T$Dxq3 zU@UK_HHc`_nI5;jh!vi9NPx*#{~{$5Azx`_VtJGT49vB_=WN`*i#{^X`xu$9P@m>Z zL|oZ5CT=Zk?SMj{^NA5E)FqA9q88h{@E96;&tVv^+;R$K`kbB_ zZneKrSN+IeIrMq;4EcH>sT2~3B zrZf-vSJfekcY4A%e2nVzK8C5~rAaP%dV2Hwl~?W87Hdo<*EnDcbZqVUb#8lz$HE@y z2DN2AQh%OcqiuWRzRE>cKd)24PCc)#@o&VCo!Rcs;5u9prhK}!->CC)H1Sn-3C7m9 zyUeD#Udh1t_OYkIMAUrGU>ccTJS0tV9tW;^-6h$HtTbon@GL1&OukJvgz>OdY)x4D zg1m6Y@-|p;nB;bZ_O>_j&{BmuW9km4a728vJV5R0nO7wt*h6sy7QOT0ny-~cWTCZ3 z9EYG^5RaAbLwJ&~d(^PAiicJJs&ECAr&C6jQcy#L{JCK&anL)GVLK?L3a zYnsS$+P>UB?(QU7EI^%#9C;R-jqb;XWX2Bx5C;Uu#n9WGE<5U=zhekru(St>|FH2$ zOG*+Tky6R9l-yVPJk7giGulOO$gS_c!DyCog5PT`Sl@P!pHarmf7Y0HRyg$X@fB7F zaQy&vnM1KZe}sHuLY5u7?_;q!>mza}J?&eLLpx2o4q8$qY+G2&Xz6P8*fnLU+g&i2}$F%6R_Vd;k)U{HBg{+uuKUAo^*FRg!#z}BajS)OnqwXd!{u>Y&aH?)z%bwu_NB9zNw+~661!> zD3%1qX2{743H1G8d~`V=W`w7xk?bWgut-gyAl*6{dW=g_lU*m?fJ>h2#0_+J3EMz_ zR9r+0j4V*k>HU`BJaGd~@*G|3Yp?~Ljpth@!_T_?{an>URYtict~N+wb}%n)^GE8eM(=NqLnn*KJnE*v(7Oo)NmKB*qk;0&FbO zkrIQs&-)ln0-j~MIt__0pLdrcBH{C(62`3GvGjR?`dtTdX#tf-2qkGbeV;Ud6Dp0& z|A6-DPgg=v*%2`L4M&p|&*;;I`=Tn1M^&oER=Gp&KHBRxu_OuFGgX;-U8F?*2>PXjb!wwMMh_*N8$?L4(RdvV#O5cUu0F|_zQ#w1zMA4* zJeRk}$V4?zPVMB=^}N7x?(P7!x6BfI%*)yaUoZS0)|$bw07XN{NygpgroPW>?VcO} z@er3&#@R2pLVwkpg$X8HJM@>FT{4^Wi&6fr#DI$5{ERpM@|+60{o2_*a7k__tIvGJ9D|NPoX@$4?i_dQPFkx0^f$=#_)-hphQ93a0|`uaufR!Nlc^AP+hFWe~(j_DCZmv;7CJ4L7tWk{b;IFDvT zchD1qB=cE)Mywg5Nw>`-k#NQhT`_X^c`s$ODVZZ-)T}vgYM3*syn41}I*rz?)`Q<* zs-^C3!9AsV-nX^0wH;GT)Y$yQC*0x3o!Bl<%>h-o$6UEG?{g1ip>njUYQ}DeIw0@qnqJyo0do(`OyE4kqE2stOFNos%!diRfe=M zeU@=V=3$1dGv5ZbX!llJ!TnRQQe6?t5o|Y&qReNOxhkEa{CE6d^UtmF@OXk<_qkc0 zc+ckH8Knc!FTjk&5FEQ}$sxj!(a4223cII&iai-nY~2`|K89YKcrYFAMo^oIh@W^; zsb{KOy?dv_D5%}zPk_7^I!C2YsrfyNBUw_ude7XDc0-+LjC0!X_moHU3wmveS@GRu zX>)G}L_j1I-_5B|b&|{ExH~;Nm!xytCyc}Ed!&Hqg;=qTK7C93f>!m3n!S5Z!m`N} zjIcDWm8ES~V2^dKuv>8@Eu)Zi{A4;qHvTW7hB6B38h%$K76BYwC3DIQ0a;2fSQvo$ z`Q?BEYF1`@I-Nr6z{@>`ty~mFC|XR`HSg(HN>&-#&eoDw-Q1g;x@Bc$@sW{Q5H&R_ z5Aici44Jq-tbGnDsu0WVM(RZ=s;CIcIq?73**v!Y^jvz7ckw*=?0=B!{I?f{68@V( z4dIgOUYbLOiQccu$X4P87wZC^IbGnB5lLfFkBzLC3hRD?q4_^%@O5G*WbD?Wug6{<|N#Fv_Zf3ST>+v_!q5!fSy#{_XVq$;k*?Ar^R&FuFM7 zKYiLaSe>Cw@`=IUMZ*U#v>o5!iZ7S|rUy2(yG+AGnauj{;z=s8KQ(CdwZ>&?Z^&Bt z+74(G;BD!N^Ke>(-wwZN5~K%P#L)59`a;zSnRa>2dCzMEz`?VaHaTC>?&o|(d6e*Z zbD!=Ua-u6T6O!gQnncZ&699BJyAg9mKXd_WO8O`N@}bx%BSq)|jgrySfnFvzOj!44 z9ci@}2V3!ag8@ZbJO;;Q5ivdTWx+TGR`?75Jcje}*ufx@%5MFUsfsi%FoEx)&uzkN zgaGFOV!s@Hw3M%pq5`)M4Nz$)~Sr9$V2rkP?B7kvI7VAcnp6iZl zOd!(TNw+UH49iHWC4!W&9;ZuB+&*@Z$}>0fx8~6J@d)fR)WG1UndfdVEeKW=HAur| z15zG-6mf`wyn&x@&?@g1ibkIMob_`x7nh7yu9M>@x~pln>!_kzsLAY#2ng0QEcj)qKGj8PdWEuYKdM!jd{ zHP6j^`1g}5=C%)LX&^kpe=)X+KR4VRNli?R2KgYlwKCN9lcw8GpWMV+1Ku)~W^jV2 zyiTv-b*?$AhvU7j9~S5+u`Ysw9&5oo0Djp8e(j25Etbx42Qa=4T~}q+PG&XdkWDNF z7bqo#7KW&%dh~ST6hbu8S=0V`{X&`kAy@8jZWZJuYE}_#b4<-^4dNUc-+%6g($yN% z5ny^;ogGh}H5+Gq3jR21rQgy@5#TCgX+(28NZ4w}dzfx-LP%uYk9LPTKABaQh1ah) z@Y(g!cLd!Mcz+e|XI@@IH9z*2=zxJ0uaJ+S(iIsk7=d>A#L<}={n`~O?UTGX{8Pda z_KhI*4jI?b{A!?~-M$xk)w0QBJb7I=EGy&o3AEB_RloU;v~F8ubD@9BbxV1c36CsTX+wzAZlvUm*;Re06D+Bq~LYg-qF4L z5kZZ80PB&4U?|hL9nIZm%jVj0;P_lXar)NSt3u8xx!K6Y0bclZ%<9fwjZ&!^;!>ug zQ}M`>k@S{BR20cyVXtKK%Qa^7?e<%VSAPGmVtGo6zc6BkO5vW5)m8_k{xT3;ocdpH zudHGT06XU@y6U!&kP8i6ubMQl>cm7=(W6P7^24Uzu4Xpwc->ib?RSHL*?!d{c-aE# zp?TrFr{4iDL3dpljl#HHbEn{~eW2Nqfksa(r-}n)lJLI%e#Bu|+1% zN&!n(nv(3^jGx?onfDcyeCC*p6)DuFn_<*62b92Pn$LH(INE{z^8y?mEvvO zZ~2I;A2qXvuj>1kk@WsECq1WbsSC!0m8n=S^t3kxAx~of0vpv{EqmAmDJ3(o;-cvf zu$33Z)C0)Y4(iBhh@)lsS|a%{;*W(@DbID^$ z|FzcJB-RFzpkBLaFLQ;EWMAW#@K(D#oYoOmcctdTV?fzM2@6U&S#+S$&zA4t<^-!V z+&#*xa)cLnfMTVE&I}o#4kxP~JT3-A)L_5O!yA2ebq?zvb0WO1D6$r9p?!L0#)Fc> z+I&?aog~FPBH}BpWfW^pyc{2i8#Io6e)^6wv}MZn&`01oq@$M@5eJ6J^IrXLI) z4C!#kh)89u5*Q@W5(rYDqBKO6&G*kPGFZfu@J}ug^7!sC(Wcv3Fbe{$Sy|{-VXTct znsP+0v}kduRs=S=x0MA$*(7xZPE-%aIt^^JG9s}8$43E~^t4=MxmMts;q2$^sj=k( z#^suR{0Wl3#9KAI<=SC6hifXuA{o02vdyq>iw%(#tv+@ov{QZBI^*^1K?Q_QQqA5n9YLRwO3a7JR+1x3#d3lZL;R1@8Z!2hnWj^_5 z^M{3wg%f15Db5Pd>tS!6Hj~n^l478ljxe@>!C;L$%rKfm#RBw^_K&i~ZyY_$BC%-L z^NdD{thVHFlnwfy(a?{%!m;U_9ic*!OPxf&5$muWz7&4VbW{PP)oE5u$uXUZU>+8R zCsZ~_*HLVnBm*^{seTAV=iN)mB0{<}C!EgE$_1RMj1kGUU?cjSWu*|zFA(ZrNE(CkY7>Mv1C)E1WjsBKAE%w}{~apwNj z0h`k)C1$TwZ<3de9+>;v6A0eZ@xHm#^7|z9`gQ3<`+lpz(1(RsgHAM@Ja+)c?;#j- zC=&5FD)m@9AX}0g9XQ_Yt4YB}aT`XxM-t>7v@BV}2^0gu0zRH%S9}!P(MBAFGyJ8F zEMdB&{eGOd$RqV77Lx>8pX^<@TdL{6^K7p$0uMTLC^n)g*yXRXMy`tqjYIZ|3b#Iv z4<)jtQU5`b{A;r2QCqIy>@!uuj^TBed3OuO1>My{GQe<^9|$4NOHTKFp{GpdFY-kC zi?uHq>lF$}<(JbQatP0*>$Aw_lygfmUyojkE=PnV)zc)7%^5BxpjkU+>ol2}WpB2hlDP(hVA;uLdu`=M_A!%RaRTd6>Mi_ozLYOEh!dfT_h0dSsnQm1bk)%K45)xLw zql&fx?ZOMBLXtUd$PRlqpo2CxNQTBb=!T|_>p&k1F})Hq&xksq>o#4b+KSs2KyxPQ z#{(qj@)9r6u2O~IqHG76@Fb~BZ4Wz_J$p_NU9-b3V$$kzjN24*sdw5spXetOuU1SR z{v}b92c>^PmvPs>BK2Ylp6&1>tnPsBA0jg0RQ{({-?^SBBm>=W>tS?_h^6%Scc)8L zgsKjSU@@6kSFX%_3%Qe{i7Z9Wg7~fM_)v?ExpM@htI{G6Db5ak(B4~4kRghRp_7zr z#Pco0_(bD$IS6l2j>%Iv^Hc)M`n-vIu;-2T+6nhW0JZxZ|NfDEh;ZnAe d|9e8rKfIInFTYPwOD9TMuEcqhmizAn{|ERF)u#Xe diff --git a/gradlew b/gradlew index 1aa94a426..f5feea6d6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30dbd..9d21a2183 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/settings.gradle b/settings.gradle index 601e86bce..86a38a64f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -16,5 +16,5 @@ pluginManagement { } plugins { - id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.27' + id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.29' } From 6c8b69e18f90a9c7219fd5e7bcb385a9c17c48ef Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Sun, 17 Nov 2024 23:49:32 -0500 Subject: [PATCH 02/16] Track frametimes Properly tracks times, from swap to swap --- .../angelica/proxy/ClientProxy.java | 16 ++++++++++------ .../mixins/early/angelica/MixinMinecraft.java | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java index b46644aa6..ab9e5a87b 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java @@ -1,5 +1,7 @@ package com.gtnewhorizons.angelica.proxy; +import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER; + import com.google.common.base.Objects; import com.gtnewhorizon.gtnhlib.client.renderer.vertex.DefaultVertexFormat; import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat; @@ -26,6 +28,10 @@ import cpw.mods.fml.common.gameevent.TickEvent; import cpw.mods.fml.common.registry.GameData; import cpw.mods.fml.relauncher.ReflectionHelper; +import it.unimi.dsi.fastutil.longs.LongArrayList; +import java.lang.management.ManagementFactory; +import java.util.Locale; +import java.util.concurrent.ConcurrentHashMap; import jss.notfine.core.Settings; import me.jellysquid.mods.sodium.client.SodiumDebugScreenHandler; import net.coderbot.iris.Iris; @@ -53,15 +59,13 @@ import net.minecraftforge.event.world.WorldEvent; import org.lwjgl.input.Keyboard; -import java.lang.management.ManagementFactory; -import java.util.Locale; -import java.util.concurrent.ConcurrentHashMap; - -import static com.gtnewhorizons.angelica.loading.AngelicaTweaker.LOGGER; - public class ClientProxy extends CommonProxy { final Minecraft mc = Minecraft.getMinecraft(); + public static final int NUM_FRAMETIMES = 240; + // Circular buffer holding the last 240 frametimes, in nanoseconds + public static final LongArrayList frametimes = new LongArrayList(NUM_FRAMETIMES); + public static int frametimesHead = 0; // one ahead of the position of the last frametime @Override public void preInit(FMLPreInitializationEvent event) { diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java index 3637120b7..8b23d1d45 100644 --- a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java @@ -1,8 +1,13 @@ package com.gtnewhorizons.angelica.mixins.early.angelica; +import static com.gtnewhorizons.angelica.proxy.ClientProxy.NUM_FRAMETIMES; +import static com.gtnewhorizons.angelica.proxy.ClientProxy.frametimes; +import static com.gtnewhorizons.angelica.proxy.ClientProxy.frametimesHead; + import net.minecraft.client.Minecraft; import org.lwjgl.opengl.GL11; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -10,6 +15,9 @@ @Mixin(Minecraft.class) public class MixinMinecraft { + @Unique + private long angelica$lastFrameTime = 0; + @Inject( method = "runGameLoop", at = @At(value = "INVOKE", target = "Lcpw/mods/fml/common/FMLCommonHandler;onRenderTickEnd(F)V", shift = At.Shift.AFTER, remap = false) @@ -17,4 +25,15 @@ public class MixinMinecraft { private void angelica$injectLightingFixPostRenderTick(CallbackInfo ci) { GL11.glEnable(GL11.GL_LIGHTING); } + + @Inject( + method = "func_147120_f", + at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;update()V", shift = At.Shift.AFTER) + ) + private void angelica$trackFrametimes(CallbackInfo ci) { + long time = System.nanoTime(); + frametimes.set(frametimesHead, time - angelica$lastFrameTime); + frametimesHead = (frametimesHead + 1) % NUM_FRAMETIMES; + angelica$lastFrameTime = time; + } } From 5f5ba8abe0b1508b978c8b47f531fe1f619076e1 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Mon, 18 Nov 2024 07:42:08 -0500 Subject: [PATCH 03/16] Initial graph renderer it's SUPPOSED to throw up a black rectangle. Frametimes are tracked, but not shown. why doesn't it work :anger: --- README.MD | 2 +- .../angelica/debug/FrametimeGraph.java | 115 ++++++++++++++++++ .../angelica/proxy/ClientProxy.java | 9 +- .../angelica/shaders/frametimes.frag.glsl | 5 + .../angelica/shaders/frametimes.vert.glsl | 10 ++ .../angelica/textures/frametimes_bg.png | Bin 0 -> 1007 bytes .../mixins/early/angelica/MixinMinecraft.java | 8 +- 7 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java create mode 100644 src/main/resources/assets/angelica/shaders/frametimes.frag.glsl create mode 100644 src/main/resources/assets/angelica/shaders/frametimes.vert.glsl create mode 100644 src/main/resources/assets/angelica/textures/frametimes_bg.png diff --git a/README.MD b/README.MD index 6d870c947..26caac652 100644 --- a/README.MD +++ b/README.MD @@ -37,7 +37,7 @@ * [Amazing Trophies 1.2.1 and below](https://github.com/GTNewHorizons/Amazing-Trophies/releases) - use 1.2.2+ * [LWJGL3ify 1.5.4 and below](https://github.com/GTNewHorizons/lwjgl3ify/releases/) - Use the latest version available, 1.5.7+ * [ArchaicFix 0.6.2 and below](https://www.curseforge.com/minecraft/mc-mods/archaicfix/files/all?page=1&pageSize=20) - Use 0.7.0 or above -* [Hodgepodge 2.4.3 and below](https://github.com/GTNewHorizons/Hodgepodge/releases) - Use 2.4.4 or above +* [Hodgepodge 2.4.3 and below](https://github.com/GTNewHorizons/Hodgepodge/releases) - Use 0.4.5 or above * CodeChicken[Core](https://github.com/GTNewHorizons/CodeChickenCore/releases)/[Lib](https://github.com/GTNewHorizons/CodeChickenLib/releases) <1.2.0 - Threading issues, use 1.3.0+ * Neodymium - Untested, but unlikely to be compatible. (Chunk Meshing is definitely incompatible, other features might work depending on config) diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java new file mode 100644 index 000000000..6bda87bbb --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -0,0 +1,115 @@ +package com.gtnewhorizons.angelica.debug; + +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_FLOAT; +import static org.lwjgl.opengl.GL11.GL_TRIANGLES; +import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glDisableClientState; +import static org.lwjgl.opengl.GL11.glDrawArrays; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glEnableClientState; +import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; +import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; +import static org.lwjgl.opengl.GL15.glBindBuffer; +import static org.lwjgl.opengl.GL15.glBufferData; +import static org.lwjgl.opengl.GL15.glGenBuffers; +import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glUniform1f; +import static org.lwjgl.opengl.GL20.glVertexAttribPointer; + +import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; +import java.nio.ByteBuffer; +import net.minecraft.client.Minecraft; +import org.lwjgl.BufferUtils; + +public class FrametimeGraph { + public static final int NUM_FRAMETIMES = 240; + public static final long[] frametimes = new long[NUM_FRAMETIMES]; + // Circular buffer holding the last 240 frametimes, in nanoseconds + public static int frametimesHead = 0; // one ahead of the position of the last frametime + private boolean initialized = false; + private ShaderProgram shader; + private static final int WEIGHT = 2; // in pixels + private static final int SAMPLES_WIDTH = NUM_FRAMETIMES * WEIGHT; + private int aPos; + private int uFBWidth; + private int vertBuf; + // Two floats (x,y) + private static final int VERT_FLOATS = 2; + private static final int VERT_COUNT = 4; + + + private void init() { + shader = new ShaderProgram( + "angelica", + "shaders/frametimes.vert.glsl", + "shaders/frametimes.frag.glsl"); + shader.use(); + + // Register attributes + aPos = shader.getAttribLocation("pos"); + + // Register uniforms + uFBWidth = shader.getUniformLocation("fbWidth"); + + // Load vertex buffer + vertBuf = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, vertBuf); + // Since we use a triangle strip, we only need 4 verts + final ByteBuffer vertexes = BufferUtils.createByteBuffer(4 * VERT_COUNT * VERT_FLOATS); + // The Y coords are simple - the rect is from top to bottom, 1.0 to -1.0 + // The X coord get scaled by the framebuffer size in the vert shader + for (int x = 0; x < 2; ++x) { + for (int y = -1; y < 2; y += 2) { + vertexes.putFloat(x == 0 ? 2 : 482); + vertexes.putFloat(y); + } + } + glBufferData(GL_ARRAY_BUFFER, vertexes, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + // Load initial value for uniforms + glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); + + ShaderProgram.clear(); + } + + public void render() { + if (!initialized) { + init(); + initialized = true; + } + /** + * We try to copy modern vanilla's tracker. + * It is 484 wide by 124 tall, including the 2px borders. + * The background is ARGB 90505050, the borders FFFFFFFF, and the text FFE0E0E0. + * First the samples are rendered, then the background/borders, then the text. The samples are rendered by a + * shader on a transparent rect 480px wide and as high as the framebuffer. Next, the background is drawn via a + * 484x124 translucent rect, and finally FontRenderer slaps the text on top. The shader pipeline is only needed + * for the first draw. + */ + + shader.use(); + + // Load uniforms + glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); + + // Draw! + glBindBuffer(GL_ARRAY_BUFFER, vertBuf); + glEnableVertexAttribArray(aPos); + glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0); + glEnableClientState(GL_VERTEX_ARRAY); + glDisable(GL_BLEND); + + glDrawArrays(GL_TRIANGLES, 0, VERT_COUNT); + + glEnable(GL_BLEND); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableVertexAttribArray(aPos); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ShaderProgram.clear(); + } +} diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java index ab9e5a87b..6a7cab53c 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java @@ -9,6 +9,7 @@ import com.gtnewhorizons.angelica.compat.bettercrashes.BetterCrashesCompat; import com.gtnewhorizons.angelica.config.AngelicaConfig; import com.gtnewhorizons.angelica.config.CompatConfig; +import com.gtnewhorizons.angelica.debug.FrametimeGraph; import com.gtnewhorizons.angelica.dynamiclights.DynamicLights; import com.gtnewhorizons.angelica.glsm.GLStateManager; import com.gtnewhorizons.angelica.glsm.debug.OpenGLDebugging; @@ -28,7 +29,6 @@ import cpw.mods.fml.common.gameevent.TickEvent; import cpw.mods.fml.common.registry.GameData; import cpw.mods.fml.relauncher.ReflectionHelper; -import it.unimi.dsi.fastutil.longs.LongArrayList; import java.lang.management.ManagementFactory; import java.util.Locale; import java.util.concurrent.ConcurrentHashMap; @@ -62,10 +62,7 @@ public class ClientProxy extends CommonProxy { final Minecraft mc = Minecraft.getMinecraft(); - public static final int NUM_FRAMETIMES = 240; - // Circular buffer holding the last 240 frametimes, in nanoseconds - public static final LongArrayList frametimes = new LongArrayList(NUM_FRAMETIMES); - public static int frametimesHead = 0; // one ahead of the position of the last frametime + final FrametimeGraph graph = new FrametimeGraph(); @Override public void preInit(FMLPreInitializationEvent event) { @@ -191,6 +188,8 @@ public void onTick(TickEvent.ServerTickEvent event) { public void onRenderOverlay(RenderGameOverlayEvent.Text event) { Minecraft mc = Minecraft.getMinecraft(); if (event.isCanceled() || !mc.gameSettings.showDebugInfo || event.left.isEmpty()) return; + // Draw a frametime graph + graph.render(); NetHandlerPlayClient cl = mc.getNetHandler(); if (cl != null) { IntegratedServer srv = mc.getIntegratedServer(); diff --git a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl new file mode 100644 index 000000000..5e21117d9 --- /dev/null +++ b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl @@ -0,0 +1,5 @@ +#version 120 + +void main() { + gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); +} diff --git a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl b/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl new file mode 100644 index 000000000..18789b1db --- /dev/null +++ b/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl @@ -0,0 +1,10 @@ +#version 120 + +attribute vec2 pos; + +uniform float fbWidth; + +void main() { + // Shift the bounds (x = 2 through x = 482) to clip space + gl_Position = vec4(pos.x / fbWidth * 2.0 - 1.0, pos.y, -1.0, 1.0); +} diff --git a/src/main/resources/assets/angelica/textures/frametimes_bg.png b/src/main/resources/assets/angelica/textures/frametimes_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..b57b832bf8a39a523454161a1a929befa10def72 GIT binary patch literal 1007 zcmeAS@N?(olHy`uVBq!ia0y~yV0;2(*Kn`_$sKPFCj$kVGo76SJe{2t3X1a6GILTH z7&Io>zVAKG@q;yQxf|@I=7eH$kp4*`i$m3$JjkwVDz0i`7?Zl8Ctb!L1J- z98bD>@MvT>d$^;(ABMuRf}oO#LjR|WL>;LpxYJ+$U9S8+!@|haRX2s%L(Uo*ootzL zdVSZy@Gr?6j7JzcXa0(@n%ngJ$FBDN_2q%{p4PrQZ@56jhwX>UBa6$t-4)FhX_qfq zz87wfj11~H->J^KOW~vP_0;M2EvCzeRixcGk@l?f@R6jI-B0z>Qk_-jsr6~Ba{K9Y zF17WuSo+qe^taWY#M`)Toie(f*{9g)s-ws&X!L5u0xs^rDAORHlnnca59Le$WEP!# zvZ`TXGNb8=2{QIS-f(AQyV`9opD*1QZVRV~Ua&m&qN&jFCvBvMlzn0k;)Np@UyL0c>?}fh@ zQdX|M!dpn3R{x5y9>jA5L~c#`DCC7 zXMsm#F$061G6*wPEVVBK3bL1Y`ns~e;1*)j(LJ1S4JgMTS>hT|;+&tGo0?a`;9QiN zSdyBeP@Y+mq2TW68xY>eCk~A56P_-PAr-gYUf;;uV8G)N*tBVZdZL)x#}4GgAnI=I&k2kVlvyMhfJh((gd8R?0uh5F8wd?f zi7;u;BsPW*ip&SzpZ&gK)omGu4PoW+b}0-$I0mz`aRz3Y1l&Ki&kaQ0Wwt!L0E~DB MPgg&ebxsLQ0AA!nDF6Tf literal 0 HcmV?d00001 diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java index 8b23d1d45..c104095a6 100644 --- a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java @@ -1,8 +1,8 @@ package com.gtnewhorizons.angelica.mixins.early.angelica; -import static com.gtnewhorizons.angelica.proxy.ClientProxy.NUM_FRAMETIMES; -import static com.gtnewhorizons.angelica.proxy.ClientProxy.frametimes; -import static com.gtnewhorizons.angelica.proxy.ClientProxy.frametimesHead; +import static com.gtnewhorizons.angelica.debug.FrametimeGraph.NUM_FRAMETIMES; +import static com.gtnewhorizons.angelica.debug.FrametimeGraph.frametimes; +import static com.gtnewhorizons.angelica.debug.FrametimeGraph.frametimesHead; import net.minecraft.client.Minecraft; import org.lwjgl.opengl.GL11; @@ -32,7 +32,7 @@ public class MixinMinecraft { ) private void angelica$trackFrametimes(CallbackInfo ci) { long time = System.nanoTime(); - frametimes.set(frametimesHead, time - angelica$lastFrameTime); + frametimes[frametimesHead] = time - angelica$lastFrameTime; frametimesHead = (frametimesHead + 1) % NUM_FRAMETIMES; angelica$lastFrameTime = time; } From 8832f269e3549b298642077a6e5549b3f36cb537 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Mon, 18 Nov 2024 08:10:10 -0500 Subject: [PATCH 04/16] attempt println debugging --- .../gtnewhorizons/angelica/debug/FrametimeGraph.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java index 6bda87bbb..558acd068 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -2,7 +2,7 @@ import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_FLOAT; -import static org.lwjgl.opengl.GL11.GL_TRIANGLES; +import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; import static org.lwjgl.opengl.GL11.glDisable; import static org.lwjgl.opengl.GL11.glDisableClientState; @@ -20,6 +20,7 @@ import static org.lwjgl.opengl.GL20.glVertexAttribPointer; import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; +import com.gtnewhorizons.angelica.glsm.GLDebug; import java.nio.ByteBuffer; import net.minecraft.client.Minecraft; import org.lwjgl.BufferUtils; @@ -42,6 +43,7 @@ public class FrametimeGraph { private void init() { + GLDebug.debugMessage("init fgshader"); shader = new ShaderProgram( "angelica", "shaders/frametimes.vert.glsl", @@ -74,6 +76,7 @@ private void init() { glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); ShaderProgram.clear(); + GLDebug.debugMessage("finish init fgshader"); } public void render() { @@ -90,7 +93,7 @@ public void render() { * 484x124 translucent rect, and finally FontRenderer slaps the text on top. The shader pipeline is only needed * for the first draw. */ - + GLDebug.debugMessage("render fgshader"); shader.use(); // Load uniforms @@ -103,7 +106,7 @@ public void render() { glEnableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); - glDrawArrays(GL_TRIANGLES, 0, VERT_COUNT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT); glEnable(GL_BLEND); glDisableClientState(GL_VERTEX_ARRAY); @@ -111,5 +114,6 @@ public void render() { glBindBuffer(GL_ARRAY_BUFFER, 0); ShaderProgram.clear(); + GLDebug.debugMessage("finish render fgshader"); } } From ebfb39c09245d8da2fa585538ebe4983f3277833 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:18:52 -0500 Subject: [PATCH 05/16] there we go thanks kurrycat --- .../gtnewhorizons/angelica/debug/FrametimeGraph.java | 10 +++------- .../com/gtnewhorizons/angelica/proxy/ClientProxy.java | 9 +++++++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java index 558acd068..ce765cac7 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -20,7 +20,6 @@ import static org.lwjgl.opengl.GL20.glVertexAttribPointer; import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; -import com.gtnewhorizons.angelica.glsm.GLDebug; import java.nio.ByteBuffer; import net.minecraft.client.Minecraft; import org.lwjgl.BufferUtils; @@ -43,7 +42,6 @@ public class FrametimeGraph { private void init() { - GLDebug.debugMessage("init fgshader"); shader = new ShaderProgram( "angelica", "shaders/frametimes.vert.glsl", @@ -63,12 +61,13 @@ private void init() { final ByteBuffer vertexes = BufferUtils.createByteBuffer(4 * VERT_COUNT * VERT_FLOATS); // The Y coords are simple - the rect is from top to bottom, 1.0 to -1.0 // The X coord get scaled by the framebuffer size in the vert shader - for (int x = 0; x < 2; ++x) { - for (int y = -1; y < 2; y += 2) { + for (int y = -1; y < 2; y += 2) { + for (int x = 0; x < 2; ++x) { vertexes.putFloat(x == 0 ? 2 : 482); vertexes.putFloat(y); } } + vertexes.rewind(); glBufferData(GL_ARRAY_BUFFER, vertexes, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -76,7 +75,6 @@ private void init() { glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); ShaderProgram.clear(); - GLDebug.debugMessage("finish init fgshader"); } public void render() { @@ -93,7 +91,6 @@ public void render() { * 484x124 translucent rect, and finally FontRenderer slaps the text on top. The shader pipeline is only needed * for the first draw. */ - GLDebug.debugMessage("render fgshader"); shader.use(); // Load uniforms @@ -114,6 +111,5 @@ public void render() { glBindBuffer(GL_ARRAY_BUFFER, 0); ShaderProgram.clear(); - GLDebug.debugMessage("finish render fgshader"); } } diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java index 6a7cab53c..fe84e7d0b 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java @@ -188,8 +188,7 @@ public void onTick(TickEvent.ServerTickEvent event) { public void onRenderOverlay(RenderGameOverlayEvent.Text event) { Minecraft mc = Minecraft.getMinecraft(); if (event.isCanceled() || !mc.gameSettings.showDebugInfo || event.left.isEmpty()) return; - // Draw a frametime graph - graph.render(); + NetHandlerPlayClient cl = mc.getNetHandler(); if (cl != null) { IntegratedServer srv = mc.getIntegratedServer(); @@ -199,6 +198,7 @@ public void onRenderOverlay(RenderGameOverlayEvent.Text event) { event.left.add(Math.min(event.left.size(), 1), s); } } + if (AngelicaConfig.showBlockDebugInfo && mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { if (!event.right.isEmpty() && !Objects.firstNonNull(event.right.get(event.right.size() - 1), "").isEmpty()) event.right.add(""); Block block = mc.theWorld.getBlock(mc.objectMouseOver.blockX, mc.objectMouseOver.blockY, mc.objectMouseOver.blockZ); @@ -206,6 +206,7 @@ public void onRenderOverlay(RenderGameOverlayEvent.Text event) { event.right.add(Block.blockRegistry.getNameForObject(block)); event.right.add("meta: " + meta); } + if (DynamicLights.isEnabled()) { var builder = new StringBuilder("Dynamic Light Sources: "); DynamicLights dl = DynamicLights.get(); @@ -213,6 +214,7 @@ public void onRenderOverlay(RenderGameOverlayEvent.Text event) { event.right.add(builder.toString()); } + if (AngelicaConfig.modernizeF3Screen) { boolean hasReplacedXYZ = false; for (int i = 0; i < event.left.size() - 3; i++) { @@ -277,6 +279,9 @@ public void onRenderOverlay(RenderGameOverlayEvent.Text event) { Gui.drawRect(strX - 1, strY - 1, strX + w + 1, strY + fontrenderer.FONT_HEIGHT - 1, rectColor); fontrenderer.drawString(msg, strX, strY, fontColor); } + + // Draw a frametime graph + graph.render(); } } From 3a754aff2334c95eebf1b170e567328012f1d3e6 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Mon, 18 Nov 2024 11:11:23 -0500 Subject: [PATCH 06/16] Technically works now But not really --- .../angelica/debug/FrametimeGraph.java | 22 ++++++++++++++---- .../angelica/proxy/ClientProxy.java | 5 ++++ .../angelica/proxy/CommonProxy.java | 4 +++- .../angelica/shaders/frametimes.frag.glsl | 23 ++++++++++++++++++- .../angelica/shaders/frametimes.vert.glsl | 7 ++++-- .../mixins/early/angelica/MixinMinecraft.java | 8 ++----- 6 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java index ce765cac7..c1de3661a 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -16,30 +16,37 @@ import static org.lwjgl.opengl.GL15.glGenBuffers; import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glUniform1; import static org.lwjgl.opengl.GL20.glUniform1f; import static org.lwjgl.opengl.GL20.glVertexAttribPointer; import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; import java.nio.ByteBuffer; +import java.nio.FloatBuffer; import net.minecraft.client.Minecraft; import org.lwjgl.BufferUtils; public class FrametimeGraph { public static final int NUM_FRAMETIMES = 240; - public static final long[] frametimes = new long[NUM_FRAMETIMES]; // Circular buffer holding the last 240 frametimes, in nanoseconds - public static int frametimesHead = 0; // one ahead of the position of the last frametime + public int frametimesHead = 0; // one ahead of the position of the last frametime private boolean initialized = false; private ShaderProgram shader; - private static final int WEIGHT = 2; // in pixels - private static final int SAMPLES_WIDTH = NUM_FRAMETIMES * WEIGHT; private int aPos; private int uFBWidth; + private int uFBHeight; + private int uFrametimes; private int vertBuf; // Two floats (x,y) private static final int VERT_FLOATS = 2; private static final int VERT_COUNT = 4; + // Due to GLSL 120 limitations, it's just easier to use floats + private final FloatBuffer frametimesBuf = BufferUtils.createFloatBuffer(NUM_FRAMETIMES); + public void putFrameTime(long time) { + frametimesBuf.put(frametimesHead, (float) time); + frametimesHead = (frametimesHead + 1) % NUM_FRAMETIMES; + } private void init() { shader = new ShaderProgram( @@ -53,6 +60,8 @@ private void init() { // Register uniforms uFBWidth = shader.getUniformLocation("fbWidth"); + uFBHeight = shader.getUniformLocation("fbHeight"); + uFrametimes = shader.getUniformLocation("frametimes"); // Load vertex buffer vertBuf = glGenBuffers(); @@ -73,6 +82,8 @@ private void init() { // Load initial value for uniforms glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); + glUniform1f(uFBHeight, Minecraft.getMinecraft().displayHeight); + glUniform1(uFrametimes, frametimesBuf); ShaderProgram.clear(); } @@ -82,6 +93,7 @@ public void render() { init(); initialized = true; } + /** * We try to copy modern vanilla's tracker. * It is 484 wide by 124 tall, including the 2px borders. @@ -95,6 +107,8 @@ public void render() { // Load uniforms glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); + glUniform1f(uFBHeight, Minecraft.getMinecraft().displayHeight); + glUniform1(uFrametimes, frametimesBuf); // Draw! glBindBuffer(GL_ARRAY_BUFFER, vertBuf); diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java index fe84e7d0b..72e2bc262 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java @@ -317,4 +317,9 @@ public void onFOVModifierUpdate(FOVUpdateEvent event) { event.newfov = 1.0F; } } + + @Override + public void putFrametime(long time) { + graph.putFrameTime(time); + } } diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/CommonProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/CommonProxy.java index 5b0409406..8ef1adfe7 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/CommonProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/CommonProxy.java @@ -2,7 +2,6 @@ import com.gtnewhorizons.angelica.common.BlockTest; import com.gtnewhorizons.angelica.config.AngelicaConfig; -import com.gtnewhorizons.angelica.utils.AssetLoader; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; @@ -20,4 +19,7 @@ public void preInit(FMLPreInitializationEvent event) { public void init(FMLInitializationEvent event) {} public void postInit(FMLPostInitializationEvent event) {} + + // Only present on the client! + public void putFrametime(long time) { throw new UnsupportedOperationException(); } } diff --git a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl index 5e21117d9..3177c9966 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl +++ b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl @@ -1,5 +1,26 @@ #version 120 +uniform float frametimes[240]; + void main() { - gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); + // Get position - gl_FragCoord starts from the lower left and returns the position of the center of the pixel + // i.e. the lower-left-most pixel is (0.5, 0.5) + // Additionally, shift them to account for the 2px border. + int dx = int(gl_FragCoord.x) - 2; + int dy = int(gl_FragCoord.x) - 2; + + // Get the frametime for this frag + int idx = clamp(dx / 2, 0, 239); + float time = frametimes[idx]; + + // Time is in nanoseconds. The bar should be 120 px high at 30 FPS, i.e. 33333ns = 120px. 0.0036 px/ns + // If it's higher or as high as we are, recolor accordingly. + // Also, apparently GLSL 120 doesn't have rounding + float height = floor(time * 0.0036 + 0.5); + + vec4 color = vec4(0.0, 0.0, 0.0, 0.0); + float r = clamp(time / 28000.0, 0, 1); + float g = clamp((time - 28000.0) / 28000.0, 0, 1); + if (dy <= height) color = vec4(mix(0.0, 255.0, r), mix(255.0, 0.0, g), 0.0, 1.0); + gl_FragColor = color; } diff --git a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl b/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl index 18789b1db..f336b138c 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl +++ b/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl @@ -2,9 +2,12 @@ attribute vec2 pos; +uniform float fbHeight; uniform float fbWidth; void main() { - // Shift the bounds (x = 2 through x = 482) to clip space - gl_Position = vec4(pos.x / fbWidth * 2.0 - 1.0, pos.y, -1.0, 1.0); + // Shift the bounds (x = 2 through x = 482, y = 0 through y = max - 2) to clip space + float x = pos.x / fbWidth * 2.0 - 1.0; + float y = clamp(pos.y, 2.0 / fbHeight * 2.0 - 1.0, 1.0); + gl_Position = vec4(x, y, -1.0, 1.0); } diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java index c104095a6..d7356172e 100644 --- a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java @@ -1,9 +1,6 @@ package com.gtnewhorizons.angelica.mixins.early.angelica; -import static com.gtnewhorizons.angelica.debug.FrametimeGraph.NUM_FRAMETIMES; -import static com.gtnewhorizons.angelica.debug.FrametimeGraph.frametimes; -import static com.gtnewhorizons.angelica.debug.FrametimeGraph.frametimesHead; - +import com.gtnewhorizons.angelica.AngelicaMod; import net.minecraft.client.Minecraft; import org.lwjgl.opengl.GL11; import org.spongepowered.asm.mixin.Mixin; @@ -32,8 +29,7 @@ public class MixinMinecraft { ) private void angelica$trackFrametimes(CallbackInfo ci) { long time = System.nanoTime(); - frametimes[frametimesHead] = time - angelica$lastFrameTime; - frametimesHead = (frametimesHead + 1) % NUM_FRAMETIMES; + AngelicaMod.proxy.putFrametime(time - angelica$lastFrameTime); angelica$lastFrameTime = time; } } From dc68a88bbbfb78b7dc6eb086bfe54c7e3889a8fd Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Mon, 18 Nov 2024 11:52:33 -0500 Subject: [PATCH 07/16] Minor patches Shift for the leading index, unreverse the graph, scale inputs properly, and actually use the y coord. --- .../angelica/debug/FrametimeGraph.java | 8 ++++++++ .../angelica/shaders/frametimes.frag.glsl | 17 ++++++++++------- .../angelica/shaders/frametimes.vert.glsl | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java index c1de3661a..882013ad4 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -1,5 +1,6 @@ package com.gtnewhorizons.angelica.debug; +import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_FLOAT; import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; @@ -18,6 +19,7 @@ import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; import static org.lwjgl.opengl.GL20.glUniform1; import static org.lwjgl.opengl.GL20.glUniform1f; +import static org.lwjgl.opengl.GL20.glUniform1i; import static org.lwjgl.opengl.GL20.glVertexAttribPointer; import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; @@ -35,6 +37,7 @@ public class FrametimeGraph { private int aPos; private int uFBWidth; private int uFBHeight; + private int uHeadIdx; private int uFrametimes; private int vertBuf; // Two floats (x,y) @@ -62,6 +65,7 @@ private void init() { uFBWidth = shader.getUniformLocation("fbWidth"); uFBHeight = shader.getUniformLocation("fbHeight"); uFrametimes = shader.getUniformLocation("frametimes"); + uHeadIdx = shader.getUniformLocation("headIdx"); // Load vertex buffer vertBuf = glGenBuffers(); @@ -83,6 +87,7 @@ private void init() { // Load initial value for uniforms glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); glUniform1f(uFBHeight, Minecraft.getMinecraft().displayHeight); + glUniform1i(uHeadIdx, frametimesHead); glUniform1(uFrametimes, frametimesBuf); ShaderProgram.clear(); @@ -108,6 +113,7 @@ public void render() { // Load uniforms glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); glUniform1f(uFBHeight, Minecraft.getMinecraft().displayHeight); + glUniform1i(uHeadIdx, frametimesHead); glUniform1(uFrametimes, frametimesBuf); // Draw! @@ -116,9 +122,11 @@ public void render() { glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0); glEnableClientState(GL_VERTEX_ARRAY); glDisable(GL_BLEND); + glEnable(GL_ALPHA_TEST); glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT); + glDisable(GL_ALPHA_TEST); glEnable(GL_BLEND); glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(aPos); diff --git a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl index 3177c9966..de74c4618 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl +++ b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl @@ -1,5 +1,6 @@ #version 120 +uniform int headIdx; uniform float frametimes[240]; void main() { @@ -7,20 +8,22 @@ void main() { // i.e. the lower-left-most pixel is (0.5, 0.5) // Additionally, shift them to account for the 2px border. int dx = int(gl_FragCoord.x) - 2; - int dy = int(gl_FragCoord.x) - 2; + int dy = int(gl_FragCoord.y) - 2; - // Get the frametime for this frag - int idx = clamp(dx / 2, 0, 239); + // Get the frametime for this frag. Last at the left edge, first at the right, shifting as needed when the head + // moves. Since head is one ahead of the last frame, remove one. + int idx = int(mod(clamp(dx / 2 , 0, 239) + headIdx - 1, 240)); float time = frametimes[idx]; - // Time is in nanoseconds. The bar should be 120 px high at 30 FPS, i.e. 33333ns = 120px. 0.0036 px/ns + // Time is in nanoseconds. The bar should be 120 px high at 30 FPS, i.e. 33333333ns = 120px. 0.0000036 px/ns // If it's higher or as high as we are, recolor accordingly. // Also, apparently GLSL 120 doesn't have rounding - float height = floor(time * 0.0036 + 0.5); + float height = floor(time * 0.0000036 + 0.5); + // Increase red from 0-28ms, and decrease green from 28-56ms vec4 color = vec4(0.0, 0.0, 0.0, 0.0); - float r = clamp(time / 28000.0, 0, 1); - float g = clamp((time - 28000.0) / 28000.0, 0, 1); + float r = clamp(time / 28000000.0, 0, 1); + float g = clamp((time - 28000000.0) / 28000000.0, 0, 1); if (dy <= height) color = vec4(mix(0.0, 255.0, r), mix(255.0, 0.0, g), 0.0, 1.0); gl_FragColor = color; } diff --git a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl b/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl index f336b138c..caef9c333 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl +++ b/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl @@ -2,8 +2,8 @@ attribute vec2 pos; -uniform float fbHeight; uniform float fbWidth; +uniform float fbHeight; void main() { // Shift the bounds (x = 2 through x = 482, y = 0 through y = max - 2) to clip space From 62bac8d0fc5c864ad06606716342728d1e8ecc72 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:17:56 -0500 Subject: [PATCH 08/16] Fix colors --- .../resources/assets/angelica/shaders/frametimes.frag.glsl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl index de74c4618..78b71f54d 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl +++ b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl @@ -22,8 +22,9 @@ void main() { // Increase red from 0-28ms, and decrease green from 28-56ms vec4 color = vec4(0.0, 0.0, 0.0, 0.0); - float r = clamp(time / 28000000.0, 0, 1); - float g = clamp((time - 28000000.0) / 28000000.0, 0, 1); - if (dy <= height) color = vec4(mix(0.0, 255.0, r), mix(255.0, 0.0, g), 0.0, 1.0); + float r = clamp(time / 28000000.0, 0.0, 1.0); + float g = 1.0 - clamp((time - 28000000.0) / 28000000.0, 0.0, 1.0); + if (dy <= height) + color = vec4(r, g, 0.0, 1.0); gl_FragColor = color; } From c9f42ff6d846287c33125c7e9a2c1b774b11a88b Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:47:31 -0500 Subject: [PATCH 09/16] Add non-working "background" draws --- .../angelica/debug/FrametimeGraph.java | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java index 882013ad4..47ffb7c9b 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -3,8 +3,12 @@ import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_FLOAT; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; +import static org.lwjgl.opengl.GL11.glBlendFunc; import static org.lwjgl.opengl.GL11.glDisable; import static org.lwjgl.opengl.GL11.glDisableClientState; import static org.lwjgl.opengl.GL11.glDrawArrays; @@ -26,6 +30,8 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.ResourceLocation; import org.lwjgl.BufferUtils; public class FrametimeGraph { @@ -45,6 +51,10 @@ public class FrametimeGraph { private static final int VERT_COUNT = 4; // Due to GLSL 120 limitations, it's just easier to use floats private final FloatBuffer frametimesBuf = BufferUtils.createFloatBuffer(NUM_FRAMETIMES); + private static final int WEIGHT = 2; + private static final int HEIGHT = 120 + 2 * WEIGHT; + private static final int WIDTH = (NUM_FRAMETIMES + 2) * WEIGHT; + private static final ResourceLocation TEXTURE = new ResourceLocation("angelica:textures/frametimes_bg.png"); public void putFrameTime(long time) { frametimesBuf.put(frametimesHead, (float) time); @@ -111,8 +121,11 @@ public void render() { shader.use(); // Load uniforms - glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); - glUniform1f(uFBHeight, Minecraft.getMinecraft().displayHeight); + final Minecraft minecraft = Minecraft.getMinecraft(); + final int width = minecraft.displayWidth; + final int height = minecraft.displayHeight; + glUniform1f(uFBWidth, width); + glUniform1f(uFBHeight, height); glUniform1i(uHeadIdx, frametimesHead); glUniform1(uFrametimes, frametimesBuf); @@ -133,5 +146,28 @@ public void render() { glBindBuffer(GL_ARRAY_BUFFER, 0); ShaderProgram.clear(); + + // Now that the graph is done, overlay the guides + + // Tesselator should be fine + final Tessellator tess = Tessellator.instance; + tess.startDrawingQuads(); + tess.addVertexWithUV(0, height, -1, 0, 0); + tess.addVertexWithUV(WIDTH, height, -1, 1, 0); + tess.addVertexWithUV(WIDTH, height - HEIGHT, -1, 1, 1); + tess.addVertexWithUV(0, height - HEIGHT, -1, 0, 1); + + glEnable(GL_TEXTURE_2D); + minecraft.getTextureManager().bindTexture(TEXTURE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + tess.draw(); + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + + // this one draws... but how? + // Gui.drawRect(0, 0, WIDTH, HEIGHT, -1); } } From 1b21720d327b74231095587ecadd64c68fdbb24b Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:47:56 -0500 Subject: [PATCH 10/16] Fix wrapping issues Turns out this was incorrect the whole time. No idea why tho --- .../resources/assets/angelica/shaders/frametimes.frag.glsl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl index 78b71f54d..0a3ee3730 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl +++ b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl @@ -11,8 +11,8 @@ void main() { int dy = int(gl_FragCoord.y) - 2; // Get the frametime for this frag. Last at the left edge, first at the right, shifting as needed when the head - // moves. Since head is one ahead of the last frame, remove one. - int idx = int(mod(clamp(dx / 2 , 0, 239) + headIdx - 1, 240)); + // moves. + int idx = int(mod(dx / 2 + headIdx, 240)); float time = frametimes[idx]; // Time is in nanoseconds. The bar should be 120 px high at 30 FPS, i.e. 33333333ns = 120px. 0.0000036 px/ns From 34760127d27a3d1508a4bc0d2a255cf562d222cd Mon Sep 17 00:00:00 2001 From: kurrycat Date: Tue, 19 Nov 2024 20:39:15 +0100 Subject: [PATCH 11/16] impl rest of frametime graph, missing resize to not go over middle of screen when small --- .../angelica/debug/FrametimeGraph.java | 175 ++++++++++-------- .../angelica/shaders/frametimes.frag.glsl | 12 +- .../angelica/shaders/frametimes.vert.glsl | 7 +- .../angelica/textures/frametimes_bg.png | Bin 1007 -> 481 bytes 4 files changed, 107 insertions(+), 87 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java index 47ffb7c9b..1a438f5b0 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -1,39 +1,19 @@ package com.gtnewhorizons.angelica.debug; -import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; -import static org.lwjgl.opengl.GL11.GL_BLEND; -import static org.lwjgl.opengl.GL11.GL_FLOAT; -import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; -import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; -import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; -import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; -import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; -import static org.lwjgl.opengl.GL11.glBlendFunc; -import static org.lwjgl.opengl.GL11.glDisable; -import static org.lwjgl.opengl.GL11.glDisableClientState; -import static org.lwjgl.opengl.GL11.glDrawArrays; -import static org.lwjgl.opengl.GL11.glEnable; -import static org.lwjgl.opengl.GL11.glEnableClientState; -import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; -import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; -import static org.lwjgl.opengl.GL15.glBindBuffer; -import static org.lwjgl.opengl.GL15.glBufferData; -import static org.lwjgl.opengl.GL15.glGenBuffers; -import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; -import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; -import static org.lwjgl.opengl.GL20.glUniform1; -import static org.lwjgl.opengl.GL20.glUniform1f; -import static org.lwjgl.opengl.GL20.glUniform1i; -import static org.lwjgl.opengl.GL20.glVertexAttribPointer; - import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.ResourceLocation; import org.lwjgl.BufferUtils; +import java.nio.FloatBuffer; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL15.*; +import static org.lwjgl.opengl.GL20.*; + public class FrametimeGraph { public static final int NUM_FRAMETIMES = 240; // Circular buffer holding the last 240 frametimes, in nanoseconds @@ -43,6 +23,7 @@ public class FrametimeGraph { private int aPos; private int uFBWidth; private int uFBHeight; + private int uScaleFactor; private int uHeadIdx; private int uFrametimes; private int vertBuf; @@ -51,9 +32,10 @@ public class FrametimeGraph { private static final int VERT_COUNT = 4; // Due to GLSL 120 limitations, it's just easier to use floats private final FloatBuffer frametimesBuf = BufferUtils.createFloatBuffer(NUM_FRAMETIMES); - private static final int WEIGHT = 2; - private static final int HEIGHT = 120 + 2 * WEIGHT; - private static final int WIDTH = (NUM_FRAMETIMES + 2) * WEIGHT; + private static final int BORDER = 1; + private static final int HEIGHT = 60; + private static final int WIDTH = NUM_FRAMETIMES; + private static final int FONT_COLOR = 0xFFE0E0E0; private static final ResourceLocation TEXTURE = new ResourceLocation("angelica:textures/frametimes_bg.png"); public void putFrameTime(long time) { @@ -74,29 +56,35 @@ private void init() { // Register uniforms uFBWidth = shader.getUniformLocation("fbWidth"); uFBHeight = shader.getUniformLocation("fbHeight"); + uScaleFactor = shader.getUniformLocation("scaleFactor"); uFrametimes = shader.getUniformLocation("frametimes"); uHeadIdx = shader.getUniformLocation("headIdx"); // Load vertex buffer vertBuf = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, vertBuf); - // Since we use a triangle strip, we only need 4 verts - final ByteBuffer vertexes = BufferUtils.createByteBuffer(4 * VERT_COUNT * VERT_FLOATS); - // The Y coords are simple - the rect is from top to bottom, 1.0 to -1.0 - // The X coord get scaled by the framebuffer size in the vert shader - for (int y = -1; y < 2; y += 2) { - for (int x = 0; x < 2; ++x) { - vertexes.putFloat(x == 0 ? 2 : 482); - vertexes.putFloat(y); - } - } - vertexes.rewind(); - glBufferData(GL_ARRAY_BUFFER, vertexes, GL_STATIC_DRAW); + final FloatBuffer vertices = BufferUtils.createFloatBuffer(VERT_COUNT * VERT_FLOATS); + // Since we use a triangle strip, we only need 4 vertices + //@formatter:off + vertices.put(new float[]{ + BORDER , BORDER, + WIDTH + BORDER, BORDER, + BORDER , HEIGHT + BORDER, + WIDTH + BORDER, HEIGHT + BORDER + }); + //@formatter:on + vertices.rewind(); + + glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); + final Minecraft mc = Minecraft.getMinecraft(); + final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + // Load initial value for uniforms - glUniform1f(uFBWidth, Minecraft.getMinecraft().displayWidth); - glUniform1f(uFBHeight, Minecraft.getMinecraft().displayHeight); + glUniform1f(uFBWidth, mc.displayWidth); + glUniform1f(uFBHeight, mc.displayHeight); + glUniform1f(uScaleFactor, sr.getScaleFactor()); glUniform1i(uHeadIdx, frametimesHead); glUniform1(uFrametimes, frametimesBuf); @@ -109,65 +97,96 @@ public void render() { initialized = true; } - /** + double min, max, sum; + min = max = sum = frametimesBuf.get(0); + for (int i = 1; i < NUM_FRAMETIMES; i++) { + min = Math.min(min, frametimesBuf.get(i)); + max = Math.max(max, frametimesBuf.get(i)); + sum += frametimesBuf.get(i); + } + + /* * We try to copy modern vanilla's tracker. - * It is 484 wide by 124 tall, including the 2px borders. + * It is 240 (FRAME_TIMES) wide by 60 tall, including the 1px borders. + * We instead make it 242x62 including borders to prevent the borders from overlapping the samples. * The background is ARGB 90505050, the borders FFFFFFFF, and the text FFE0E0E0. - * First the samples are rendered, then the background/borders, then the text. The samples are rendered by a - * shader on a transparent rect 480px wide and as high as the framebuffer. Next, the background is drawn via a - * 484x124 translucent rect, and finally FontRenderer slaps the text on top. The shader pipeline is only needed - * for the first draw. + * First the background is rendered, then the samples, then the foreground texture and the text. + * The background is drawn via a 242x62 translucent rect. + * Next, the samples are rendered by a shader on a transparent 240x60 rect. + * Finally, the foreground texture and the text is rendered on top. + * The shader pipeline is only needed for the sample draw. */ + + final Minecraft mc = Minecraft.getMinecraft(); + final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + final int height = sr.getScaledHeight(); + + // Setup GL state + final Tessellator tess = Tessellator.instance; + glDisable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Draw background + glDisable(GL_TEXTURE_2D); + glColor4f(0x50 / 255.0F, 0x50 / 255.0F, 0x50 / 255.0F, 0x90 / 255.0F); + tess.startDrawingQuads(); + tess.addVertex(WIDTH + BORDER * 2, height - HEIGHT - BORDER * 2, 0.0D); + tess.addVertex(0, height - HEIGHT - BORDER * 2, 0.0D); + tess.addVertex(0, height, 0.0D); + tess.addVertex(WIDTH + BORDER * 2, height, 0.0D); + tess.draw(); + glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + glEnable(GL_TEXTURE_2D); + + + // Draw samples shader.use(); // Load uniforms - final Minecraft minecraft = Minecraft.getMinecraft(); - final int width = minecraft.displayWidth; - final int height = minecraft.displayHeight; - glUniform1f(uFBWidth, width); - glUniform1f(uFBHeight, height); + glUniform1f(uFBWidth, mc.displayWidth); + glUniform1f(uFBHeight, mc.displayHeight); + glUniform1f(uScaleFactor, sr.getScaleFactor()); glUniform1i(uHeadIdx, frametimesHead); glUniform1(uFrametimes, frametimesBuf); - // Draw! glBindBuffer(GL_ARRAY_BUFFER, vertBuf); glEnableVertexAttribArray(aPos); glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0); glEnableClientState(GL_VERTEX_ARRAY); - glDisable(GL_BLEND); - glEnable(GL_ALPHA_TEST); glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT); - glDisable(GL_ALPHA_TEST); - glEnable(GL_BLEND); glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(aPos); glBindBuffer(GL_ARRAY_BUFFER, 0); ShaderProgram.clear(); - // Now that the graph is done, overlay the guides - - // Tesselator should be fine - final Tessellator tess = Tessellator.instance; - tess.startDrawingQuads(); - tess.addVertexWithUV(0, height, -1, 0, 0); - tess.addVertexWithUV(WIDTH, height, -1, 1, 0); - tess.addVertexWithUV(WIDTH, height - HEIGHT, -1, 1, 1); - tess.addVertexWithUV(0, height - HEIGHT, -1, 0, 1); - - glEnable(GL_TEXTURE_2D); - minecraft.getTextureManager().bindTexture(TEXTURE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + // Draw foreground + mc.getTextureManager().bindTexture(TEXTURE); + tess.startDrawingQuads(); + tess.addVertexWithUV(WIDTH + BORDER * 2, height - HEIGHT - BORDER * 2, 0.0D, 1, 0); + tess.addVertexWithUV(0, height - HEIGHT - BORDER * 2, 0.0D, 0, 0); + tess.addVertexWithUV(0, height, 0.0D, 0, 1); + tess.addVertexWithUV(WIDTH + BORDER * 2, height, 0.0D, 1, 1); tess.draw(); + // Reset GL state + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - // this one draws... but how? - // Gui.drawRect(0, 0, WIDTH, HEIGHT, -1); + // Draw text + String minStr = (int) min / 1_000_000 + " ms min"; + String avgStr = (int) sum / 1_000_000 / NUM_FRAMETIMES + " ms avg"; + String maxStr = (int) max / 1_000_000 + " ms max"; + final FontRenderer fr = mc.fontRenderer; + final int top = height - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT; + fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true); + fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true); + fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true); } } diff --git a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl index 0a3ee3730..2a75495b8 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl +++ b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl @@ -1,24 +1,24 @@ #version 120 uniform int headIdx; +uniform float scaleFactor; uniform float frametimes[240]; void main() { // Get position - gl_FragCoord starts from the lower left and returns the position of the center of the pixel // i.e. the lower-left-most pixel is (0.5, 0.5) - // Additionally, shift them to account for the 2px border. - int dx = int(gl_FragCoord.x) - 2; - int dy = int(gl_FragCoord.y) - 2; + int dx = int(gl_FragCoord.x / scaleFactor); + int dy = int(gl_FragCoord.y / scaleFactor); // Get the frametime for this frag. Last at the left edge, first at the right, shifting as needed when the head // moves. - int idx = int(mod(dx / 2 + headIdx, 240)); + int idx = int(mod(dx + headIdx, 240)); float time = frametimes[idx]; - // Time is in nanoseconds. The bar should be 120 px high at 30 FPS, i.e. 33333333ns = 120px. 0.0000036 px/ns + // Time is in nanoseconds. The bar should be 60 px high at 30 FPS, i.e. 33333333ns = 60px. 0.0000018 px/ns // If it's higher or as high as we are, recolor accordingly. // Also, apparently GLSL 120 doesn't have rounding - float height = floor(time * 0.0000036 + 0.5); + float height = floor(time * 0.0000018 + 0.5); // Increase red from 0-28ms, and decrease green from 28-56ms vec4 color = vec4(0.0, 0.0, 0.0, 0.0); diff --git a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl b/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl index caef9c333..feda059bb 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl +++ b/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl @@ -4,10 +4,11 @@ attribute vec2 pos; uniform float fbWidth; uniform float fbHeight; +uniform float scaleFactor; void main() { // Shift the bounds (x = 2 through x = 482, y = 0 through y = max - 2) to clip space - float x = pos.x / fbWidth * 2.0 - 1.0; - float y = clamp(pos.y, 2.0 / fbHeight * 2.0 - 1.0, 1.0); - gl_Position = vec4(x, y, -1.0, 1.0); + float x = pos.x / fbWidth * scaleFactor * 2.0 - 1.0; + float y = pos.y / fbHeight * scaleFactor * 2.0 - 1.0; + gl_Position = vec4(x, y, 0.0, 1.0); } diff --git a/src/main/resources/assets/angelica/textures/frametimes_bg.png b/src/main/resources/assets/angelica/textures/frametimes_bg.png index b57b832bf8a39a523454161a1a929befa10def72..8e6cde33bff288ddbbb3d3fb6d606b0a6b19abbe 100644 GIT binary patch literal 481 zcmeAS@N?(olHy`uVBq!ia0vp^pMcnogAGUuI=N*7DaPU;cPEB*=VV?2*|R-e978JR zyuBNk*W@75c5!22^SUKEtmTjR^5+|LHC&m+Re!EBYgt(nf4tkOk8-P4No~kJel5y+ zuHSS2_!AF`c9zWF$97}#s#TBQI^F+%|M2

vQL?J^%OZ+vMY~i+}6A<<;5UcIW%w z?-rXBkF5N<^6a%W=ihSgc_;O0){13*cURu;|31s=;_>BMS3E2|{_#*yPq6;f{JoEt z{Cg|R5cOM1za+L?j$Pa6#*s8#|M(`=YQw#|wx8@Q0sK9^f&xNYV{!)1ntw%PWC&Yk^p%a<9A znLQsQHz$WKpK*-i_Li&*mBzh-W^eVL?A+kOc6-~a+7zJ1+dj!H3_xAyW**~U1hNI3 i+8D?~$5uHt$S;%E>pc14a3V0y7(8A5T-G@yGywqoYs(1$ literal 1007 zcmeAS@N?(olHy`uVBq!ia0y~yV0;2(*Kn`_$sKPFCj$kVGo76SJe{2t3X1a6GILTH z7&Io>zVAKG@q;yQxf|@I=7eH$kp4*`i$m3$JjkwVDz0i`7?Zl8Ctb!L1J- z98bD>@MvT>d$^;(ABMuRf}oO#LjR|WL>;LpxYJ+$U9S8+!@|haRX2s%L(Uo*ootzL zdVSZy@Gr?6j7JzcXa0(@n%ngJ$FBDN_2q%{p4PrQZ@56jhwX>UBa6$t-4)FhX_qfq zz87wfj11~H->J^KOW~vP_0;M2EvCzeRixcGk@l?f@R6jI-B0z>Qk_-jsr6~Ba{K9Y zF17WuSo+qe^taWY#M`)Toie(f*{9g)s-ws&X!L5u0xs^rDAORHlnnca59Le$WEP!# zvZ`TXGNb8=2{QIS-f(AQyV`9opD*1QZVRV~Ua&m&qN&jFCvBvMlzn0k;)Np@UyL0c>?}fh@ zQdX|M!dpn3R{x5y9>jA5L~c#`DCC7 zXMsm#F$061G6*wPEVVBK3bL1Y`ns~e;1*)j(LJ1S4JgMTS>hT|;+&tGo0?a`;9QiN zSdyBeP@Y+mq2TW68xY>eCk~A56P_-PAr-gYUf;;uV8G)N*tBVZdZL)x#}4GgAnI=I&k2kVlvyMhfJh((gd8R?0uh5F8wd?f zi7;u;BsPW*ip&SzpZ&gK)omGu4PoW+b}0-$I0mz`aRz3Y1l&Ki&kaQ0Wwt!L0E~DB MPgg&ebxsLQ0AA!nDF6Tf From b182c16c221cfb1d0c27fcd8cd5e5c9d5e19f49b Mon Sep 17 00:00:00 2001 From: kurrycat Date: Tue, 19 Nov 2024 21:46:36 +0100 Subject: [PATCH 12/16] only show fps graph with alt+f3 like in modern --- .../gtnewhorizons/angelica/mixins/Mixins.java | 1 + .../mixins/interfaces/IGameSettingsExt.java | 6 +++++ .../angelica/proxy/ClientProxy.java | 5 ++++- .../early/angelica/MixinGameSettings.java | 22 +++++++++++++++++++ .../mixins/early/angelica/MixinMinecraft.java | 13 ++++++++++- 5 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/gtnewhorizons/angelica/mixins/interfaces/IGameSettingsExt.java create mode 100644 src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinGameSettings.java diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java b/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java index 0e31789d8..615767fc2 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java @@ -27,6 +27,7 @@ public enum Mixins { .setPhase(Phase.EARLY).addMixinClasses( "angelica.MixinActiveRenderInfo" ,"angelica.MixinEntityRenderer" + ,"angelica.MixinGameSettings" ,"angelica.MixinMinecraft" ,"angelica.optimizations.MixinRendererLivingEntity" ,"angelica.MixinFMLClientHandler" diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/interfaces/IGameSettingsExt.java b/src/main/java/com/gtnewhorizons/angelica/mixins/interfaces/IGameSettingsExt.java new file mode 100644 index 000000000..996810fd0 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/interfaces/IGameSettingsExt.java @@ -0,0 +1,6 @@ +package com.gtnewhorizons.angelica.mixins.interfaces; + +public interface IGameSettingsExt { + boolean angelica$showFpsGraph(); + void angelica$setShowFpsGraph(boolean renderFpsGraph); +} diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java index 72e2bc262..677e5a7f7 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java @@ -10,6 +10,7 @@ import com.gtnewhorizons.angelica.config.AngelicaConfig; import com.gtnewhorizons.angelica.config.CompatConfig; import com.gtnewhorizons.angelica.debug.FrametimeGraph; +import com.gtnewhorizons.angelica.mixins.interfaces.IGameSettingsExt; import com.gtnewhorizons.angelica.dynamiclights.DynamicLights; import com.gtnewhorizons.angelica.glsm.GLStateManager; import com.gtnewhorizons.angelica.glsm.debug.OpenGLDebugging; @@ -281,7 +282,9 @@ public void onRenderOverlay(RenderGameOverlayEvent.Text event) { } // Draw a frametime graph - graph.render(); + if (((IGameSettingsExt)mc.gameSettings).angelica$showFpsGraph()) { + graph.render(); + } } } diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinGameSettings.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinGameSettings.java new file mode 100644 index 000000000..9a9b4c3b6 --- /dev/null +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinGameSettings.java @@ -0,0 +1,22 @@ +package com.gtnewhorizons.angelica.mixins.early.angelica; + +import com.gtnewhorizons.angelica.mixins.interfaces.IGameSettingsExt; +import net.minecraft.client.settings.GameSettings; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(GameSettings.class) +public class MixinGameSettings implements IGameSettingsExt { + @Unique + private boolean angelica$showFpsGraph = false; + + @Override + public boolean angelica$showFpsGraph() { + return this.angelica$showFpsGraph; + } + + @Override + public void angelica$setShowFpsGraph(boolean renderFpsGraph) { + this.angelica$showFpsGraph = renderFpsGraph; + } +} diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java index d7356172e..01c3ec006 100644 --- a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java @@ -1,9 +1,13 @@ package com.gtnewhorizons.angelica.mixins.early.angelica; import com.gtnewhorizons.angelica.AngelicaMod; +import com.gtnewhorizons.angelica.mixins.interfaces.IGameSettingsExt; import net.minecraft.client.Minecraft; +import net.minecraft.client.settings.GameSettings; +import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.GL11; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -11,6 +15,8 @@ @Mixin(Minecraft.class) public class MixinMinecraft { + @Shadow + public GameSettings gameSettings; @Unique private long angelica$lastFrameTime = 0; @@ -25,11 +31,16 @@ public class MixinMinecraft { @Inject( method = "func_147120_f", - at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;update()V", shift = At.Shift.AFTER) + at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;update()V", shift = At.Shift.AFTER, remap = false) ) private void angelica$trackFrametimes(CallbackInfo ci) { long time = System.nanoTime(); AngelicaMod.proxy.putFrametime(time - angelica$lastFrameTime); angelica$lastFrameTime = time; } + + @Inject(method = "runTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;isShiftKeyDown()Z", shift = At.Shift.AFTER)) + private void angelica$setShowFpsGraph(CallbackInfo ci) { + ((IGameSettingsExt) gameSettings).angelica$setShowFpsGraph(Keyboard.isKeyDown(Keyboard.KEY_LMENU) || Keyboard.isKeyDown(Keyboard.KEY_RMENU)); + } } From 3cdd18c611d8e1ffb7f1b2e68198660e31db4565 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Tue, 19 Nov 2024 16:46:44 -0500 Subject: [PATCH 13/16] Create TPS graph Not rendered yet - I need to deduplicate a bunch of code --- .../angelica/debug/FrametimeGraph.java | 81 ++++--- .../angelica/debug/TPSGraph.java | 222 ++++++++++++++++++ .../angelica/shaders/debug_graph.frag.glsl | 33 +++ ...etimes.vert.glsl => debug_graph.vert.glsl} | 2 +- .../angelica/shaders/frametimes.frag.glsl | 30 --- .../{frametimes_bg.png => frametimes_fg.png} | Bin .../assets/angelica/textures/tps_fg.png | Bin 0 -> 4519 bytes 7 files changed, 310 insertions(+), 58 deletions(-) create mode 100644 src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java create mode 100644 src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl rename src/main/resources/assets/angelica/shaders/{frametimes.vert.glsl => debug_graph.vert.glsl} (75%) delete mode 100644 src/main/resources/assets/angelica/shaders/frametimes.frag.glsl rename src/main/resources/assets/angelica/textures/{frametimes_bg.png => frametimes_fg.png} (100%) create mode 100644 src/main/resources/assets/angelica/textures/tps_fg.png diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java index 1a438f5b0..b2e281044 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -1,6 +1,35 @@ package com.gtnewhorizons.angelica.debug; +import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; +import static org.lwjgl.opengl.GL11.GL_FLOAT; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; +import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; +import static org.lwjgl.opengl.GL11.glBlendFunc; +import static org.lwjgl.opengl.GL11.glColor4f; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glDisableClientState; +import static org.lwjgl.opengl.GL11.glDrawArrays; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glEnableClientState; +import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; +import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; +import static org.lwjgl.opengl.GL15.glBindBuffer; +import static org.lwjgl.opengl.GL15.glBufferData; +import static org.lwjgl.opengl.GL15.glGenBuffers; +import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glUniform1; +import static org.lwjgl.opengl.GL20.glUniform1f; +import static org.lwjgl.opengl.GL20.glUniform1i; +import static org.lwjgl.opengl.GL20.glVertexAttribPointer; + import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; +import java.nio.FloatBuffer; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.ScaledResolution; @@ -8,16 +37,10 @@ import net.minecraft.util.ResourceLocation; import org.lwjgl.BufferUtils; -import java.nio.FloatBuffer; - -import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL15.*; -import static org.lwjgl.opengl.GL20.*; - public class FrametimeGraph { - public static final int NUM_FRAMETIMES = 240; + public static final int NUM_SAMPLES = 240; // Circular buffer holding the last 240 frametimes, in nanoseconds - public int frametimesHead = 0; // one ahead of the position of the last frametime + public int samplesHead = 0; // one ahead of the position of the last frametime private boolean initialized = false; private ShaderProgram shader; private int aPos; @@ -25,29 +48,31 @@ public class FrametimeGraph { private int uFBHeight; private int uScaleFactor; private int uHeadIdx; - private int uFrametimes; + private int uSamples; private int vertBuf; // Two floats (x,y) private static final int VERT_FLOATS = 2; private static final int VERT_COUNT = 4; // Due to GLSL 120 limitations, it's just easier to use floats - private final FloatBuffer frametimesBuf = BufferUtils.createFloatBuffer(NUM_FRAMETIMES); + private final FloatBuffer sampleBuf = BufferUtils.createFloatBuffer(NUM_SAMPLES); private static final int BORDER = 1; private static final int HEIGHT = 60; - private static final int WIDTH = NUM_FRAMETIMES; + private static final int WIDTH = NUM_SAMPLES; private static final int FONT_COLOR = 0xFFE0E0E0; - private static final ResourceLocation TEXTURE = new ResourceLocation("angelica:textures/frametimes_bg.png"); + private static final ResourceLocation TEXTURE = new ResourceLocation("angelica:textures/frametimes_fg.png"); + // At 1x scale, 30 FPS should be 60 px. 30 FPS = 33_333_333ns per frame, 60px/33_333_333ns = 0.0000018f px/ns + private static final float PIXELS_PER_NS = 0.0000018f; public void putFrameTime(long time) { - frametimesBuf.put(frametimesHead, (float) time); - frametimesHead = (frametimesHead + 1) % NUM_FRAMETIMES; + sampleBuf.put(samplesHead, (float) time); + samplesHead = (samplesHead + 1) % NUM_SAMPLES; } private void init() { shader = new ShaderProgram( "angelica", - "shaders/frametimes.vert.glsl", - "shaders/frametimes.frag.glsl"); + "shaders/debug_graph.vert.glsl", + "shaders/debug_graph.frag.glsl"); shader.use(); // Register attributes @@ -57,8 +82,9 @@ private void init() { uFBWidth = shader.getUniformLocation("fbWidth"); uFBHeight = shader.getUniformLocation("fbHeight"); uScaleFactor = shader.getUniformLocation("scaleFactor"); - uFrametimes = shader.getUniformLocation("frametimes"); + uSamples = shader.getUniformLocation("samples"); uHeadIdx = shader.getUniformLocation("headIdx"); + final int uPxPerNs = shader.getUniformLocation("pxPerNs"); // Load vertex buffer vertBuf = glGenBuffers(); @@ -85,8 +111,9 @@ private void init() { glUniform1f(uFBWidth, mc.displayWidth); glUniform1f(uFBHeight, mc.displayHeight); glUniform1f(uScaleFactor, sr.getScaleFactor()); - glUniform1i(uHeadIdx, frametimesHead); - glUniform1(uFrametimes, frametimesBuf); + glUniform1i(uHeadIdx, samplesHead); + glUniform1(uSamples, sampleBuf); + glUniform1f(uPxPerNs, PIXELS_PER_NS); ShaderProgram.clear(); } @@ -98,11 +125,11 @@ public void render() { } double min, max, sum; - min = max = sum = frametimesBuf.get(0); - for (int i = 1; i < NUM_FRAMETIMES; i++) { - min = Math.min(min, frametimesBuf.get(i)); - max = Math.max(max, frametimesBuf.get(i)); - sum += frametimesBuf.get(i); + min = max = sum = sampleBuf.get(0); + for (int i = 1; i < NUM_SAMPLES; i++) { + min = Math.min(min, sampleBuf.get(i)); + max = Math.max(max, sampleBuf.get(i)); + sum += sampleBuf.get(i); } /* @@ -148,8 +175,8 @@ public void render() { glUniform1f(uFBWidth, mc.displayWidth); glUniform1f(uFBHeight, mc.displayHeight); glUniform1f(uScaleFactor, sr.getScaleFactor()); - glUniform1i(uHeadIdx, frametimesHead); - glUniform1(uFrametimes, frametimesBuf); + glUniform1i(uHeadIdx, samplesHead); + glUniform1(uSamples, sampleBuf); glBindBuffer(GL_ARRAY_BUFFER, vertBuf); glEnableVertexAttribArray(aPos); @@ -181,7 +208,7 @@ public void render() { // Draw text String minStr = (int) min / 1_000_000 + " ms min"; - String avgStr = (int) sum / 1_000_000 / NUM_FRAMETIMES + " ms avg"; + String avgStr = (int) sum / 1_000_000 / NUM_SAMPLES + " ms avg"; String maxStr = (int) max / 1_000_000 + " ms max"; final FontRenderer fr = mc.fontRenderer; final int top = height - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT; diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java new file mode 100644 index 000000000..a052aa3b1 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java @@ -0,0 +1,222 @@ +package com.gtnewhorizons.angelica.debug; + +import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; +import static org.lwjgl.opengl.GL11.GL_FLOAT; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; +import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; +import static org.lwjgl.opengl.GL11.glBlendFunc; +import static org.lwjgl.opengl.GL11.glColor4f; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glDisableClientState; +import static org.lwjgl.opengl.GL11.glDrawArrays; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glEnableClientState; +import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; +import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; +import static org.lwjgl.opengl.GL15.glBindBuffer; +import static org.lwjgl.opengl.GL15.glBufferData; +import static org.lwjgl.opengl.GL15.glGenBuffers; +import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glUniform1; +import static org.lwjgl.opengl.GL20.glUniform1f; +import static org.lwjgl.opengl.GL20.glUniform1i; +import static org.lwjgl.opengl.GL20.glVertexAttribPointer; + +import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; +import java.nio.FloatBuffer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.BufferUtils; + +/** + * Pretty much just {@link FrametimeGraph} but on the left + */ +public class TPSGraph { + public static final int NUM_SAMPLES = 240; + // Circular buffer holding the last 240 samples, in nanoseconds + public int samplesHead = 0; // one ahead of the position of the last sample + private boolean initialized = false; + private ShaderProgram shader; + private int aPos; + private int uFBWidth; + private int uFBHeight; + private int uScaleFactor; + private int uHeadIdx; + private int uSamples; + private int vertBuf; + // Two floats (x,y) + private static final int VERT_FLOATS = 2; + private static final int VERT_COUNT = 4; + // Due to GLSL 120 limitations, it's just easier to use floats + private final FloatBuffer sampleBuf = BufferUtils.createFloatBuffer(NUM_SAMPLES); + private static final int BORDER = 1; + private static final int HEIGHT = 60; + private static final int WIDTH = NUM_SAMPLES; + private static final int FONT_COLOR = 0xFFE0E0E0; + private static final ResourceLocation TEXTURE = new ResourceLocation("angelica:textures/tps_fg.png"); + // At 1x scale, 20 TPS should be 60 px. 20 FPS = 50_000_000ns per frame, 60px/50_000_000ns = 0.0000012 px/ns + private static final float PIXELS_PER_NS = 0.0000012f; + + public void putSample(long time) { + sampleBuf.put(samplesHead, (float) time); + samplesHead = (samplesHead + 1) % NUM_SAMPLES; + } + + private void init() { + shader = new ShaderProgram( + "angelica", + "shaders/debug_graph.vert.glsl", + "shaders/debug_graph.frag.glsl"); + shader.use(); + + // Register attributes + aPos = shader.getAttribLocation("pos"); + + // Register uniforms + uFBWidth = shader.getUniformLocation("fbWidth"); + uFBHeight = shader.getUniformLocation("fbHeight"); + uScaleFactor = shader.getUniformLocation("scaleFactor"); + uSamples = shader.getUniformLocation("samples"); + uHeadIdx = shader.getUniformLocation("headIdx"); + final int uPxPerNs = shader.getUniformLocation("pxPerNs"); + + // Load vertex buffer + vertBuf = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, vertBuf); + final FloatBuffer vertices = BufferUtils.createFloatBuffer(VERT_COUNT * VERT_FLOATS); + // Since we use a triangle strip, we only need 4 vertices + //@formatter:off + vertices.put(new float[]{ + BORDER , BORDER, + WIDTH + BORDER, BORDER, + BORDER , HEIGHT + BORDER, + WIDTH + BORDER, HEIGHT + BORDER + }); + //@formatter:on + vertices.rewind(); + + glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + final Minecraft mc = Minecraft.getMinecraft(); + final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + + // Load initial value for uniforms + glUniform1f(uFBWidth, mc.displayWidth); + glUniform1f(uFBHeight, mc.displayHeight); + glUniform1f(uScaleFactor, sr.getScaleFactor()); + glUniform1i(uHeadIdx, samplesHead); + glUniform1(uSamples, sampleBuf); + glUniform1f(uPxPerNs, PIXELS_PER_NS); + + ShaderProgram.clear(); + } + + public void render() { + if (!initialized) { + init(); + initialized = true; + } + + double min, max, sum; + min = max = sum = sampleBuf.get(0); + for (int i = 1; i < NUM_SAMPLES; i++) { + min = Math.min(min, sampleBuf.get(i)); + max = Math.max(max, sampleBuf.get(i)); + sum += sampleBuf.get(i); + } + + /* + * We try to copy modern vanilla's tracker. + * It is 240 (FRAME_TIMES) wide by 60 tall, including the 1px borders. + * We instead make it 242x62 including borders to prevent the borders from overlapping the samples. + * The background is ARGB 90505050, the borders FFFFFFFF, and the text FFE0E0E0. + * First the background is rendered, then the samples, then the foreground texture and the text. + * The background is drawn via a 242x62 translucent rect. + * Next, the samples are rendered by a shader on a transparent 240x60 rect. + * Finally, the foreground texture and the text is rendered on top. + * The shader pipeline is only needed for the sample draw. + */ + + final Minecraft mc = Minecraft.getMinecraft(); + final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + final int height = sr.getScaledHeight(); + + // Setup GL state + final Tessellator tess = Tessellator.instance; + glDisable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Draw background + glDisable(GL_TEXTURE_2D); + glColor4f(0x50 / 255.0F, 0x50 / 255.0F, 0x50 / 255.0F, 0x90 / 255.0F); + tess.startDrawingQuads(); + tess.addVertex(WIDTH + BORDER * 2, height - HEIGHT - BORDER * 2, 0.0D); + tess.addVertex(0, height - HEIGHT - BORDER * 2, 0.0D); + tess.addVertex(0, height, 0.0D); + tess.addVertex(WIDTH + BORDER * 2, height, 0.0D); + tess.draw(); + glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + glEnable(GL_TEXTURE_2D); + + + // Draw samples + shader.use(); + + // Load uniforms + glUniform1f(uFBWidth, mc.displayWidth); + glUniform1f(uFBHeight, mc.displayHeight); + glUniform1f(uScaleFactor, sr.getScaleFactor()); + glUniform1i(uHeadIdx, samplesHead); + glUniform1(uSamples, sampleBuf); + + glBindBuffer(GL_ARRAY_BUFFER, vertBuf); + glEnableVertexAttribArray(aPos); + glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0); + glEnableClientState(GL_VERTEX_ARRAY); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableVertexAttribArray(aPos); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ShaderProgram.clear(); + + // Draw foreground + + mc.getTextureManager().bindTexture(TEXTURE); + tess.startDrawingQuads(); + tess.addVertexWithUV(WIDTH + BORDER * 2, height - HEIGHT - BORDER * 2, 0.0D, 1, 0); + tess.addVertexWithUV(0, height - HEIGHT - BORDER * 2, 0.0D, 0, 0); + tess.addVertexWithUV(0, height, 0.0D, 0, 1); + tess.addVertexWithUV(WIDTH + BORDER * 2, height, 0.0D, 1, 1); + tess.draw(); + + // Reset GL state + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + + // Draw text + String minStr = (int) min / 1_000_000 + " ms min"; + String avgStr = (int) sum / 1_000_000 / NUM_SAMPLES + " ms avg"; + String maxStr = (int) max / 1_000_000 + " ms max"; + final FontRenderer fr = mc.fontRenderer; + final int top = height - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT; + fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true); + fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true); + fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true); + } +} diff --git a/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl b/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl new file mode 100644 index 000000000..19cb4429e --- /dev/null +++ b/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl @@ -0,0 +1,33 @@ +#version 120 + +uniform int headIdx; +uniform float scaleFactor; +uniform float samples[240]; +uniform float pxPerNs; + +void main() { + // Get position - gl_FragCoord starts from the lower left and returns the position of the center of the pixel + // i.e. the lower-left-most pixel is (0.5, 0.5) + int dx = int(gl_FragCoord.x / scaleFactor); + int dy = int(gl_FragCoord.y / scaleFactor); + + // Get the time for this frag. Last at the left edge, first at the right, shifting as needed when the head moves. + int idx = int(mod(dx + headIdx, 240)); + float time = samples[idx]; + + // Time is in nanoseconds. Height is calculated from the given pixels/ns factor. + // If it's higher or as high as we are, recolor accordingly. + // Also, apparently GLSL 120 doesn't have rounding. + float height = floor(time * pxPerNs + 0.5); + + // Calculate the nanoseconds at the midpoint, 30px. The bar can exceed twice that, but it's used for coloring + float midNs = 30.0 / pxPerNs; + + // Increase red from 0-midpoint, and decrease green from midpoint-"max" + vec4 color = vec4(0.0, 0.0, 0.0, 0.0); + float r = clamp(time / midNs, 0.0, 1.0); + float g = 1.0 - clamp((time - midNs) / midNs, 0.0, 1.0); + if (dy <= height) + color = vec4(r, g, 0.0, 1.0); + gl_FragColor = color; +} diff --git a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl b/src/main/resources/assets/angelica/shaders/debug_graph.vert.glsl similarity index 75% rename from src/main/resources/assets/angelica/shaders/frametimes.vert.glsl rename to src/main/resources/assets/angelica/shaders/debug_graph.vert.glsl index feda059bb..db8ff8148 100644 --- a/src/main/resources/assets/angelica/shaders/frametimes.vert.glsl +++ b/src/main/resources/assets/angelica/shaders/debug_graph.vert.glsl @@ -7,7 +7,7 @@ uniform float fbHeight; uniform float scaleFactor; void main() { - // Shift the bounds (x = 2 through x = 482, y = 0 through y = max - 2) to clip space + // Shift the bounds (originally in pixel coords) to clip space float x = pos.x / fbWidth * scaleFactor * 2.0 - 1.0; float y = pos.y / fbHeight * scaleFactor * 2.0 - 1.0; gl_Position = vec4(x, y, 0.0, 1.0); diff --git a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl b/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl deleted file mode 100644 index 2a75495b8..000000000 --- a/src/main/resources/assets/angelica/shaders/frametimes.frag.glsl +++ /dev/null @@ -1,30 +0,0 @@ -#version 120 - -uniform int headIdx; -uniform float scaleFactor; -uniform float frametimes[240]; - -void main() { - // Get position - gl_FragCoord starts from the lower left and returns the position of the center of the pixel - // i.e. the lower-left-most pixel is (0.5, 0.5) - int dx = int(gl_FragCoord.x / scaleFactor); - int dy = int(gl_FragCoord.y / scaleFactor); - - // Get the frametime for this frag. Last at the left edge, first at the right, shifting as needed when the head - // moves. - int idx = int(mod(dx + headIdx, 240)); - float time = frametimes[idx]; - - // Time is in nanoseconds. The bar should be 60 px high at 30 FPS, i.e. 33333333ns = 60px. 0.0000018 px/ns - // If it's higher or as high as we are, recolor accordingly. - // Also, apparently GLSL 120 doesn't have rounding - float height = floor(time * 0.0000018 + 0.5); - - // Increase red from 0-28ms, and decrease green from 28-56ms - vec4 color = vec4(0.0, 0.0, 0.0, 0.0); - float r = clamp(time / 28000000.0, 0.0, 1.0); - float g = 1.0 - clamp((time - 28000000.0) / 28000000.0, 0.0, 1.0); - if (dy <= height) - color = vec4(r, g, 0.0, 1.0); - gl_FragColor = color; -} diff --git a/src/main/resources/assets/angelica/textures/frametimes_bg.png b/src/main/resources/assets/angelica/textures/frametimes_fg.png similarity index 100% rename from src/main/resources/assets/angelica/textures/frametimes_bg.png rename to src/main/resources/assets/angelica/textures/frametimes_fg.png diff --git a/src/main/resources/assets/angelica/textures/tps_fg.png b/src/main/resources/assets/angelica/textures/tps_fg.png new file mode 100644 index 0000000000000000000000000000000000000000..4bca20934aaa5f96e3758dfccbdbfdecaedabaff GIT binary patch literal 4519 zcmeHLdr%Zd8sCKk$f_wr@HAM7lZ|C!WOiou!OqUHD6j}?SVSaHcgf>zW3H25zv0y70rNnFRRqGvK&kx(b2m6UICIW0q z8=;v6brTdL*l|$52SwZ(n(GAE$`zx2GQm=q$Lb8HD+e4PaSY8y<(sG<>X_#N~xy3T1(FB|78tj>W%!%8)a&_~8Ia@1d zmv`p8as7b)g6zO&qy9iOgU6TK#7_NcbJ(w{3g z#11~C!@1hO1sDAFc;KVK^~;L$_qu;vsByJ@p7rG7?}y&!2IfS*gz2z_raw3Ce%oBz z(_@bqZQnkeaHncxOG;}Yg<-LeH?qB_=btvc{$WS;oAjA8M^@BkC$YKDpWgZGnxx6+q=s2`rgOC|8aY>A^+pXJ+9vc_tEc^FyGCv?R>iHnWol~H(IZKyL9H2ClzWMmz;ti+1 zyPq5tI^VgzBBeL=a7_D~-Hk)bzWvp}bHleUocQcYM=+@ngF!K`KrV1)F}%-XU{5HEX#g|AgZdW z3{@tBPbwlPo6Sa$M#5;s0f7gqy)qlby@AIRiV%kb1$asH%c9SVDV!|ltB~z_J@jK^ z{(1Z^*Eqd55LN;7AcCx)pbRA8@eq?o1myHeAPGD4vm*j|)qX_eqJXbL;!%1f^2(1* zrV#k?@%{>_OkIw^6Q~S%02+W?ufDbWeyi#W$r#UCv}j zVE8!i6!h5IRWP7jF2>>GD-`#f4!d5NpAme#C@`vNr3D*nrLDLXaWrmbSvStnB##R` zO`AQmBC3AOa7fDZy0`tKqM-hYVK5flx<;PF(53f#3>M{?XVUmO+u{flk$ANGP`~}>yCH3;5Z4a z%sN;Z0qJ-i&Kt|aIB8+XkoyXq%O{BL>i>jR4iAx;whXn zxjEd#8O@0nBQ5ZzkVxa~0iRp0VkMMP1UiCN5T5Ec6!wI=QH!VgQdNwUT>!ywioz+| zm|)hhU_^MqgpxDHR-8oqn{l2c&tE&4yW z?oKi-k?+cNSFUL(FfH)i=(;P{v=o>Y`2QoibQ7;r$P2%Ms^Dd5TgjDSc+raDp2~1& z?kJ!A#}Dm>mizpfYXch1j0csX)$D7U2aVCP)0G}QFyq0vSwz&}k=NjD+TnDhc-!?mKsK(Svpsg68Kg5;-x)Vn6SG@AhlA&RqNOX7>jd4s1#7tjnvTNA?UQ{OSE$ONtuu^K16c zxRvngSNhn8+ArL=x~{Ee-N=rY7T8_UOQf&6q>bmVuI)L}((smd#jXr}^_N$Ue%0{x zp@rf Date: Tue, 19 Nov 2024 23:15:17 -0500 Subject: [PATCH 14/16] Deduplicate code And almost handle left-side graphs --- .../gtnewhorizons/angelica/debug/F3Graph.java | 256 ++++++++++++++++++ .../angelica/debug/FrametimeGraph.java | 221 +-------------- .../angelica/debug/TPSGraph.java | 224 +-------------- .../angelica/proxy/ClientProxy.java | 2 +- .../angelica/shaders/debug_graph.frag.glsl | 6 +- .../angelica/shaders/debug_graph.vert.glsl | 6 +- 6 files changed, 282 insertions(+), 433 deletions(-) create mode 100644 src/main/java/com/gtnewhorizons/angelica/debug/F3Graph.java diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/F3Graph.java b/src/main/java/com/gtnewhorizons/angelica/debug/F3Graph.java new file mode 100644 index 000000000..c192b53a3 --- /dev/null +++ b/src/main/java/com/gtnewhorizons/angelica/debug/F3Graph.java @@ -0,0 +1,256 @@ +package com.gtnewhorizons.angelica.debug; + +import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; +import static org.lwjgl.opengl.GL11.GL_FLOAT; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; +import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; +import static org.lwjgl.opengl.GL11.glBlendFunc; +import static org.lwjgl.opengl.GL11.glColor4f; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glDisableClientState; +import static org.lwjgl.opengl.GL11.glDrawArrays; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glEnableClientState; +import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; +import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; +import static org.lwjgl.opengl.GL15.glBindBuffer; +import static org.lwjgl.opengl.GL15.glBufferData; +import static org.lwjgl.opengl.GL15.glGenBuffers; +import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; +import static org.lwjgl.opengl.GL20.glUniform1; +import static org.lwjgl.opengl.GL20.glUniform1f; +import static org.lwjgl.opengl.GL20.glUniform1i; +import static org.lwjgl.opengl.GL20.glVertexAttribPointer; + +import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; +import java.nio.FloatBuffer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.BufferUtils; + +public abstract class F3Graph { + private static final int NUM_SAMPLES = 240; + // Two floats (x,y) + private static final int VERT_FLOATS = 2; + private static final int VERT_COUNT = 4; + private static final int BORDER = 1; + private static final int HEIGHT = 60; + private static final int WIDTH = NUM_SAMPLES; + private static final int FONT_COLOR = 0xFFE0E0E0; + // Due to GLSL 120 limitations, it's just easier to use floats + private final FloatBuffer sampleBuf = BufferUtils.createFloatBuffer(NUM_SAMPLES); + private final long[] samples = new long[NUM_SAMPLES]; // CPU-side copy for reads + // Circular buffer holding the last 240 samples, in nanoseconds + private int samplesHead = 0; // one ahead of the position of the last sample + private boolean initialized = false; + private ShaderProgram shader; + private int aPos; + private int uFBWidth; + private int uFBHeight; + private int uScaleFactor; + private int uHeadIdx; + private int uSamples; + private int vertBuf; + private final ResourceLocation texture; + private final float pxPerNs; + private final boolean left; + private long sum; + + protected F3Graph(ResourceLocation texture, float pxPerNs, boolean left) { + this.texture = texture; + this.pxPerNs = pxPerNs; + this.left = left; + } + + public void putSample(long time) { + // Manage running trackers + sum -= samples[samplesHead]; + sum += time; + samples[samplesHead] = time; + + sampleBuf.put(samplesHead, (float) time); + samplesHead = (samplesHead + 1) % NUM_SAMPLES; + } + + private int getVertX(ScaledResolution sres, int idx) { + if (left) { + return switch (idx) { + case 0, 3 -> WIDTH + BORDER * 2; + case 1, 2 -> 0; + default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!"); + }; + } + + final int displayWidth = sres.getScaledWidth(); + return switch (idx) { + case 0, 3 -> displayWidth; + case 1, 2 -> displayWidth - WIDTH - BORDER * 2; + default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!"); + }; + } + + private int getVertY(ScaledResolution sres, int idx) { + final int displayHeight = sres.getScaledHeight(); + return switch (idx) { + case 0, 1 -> displayHeight - HEIGHT - BORDER * 2; + case 2, 3 -> displayHeight; + default -> throw new RuntimeException("Tried to get out-of-bounds vertex for graph!"); + }; + } + + private void init() { + shader = new ShaderProgram( + "angelica", + "shaders/debug_graph.vert.glsl", + "shaders/debug_graph.frag.glsl"); + shader.use(); + + // Register attributes + aPos = shader.getAttribLocation("pos"); + + // Register uniforms + uFBWidth = shader.getUniformLocation("fbWidth"); + uFBHeight = shader.getUniformLocation("fbHeight"); + uScaleFactor = shader.getUniformLocation("scaleFactor"); + uSamples = shader.getUniformLocation("samples"); + uHeadIdx = shader.getUniformLocation("headIdx"); + final int uPxPerNs = shader.getUniformLocation("pxPerNs"); + final int uLeft = shader.getUniformLocation("left"); + + // Load vertex buffer + vertBuf = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, vertBuf); + final FloatBuffer vertices = BufferUtils.createFloatBuffer(VERT_COUNT * VERT_FLOATS); + // Since we use a triangle strip, we only need 4 vertices. The quad extends to the top of the screen so spikes + // don't get truncated. The max height is replaced in the vert shader, no need to be precise. + vertices.put(new float[]{ + BORDER, BORDER, + WIDTH + BORDER, BORDER, + BORDER, Float.MAX_VALUE, + WIDTH + BORDER, Float.MAX_VALUE + }); + vertices.rewind(); + + glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + final Minecraft mc = Minecraft.getMinecraft(); + final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + + // Load initial value for uniforms + glUniform1f(uFBWidth, mc.displayWidth); + glUniform1f(uFBHeight, mc.displayHeight); + glUniform1f(uScaleFactor, sr.getScaleFactor()); + glUniform1i(uHeadIdx, samplesHead); + glUniform1(uSamples, sampleBuf); + glUniform1f(uPxPerNs, pxPerNs); + glUniform1i(uLeft, left ? 1 : 0); // this is how you load bool uniforms + + ShaderProgram.clear(); + } + + public void render() { + if (!initialized) { + init(); + initialized = true; + } + + /* + * We try to copy modern vanilla's tracker. + * It is 240 (FRAME_TIMES) wide by 60 tall, including the 1px borders. + * We instead make it 242x62 including borders to prevent the borders from overlapping the samples. + * The background is ARGB 90505050, the borders FFFFFFFF, and the text FFE0E0E0. + * First the background is rendered, then the samples, then the foreground texture and the text. + * The background is drawn via a 242x62 translucent rect. + * Next, the samples are rendered by a shader on a transparent 240x60 rect. + * Finally, the foreground texture and the text is rendered on top. + * The shader pipeline is only needed for the sample draw. + */ + + final Minecraft mc = Minecraft.getMinecraft(); + final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); + + // Setup GL state + final Tessellator tess = Tessellator.instance; + glDisable(GL_DEPTH_TEST); + glEnable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // Draw background + glDisable(GL_TEXTURE_2D); + glColor4f(0x50 / 255.0F, 0x50 / 255.0F, 0x50 / 255.0F, 0x90 / 255.0F); + tess.startDrawingQuads(); + for (int i = 0; i < 4; ++i) { + tess.addVertex(getVertX(sr, i), getVertY(sr, i), 0); + } + tess.draw(); + glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + glEnable(GL_TEXTURE_2D); + + + // Draw samples + shader.use(); + + // Load uniforms + glUniform1f(uFBWidth, mc.displayWidth); + glUniform1f(uFBHeight, mc.displayHeight); + glUniform1f(uScaleFactor, sr.getScaleFactor()); + glUniform1i(uHeadIdx, samplesHead); + glUniform1(uSamples, sampleBuf); + + glBindBuffer(GL_ARRAY_BUFFER, vertBuf); + glEnableVertexAttribArray(aPos); + glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0); + glEnableClientState(GL_VERTEX_ARRAY); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableVertexAttribArray(aPos); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + ShaderProgram.clear(); + + // Draw foreground + + mc.getTextureManager().bindTexture(texture); + tess.startDrawingQuads(); + tess.addVertexWithUV(getVertX(sr, 0), getVertY(sr, 0), 0.0D, 1, 0); + tess.addVertexWithUV(getVertX(sr, 1), getVertY(sr, 1), 0.0D, 0, 0); + tess.addVertexWithUV(getVertX(sr, 2), getVertY(sr, 2), 0.0D, 0, 1); + tess.addVertexWithUV(getVertX(sr, 3), getVertY(sr, 3), 0.0D, 1, 1); + tess.draw(); + + // Reset GL state + glEnable(GL_DEPTH_TEST); + glDisable(GL_ALPHA_TEST); + glDisable(GL_BLEND); + + // Draw text + // Ensure running counters are reset on first sample + long min = Long.MAX_VALUE; + long max = Long.MIN_VALUE; + for (int i = 0; i < NUM_SAMPLES; ++i) { + min = Math.min(min, samples[i]); + max = Math.max(max, samples[i]); + } + String minStr = String.format("%.1f ms min", min / 1_000_000D); + String avgStr = String.format("%.1f ms avg", sum / 1_000_000 / (double) NUM_SAMPLES); + String maxStr = String.format("%.1f ms max", max / 1_000_000D); + final FontRenderer fr = mc.fontRenderer; + final int top = sr.getScaledHeight() - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT; + fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true); + fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true); + fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true); + } +} diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java index b2e281044..7f2b10504 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/FrametimeGraph.java @@ -1,219 +1,14 @@ package com.gtnewhorizons.angelica.debug; -import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; -import static org.lwjgl.opengl.GL11.GL_BLEND; -import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; -import static org.lwjgl.opengl.GL11.GL_FLOAT; -import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; -import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; -import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; -import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; -import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; -import static org.lwjgl.opengl.GL11.glBlendFunc; -import static org.lwjgl.opengl.GL11.glColor4f; -import static org.lwjgl.opengl.GL11.glDisable; -import static org.lwjgl.opengl.GL11.glDisableClientState; -import static org.lwjgl.opengl.GL11.glDrawArrays; -import static org.lwjgl.opengl.GL11.glEnable; -import static org.lwjgl.opengl.GL11.glEnableClientState; -import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; -import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; -import static org.lwjgl.opengl.GL15.glBindBuffer; -import static org.lwjgl.opengl.GL15.glBufferData; -import static org.lwjgl.opengl.GL15.glGenBuffers; -import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; -import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; -import static org.lwjgl.opengl.GL20.glUniform1; -import static org.lwjgl.opengl.GL20.glUniform1f; -import static org.lwjgl.opengl.GL20.glUniform1i; -import static org.lwjgl.opengl.GL20.glVertexAttribPointer; - -import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; -import java.nio.FloatBuffer; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.ResourceLocation; -import org.lwjgl.BufferUtils; - -public class FrametimeGraph { - public static final int NUM_SAMPLES = 240; - // Circular buffer holding the last 240 frametimes, in nanoseconds - public int samplesHead = 0; // one ahead of the position of the last frametime - private boolean initialized = false; - private ShaderProgram shader; - private int aPos; - private int uFBWidth; - private int uFBHeight; - private int uScaleFactor; - private int uHeadIdx; - private int uSamples; - private int vertBuf; - // Two floats (x,y) - private static final int VERT_FLOATS = 2; - private static final int VERT_COUNT = 4; - // Due to GLSL 120 limitations, it's just easier to use floats - private final FloatBuffer sampleBuf = BufferUtils.createFloatBuffer(NUM_SAMPLES); - private static final int BORDER = 1; - private static final int HEIGHT = 60; - private static final int WIDTH = NUM_SAMPLES; - private static final int FONT_COLOR = 0xFFE0E0E0; - private static final ResourceLocation TEXTURE = new ResourceLocation("angelica:textures/frametimes_fg.png"); - // At 1x scale, 30 FPS should be 60 px. 30 FPS = 33_333_333ns per frame, 60px/33_333_333ns = 0.0000018f px/ns - private static final float PIXELS_PER_NS = 0.0000018f; - - public void putFrameTime(long time) { - sampleBuf.put(samplesHead, (float) time); - samplesHead = (samplesHead + 1) % NUM_SAMPLES; - } - - private void init() { - shader = new ShaderProgram( - "angelica", - "shaders/debug_graph.vert.glsl", - "shaders/debug_graph.frag.glsl"); - shader.use(); - - // Register attributes - aPos = shader.getAttribLocation("pos"); - - // Register uniforms - uFBWidth = shader.getUniformLocation("fbWidth"); - uFBHeight = shader.getUniformLocation("fbHeight"); - uScaleFactor = shader.getUniformLocation("scaleFactor"); - uSamples = shader.getUniformLocation("samples"); - uHeadIdx = shader.getUniformLocation("headIdx"); - final int uPxPerNs = shader.getUniformLocation("pxPerNs"); - - // Load vertex buffer - vertBuf = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, vertBuf); - final FloatBuffer vertices = BufferUtils.createFloatBuffer(VERT_COUNT * VERT_FLOATS); - // Since we use a triangle strip, we only need 4 vertices - //@formatter:off - vertices.put(new float[]{ - BORDER , BORDER, - WIDTH + BORDER, BORDER, - BORDER , HEIGHT + BORDER, - WIDTH + BORDER, HEIGHT + BORDER - }); - //@formatter:on - vertices.rewind(); - - glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - final Minecraft mc = Minecraft.getMinecraft(); - final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); - - // Load initial value for uniforms - glUniform1f(uFBWidth, mc.displayWidth); - glUniform1f(uFBHeight, mc.displayHeight); - glUniform1f(uScaleFactor, sr.getScaleFactor()); - glUniform1i(uHeadIdx, samplesHead); - glUniform1(uSamples, sampleBuf); - glUniform1f(uPxPerNs, PIXELS_PER_NS); - - ShaderProgram.clear(); - } - - public void render() { - if (!initialized) { - init(); - initialized = true; - } - - double min, max, sum; - min = max = sum = sampleBuf.get(0); - for (int i = 1; i < NUM_SAMPLES; i++) { - min = Math.min(min, sampleBuf.get(i)); - max = Math.max(max, sampleBuf.get(i)); - sum += sampleBuf.get(i); - } - - /* - * We try to copy modern vanilla's tracker. - * It is 240 (FRAME_TIMES) wide by 60 tall, including the 1px borders. - * We instead make it 242x62 including borders to prevent the borders from overlapping the samples. - * The background is ARGB 90505050, the borders FFFFFFFF, and the text FFE0E0E0. - * First the background is rendered, then the samples, then the foreground texture and the text. - * The background is drawn via a 242x62 translucent rect. - * Next, the samples are rendered by a shader on a transparent 240x60 rect. - * Finally, the foreground texture and the text is rendered on top. - * The shader pipeline is only needed for the sample draw. - */ - - final Minecraft mc = Minecraft.getMinecraft(); - final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); - final int height = sr.getScaledHeight(); - - // Setup GL state - final Tessellator tess = Tessellator.instance; - glDisable(GL_DEPTH_TEST); - glEnable(GL_ALPHA_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // Draw background - glDisable(GL_TEXTURE_2D); - glColor4f(0x50 / 255.0F, 0x50 / 255.0F, 0x50 / 255.0F, 0x90 / 255.0F); - tess.startDrawingQuads(); - tess.addVertex(WIDTH + BORDER * 2, height - HEIGHT - BORDER * 2, 0.0D); - tess.addVertex(0, height - HEIGHT - BORDER * 2, 0.0D); - tess.addVertex(0, height, 0.0D); - tess.addVertex(WIDTH + BORDER * 2, height, 0.0D); - tess.draw(); - glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - glEnable(GL_TEXTURE_2D); - - - // Draw samples - shader.use(); - - // Load uniforms - glUniform1f(uFBWidth, mc.displayWidth); - glUniform1f(uFBHeight, mc.displayHeight); - glUniform1f(uScaleFactor, sr.getScaleFactor()); - glUniform1i(uHeadIdx, samplesHead); - glUniform1(uSamples, sampleBuf); - - glBindBuffer(GL_ARRAY_BUFFER, vertBuf); - glEnableVertexAttribArray(aPos); - glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0); - glEnableClientState(GL_VERTEX_ARRAY); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableVertexAttribArray(aPos); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - ShaderProgram.clear(); - - // Draw foreground - - mc.getTextureManager().bindTexture(TEXTURE); - tess.startDrawingQuads(); - tess.addVertexWithUV(WIDTH + BORDER * 2, height - HEIGHT - BORDER * 2, 0.0D, 1, 0); - tess.addVertexWithUV(0, height - HEIGHT - BORDER * 2, 0.0D, 0, 0); - tess.addVertexWithUV(0, height, 0.0D, 0, 1); - tess.addVertexWithUV(WIDTH + BORDER * 2, height, 0.0D, 1, 1); - tess.draw(); - - // Reset GL state - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - // Draw text - String minStr = (int) min / 1_000_000 + " ms min"; - String avgStr = (int) sum / 1_000_000 / NUM_SAMPLES + " ms avg"; - String maxStr = (int) max / 1_000_000 + " ms max"; - final FontRenderer fr = mc.fontRenderer; - final int top = height - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT; - fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true); - fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true); - fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true); +public class FrametimeGraph extends F3Graph { + public FrametimeGraph() { + // At 1x scale, 30 FPS should be 60 px. 30 FPS = 33_333_333ns per frame, 60px/33_333_333ns = 0.0000018f px/ns + super( + new ResourceLocation("angelica:textures/frametimes_fg.png"), + 0.0000018f, + true + ); } } diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java index a052aa3b1..7b06f241f 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java @@ -1,222 +1,14 @@ package com.gtnewhorizons.angelica.debug; -import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; -import static org.lwjgl.opengl.GL11.GL_BLEND; -import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; -import static org.lwjgl.opengl.GL11.GL_FLOAT; -import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; -import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; -import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; -import static org.lwjgl.opengl.GL11.GL_TRIANGLE_STRIP; -import static org.lwjgl.opengl.GL11.GL_VERTEX_ARRAY; -import static org.lwjgl.opengl.GL11.glBlendFunc; -import static org.lwjgl.opengl.GL11.glColor4f; -import static org.lwjgl.opengl.GL11.glDisable; -import static org.lwjgl.opengl.GL11.glDisableClientState; -import static org.lwjgl.opengl.GL11.glDrawArrays; -import static org.lwjgl.opengl.GL11.glEnable; -import static org.lwjgl.opengl.GL11.glEnableClientState; -import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; -import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; -import static org.lwjgl.opengl.GL15.glBindBuffer; -import static org.lwjgl.opengl.GL15.glBufferData; -import static org.lwjgl.opengl.GL15.glGenBuffers; -import static org.lwjgl.opengl.GL20.glDisableVertexAttribArray; -import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; -import static org.lwjgl.opengl.GL20.glUniform1; -import static org.lwjgl.opengl.GL20.glUniform1f; -import static org.lwjgl.opengl.GL20.glUniform1i; -import static org.lwjgl.opengl.GL20.glVertexAttribPointer; - -import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; -import java.nio.FloatBuffer; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.ResourceLocation; -import org.lwjgl.BufferUtils; - -/** - * Pretty much just {@link FrametimeGraph} but on the left - */ -public class TPSGraph { - public static final int NUM_SAMPLES = 240; - // Circular buffer holding the last 240 samples, in nanoseconds - public int samplesHead = 0; // one ahead of the position of the last sample - private boolean initialized = false; - private ShaderProgram shader; - private int aPos; - private int uFBWidth; - private int uFBHeight; - private int uScaleFactor; - private int uHeadIdx; - private int uSamples; - private int vertBuf; - // Two floats (x,y) - private static final int VERT_FLOATS = 2; - private static final int VERT_COUNT = 4; - // Due to GLSL 120 limitations, it's just easier to use floats - private final FloatBuffer sampleBuf = BufferUtils.createFloatBuffer(NUM_SAMPLES); - private static final int BORDER = 1; - private static final int HEIGHT = 60; - private static final int WIDTH = NUM_SAMPLES; - private static final int FONT_COLOR = 0xFFE0E0E0; - private static final ResourceLocation TEXTURE = new ResourceLocation("angelica:textures/tps_fg.png"); - // At 1x scale, 20 TPS should be 60 px. 20 FPS = 50_000_000ns per frame, 60px/50_000_000ns = 0.0000012 px/ns - private static final float PIXELS_PER_NS = 0.0000012f; - - public void putSample(long time) { - sampleBuf.put(samplesHead, (float) time); - samplesHead = (samplesHead + 1) % NUM_SAMPLES; - } - - private void init() { - shader = new ShaderProgram( - "angelica", - "shaders/debug_graph.vert.glsl", - "shaders/debug_graph.frag.glsl"); - shader.use(); - - // Register attributes - aPos = shader.getAttribLocation("pos"); - - // Register uniforms - uFBWidth = shader.getUniformLocation("fbWidth"); - uFBHeight = shader.getUniformLocation("fbHeight"); - uScaleFactor = shader.getUniformLocation("scaleFactor"); - uSamples = shader.getUniformLocation("samples"); - uHeadIdx = shader.getUniformLocation("headIdx"); - final int uPxPerNs = shader.getUniformLocation("pxPerNs"); - - // Load vertex buffer - vertBuf = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, vertBuf); - final FloatBuffer vertices = BufferUtils.createFloatBuffer(VERT_COUNT * VERT_FLOATS); - // Since we use a triangle strip, we only need 4 vertices - //@formatter:off - vertices.put(new float[]{ - BORDER , BORDER, - WIDTH + BORDER, BORDER, - BORDER , HEIGHT + BORDER, - WIDTH + BORDER, HEIGHT + BORDER - }); - //@formatter:on - vertices.rewind(); - - glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - final Minecraft mc = Minecraft.getMinecraft(); - final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); - - // Load initial value for uniforms - glUniform1f(uFBWidth, mc.displayWidth); - glUniform1f(uFBHeight, mc.displayHeight); - glUniform1f(uScaleFactor, sr.getScaleFactor()); - glUniform1i(uHeadIdx, samplesHead); - glUniform1(uSamples, sampleBuf); - glUniform1f(uPxPerNs, PIXELS_PER_NS); - - ShaderProgram.clear(); - } - - public void render() { - if (!initialized) { - init(); - initialized = true; - } - - double min, max, sum; - min = max = sum = sampleBuf.get(0); - for (int i = 1; i < NUM_SAMPLES; i++) { - min = Math.min(min, sampleBuf.get(i)); - max = Math.max(max, sampleBuf.get(i)); - sum += sampleBuf.get(i); - } - - /* - * We try to copy modern vanilla's tracker. - * It is 240 (FRAME_TIMES) wide by 60 tall, including the 1px borders. - * We instead make it 242x62 including borders to prevent the borders from overlapping the samples. - * The background is ARGB 90505050, the borders FFFFFFFF, and the text FFE0E0E0. - * First the background is rendered, then the samples, then the foreground texture and the text. - * The background is drawn via a 242x62 translucent rect. - * Next, the samples are rendered by a shader on a transparent 240x60 rect. - * Finally, the foreground texture and the text is rendered on top. - * The shader pipeline is only needed for the sample draw. - */ - - final Minecraft mc = Minecraft.getMinecraft(); - final ScaledResolution sr = new ScaledResolution(mc, mc.displayWidth, mc.displayHeight); - final int height = sr.getScaledHeight(); - - // Setup GL state - final Tessellator tess = Tessellator.instance; - glDisable(GL_DEPTH_TEST); - glEnable(GL_ALPHA_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - // Draw background - glDisable(GL_TEXTURE_2D); - glColor4f(0x50 / 255.0F, 0x50 / 255.0F, 0x50 / 255.0F, 0x90 / 255.0F); - tess.startDrawingQuads(); - tess.addVertex(WIDTH + BORDER * 2, height - HEIGHT - BORDER * 2, 0.0D); - tess.addVertex(0, height - HEIGHT - BORDER * 2, 0.0D); - tess.addVertex(0, height, 0.0D); - tess.addVertex(WIDTH + BORDER * 2, height, 0.0D); - tess.draw(); - glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - glEnable(GL_TEXTURE_2D); - - - // Draw samples - shader.use(); - - // Load uniforms - glUniform1f(uFBWidth, mc.displayWidth); - glUniform1f(uFBHeight, mc.displayHeight); - glUniform1f(uScaleFactor, sr.getScaleFactor()); - glUniform1i(uHeadIdx, samplesHead); - glUniform1(uSamples, sampleBuf); - - glBindBuffer(GL_ARRAY_BUFFER, vertBuf); - glEnableVertexAttribArray(aPos); - glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0); - glEnableClientState(GL_VERTEX_ARRAY); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableVertexAttribArray(aPos); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - ShaderProgram.clear(); - - // Draw foreground - - mc.getTextureManager().bindTexture(TEXTURE); - tess.startDrawingQuads(); - tess.addVertexWithUV(WIDTH + BORDER * 2, height - HEIGHT - BORDER * 2, 0.0D, 1, 0); - tess.addVertexWithUV(0, height - HEIGHT - BORDER * 2, 0.0D, 0, 0); - tess.addVertexWithUV(0, height, 0.0D, 0, 1); - tess.addVertexWithUV(WIDTH + BORDER * 2, height, 0.0D, 1, 1); - tess.draw(); - - // Reset GL state - glEnable(GL_DEPTH_TEST); - glDisable(GL_ALPHA_TEST); - glDisable(GL_BLEND); - // Draw text - String minStr = (int) min / 1_000_000 + " ms min"; - String avgStr = (int) sum / 1_000_000 / NUM_SAMPLES + " ms avg"; - String maxStr = (int) max / 1_000_000 + " ms max"; - final FontRenderer fr = mc.fontRenderer; - final int top = height - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT; - fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true); - fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true); - fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true); +public class TPSGraph extends F3Graph { + protected TPSGraph() { + // At 1x scale, 20 TPS should be 60 px. 20 FPS = 50_000_000ns per frame, 60px/50_000_000ns = 0.0000012 px/ns + super( + new ResourceLocation("angelica:textures/tps_fg.png"), + 0.0000012f, + false + ); } } diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java index 677e5a7f7..c9854cb58 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java @@ -323,6 +323,6 @@ public void onFOVModifierUpdate(FOVUpdateEvent event) { @Override public void putFrametime(long time) { - graph.putFrameTime(time); + graph.putSample(time); } } diff --git a/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl b/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl index 19cb4429e..e99aed995 100644 --- a/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl +++ b/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl @@ -4,11 +4,13 @@ uniform int headIdx; uniform float scaleFactor; uniform float samples[240]; uniform float pxPerNs; +uniform bool left; +uniform float fbWidth; void main() { // Get position - gl_FragCoord starts from the lower left and returns the position of the center of the pixel - // i.e. the lower-left-most pixel is (0.5, 0.5) - int dx = int(gl_FragCoord.x / scaleFactor); + // i.e. the lower-left-most pixel is (0.5, 0.5). Shift if we're on the right side of the screen. + int dx = int((left ? gl_FragCoord.x : fbWidth - gl_FragCoord.x) / scaleFactor) - 1; int dy = int(gl_FragCoord.y / scaleFactor); // Get the time for this frag. Last at the left edge, first at the right, shifting as needed when the head moves. diff --git a/src/main/resources/assets/angelica/shaders/debug_graph.vert.glsl b/src/main/resources/assets/angelica/shaders/debug_graph.vert.glsl index db8ff8148..87c578a3c 100644 --- a/src/main/resources/assets/angelica/shaders/debug_graph.vert.glsl +++ b/src/main/resources/assets/angelica/shaders/debug_graph.vert.glsl @@ -5,10 +5,14 @@ attribute vec2 pos; uniform float fbWidth; uniform float fbHeight; uniform float scaleFactor; +uniform bool left; void main() { - // Shift the bounds (originally in pixel coords) to clip space + // Shift the bounds (originally in pixel coords) to clip space. Flip horizontally if on the right, and ensure the + // top vertices are pinned to the top of the screen. float x = pos.x / fbWidth * scaleFactor * 2.0 - 1.0; float y = pos.y / fbHeight * scaleFactor * 2.0 - 1.0; + x = left ? x : -x; + y = y < -0.9 ? y : 1.0; // -0.9 arbitrariy chosen as "probably between bottom and top verts" gl_Position = vec4(x, y, 0.0, 1.0); } From 5e07820552052f3cb4629fae16ccfa0b461a2124 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Tue, 19 Nov 2024 23:35:22 -0500 Subject: [PATCH 15/16] TPS graph works Now just need to feed it valid TPS data --- .../gtnewhorizons/angelica/debug/F3Graph.java | 20 ++++++++++++++++--- .../angelica/debug/TPSGraph.java | 2 +- .../angelica/proxy/ClientProxy.java | 14 ++++++++++--- .../angelica/proxy/CommonProxy.java | 2 ++ .../angelica/shaders/debug_graph.frag.glsl | 2 +- .../mixins/early/angelica/MixinMinecraft.java | 2 ++ 6 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/F3Graph.java b/src/main/java/com/gtnewhorizons/angelica/debug/F3Graph.java index c192b53a3..7b024b2a3 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/F3Graph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/F3Graph.java @@ -2,6 +2,7 @@ import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_CULL_FACE; import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; import static org.lwjgl.opengl.GL11.GL_FLOAT; import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; @@ -213,8 +214,13 @@ public void render() { glVertexAttribPointer(aPos, VERT_FLOATS, GL_FLOAT, false, VERT_FLOATS * 4, 0); glEnableClientState(GL_VERTEX_ARRAY); + // Left side graphs are inverted, so temporarily disable culling + if (!left) glDisable(GL_CULL_FACE); + glDrawArrays(GL_TRIANGLE_STRIP, 0, VERT_COUNT); + if (!left) glEnable(GL_CULL_FACE); + glDisableClientState(GL_VERTEX_ARRAY); glDisableVertexAttribArray(aPos); glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -249,8 +255,16 @@ public void render() { String maxStr = String.format("%.1f ms max", max / 1_000_000D); final FontRenderer fr = mc.fontRenderer; final int top = sr.getScaledHeight() - HEIGHT - BORDER * 2 - fr.FONT_HEIGHT; - fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true); - fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true); - fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true); + final int scaledWidth = sr.getScaledWidth(); + + if (left) { + fr.drawString(minStr, BORDER * 2, top, FONT_COLOR, true); + fr.drawString(avgStr, BORDER + WIDTH / 2 - fr.getStringWidth(avgStr) / 2, top, FONT_COLOR, true); + fr.drawString(maxStr, BORDER * 2 + WIDTH - fr.getStringWidth(maxStr), top, FONT_COLOR, true); + } else { + fr.drawString(minStr, scaledWidth - (BORDER * 2 + WIDTH), top, FONT_COLOR, true); + fr.drawString(avgStr, scaledWidth - (BORDER + WIDTH / 2 + fr.getStringWidth(avgStr) / 2), top, FONT_COLOR, true); + fr.drawString(maxStr, scaledWidth - (BORDER * 2 + fr.getStringWidth(maxStr)), top, FONT_COLOR, true); + } } } diff --git a/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java b/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java index 7b06f241f..88c827ed8 100644 --- a/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java +++ b/src/main/java/com/gtnewhorizons/angelica/debug/TPSGraph.java @@ -3,7 +3,7 @@ import net.minecraft.util.ResourceLocation; public class TPSGraph extends F3Graph { - protected TPSGraph() { + public TPSGraph() { // At 1x scale, 20 TPS should be 60 px. 20 FPS = 50_000_000ns per frame, 60px/50_000_000ns = 0.0000012 px/ns super( new ResourceLocation("angelica:textures/tps_fg.png"), diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java index c9854cb58..bd2dcc844 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java @@ -10,6 +10,7 @@ import com.gtnewhorizons.angelica.config.AngelicaConfig; import com.gtnewhorizons.angelica.config.CompatConfig; import com.gtnewhorizons.angelica.debug.FrametimeGraph; +import com.gtnewhorizons.angelica.debug.TPSGraph; import com.gtnewhorizons.angelica.mixins.interfaces.IGameSettingsExt; import com.gtnewhorizons.angelica.dynamiclights.DynamicLights; import com.gtnewhorizons.angelica.glsm.GLStateManager; @@ -63,7 +64,8 @@ public class ClientProxy extends CommonProxy { final Minecraft mc = Minecraft.getMinecraft(); - final FrametimeGraph graph = new FrametimeGraph(); + final FrametimeGraph frametimeGraph = new FrametimeGraph(); + final TPSGraph tpsGraph = new TPSGraph(); @Override public void preInit(FMLPreInitializationEvent event) { @@ -283,7 +285,8 @@ public void onRenderOverlay(RenderGameOverlayEvent.Text event) { // Draw a frametime graph if (((IGameSettingsExt)mc.gameSettings).angelica$showFpsGraph()) { - graph.render(); + frametimeGraph.render(); + tpsGraph.render(); } } } @@ -323,6 +326,11 @@ public void onFOVModifierUpdate(FOVUpdateEvent event) { @Override public void putFrametime(long time) { - graph.putSample(time); + frametimeGraph.putSample(time); + } + + @Override + public void putTicktime(long time) { + tpsGraph.putSample(time); } } diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/CommonProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/CommonProxy.java index 8ef1adfe7..26ffe4dd8 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/CommonProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/CommonProxy.java @@ -22,4 +22,6 @@ public void postInit(FMLPostInitializationEvent event) {} // Only present on the client! public void putFrametime(long time) { throw new UnsupportedOperationException(); } + + public void putTicktime(long time) { throw new UnsupportedOperationException(); } } diff --git a/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl b/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl index e99aed995..72876c9ee 100644 --- a/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl +++ b/src/main/resources/assets/angelica/shaders/debug_graph.frag.glsl @@ -10,7 +10,7 @@ uniform float fbWidth; void main() { // Get position - gl_FragCoord starts from the lower left and returns the position of the center of the pixel // i.e. the lower-left-most pixel is (0.5, 0.5). Shift if we're on the right side of the screen. - int dx = int((left ? gl_FragCoord.x : fbWidth - gl_FragCoord.x) / scaleFactor) - 1; + int dx = int((left ? gl_FragCoord.x : gl_FragCoord.x - fbWidth) / scaleFactor) - 1; int dy = int(gl_FragCoord.y / scaleFactor); // Get the time for this frag. Last at the left edge, first at the right, shifting as needed when the head moves. diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java index 01c3ec006..68658aa6e 100644 --- a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java @@ -36,6 +36,8 @@ public class MixinMinecraft { private void angelica$trackFrametimes(CallbackInfo ci) { long time = System.nanoTime(); AngelicaMod.proxy.putFrametime(time - angelica$lastFrameTime); + // testing + AngelicaMod.proxy.putTicktime(time - angelica$lastFrameTime); angelica$lastFrameTime = time; } From 0f6280745dfc168903ecfce4e90729cc403825c4 Mon Sep 17 00:00:00 2001 From: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com> Date: Wed, 20 Nov 2024 00:07:37 -0500 Subject: [PATCH 16/16] Add integrated server TPS reporting --- .../gtnewhorizons/angelica/mixins/Mixins.java | 1 + .../angelica/proxy/ClientProxy.java | 4 +++- .../mixins/early/angelica/MixinMinecraft.java | 2 -- .../early/angelica/MixinMinecraftServer.java | 17 +++++++++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraftServer.java diff --git a/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java b/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java index 615767fc2..f5b5318be 100644 --- a/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java +++ b/src/main/java/com/gtnewhorizons/angelica/mixins/Mixins.java @@ -29,6 +29,7 @@ public enum Mixins { ,"angelica.MixinEntityRenderer" ,"angelica.MixinGameSettings" ,"angelica.MixinMinecraft" + ,"angelica.MixinMinecraftServer" ,"angelica.optimizations.MixinRendererLivingEntity" ,"angelica.MixinFMLClientHandler" ,"angelica.bugfixes.MixinRenderGlobal_DestroyBlock" diff --git a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java index bd2dcc844..92f3cfb6b 100644 --- a/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java +++ b/src/main/java/com/gtnewhorizons/angelica/proxy/ClientProxy.java @@ -286,7 +286,9 @@ public void onRenderOverlay(RenderGameOverlayEvent.Text event) { // Draw a frametime graph if (((IGameSettingsExt)mc.gameSettings).angelica$showFpsGraph()) { frametimeGraph.render(); - tpsGraph.render(); + if (Minecraft.getMinecraft().isSingleplayer()) { + tpsGraph.render(); + } } } } diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java index 68658aa6e..01c3ec006 100644 --- a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraft.java @@ -36,8 +36,6 @@ public class MixinMinecraft { private void angelica$trackFrametimes(CallbackInfo ci) { long time = System.nanoTime(); AngelicaMod.proxy.putFrametime(time - angelica$lastFrameTime); - // testing - AngelicaMod.proxy.putTicktime(time - angelica$lastFrameTime); angelica$lastFrameTime = time; } diff --git a/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraftServer.java b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraftServer.java new file mode 100644 index 000000000..3d27f9769 --- /dev/null +++ b/src/mixin/java/com/gtnewhorizons/angelica/mixins/early/angelica/MixinMinecraftServer.java @@ -0,0 +1,17 @@ +package com.gtnewhorizons.angelica.mixins.early.angelica; + +import com.gtnewhorizons.angelica.AngelicaMod; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.server.MinecraftServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MinecraftServer.class) +public class MixinMinecraftServer { + @Inject(method = "tick", at = @At(value = "TAIL")) + private void angelica$trackTicktimes(CallbackInfo ci, @Local(ordinal = 0) long preTime) { + AngelicaMod.proxy.putTicktime(System.nanoTime() - preTime); + } +}