From 9fcd8240e4451b56dcb25090a729e7c1205a7946 Mon Sep 17 00:00:00 2001 From: "Grayson Riffe (Laptop)" Date: Mon, 30 Aug 2021 21:26:06 -0500 Subject: [PATCH] Added asset loading and OBJ parsing, including indexing --- ... With Assets Read From A Custom Format.png | Bin 0 -> 28866 bytes Game/Game.vcxproj | 10 +- NFPackCreator/NFPackCreator.vcxproj.user | 1 - NFPackCreator/src/main.cpp | 21 ++-- NothinFancy/src/Application.cpp | 2 +- NothinFancy/src/Assets.cpp | 64 +++++++++-- NothinFancy/src/Renderer/Drawable/Entity.cpp | 39 +++++-- NothinFancy/src/Renderer/Drawable/Model.cpp | 9 +- NothinFancy/src/Renderer/Texture.cpp | 9 +- NothinFancy/src/Utility.cpp | 108 ++++++++++++++++-- NothinFancy/src/include/Assets.h | 20 ++-- NothinFancy/src/include/Entity.h | 19 +-- NothinFancy/src/include/Model.h | 2 +- NothinFancy/src/include/NothinFancy.h | 20 ++-- NothinFancy/src/include/Texture.h | 2 +- NothinFancy/src/include/Utility.h | 2 + 16 files changed, 249 insertions(+), 79 deletions(-) create mode 100644 DevScreenshots/3. Textured Cube With Assets Read From A Custom Format.png diff --git a/DevScreenshots/3. Textured Cube With Assets Read From A Custom Format.png b/DevScreenshots/3. Textured Cube With Assets Read From A Custom Format.png new file mode 100644 index 0000000000000000000000000000000000000000..f899d8c017aa465aa70f9b82e962305516f689fb GIT binary patch literal 28866 zcmeFZbyQSuxGz2+%BTp8NJxi@f|P-t^aHRA03?svcOJfC=8!Zp;CP8?%AhC-oE+`J)w z8-+Sdib9btppU@6d^>|Sf)5hs+e+6_g>B4J@B^8ptg0*uRT6uA=k8(n`RIcicbriu z%0}dWl248~_fV(@dN<`|wLOgIhRI(U-tQq_xVjR;$o|$H&0ZTG5Of10uT6GTCs8<4 zUW(~_*b(zh`BMvrF7R~aAL9%=@r1wYFh!TjUxhrp&zr06rtf|vBn`uV3ESI}?GnzD zZN=h}L;K0g$#>1qMJ2p}9-snZ;)5HwO+4RKpphS45<9sRv!^2LksnfnkCKugpJZf# z$j=(2K{Ckac@kN6Ft&V@nfVa zS))61$-;J3U$oS^)z!Ldod**c-!z7o6Z2mv zw%6aD{fx)^+t+?ldJLfQop(X+t#|NMvI3`yl>iir+>GrcJh{ytj9otdABv;3exiT zE)fdm&(wk|Hj8!QDIRBr_jfW@c3!t<>vcy?t=<)&?Yk9D@|gBlpe4)ZZAKx3iK-EO z$!O`ZN|#^F`RbJwT|cHO4>i}ncaKOa^XHemT6fL9UhBT2nDZ{<1zKHu+8rHSc8?bg>5|4#WGymMJz zV?!VXiCj@oLtocd>*k-18K*5gCxw@ptefu`3lxT<7izyWd~L0^!g>|D>$T>a=i*2G zdN}%2r#jNt)z=*sdfdz0l`S1#ckSuS%q6*5WFB_kcloj1oVmD6tJl>2Lol;;yvmth z<+a1Mp%}-U$V3^@(3oexCL(W;)!R;)>5ay!GtbE8a1USoWQK5Ib;Ck#_*9$OaxFWt z+1=lGpXeC8j;!0%qdW@Al1WzTwZ}*;8CZXgif1R7q&!TtR;JdsK3b^n_50c8_xIBx zq`Z8k*_kDi87|*8%x{ZjtGu??M*q1w^j%JIsa>=hP2pI7-e|3DLd8K~ywS%q7e8Cg zVc27za!q)5qb;-RRp(~J`nU2~@qGoI83-x;e{-ye?kZ8I-QK>xil5Cfb7p)=Tc3X|>Bs$vdhWfrc^sMBu=T+1+|Pd| zDZZ-kXuoS~gN5xyH1m~xy{YH~H0j+cX!ysjT2_k8|C7__^Gg%Dy5y zlW6j^%Wu0!zr5)5dimRJB&5ky=ZY}gV{dE-4QePKO@0$^;`S8Zu5?As+p*YsU|H^U zcDwK2=ho}1QVHwrVlxHSD}Obu=RNUxaW-4^1IK-Qky)roby@RcIA zjY)Unpm(Fx$n(KKXC`N-*NaZ0>xq{XDlV*-mmG9e!vcwG!&xH{4$Sl8T_=`zrI!?-6FDk0)XFnat9?f{=Yq79hsAAqB^5BE$9JaEP?xx8=7d37 z`YQ}sNfUFBhwiftGh`oGtv4E4e7XaC>r|8MC28%y#3EgRJT|F%p(%vH~&-&NeG zfJ;b}=qRf?zFH-|n$bB(g2G>xWk;d-a>YL9yV{fm?)*TZpeWFK{AN6D<32;M#jg@&1i8hWV_^UG&3eN)%mx;`yd|{JhWpB)jN{vJA36*h` z(VmgFTpS?%r!yV*dIHsPG!uV(Q7DST$UOquk3CD(I?fZBP^N+i_#V+@`TSk{gUq7T zA=HsX=*eG?9ugHC4gMri6=li}%?6a|vb_2(CM&*dd<2!K0Plz|m_}vv9&KsbW<~v_ zf@THJW8gOYz5{*idrAEtK&}M7u6(i}mJo*~dQ3vJU!gQ zm%oL2KXNqS?WFf<6gGvOI)Fpdw?Th~OvZajk`jfx3C(otAR~)%ks94bbzq?x;pkvV zlnv$>X+y_B-U?Pe4_%gnexoQ(zhy^JutLkKm+ktC&5onI)Y;LfLn_FZ_)|JTC_%x{ z=mbHFr6##^bo3;t{>*ri;HkZBqWb!BF=I`gCV@x78+E}+A_q+eRc1%``W!-g%8yR%0PcrtN zD|OkL%AV|Y?K670w>`T5XNFN^d-i?yX^U4JkHatwB1^-<>qE|y5g*$9*4|Gor|kRe zoeui2#tsimhQ(?nCd=N@!?wTi$z|i`_g8p%wt5)MYBoQ^$*tmY{9Ybyl_s`~9=Vi)xJ zO`GKU5Hs}^&QR}y(q8No)98kx*Z%fs%Ap2}NLO<8Yd=F)%IkOehMhjK5Js#OP^SaO zV#Mb+=4DP|Q#7biureu7vh4SlnrPI2ul49Z=Kq+UUs%Oc6ukbKEA~`*j$`?-n@aV3 zl`Z80U1{_$92w~?PoSN6$z^ zuZghbv#6hDe>H1xWZo0*o`BSCIBqnD$QKmFRV z?#}yT1)4$?oI!axjFAgAfrsgC92cm0;BcIk0&`E{FFmgCrLmW_@o`7Ni>2Rhdk)N# zODzQA=c{JuyqRch*MRcmTi5TdeSID@6Fyb<+P>`0*2X940PZs51N@uK}ukv_vsOTw@4PqaU+$Xqa?gk_H(_g_xLk66*e*71_s{Gy)a=(qgZ z`l$ll7uw+HoS{jg&!o8L6QzlDckbjFeR0A0b=XARFX)Chb{F?5eugr2eIRFhGb&yB z?aH8?C@QMu1FfE6C-qZG*e9u4uumAMgJh1}4$kCZC^E zZ7HA1XHZJRAw1ML*`5)}?!Y4EnAQ zJ1@}dMEKISua55Tt-JK!eLT@S<&`G(aDR7Q9io{V7UD`oZFIOztI5td{ieIZ69W}( zu4ba>-_+o)MBBnUv-Y>N1DiEoLU5B*7m49%LC4G__^$ovw#moEQ%bIM?0A!#1ss)A zKaZB-hIlE+P8PVLq`fG)v(V^?RtmvtK6Tw)?VFtYK&|s&x%H}v*jm52^Nh82QmG9C zbxNszk>K?PEp^FK2M=2NFPcBgU>E%sIrjPj4@O;T^LNeO7|ey%Y*Mc>FYZO%T4_-x z1eu~f+i3zedh(64n!`j)OB0qeHBy702U9*^lP~PEu^{X;-ozZQc-UN9841W!?f!et zekrTE__LpONAJHhTH1 zr-q+XR4{pC)>`Lb(mdc#&ip`TYeK+3LGEp`p9$WV)${jL(T0eI>>l~AcG_QjCwNW1 z#5tF;s^h;YT8TIeRY?3cPaSxf;JA)=Ol|hqQYisZB!aix6 zX&ZJMwD&ZX=j%*1I9-S7vDfUO)3P;xXzSP)8tF=E&R3gb8o4^}b&SlMT^=8x$ZMZ& zJA5J(eVbVED~36v`B(1QpnQFDL2OW;iT|z{u_26ZP+wgT>#`3qn$A1Bbf&O6>kyTM zAh~TxnVF-)Uj~jPqThP;j@TOB_^u?;dvv=iEs{U6PbsRyV?*Y=ZYIC zt>bibZ>B57@~=@Qp#{09#UWRAm)EW0R%YL~)AhLskhZ4m{N@&&Wz5NI*x32R_=r2n z<@VORd;M!9AdV;IDgZT~Rh zO-wSW&rysDIGrd9%QqhojG$>qApW^kQSDUL>n3L&;7~=DB8}+$+7*Q9SS7 z!upM!&>b{^LGlbxCd(NPU!61CxOr=N7_h|hy)lc(2bX$Xqe$4YQ~bPIO&!`qC%?)5 zgqeDo(r6KKzVq46;OO2JJ+xwvC12+>Q`}SU`ASPl*S9}Hf>3x)B-|=OxD7|~UeDL} z=IM>yh-eM)qPpzK-r zAZm3!QS_aiVg?n4ZwM__+-udSj2f4qtb7 ziT){lKC?FqN*FlC0G7PgHLx$;@jjxg?GCv&!IR}P1f1G_ah#QE%m+ctwBn2)#i_UK zC^KvZPyXQ(Mjc}{;JZ5vXMgF@pmG&MGl1~?xo?xQoYZt2c^+HSS z%M82Xgb}XnXW@9AQkvhzp3s8DZd** z4!nDXHA^iA*r9CTj%AXFdT%tlFwdd%``3DRBU?UOamQS!L1H!K9-Wa(=g>4$@HMQ_ zt!ycn;cg@VxD48tXX+VyW>#2Wk)+wxUt-?f%;flnSL!bN(ZeJRH-aEDN3lOqqYIXI zsN4J_eD`CB3uM((-nNl>@9fKdoWs?w4OqW@M8~ss>3bUIf?oZWPVyz@VBNgFps3R0 z>5oK16Xahp#UysgK3!;Z{wAbkEdJoR>Xk3H z6Va@aRTZJSm=C7fMkObJ8#W0>ThR_f66i8=ACAjj>80VT zKoUvvMdmp?Kv#E%FLTzlvPaY@l)_yp9tGf^Z8Tyh$WXgL@JwZLOj9qWJrd5_r4*kn zUKx)R$O7OdjH{Z?^E8p zD_{AogDdp!Mu-XfZjv9RbjUQdFyDI3=p; z(nT_qDYd-L*v0qXp3xb5{KWr$rgDrVkR)4~I$$1Q)hMx7kYbQ6kCM3wxUU7F`6!L+ z*JT5ikgRTcQJWGqC(Dl3poDoqp)LV^OFFowK^WdM31O-z86&v7?Lah4y$gR`LpU)i zRh=vdHHT1YluUijNir*{gBJerzYf{-7vCk&L5s-FhL8V^f+GBg<1Pw!@ZkUaQicb; z$3Z`3@cMTTfmZ)9*#i9DpF+#b{2wT+!5>M-;WoJgvih%2N;T2mJA@~fWruJ6&9?hr zs9p@h=Z=xeOfC||Ww!rsBv_dg3Z^Rs{iLZZ2Xpj~g-F2@hZr9JknDf$8tT6gDpwLo zOi^75s}o3DZs?CCd(t{TFYOs#manydxP|kpH=F8NhMZo&)U94+k^-KX=0F z)r2H!0NDcYNBMs-PVn`CJ4$g{iyS(2Bo?_PAasL^^}j8L!&4fbFkZ3KFFB0DU)r}g zgqN0OhxY%AH~gQw{I4$Ucaa0hBEan&vV{M+O7OS#Y4|&Zge*IJ{1*+Tp0nK~b)o#P zFG)SC?+**z)D&!d3UDCk-;ZvCu=eyJ7esP_ zKmVVv{C_a;_!oB@Lun0A4H}C?AsNe){}*;aLv`p0CS5y{4r^F0cxG~>53St)`xk-B z{>2GT__F&iG3B47ntC?(27GJ9FUt-e|C{$Q)u8`R#|dscXrAvY7BP-nxzJ>(+K4U$ zdK4L}`S+LS-2emLuzHLIu7F~2${R+u1(D6HB_QQZ)hxHEY!mDK#in!8yMR>b z86HASScp;{$Z;CS9P4-8s`j>Kx219(Nyv(9~0A_6Wlfk=**5 zj)*pD?UL(;2n|BSBjX{6R;lk{F`R#-PqQ#!Tcqk(w`oyg8NpjrbIHi#=Oe;dSbuG> z!BS5d`z#U=DQvvU+ZYremnMu-22kwWeh3I13COtPE%=Q05Q)Q}dke&;LLS&ie?5X^ zP|81Zvy*wss>*-Gi2n)XguW#yBf8)>pvVMW<@et%sg#J6I{j*fRiMGznpa1jx_Z#5 z>EJg9S_BZAnhWa+y1Ee_q zK>vDq+Y8<(k`I{y$ZM&>Yda_>|RW9Fa48fo0a4~BI;-YO5i3ljD^-gQ!Vmi zea7B=DejYF!BlGLiqXn|Oidysk**%BDiB;GV9@)T>e8PB^|+=n!0;W{feq_K&GMk;}_+lc5HiL*YzCRNj)IB@o* z;WLC-)4oKd`kweF-&{oYMT<*!?YjCX%vJJy?fS_0?RHqNbv}Loy$l3kU0I1kn*-M` z=hHPuGrepFax#Y~44JT^E}P7Mxplc!+b+`uNEbaaNpr}XPswlSIW?cQ%y{ikm0R)s zJ?sXl6gIEFZx2S#2pPSkr(8-|kLZmnDqeKKZZL9xaHCXmt)D9eW_$SGF3Us)h0uG- z{8J2H*>pbZl_kKRr;rEX)RA?K&_DRP_>2veVPMsi z*GK*RopQ_CednF0QiCa#5kyx4&Hl4(a2PJd3`8L!WL_xyVe#55zYe-zelV{H{uyYN z!3!zqj4k|Zj8wURFvk-(+G~hToM4fdTLC$zV+)ys5fF(q?Nk?QiM~bsdF@-uurtJw zo#ADRE7jflo-L&V{n_{xD^LcnE(SeCjX1Sj$UbGD^#*wLKRXGaM}zpESLQJ;OJBI@ zU*6v8dReD!MQwlU*Xz?kHsaqzMikmc{`z4ZIbRP@!6&x1Xn4;JDF9jakHf-esCc|cj$ z=;1c$tNf>^UCs+uXQZUBGeS0y)o=(| z4Y>s%^=|Hfg3vZOoZ!E=83|g_Vl=E5;vK8EkGhcHkL)fpb)rJ)Pgs1f_^bY=nNgwS z=0N0i^qMQ}TXGjhxuhLbd`T=m35O~qE8ksFnaF*&s;R6UmV%M?1IY}L=*y9vkjsNf z0XQyf^F7DM3x++iww9*e8#v0%qPi`cEsy}#=6y*`7n;_+3%0!wKD9kxEx=dObkaIn zr1u8&Uyo7B$HOVVt!uQ!3pLOOwP8qrPubJ8(WVTV-hGp^0j%Q3(i-BCD1tgrF1PBs zTPc7juu`bGtz{Ah4@7Q1a64Srdh|?^cu9UyNx+6tMfB-z2qFDX-zKnAr`B+ywf#^s z*2ugQdhr%XuDxcwnObV1nf-}oKq(+(cmcP#w3o?VsvdJ9q0TZ0+08`;IbO}GkA%z=HdqClHD;lwEzXx^ zQBY3hgFzsg;(mgWgyEXz7Z(4paB9Kc$Y|>&O%?_yAIo&<(b1du8t04ZxQXnGHjc;4 z&)WT0(%B}KvCXk;DedV-1z1<=jSe{~T7%m4y7gLtluxqfQNdhw-Hsr?uFRP1ixqWa z`Fbg$N=eME&?py9S$0(B`_G(_zn85}sdQUpS9(P-L!md!Dj|nzH|k3 zXl8RVrQQC6(}>Q_Ye8hA(wq1QAyx~)81z_mUoO#BeGRvG3tP9r}e3@ytlzmWRRliC*`-Ywy@d8{Gf+t`ls$`(36MR>VNxrr4u;s@{x4PM zjvPWZ*^4re24M~%URU-f_Ck!C@j*x$=oT(3f-&`$m6D2=hh%g6)HI;_r~iO zsm>wNj$CATZ@cO=$&#~Z+o{@it6puLH0mQYgeAGW2{;lT_EDWl$Ei7`+@=FguDwtlADeV3JdAe+*4*TH4 zVc5e+S~5Ex5O@+Ed>mvW%LvKt2%EX&poUjGI}oQbKC$^r)GoE~R(2KNwnw9Iw_tp& zRi$@VtYJCv@n<6Wiq?Rb>oAHdWKV$T5{bJ&9x@zmx(NHFwTF8+m-4jj@R5K&;j1Jj zfW;D@5B!RifKX2qmNgxcI(Onz#s*>ofm-OGjHveAfU*)}04TbAVsXy^S=H!1II9OS z$Or}ylD-nNQfJE^pe7;1@l+0U5`wUN+IZGc*s`?aoRO(8sp7)Fm+yGYI8r|wGUvl3;Obuk$ zFbk8)@B-cKh|hcMyP{M;QUU0P_GMPV30JuKcU}xAOkA*SjR+!IR21QZIxc#x^!vL9 z?&E-Ub|!#Dej^xb_&V}Xn?}CaVHgVHA1~Q4SPpS=4I5YgbSkl_!d7q+19aPs=oNJ< znF15i3`t-TRC0p0{0ppJ7zkfVN`pJ^_lC(*YY|*o`&?ZLmgYEU$i`K~y6uPgdU!t_ z`TIBA(~f22U%M8CT4>=dx}|62sNf}iU32B5#}bLIpR+ua8K*RQ_=w4gLaWHF?EP-L&nKk`H>QSU3aD`X7siS zUtBxD^d%qTxlksDSAXiM003(w3*HeLw0jT9dqq#%M0&A_rZPx;Z{wtGHR6?2esn~< zA!G$q(InD4KdG|8-KF4_fq8!y&3~U!{hCixK>L zBoNks1&hAhrCStFn!38#cMNrm$*x!y>rgonq0*fQCVvF(LOd*MGg~YI;z~qtIojbO zIUm8NN@#BcsoMnTXAVOzMr**_sE?uLRIpSXOl#J2HL(j+dkkUH?=Ipyu3N*iRgf(+ zU>3=jm3W5gAS|GC%-(M3=-$b!5H2nJF#7H*zk!`9_#g8;Wm&K8$KQcRQ-Y6bNI0o; zhPJcoh>ST;u(X=QViO+nb~fV47yS^UZhUE$s;&Ki2u8*fBpk0TSTZT+ZoPVfmNI9nE27a4Y?N1$cxXe{J8hrr9+lH6EWj=$H=8W+c#j2H1EafVlT9c zPQD@FNKz#M$XOX2()md}b2AA7B~cfpSo#SN^UnN>v51!9C-WC;7CsVmTXg(^!#X-2 zzf-!unX-Qqp{LAh-vOBtzuq+=3s{t7=?Mi~ zZ(WEsgoU)c3d}Bfno0`Q!4D~=Big=v_zHmKl&{a()0fPVV0HXrv5eE)sny<)2<5nl z-L*jhwrdW+%%-$bwzNyGW*!7M*i8KVnG!!w!kf#Fk+XWFR(xkJSsUfAo_&U}u^pn! z4#o<+>(8V6V6xjf@uI9uV3+?@yyXv;X8kL_&95d|AgW8-gAnb?eZ3Cy0qj94>755s zDL_WL5eqAniY=MW@WF?J+KpX~j~}Ox#&_~iXwV5Y{aXCQrVjXJwwkuHWZoowynbfx zNoLMQ{@Hk^euU=g)h)%XyruFz?{C>xEs4T&!PI`I)(SF@&Y|)dJ0z(aB=3zaMekn^ z@pW#ObRVHaidUeVK+EaE#FLV7s9QK+h7xNBJ2t+4f1HX_NOTvFsv6{g(Jq91?SUJY zg(Ok(py-gm#bL(s=#)F^K9kMsi%VYxQeHZTeJ#a$r4N_ePF#hf2mb-13e@JZovN=s22&73*D! zoSsAqCsM}6h4v~=${OF=jn170s;-8GMBYtjVE2@F(afaQ)fCDcdUh_?1CgAtCN4Vj za4tkHfRgd&Yoo-tC1Ep1GrbE$_xQs4y{(ns&(-P5{nQKg>1|2<{#;JEu;y}vCYU6L z;qu)m!24@gzRQlq8#p8YUL4Il8?Vnf4C71~dBJ_BS@wRIE2^3`j9_0)$rR2LH(h#| zWZ({dPVLP#p`yoL;6i30WP1vB&X=F2s}C}i&okIA&H<;`^cLY+PUESLfAww;sR@eY zuR0H4%5yW84~iP@?ftq%7GANabwrU;;&`5Rp0Pn#9zKr#0xxJ;Ex-=aJ*`I-vZ#0XDe@j z?x|6|=n!ShG=WVVsNrY^0K#j-0L3Kz$_eXtwdZgU)kUKsryHj4(^f@npS1s=F0m*t z6)T-l1NxHZ$!)v$t?~PV`st)fn;uY}AWinte0^&`+&Tb|k~8kYZK zB$)LlV$W_w+B9J06w?%NSUipd|Lm28ACfZ-94gQ1jjf)!UTM_>{Mx*m%5Ndq1w01f z74n#kLZ7M3mrG)SB^IW3dU_|^Xn*Qz@AB1cj8~o%#0Hv+d23^pR37wE3pPD?hNezW zEY9CZj^X)$<|0Xb4mrZgR?cXu80ZAOf!1q?OAtNfl&ZQ*r!%U9wE{lS;i?e<<^VEG z0uq+!{{@9C-wsI{17OVMNysNu`3mj)3ge2oF`4Y`-~}8c(w31%g{ukck9ak8RMGr# z)T1S<17W=5b&o4jjKG_Y<=tb~npq@~;YNz&q_x#w6%-ohQj*$+)0OEz&r9#_bjTr7yG|M@in&sB-?J;pl)Xw2(c z3mdY)#rNr3#o~}^{EfA!QDVTJP+J_7%)B-%_-0vGzQ?RyRwW{t$H+}{n%wmZ=GFmJ zh?KAH!76GGG^E%KTSk+x`EC3h?0e-?78MMBZ#0> zX|@2=+hT%A4}xARe-nFx=9F`e%IHCKw0Z_c>|3CBNO{*J64#}O zYGmOE?R2`3z(_%n02%TOd7#i#jrij3sh&XEP77}Y(jtg32^jQnVQpUzQXoa{)%0Qo zJMNA!aL?+5nN@{XcZgEWPcSn;CZ>?cf5smoFsuNmdwK7J1f9ucEKm9IgA{&Pup-S% zG;fTxO_SL^0!Sj)+~((w>}??HV^w;;q+^1EAJrAN9GdN zO+#W@SyNBN<{J~zWI0eT0+IQc;$qvpAqBYS>#`>Sp!%D3pxo0w#$QRunKkS(6XUL- z4)J{~_o8*ClG-q(Y)SLIQkRd=6$y=u+qHW3O<@>MhAyP$fO#+JVao+k)R1ZL2{<%W zl%fl=t1zrUy7FY~&|~z`Up04dIH!7Z-v+dRZ8*CIFCQvN4ScNKmDM7DNuaZ&ec-S9 zupXc9d%redOK)%_6eX8!tYZ=;$QOSpEMOjR*$u>Ju4Z99nYQcx(#Y+m_zvgpU20Ks)E(>UU|kvxje?_nrLLFO2)W&%7x8&kFQaAhXJ$Gm7RA{QSs*BKgYnhsT718Z4xm zH;kN2%*Sr>Eq}WVeoa6OX#D|x5d@+% zdEx9kE@F-mIzqXVJvfU_(9e`9plRit#(ll|jNCJ!7E8Q{m!3lfAJ;rLzGYD~r)!}u zz3Wm10HGVS`}v$*LS3)f?rwVQpb5$K}?LX;U1Z-%`e;$yP$k-n?s6RW|jue!Fuu*a`x zQEGjliQVMV8y^yn&&ioIZ3|zoMelG{#EfMuRYr_m$TCsdI7O?aNlW+kW@gV4jFZZ7 z{t8p1meiS@l|#KI+x&+7ka3*OFHWn-h-w4JS`n)GuwsFr_tyxnn0sJvi{W53dyX|D z*e`#^jMUR#t^hF{%C`~xPDsur_+Ep(xV-)YvfG{6B+k4Y9$Qj}n#E>UqKZToZ(#+e z@3dA5&)TgSAlzRLDIz6~X6pM*Vxc8jKY{)j&L#{Xzyis>6YF+3)cfI$A(D=se-tQ} z(6^MNjYy#bD6CAXt_!RF`|JLqLy?5VUk&B)P`oKoPKPKi-M82%F&$0qTS%=(ei4AA zq715$w}f zF9*Fqr;krIp^`k>ivWsN5-#Ue=kNuUpt0#6myiMthe{m9pRff!sb$TC(~bO`A<-Qo zb(U#!SF&OdcHUm3qFuTwLJ^h1!ZCJ}JLyH={)}499s+L5RTwTJz5$}(Lam0cF?n$^ zI+4pIa`ljH`1VpstnbC5!9EI1-X1{7&wO8p!`E#M*=VDau7i?*1X3|YUb4X9@YFMu z19G+76-_5qeixsm{LOV^isu}a(pj|-GEGk!@?jtejsyPtyO9Pm?P=4(LG_4|Iqb9C zItB3WGqD`)!6_W(Hikx}^FTdZ;rJD!(NA%CeJy*+GNmm%`M*WRb@lH)GOTR=&hy-z z>vzgEC$l}fPqrrmb!yZw@vFiYx$-8)E2E`l>`Dl9m7MR3+FfhrEt5Sh_JSJ^z`Feq zqKP58>Vyp;x#^b_=%&l=`tF?9Vyv4=_H5MOnx&`3?LuML*SOH(A5h)b^;C&9p*~Xl z5p3>4PBb3Q<5Hwr#oEc=#}&+fd`WE^te`=i_K=&>COx|79aR-goB>AA1j$QCF~`;y zb-!nIP|o{j8SQH}T!}uC-g-H&VSM+LeQxQ<WGH6N;I?RCC5*R zCZ$oQFK6{9>f&vTT{;yAnd|Z*FV{@-6g*DdRSNMh$-0M6_~bo_sK(g{QX|F|=U(dP z8n{hvhIJ(i!Tgp#%&R5OK+6G4Z>w*GAmAqiLb37GC+R(>Dj*rlGoAE{jLrT`v~F?n z<8`+l#IOtQeeM`!7tEthKYI;p!(^`l|Mam9%Spy8WG3Go+~C!yV`l%=s_{sG8WK)P z)_%16T}knuQZZ?n9Nugom(s9P6=g4?d(LmG(=LBlgY4)FJu>DJV-x(c)Jlikrlb?- z-Wi}Rmro%oBuOWdM^~UjLXSI3=!~>eb@dicgrFa$@kzBMaOR=Xk1azGZJqJ$J>KZW zWxUVu`(#{-rX=%AZ{EEz>c9s+qrx`eh22Dokg!5Oj_MR-q_HSmT#Tp<5a8AS#vjCqC3L;mfn*9GX(oUT7NM>twyLDgTO|M2%uQ zY`UJo4GNrh*o*q;=IVvciUeg>NR99Ya}4mBCsiQqRWI`NsY_??Me=;}us7>ar}!9F zHl;Y=@6FY_7P-pCMLmzpA&UyA=%g0PTQxgT4`=r9dWV$9C7Fl>MMzPHofo$mbFbT3 z9OnGzFbT`sxIQ=Ry{8HQM!GLm1B#ddpY%we<|1vJeCZC<(0*Hw7 z*7jO?ebO4#2})f117P&?3;{vwuA`R^UHJH#;nc~WWjy&8QbrljOaG|L`n=yALvz-m zR!{$0jU63)O$^x>2`6SNVuQIh3?MHo2RzF;Hru-HsQpJl5G#O=nmA=f>iS-O3@hLh zwf^^wbK4J1``KP`vQ#=`G=o}xkGjXY}+- zRoF2c`foU8Y~#@>Y03h|=~h2uQwxivrLm4ox%!c^*EM|^W`3@oLr0a3dF(i)cwYkE zmsMi^DNCeRKV6US1IP8sjhLBS)$)Y5hC6K@QZ|PJ7q``$X<>Uhks_W;<)q;;JT^SSE{uP%B6AkF;BUwyGW zfU+qy)&}#e0Mgxoubi^^&GMo6UxcnBDiBhu_{X}WlXVLb`*FZ4H+>m;0*o3z>e8g- z>#GP2WT)RIM(`HiK){Ee8duKr*M?{tj1+-AHm4)1rIkCy=UqjX5T>xOY{14EkiktD zUOB%LoB=brJz_kR=K9}2?(WHtA4VtI>RfcEE%L3QPdi*wKJFPVQ)v9!L3>i<{WJVK zDO22&_a`NgO%VJa$hQe@h>?l>ho%s%1LQ+IV7Q4n8>cZQ@&ch7ra(b>*0NkcAfIf= zhkvpDj-Swj# z7pGl>h5%OTCDta_aDqNi-KUQ8M)-1tH0B1ulgv=alruD_DKP+Z5;1x=tZ`h)qb<%1 z?e;#D;Gwq}cG7*&3j1_Aa1cr_;~LjmEX&F{XRG%2wwJe(Fv3@=EKDT&ggm%-=Eg7A z!O?+QgQH>qx+G@L=1KpO>?nO$fhBv46a-{#jr_ei)Q(7CC;q6{6jgQE;v)mB z{G{}_;09{)Rt&X#ocgV`SstDoGox|_{v|kBQQZIfp%vz>OjvL=II36Y0Df(`50@mJZN6)HE>L7Y|5dCno93M)b*@Fr{=LR_Gzff z_AYFR_#hxOb(Nr4P?v1A>RQLo@s|AbW^;rBLAowsZzUGRn1;sM*?W`+hQX#<0lh z*Bn{g={vSy6W(sQQ-iJ=-;A1W!%B0Je)mY`Du}%K5rJitB<3s)*A!mc44qSR@+$0=-TJ zS6Qwl59VBBzUpAeT7{vl$K>_elt%kHMa-nz@L`K*9tC#pF%xsGemI=bh%6Qy$e1}C zs2RsFD&1Md%;980*sdLspUH`e*&h0~Zmit{wUFssA|u?w`F1J&Pk@z@=-8S@90Hdsy_S7p?|t~7>swJH(^+IDSmH)xVhTCIxf0~zV}tw6h~LL26%~dprMG|VBsN)A zUM-Rvy0Rx&3?yOY+6^v;zR$a{D3Q9yWR9>DNZYT0)QD-5e z?Ql=ti>O^qU;31EFmMHiq1KxqvP;u`N4vWx|4Dw1b_GG^8NjJjICa2K^9~I3iM4?o znVHyWo}XAo7C%h;T{6ejpzfS=(HtC_wEZci+vAma+B-cbZLc-YFmTv$wfn1c0;Zz_ z9E8bJ^mg+1a8wjmYq7kQS&O+B$2OHCv|7R3&JN z(2?9NC>8bF*%%^ac^<%YheiNvz;z>fx(ushiE$Gd$YM!(uRkc1CDmt3hz_sUtUb+P z>i_Wv`jgq|K##iV+TQ5U2B&>47aVt<$}h>@(RJOS^$L^4fu57=XC3H^?)xWaN8}X7 ztdiLJvME-a&UV`!LdiIS%4_-rSJKSbeQReH%hBz6cROd}xYHBE{5e4%5VxTOh*HPO z7vm7aM8we;QClN&7{ZFC(GI+YQ> zQ8&|?8t*l}h~zawW^OBpjh?t(^yAly{iuV=YtttLl1W77F`OPjs>$qBHFI?ysOVYVpwh`-c>9VF|bYL!6IptoKzi&V`iX3@Kc3^IFaDc;(E>KSL z$88faAE-#eiv=8*dIFsW5d#}Z42Td4(M0K{!x`aL->-*Xpl|LMsS3yOxYZCYZSejoopbTv&}dYmhV_et3w zKmnld#syURo96QVuqE@pSbf6vMKHDBd4GhJ(4N~v$E?-QrQwK=W<-f0B5G&@6mPy5 zq_M38!58QfkB$j)7-b6%P$wRG!VpGn>#gt#la0Pnb28rY~V~OvDq}qDrw~IW0o%D{B@sN z6uZdvtQKe1l!W;vR}AIqDQbdmbi<{O4bw7pSc=1&2)Cy*@mb8Obz5}i)Gk;}4u8TI zRILaHykhcSp8d^FrFxB=)?{v}47_-Zt7e1%eU&D4Y9`)28I8k%&o%4v1b}Vj#tJ zBee-Gf8Rd-LoFyJ-7`a?sDHBE8^PAY;4&0p|To2})E$h3Md}mbCr22jieweVL>!C2d4+7lN5) z$l(DBH44)7TFE@UnG=u0iurhUphSDV*E_Pq768DF zg92tKOXx;a(8eq*hx%+0JxW2rD8!>QsL6vREsbyBIkA3!4|HHemfQJZuN$U|ku}}f z!|J$VMiguxs6T(ebt7tW7v#{3YqxlLPMdc*am}2#!kN6jai?_N+lMucvG`8CK=O9G z&!5XvP*7|)04uC}e~-AIgtC9{ z>wGKU(7OBBAKH{Y9|6`2ABh$^RECUOsW{#sYcyywnY z6De4noyyCqv=ikeYbrsH3A@589J%i4Za+-hS;aKh*ve3Fa=bJq2$l_qeR-Ok^tO$EVkbH?wgVhS;-tgVT=!R^|WF z{~Vo^TCW_UGd%sG`?*Jzq_&46IQ-OVKb)zh4K%Cm6Zg}rxuV(m<6>(S5!G>YCm)UCW5)(V zHPWtxekx}um$o()V~$Sd_oV5g1^6uV1y1HERRz;*aM`a-pNP)k&ij7wn-xHh$N*)p zTJM8qi0ZITg#wE9gOB!KMO%AZu^@In{cwGDyIz5MUzBxq4=07+N~h8?HXL)qO$3gg zXF}-)-~I@8y`D3u0ZltodS8i}fi_=qw?I*$f{`}5RNlbtmcGNE2eha$Nx%wLBu-CQ z$OkdU?7`;nG$~-y*EH%pDW_<*xNQ|)aP`Y&%8J)L#-AF(`|3I)8q|)F$c12ibB{!g z`5<*Ih=PGQ^WHsWjO`}cQwkmQoH9`&3kQM;lxb!P0Ii$?)y;G`n}+!;!V4v3;KLi?8XgpGoXyB(H9P;N7RCNH#h4#t!+b5@xEnXBE zyE;!-L@z3Si~J7-k_sYQuV!i|=UMO@zKmoSjE{xGa3 zNcfWx)G-@Di(_=(Uwk0MycL;W);`2BF0`djAaoK2VGUNaCKq+sT~-__{QUY!-{?eU z?8ivCT~?5LIEDNIf634S-PTLrnmby0a#zIt-aaiMvZmUb+E;qfEv%?F;6?u-&5y&d zW=i=8;WAZZFZ+IN-|d%$lb@BlA;4BBmVOtv_LkMDwedy8i`9Ozd478HMNhGCwY(G! z+P>pm$A(kSl^Py?TU7?d+{Je(gjfVt8k;Wp@tU^?)&pq0w{cOk!}q$YRF@u-qNczw zc1sh8w-4+I7bg`ODy;ofnZIy~taS_)nf5@*=hri2dJ&nJ?;#nw6S?8{dLkqne_xq? z74snaK-%X+8mw>ri*nbuV^G|hy#z`v>2LqAThi81vTEtpBjolhbn^|WcIDrbH2 zM?77t57X0{uiR3~T(3>xdloHVKt$*p2mcy~^IdDlSp`0f!m_H#Dr1MsmMJg)wtnH1 zcyy?0d>4WchbNJ0jv%hLhb;$EDFOj7uvn6@!ULezv2I<}%64h<$dj%XXW4wp)(%&8 z=Odl-o(q_~NoMt^2Q}QTVsY{*yZYl0cXF0Z_isf$fK5(X$YCSEDK{-SboG4xG;SG{ zsg^yCT~UhObr!)BP`mF7YIIto-I5bNcE{U~IyT(su;(fzUN;%4__(EZe`Ez_YuaJk z9B}r~!C*;3rvzSL!pzLN;(RA19Y`Z;0RTKV&kooGiqg(s7g8;)jw2dH&StZ2@yZIo zCBH4xv;h^8k;?Arb*`8@L1aiW7YH>zGBf+T%G0()FIL-KKyR}@yU#ctlK0XKtzo;# z7LKs_r{une=lfRrHWjGqq-CY-o@z>;;djJT)B9_ae&rndSRWuaUhHP!Ic2JD);hDt zJ!oab!|;g;f^~9cbRO4mVY8lEO*Bo6bDG}yXm!oiv@H`Y_OguXUF^ZylFKN3G7Um6 z)(94rp}hVA%bshkDRE<87{Q+b%J}AD(}UR9(g%@7$+m?#cbX zQEg-^S>?$d)uf&K)&;Isd-3!4BN_J%J=U;|Eo2$vt6SC5x1 zoQ_z<7R^J)dn>x3M)@U`S49u^kBlxI^Elo+8Xxp};`Nz>VgxS$09w5INBovpbaJi2 z;95$NWdxu0C-Vo7t51Z{xg&AaOLb2gI6paX?+BZ)9PMVszUO0wp%IW4&H2{+*t*yK zHw`wL<))-`UFvT5>9dhVu!4NjXoNsEncI-o^)w`+E2gCvc7f~29jW(*pbfm`H4h=A zuXEf!cIU8m+HA0|_q=f3mm8uI&na)Z^}IQaU=4gOHX`_!Q?5FHHklnZ0n74sziqK< zTbQwzx`V#33u?qCu8~!p1vBLz^720vjkma$8g_&3()pE+Ti1M8{NU5suvo9M_<|!& z+cgTSb@`deHMvk2HMzT`Rqog116JGFVlDGK4#!y61iJ#t@za#z@$v4hpYB4rD;qb^ zCMH#d7teJ(QRHr4Te>B!M@gM=E@>Dt*BqlaN#>1^7w+PRgT|RR0^H7rgxYrQ>V>6A zv>$-O-U!0S|`%C~RGXDpXLQ zqD_klg3KWz2HqYnoss$_`U#G=Df_DPdp#BTSbA*BFziEeu<%nX&nT?vlAg@nv-h=b z9u2a{&pO*(wL4v*hV^CHyiDUt?dLnG`JWZHx_ky={Y9iYkf{==|LG6HR(Eo=%n-n} zY47`9a?*ZFpB&Z$wobpY-Oi?)@6tj)1_Ht7-QY%EqG)itJwL&6UK=L&b0)@?`$C|6hFbyC6gg-ahRo;ez8z<6!& z3UdC#16`Mx=220t5?ssr+YOt&Nd0J30xgv!jJDsV{IW+*#QI=8AGm05wv_@-$L7I~ z(3=Ir<8kg&>W<^mH)x^z+nzv7zSJ5S$Gjc9%%W{kcr(t zz@Y#l3`){(ju8ji18nv?2@xb72)YJ+rc0;2y5fhP)ZH}6Scg1&R@UPk45a7YK6Y4^ zk?A}DoQk>*oLo(?jX5bE>9eY)gmxygc^ou7R*%VCrM2u={E0ndQLdo%Fxhrf4X-VM zcbJzy#5C;zq*s#54}joc08L|P4~>!)tKA-!rS%#=b59c6}M1 z!thO$Z!mXN&yF{Ig)1HA_XFefupv=lE{#%1r?IvUyb;X?sRusnoDuI5YMjJvksWHF z6^MVRQiQk#DEZA!@1W>zg#c=j1|nnB&+FX%02ZU~B+B76WzWfyKd$5Kwyc9K;EDK~#Mi zSWcx9UjcqX_%Pc=^DSy$fZ&7MzRWIM4%%v)WpS2aB5U|wfZU25R>1bE_pY`mQSiyP z%TUN^Tgr@=l8pJ*!OS?-nOJVpV676qFES!tW(VvU9Q`eRIAWnw2?|Wv2*$1g=*&ZK#ONGTt*Ho(-@khpM7Yw{7#-Ne zwN~0NC$Pwiw-DM7=DSZHz6T}Txb60v0kl%9P?)#g_)f9fBdF~2$}~<_l3^ACtqG^ zUBP_5zjp|c??9@;Vj<9-e?Mbl8L#NjnP&{!0}c7`{2(8aoo`In0WTh~gj~bLh3TbHPGvwL)Df4n(+t8~WfRoE z9rkU{_tK{!NClCJUwA3NE7oG_THH%#8%+c2uTrF;`$2;SxW$qlPPOFxxaa-H=|F<@ujH`PVN;&` zqg{B5Z?Eo#-E^lVH4S;`U9^$j$z^(;&nlC{k@6wq?Fcw^l%TtTFzug1=wEA{PdEHo z1@Fc;t=c!f+q!*x!^6pXKH&Yc5fEK5Ul_tA1T4mXf&>3-y{UDJzT(k~9%p1kBNj11 z%Dm$x zk-AL49i;Cv_KS_p3=x$~0};3pq(Wcf$XA^(v5fB8W*UUkqNOKjvJ-@w!ep|}es=>! z3&y-U%a3{i4xvtzbq98Uoplc(R{_e@TvG%e$?%nlq)E)LUl zRB8T#uzweREGV+SEXw&cPvmv!BVLka)Y-_O>1U6pKfV}Jin=&1Pn-nN1g=Z~+_NuZ z-rz=7<~gSLF#Q~^Uhl@(=THec#WMMT@n8$ow}o{Onl9|g5tD?)W-umOyRY3*WG0s7 z814{*>}b4L7?`|^o|uyp%L+FnSi?wZF54w7x&bQhBarRgGzeUu6YIU$4u!DgJ=VJ5 zM-DqeP#0u;jc@6(Ibl6tOqAdw5IZmz1r`zEu@Ni>^C7`c}MUcKwaeGX}0)jgO1H&>E3T!{% zCF<0_Z>swNMi;q0x1YnZPYygpL^&;4LwS8vzfo~BEWomn{snYwQU{l9ckGdEwC!56 z2Wf%M79LeCJt-kopk$c?gab`S`0WniX}qz5teU%xX<#Jx+HN{S^r!uU4{4&6N}jiC z=C8>HPR}d8H^E(j+uX%w;$kjGm=yDs_qT#f#AAK`H&6Mng};u94DPUCt7w7|y7K+- z<>%R0C&8G17Y0R$q}%=|ouuj(tLyI94a((SrQ6LbhY6U27^T8H?M$SZA)WeZ2NqG< zAqn1u`lUW)suwPwPM_-zOS0dKW69zBm#Az>(S?NF+gJgJWEml_!rur&KXJB_!c}Cu>NtfoDR!=w4_AxgJ_CA?7bM+xD*5p3NM?+b-ZR^Mk^~Et zJqTwO8$iaNEWqDzI&+3ULzz>?eUZUTsuo^}6$IOaxP#}gSjbiQ1X1N3tK?#C+7(Do zIS54v;UVm6_=h!O<~F~Xd8T@;un!a=`jJEi_OGU4&6%>Z@$8o`Kd&af{xQ3a!V*;u z(-o@I3R)GFO?#s08f+AI#%4H4I!WP+ys0g6B0WG({QD%0V5QGl32mzrFa%5Hg%iXG zk{d!yX}__eiBEvLKC%kLT(}QV8-~xtVEmq>X6;-PApmV#QwE4@VKcl-R9$@+DiA$;{|{j*mPH1^q&PmB70ur+RttupvQ*=fN;~OU;oG2+NCfvRlpS^XLOQ0L1+J! zVz^$tzP&SmI-7u}>Hq>5q?RusRmzz}I%^a719VK{eo&_qMX+G?!pCupLa>H#+n5eF zaVJr8M{DJq04n7IfM^8cBcbx5`>Dw=7q}tf9R;#+gdZ&Iwp;fPT5#V{-cuU~RMwW$koXzyX`XMIC72JQ zB)jZa(=NoB7>Wp`=G2f`dJ>}V6QK^NhMKD@E`lfe|M36aGjwq0}7?sziNn_aY({)w)Cl;YuJ>0kjxAgZy0^hH4(n zckZ75P%sh@yX9%n(0o%>5U-H@@?<%YiUMAu&%!}6ML7RIucne$XMpGu*Hm4KN)S=M zfYacQRF67i1-B=3*yI&jkC!D73|a(M*JVC}KuZP~4QG-NBhfae*yH zU`c--O}K>lSNhN~!Wm1h1TQA?^qjx>tHhItLGuZ5)_1T6hez@Jrv=;~T%sww>siPf zW!IQ=HxPU!Q&sTj0=O!W0w4Js#jg?OTj44cVkHRn&B)UfK&Zz<m z14T4gP1!@V&=QO)Bo*fL!FD-f;UCkH63fey27V|4m4QbM?t{6=160dqkF#OYwv|NN)38M`HB z?}N77SCC>LSljVTvH&EM&5#n^1}5oz!sexx;GKGKen`u;38i4teUpG0iLPe&L5H~+ zuFXBb4khm`wLi5ip6M@l|v@ z2?cz(H)PkA8NxRL+{~46AZHvwHB}{q`jniEmCytUDHpOSxz*%1I-Y0<0fFFcKsPr@ zSUu~s?Mo1a8E6S!4b+}AooVrkR literal 0 HcmV?d00001 diff --git a/Game/Game.vcxproj b/Game/Game.vcxproj index cc6dc90..3c4b186 100644 --- a/Game/Game.vcxproj +++ b/Game/Game.vcxproj @@ -109,7 +109,7 @@ nf.res;%(AdditionalDependencies) - cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && copy "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\" + cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && move "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\" @@ -135,7 +135,7 @@ nf.res;%(AdditionalDependencies) - cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && copy "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\" + cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && move "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\" @@ -157,7 +157,7 @@ nf.res;%(AdditionalDependencies) - cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && copy "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\" + cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && move "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\" @@ -183,7 +183,7 @@ nf.res;%(AdditionalDependencies) - cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && copy "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\" + cd "$(SolutionDir)NFPackCreator\bin\AssetBuild" && "$(SolutionDir)NFPackCreator\bin\Win32$(Configuration)\NFPackCreator.exe" && del "$(OutDir)assets\" /Q /S && move "$(SolutionDir)NFPackCreator\bin\AssetBuild\*.nfpack" "$(OutDir)assets\" @@ -203,7 +203,7 @@ - <_delete Include="$(OutDir)**\*"/> + <_delete Include="$(OutDir)**\*" /> diff --git a/NFPackCreator/NFPackCreator.vcxproj.user b/NFPackCreator/NFPackCreator.vcxproj.user index 5e75a14..67e52a5 100644 --- a/NFPackCreator/NFPackCreator.vcxproj.user +++ b/NFPackCreator/NFPackCreator.vcxproj.user @@ -6,7 +6,6 @@ $(OutDir) WindowsLocalDebugger - -h $(OutDir) diff --git a/NFPackCreator/src/main.cpp b/NFPackCreator/src/main.cpp index ebbed33..7a27b3e 100644 --- a/NFPackCreator/src/main.cpp +++ b/NFPackCreator/src/main.cpp @@ -33,7 +33,7 @@ void Success(const std::string& in) { std::string readFile(const std::string& filename) { std::ifstream in; - in.open(filename); + in.open(filename, std::ios::binary); if (!in) Error("File \"" + (std::string)filename + (std::string)"\" could not be read!"); std::stringstream ss; @@ -49,13 +49,15 @@ std::string readFile(const std::string& filename) { void writeFile(const std::string& filename, const std::string& in, bool encrypted) { std::ofstream out; - out.open(filename); + out.open(filename, std::ios::binary); if (!out) Error("File \"" + (std::string)filename + (std::string)"\" could not be written!"); std::string write(in); if (encrypted) { - for (unsigned int i = 0; i < write.size(); i++) - write[i] = write[i] + 100; + for (unsigned int i = 0; i < write.size(); i++) { + char temp = write[i] + 100; + write[i] = temp; + } write.insert(0, "NFEF"); } out << write; @@ -82,7 +84,7 @@ int main(int argc, char* argv[]) { continue; std::string filename = currDir.path().filename().string().append(".nfpack"); Log("Creating pack \"" + filename + (std::string)"\""); - std::ifstream in; + std::string currFileContents; std::stringstream out; unsigned int fileCount = 0; for (const auto& curr : std::filesystem::recursive_directory_iterator(currDir)) { @@ -93,15 +95,12 @@ int main(int argc, char* argv[]) { Error("File \"" + relative.string() + (std::string)"\" is not of supported type!"); Log("Current file: " + relative.string()); - in.open(curr.path(), std::ios::binary); - if (!in) - Error("Couldn't open \"" + relative.string() + (std::string)"\"!"); + currFileContents = readFile(curr.path().string()); if (out.rdbuf()->in_avail() != 0) out << "\n"; out << "#NFASSET " + curr.path().filename().string(); out << "\n"; - out << in.rdbuf(); - in.close(); + out << currFileContents; fileCount++; } if (fileCount == 0) { @@ -114,6 +113,8 @@ int main(int argc, char* argv[]) { } if (dirCount > 0) Log("Wrote " + std::to_string(dirCount) + (std::string)" asset pack(s)."); + else + Log("No directories found!"); Log("Done"); std::this_thread::sleep_for(std::chrono::seconds(2)); return 0; diff --git a/NothinFancy/src/Application.cpp b/NothinFancy/src/Application.cpp index ef17049..2c376e5 100644 --- a/NothinFancy/src/Application.cpp +++ b/NothinFancy/src/Application.cpp @@ -144,7 +144,7 @@ namespace nf { RegisterClass(&wclass); } else - Error("Cannot run two NF applications at once!"); + Error("Cannot run multiple NF applications concurrently!"); } RECT Application::getWindowRect() const { diff --git a/NothinFancy/src/Assets.cpp b/NothinFancy/src/Assets.cpp index f7eecba..e8e85b6 100644 --- a/NothinFancy/src/Assets.cpp +++ b/NothinFancy/src/Assets.cpp @@ -1,5 +1,6 @@ #include "Assets.h" +#include "Model.h" #include "Utility.h" namespace nf { @@ -7,14 +8,12 @@ namespace nf { } - AGeometry::~AGeometry() { - delete[] m_vertexBufferData; - delete[] m_indexBufferData; - delete[] m_textureCoordinatesBufferData; + AModel::~AModel() { + delete[] data; } ATexture::~ATexture() { - delete[] m_data; + delete[] data; } AssetPack::AssetPack() { @@ -22,8 +21,59 @@ namespace nf { } void AssetPack::load(const char* packName) { - std::string path = "assets/" + (std::string)packName + ".nfpack"; - std::string contents = readFile(path); + std::string path = "assets/" + (std::string)packName; + std::string packContents = readFile(path); + while (packContents.size()) { + unsigned int startingPos = packContents.find_first_of("#NFASSET ") + 9; + packContents = packContents.substr(9); + unsigned int endAssetNamePos = packContents.find_first_of('\n'); + std::string assetName = packContents.substr(0, endAssetNamePos); + packContents = packContents.substr(endAssetNamePos + 1); + unsigned int extensionPos = assetName.find_first_of('.'); + std::string extension = assetName.substr(extensionPos + 1); + std::string assetContents; + unsigned int nextAssetPos = packContents.find("#NFASSET "); + if (nextAssetPos != std::string::npos) { + assetContents = packContents.substr(0, nextAssetPos - 1); + packContents = packContents.substr(nextAssetPos); + } + else { + assetContents = packContents; + packContents = ""; + } + size_t assetSize = assetContents.size(); + + if (extension == "obj") { + AModel* geometry = new AModel; + geometry->data = new char[assetSize + 1]; + std::memcpy(geometry->data, &assetContents[0], assetSize); + geometry->data[assetSize] = '\0'; + geometry->alreadyLoaded = false; + geometry->loadedModel = nullptr; + m_assets[assetName] = geometry; + continue; + } + if (extension == "png") { + ATexture* texture = new ATexture; + texture->data = new unsigned char[assetSize]; + std::memcpy(texture->data, &assetContents[0], assetSize); + texture->size = assetSize; + m_assets[assetName] = texture; + continue; + } + Error("Invalid asset extention in pack \"" + (std::string)packName + (std::string)"\"!"); + } + } + + Asset* AssetPack::operator[](const char* in) { + if (m_assets.find(in) == m_assets.end()) + Error("Could not find asset \"" + (std::string)in + (std::string)"\" in asset pack!"); + return m_assets[in]; + } + Asset* AssetPack::operator[](std::string& in) { + if (m_assets.find(in) == m_assets.end()) + Error("Could not find asset \"" + in + (std::string)"\" in asset pack!"); + return m_assets[in]; } AssetPack::~AssetPack() { diff --git a/NothinFancy/src/Renderer/Drawable/Entity.cpp b/NothinFancy/src/Renderer/Drawable/Entity.cpp index dedd125..083aaf9 100644 --- a/NothinFancy/src/Renderer/Drawable/Entity.cpp +++ b/NothinFancy/src/Renderer/Drawable/Entity.cpp @@ -1,5 +1,9 @@ #include "Entity.h" +#include + +#include "Utility.h" + namespace nf { Entity::Entity() : m_model(nullptr), @@ -10,25 +14,40 @@ namespace nf { } - void Entity::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const char* textureName) { + void Entity::create(Asset* modelAsset, Asset* textureAsset) { + AModel& model = *(AModel*)modelAsset; + if (model.alreadyLoaded) { + m_model = model.loadedModel; + return; + } + if (!textureAsset) + Error("No texture given to Entity create function on new model load!"); + ATexture& texture = *(ATexture*)textureAsset; + std::string obj = model.data; m_model = new Model; - m_model->create(vertexBufferData, vertexBufferSize, indexBufferData, indexBufferCount, textureCoordinatesBufferData, textureCoordinatesBufferSize, textureName); - //TODO: Replace this with getting the information from the AGeometry and ATexture structs + std::vector vb; + std::vector ib; + size_t ibCount = 0; + std::vector tc; + parseOBJ(obj, vb, ib, ibCount, tc); + m_model->create(&vb[0], vb.size() * sizeof(float), &ib[0], ibCount, &tc[0], tc.size() * sizeof(float), texture.data, texture.size); + model.alreadyLoaded = true; + model.loadedModel = m_model; } - void Entity::setPosition(float x, float y, float z) { + void Entity::setPosition(double x, double y, double z) { m_position = { x, y, z }; } - void Entity::setRotation(float x, float y, float z) { + void Entity::setRotation(double x, double y, double z) { m_rotation = { x, y, z }; } - void Entity::setScale(float x) { + void Entity::setScale(double x) { m_rotation = { x, x, x }; } - void Entity::setScale(float x, float y, float z) { + void Entity::setScale(double x, double y, double z) { m_scale = { x, y, z }; } @@ -45,9 +64,9 @@ namespace nf { void Entity::setModelMatrix(Shader* shader) { glm::mat4 model(1.0f); model = glm::translate(model, glm::vec3(m_position.x, m_position.y, m_position.z)); - model = glm::rotate(model, glm::radians(m_rotation.x), glm::vec3(1.0, 0.0, 0.0)); - model = glm::rotate(model, glm::radians(m_rotation.y), glm::vec3(0.0, 1.0, 0.0)); - model = glm::rotate(model, glm::radians(m_rotation.z), glm::vec3(0.0, 0.0, 1.0)); + model = glm::rotate(model, glm::radians((float)m_rotation.x), glm::vec3(1.0, 0.0, 0.0)); + model = glm::rotate(model, glm::radians((float)m_rotation.y), glm::vec3(0.0, 1.0, 0.0)); + model = glm::rotate(model, glm::radians((float)m_rotation.z), glm::vec3(0.0, 0.0, 1.0)); model = glm::scale(model, glm::vec3(m_scale.x, m_scale.y, m_scale.z)); shader->setUniform("model", model); } diff --git a/NothinFancy/src/Renderer/Drawable/Model.cpp b/NothinFancy/src/Renderer/Drawable/Model.cpp index 065fdfe..e20b67a 100644 --- a/NothinFancy/src/Renderer/Drawable/Model.cpp +++ b/NothinFancy/src/Renderer/Drawable/Model.cpp @@ -6,18 +6,17 @@ namespace nf { Model::Model() { } - void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const char* textureName) { + void Model::create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData, size_t textureCoordinatesBufferSize, const unsigned char* textureData, size_t textureSize) { m_vao = new VertexArray; m_vao->addBuffer(vertexBufferData, vertexBufferSize); - m_vao->push(2); - //TODO: Change this to 3 + m_vao->push(3); m_vao->finishBufferLayout(); - if (textureCoordinatesBufferData && textureCoordinatesBufferSize && textureName) { + if (textureCoordinatesBufferData && textureCoordinatesBufferSize && textureData) { m_vao->addBuffer(textureCoordinatesBufferData, textureCoordinatesBufferSize); m_vao->push(2); m_vao->finishBufferLayout(); m_texture = new Texture; - m_texture->create(textureName); + m_texture->create(textureData, textureSize); } m_ib = new IndexBuffer(indexBufferData, indexBufferCount); } diff --git a/NothinFancy/src/Renderer/Texture.cpp b/NothinFancy/src/Renderer/Texture.cpp index c5b192b..eff2c0f 100644 --- a/NothinFancy/src/Renderer/Texture.cpp +++ b/NothinFancy/src/Renderer/Texture.cpp @@ -11,18 +11,17 @@ namespace nf { glGenTextures(1, &m_id); } - void Texture::create(const char* textureName) { + void Texture::create(const unsigned char* textureData, size_t textureSize) { int width, height, nChannels; stbi_set_flip_vertically_on_load(true); - unsigned char* texture = stbi_load(textureName, &width, &height, &nChannels, 0); - //TODO: Load from memory + unsigned char* texture = stbi_load_from_memory(textureData, textureSize, &width, &height, &nChannels, 0); if (!texture) - Error("Texture \"" + (std::string)textureName + "\" failed to load from memory!"); + Error("Texture failed to load from memory!"); glBindTexture(GL_TEXTURE_2D, m_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); - //glGenerateMipmap(GL_TEXTURE_2D); + glGenerateMipmap(GL_TEXTURE_2D); stbi_image_free(texture); } diff --git a/NothinFancy/src/Utility.cpp b/NothinFancy/src/Utility.cpp index 859c525..a25c418 100644 --- a/NothinFancy/src/Utility.cpp +++ b/NothinFancy/src/Utility.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "Config.h" @@ -28,24 +29,22 @@ namespace nf { std::chrono::duration time = getCurrentTime(); std::printf("[%.4f] Debug: %.4f\n", time.count(), in); } - + //TODO: Test every Error in release mode void Debug::ErrorImp(const char* in, const char* filename, int line) { std::chrono::duration time = getCurrentTime(); - HANDLE cmd = GetStdHandle(STD_OUTPUT_HANDLE); + static HANDLE cmd = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(cmd, FOREGROUND_RED); std::printf("[%.4f] Error (%s, %i): %s\n", time.count(), filename, line, in); SetConsoleTextAttribute(cmd, 7); - FindClose(cmd); } void Debug::ErrorImp(const std::string& in, const char* filename, int line) { std::chrono::duration time = getCurrentTime(); - HANDLE cmd = GetStdHandle(STD_OUTPUT_HANDLE); + static HANDLE cmd = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(cmd, FOREGROUND_RED); std::printf("[%.4f] Error (%s, %i): ", time.count(), filename, line); std::cout << in << "\n"; SetConsoleTextAttribute(cmd, 7); - FindClose(cmd); } std::chrono::duration Debug::getCurrentTime() { @@ -96,7 +95,7 @@ namespace nf { CreateDirectory(folders.c_str(), NULL); } std::ofstream out; - out.open(filename); + out.open(filename, std::ios::binary); if (!out) Error("File \"" + (std::string)filename + (std::string)"\" could not be written!"); std::string write(in); @@ -118,13 +117,108 @@ namespace nf { std::stringstream ss; ss << in.rdbuf(); std::string read(ss.str()); - if (read.size() > 4 && read.substr(0, 4) == "NFEF" ){ + if (read.size() > 4 && read.substr(0, 4) == "NFEF") { read = read.substr(4); for (unsigned int i = 0; i < read.size(); i++) read[i] = read[i] - 100; } return read; } + + void parseOBJ(std::string& in, std::vector& vbOut, std::vector& ibOut, size_t& ibCountOut, std::vector& tcOut) { + std::string file = in; + std::vector vbRaw, tcRaw; + std::vector vertexIndices, uvIndices, normalIndices; + std::vector tempVertices; + std::vector tempTC; + + while (true) { + char line[500]; + int remove = 0; + int result = sscanf_s(file.c_str(), "\n%s", line, (unsigned)_countof(line)); + if (result == EOF) + break; + if (std::strcmp(line, "v") == 0) { + float x = 0.0, y = 0.0, z = 0.0; + sscanf_s(file.c_str(), "\nv %f %f %f\n", &x, &y, &z); + remove = 28; + tempVertices.push_back(x); + tempVertices.push_back(y); + tempVertices.push_back(z); + } + else if (std::strcmp(line, "vt") == 0) { + float u = 0.0, v = 0.0; + sscanf_s(file.c_str(), "\nvt %f %f\n", &u, &v); + remove = 18; + tempTC.push_back(u); + tempTC.push_back(v); + } + else if (std::strcmp(line, "f") == 0) { + unsigned int vertexIndex[3], uvIndex[3]; + sscanf_s(file.c_str(), "\nf %d/%d %d/%d %d/%d\n", &vertexIndex[0], &uvIndex[0], &vertexIndex[1], &uvIndex[1], &vertexIndex[2], &uvIndex[2]); + remove = 12; + vertexIndices.push_back(vertexIndex[0]); + vertexIndices.push_back(vertexIndex[1]); + vertexIndices.push_back(vertexIndex[2]); + uvIndices.push_back(uvIndex[0]); + uvIndices.push_back(uvIndex[1]); + uvIndices.push_back(uvIndex[2]); + } + + unsigned int pos = file.find(line) + strlen(line) + remove; + file = file.substr(pos); + } + + for (unsigned int i = 0; i < vertexIndices.size(); i++) { + unsigned int vertexIndex = vertexIndices[i]; + unsigned int uvIndex = uvIndices[i]; + float vertexX = tempVertices[(vertexIndex - 1) * 3]; + float vertexY = tempVertices[(vertexIndex - 1) * 3 + 1]; + float vertexZ = tempVertices[(vertexIndex - 1) * 3 + 2]; + float vertexU = tempTC[(uvIndex - 1) * 2]; + float vertexV = tempTC[(uvIndex - 1) * 2 + 1]; + vbRaw.push_back(vertexX); + vbRaw.push_back(vertexY); + vbRaw.push_back(vertexZ); + tcRaw.push_back(vertexU); + tcRaw.push_back(vertexV); + } + + struct Vertex { + float x; + float y; + float z; + + float u; + float v; + + bool operator<(const Vertex other) const { + return std::memcmp((void*)this, (void*)&other, sizeof(Vertex)) > 0; + } + }; + std::map vertexMap; + for (unsigned int i = 0; i * 3 < vbRaw.size(); i++) { + Vertex curr = { vbRaw[(i * 3)], vbRaw[(i * 3) + 1], vbRaw[(i * 3) + 2], tcRaw[(i * 2)], tcRaw[(i * 2) + 1] }; + bool found = false; + found = vertexMap.find(curr) != vertexMap.end(); + if (found) { + unsigned int index = vertexMap[curr]; + ibOut.push_back(index); + ibCountOut++; + } + else { + vbOut.push_back(curr.x); + vbOut.push_back(curr.y); + vbOut.push_back(curr.z); + tcOut.push_back(curr.u); + tcOut.push_back(curr.v); + unsigned int index = (vbOut.size() / 3) - 1; + ibOut.push_back(index); + vertexMap[curr] = index; + ibCountOut++; + } + } + } } //Nvidia Optimius support diff --git a/NothinFancy/src/include/Assets.h b/NothinFancy/src/include/Assets.h index 73a759e..beeb369 100644 --- a/NothinFancy/src/include/Assets.h +++ b/NothinFancy/src/include/Assets.h @@ -1,21 +1,25 @@ #pragma once #include -#include namespace nf { + class Model; + struct Asset { virtual ~Asset(); }; - struct AGeometry : Asset { - const float* m_vertexBufferData; - const unsigned int* m_indexBufferData; - const float* m_textureCoordinatesBufferData; - ~AGeometry() override; + struct AModel : Asset { + char* data; + bool alreadyLoaded; + Model* loadedModel; + + ~AModel() override; }; struct ATexture : Asset { - const void* m_data; + unsigned char* data; + size_t size; + ~ATexture() override; }; @@ -24,6 +28,8 @@ namespace nf { AssetPack(); void load(const char* packName); + Asset* operator[](const char* in); + Asset* operator[](std::string& in); ~AssetPack(); private: diff --git a/NothinFancy/src/include/Entity.h b/NothinFancy/src/include/Entity.h index 62508a7..68aede4 100644 --- a/NothinFancy/src/include/Entity.h +++ b/NothinFancy/src/include/Entity.h @@ -1,22 +1,23 @@ #pragma once #include "Model.h" +#include "Assets.h" namespace nf { class Entity { struct Vec3 { - Vec3(float x1) : x(x1), y(x1), z(x1) {} - Vec3(float x1, float y1, float z1) : x(x1), y(y1), z(z1) {} - float x, y, z; + Vec3(double x1) : x(x1), y(x1), z(x1) {} + Vec3(double x1, double y1, double z1) : x(x1), y(y1), z(z1) {} + double x, y, z; }; public: Entity(); - void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData = nullptr, size_t textureCoordinatesBufferSize = 0, const char* textureName = nullptr); - //TODO: Do this using loaded assets somehow - void setPosition(float x, float y, float z); - void setRotation(float x, float y, float z); - void setScale(float x); - void setScale(float x, float y, float z); + void create(Asset* modelAsset, Asset* textureAsset = nullptr); + + void setPosition(double x, double y, double z); + void setRotation(double x, double y, double z); + void setScale(double x); + void setScale(double x, double y, double z); void bind(Shader* shader); Model* getModel() const; diff --git a/NothinFancy/src/include/Model.h b/NothinFancy/src/include/Model.h index 517a823..2c05e1e 100644 --- a/NothinFancy/src/include/Model.h +++ b/NothinFancy/src/include/Model.h @@ -12,7 +12,7 @@ namespace nf { public: Model(); - void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinates = nullptr, size_t textureCoordinatesBufferSize = 0, const char* textureName = nullptr); + void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinates, size_t textureCoordinatesBufferSize, const unsigned char* textureData, size_t textureSize); void bind() override; ~Model(); diff --git a/NothinFancy/src/include/NothinFancy.h b/NothinFancy/src/include/NothinFancy.h index c23eafb..502070d 100644 --- a/NothinFancy/src/include/NothinFancy.h +++ b/NothinFancy/src/include/NothinFancy.h @@ -7,6 +7,7 @@ #include "Config.h" #include "IntroGamestate.h" +#include "Assets.h" namespace nf { class Drawable; @@ -15,19 +16,19 @@ namespace nf { class Entity { struct Vec3 { - Vec3(float x1) : x(x1), y(x1), z(x1) {} - Vec3(float x1, float y1, float z1) : x(x1), y(y1), z(z1) {} - float x, y, z; + Vec3(double x1) : x(x1), y(x1), z(x1) {} + Vec3(double x1, double y1, double z1) : x(x1), y(y1), z(z1) {} + double x, y, z; }; public: Entity(); - void create(const void* vertexBufferData, const size_t vertexBufferSize, const void* indexBufferData, size_t indexBufferCount, const void* textureCoordinatesBufferData = nullptr, size_t textureCoordinatesBufferSize = 0, const char* textureName = nullptr); - //TODO: Do this using loaded assets somehow - void setPosition(float x, float y, float z); - void setRotation(float x, float y, float z); - void setScale(float x); - void setScale(float x, float y, float z); + void create(Asset* modelAsset, Asset* textureAsset = nullptr); + + void setPosition(double x, double y, double z); + void setRotation(double x, double y, double z); + void setScale(double x); + void setScale(double x, double y, double z); void bind(Shader* shader); Model* getModel() const; @@ -131,6 +132,5 @@ namespace nf { Renderer* m_renderer; }; } -#include "Assets.h" #include "Input.h" #include "Utility.h" \ No newline at end of file diff --git a/NothinFancy/src/include/Texture.h b/NothinFancy/src/include/Texture.h index c7d3af2..ab7e9cc 100644 --- a/NothinFancy/src/include/Texture.h +++ b/NothinFancy/src/include/Texture.h @@ -5,7 +5,7 @@ namespace nf { public: Texture(); - void create(const char* textureName); + void create(const unsigned char* textureData, size_t textureSize); void bind(); ~Texture(); diff --git a/NothinFancy/src/include/Utility.h b/NothinFancy/src/include/Utility.h index 66d7d90..a251e46 100644 --- a/NothinFancy/src/include/Utility.h +++ b/NothinFancy/src/include/Utility.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include namespace nf { @@ -49,4 +50,5 @@ std::exit(-1);} void writeFile(const std::string& filename, const std::string& in, bool encrypted = false); std::string readFile(const std::string& filename); + void parseOBJ(std::string& in, std::vector& vbOut, std::vector& ibOut, size_t& ibCountOut, std::vector& tcOut); } \ No newline at end of file