From df3305dfa691052eef0bc4c16aed80bc4e32570b Mon Sep 17 00:00:00 2001 From: ATLAS_Moon Date: Sat, 15 Aug 2020 14:12:30 +0000 Subject: [PATCH] Got OpenGL window to render for gamestate. Had to include gl3w.c since it didn't compile to a library, so it's easier just to add it to the project. --- .gitignore | 1 + assets/images/board.jpg | Bin 0 -> 32420 bytes assets/images/o.jpg | Bin 0 -> 28938 bytes assets/images/x.jpg | Bin 0 -> 32794 bytes include/render.hpp | 20 + makefile | 2 +- shaders/game_board.frag | 0 shaders/game_board.vert | 0 src/gl3w.cpp | 846 ++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 6 + src/render.cpp | 33 ++ 11 files changed, 907 insertions(+), 1 deletion(-) create mode 100644 assets/images/board.jpg create mode 100644 assets/images/o.jpg create mode 100644 assets/images/x.jpg create mode 100644 include/render.hpp create mode 100644 shaders/game_board.frag create mode 100644 shaders/game_board.vert create mode 100644 src/gl3w.cpp create mode 100644 src/render.cpp diff --git a/.gitignore b/.gitignore index 52c59d1..bb98d63 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ src/tester.cpp build include/shim.hpp *.tmp +.ycm_extra_conf.py diff --git a/assets/images/board.jpg b/assets/images/board.jpg new file mode 100644 index 0000000000000000000000000000000000000000..365fd725719b49f2833640b50134f873a6c63ea2 GIT binary patch literal 32420 zcmeEu2|QHo+yBv2%F-lcDTXK_DNC|slx(R`m?EZ zB~2YofQe}b;12!)j1fQ`*t2^#^X^@Hn3LLY%F4!ffD_6kzz-7?;6Hp= zNc5zb(2)}&hYyP@96xdDw49tAOic0ISs9g+vT`y%zJzJ--o0$BY`pC3yfVUvg=PNm zi%|=3?Ag(^3xF^k0d{aOK{%Kg4FC)Pn07J!J$qSL!2^o-13Q=? zkR3ZAyLRo|2_EeSeh%#9*mXeo^!eSK26vc`IC04YM!(%7av{Ht`&##^sO(+mM|)Wg z^6>KUA3Y`}eq2IM{*1y|MJ4r%8k$<#I+v~+8W|&Q+%&PcXL;Ys+Q!z!)y>_*)5|;P zad1dz*pu*>*ynLCUcP!ApYkp>?R|PiW>!IAQE^G>$FlNI^$m?p%`L5MJ-vPX1A||O zhH;blsp;=Cvvc!=we^in;udL}{G(q?U_bx<`fJC2>K6ytuN^ygLUuC$=oixt4{(EU z?A#@MdiR0z2F!PyIFHB#?%}!+{WiaDuZZlmRqnga-7E)1<#0y{Kf3mpp8e-K_UOOV zvw!K>zxHbwV1qD$HxI%Az=18YcuD}v|KI-q82mHO0SVTMj1vw=E6QIBmj<)8ibfV2 zsI`g`xz}eJq@%WEJDt)<*SCz@*c|;wl?62|>Tursn=!V)7Q01b{O*9$Sqle^(NDvs zU#mwimbK>XU;xC&tA2^~8atH|Ctzzmy!yfnp!$vA*sJf=cPgsNYd+dVw7l;VXuo1pT37ie)`^q#wRCzfB)D*c zIJc_IH>BC9wJLvNa>3IgmoZ`C>D$`Eys)w;QY+aF*r?&5-dk-BHp_kYY98@U;%=d( z(;>Fir8jIGkCZ3~^gIJ7f<`ztvC#C|kE*=7mjMI}K9?=bzkm0}n;4&7 zYsiP#NlcWbed!ZyGbNA9|51@#=hHF8-t+@!@*KI?ygan|^lEtF*jz6f7t;nbq{h1A zOTK5qWy76;GhdI_&SZ-ysGZwOMig5o3H4NJ+%1j2LgjICs%U%IxR0rxjhdbmQq7gS z!b+;Ru^N*4vi!=3=J`XoyO*8On);erFcW|h5{`~O%+1vAvIG;06<00l?rJ=9bgmT&Bebeku4pKwj+2y4jO96YylL0Cy zyk0|VaqcxF``mREZ?|{P%c6OMRDvYxgWA|O&S{eok-guBwXEDve0IJWrK7sh28gGG z|7DX@*BX#6k}@7Q=v@{(6n0pqApcN+(2_kz+}SCQ9I`lM2_8BoS3+nG#`ReUnzi}Q z&!1G)QQL`+U3)WSRqPhGrd5YJSQA2ZakM)TWnX+m>Za^k=zV=GTHmwtt^8)ypS&ZN zV>H5#MStNwZ?Py2X{uK7Bwjgm8C~z~+99ws@A%P`&bx0~^3CcE^wrmMNI8TCKGIo_ z!?V}8&)o5h;z_eR$^|>mhp8#fMS0?nl@0$(w|{hhPK9%_y>mC|#fVW!G&Q;I!CiCT zuTKuWzOG(rZ_r*nzquEumdO(MT6hlmUND$VQd+ zj$PkUuj9%iXAdRm<@$;tZ~Gn^jJ-v2cpqFF)8H4brpyI_#mC7pjdyEs0S5oY4FShT zygor?o@5PslNvoY$o5nz+somRYDhWDjEdi(E2~=#P8mm|5>x@c*0t7TXxQxER>!}r zk}iL?g_#Sa=-Yb*jTiu#a|(Z`MT7wevThGzjJ^qOQ4~x*RKwPmoDPp~wL@s)kQE6D zR^{M|f=AQPRyn&Pv^|}hnX^DjxcEQShJC>RtOK+fd|VdZH=qdHyZm&JD&RyBVWo+g z8?4D8EuKwn?n*=@(4R9+Z2V*zxmOrKp?ltRaV{7BHmiG3wWlTn7_zIC?4tv=do2lK zZSJ)dg)tn<9+FVn?f})CKQnq64{qyb+c->3AHDGOTv+234Zv4&@`^Ntr-A(bW$|+p zGaZ(YFPF0SL(hfPbyy;D=w05f?nsU!N#Z4}6bsgujCGL4^JWRA!695nr@Hop~8%;A!)}nphz|#a zl+3e}4>q=S5c?1NwpJ~4|{^V{p(@) zC-Ec9&Evcq=tcCC@?@jom-Z)XA&{9?F@g|XF>iNO0uf!bR%!FzeBVwY6SUu~<{b+m z{x{=E(ZWT3ts>dswwP7To;z95>PpE7Gjp?5mep^*GLftg&I~#?_*E}JyMzDa3UjLA z+L+yhhs4h-P1W0Ou{K`_^4P#W&0dMfwqB7sR`UG5V)Q$w`8{>mP+y(YGl7$4x;nQ> zMP)HZrTd?s;YLF;>ZsO`W8vb-JASdT3+&!@?c}g|x%jZ8)akMwCGQX!@lC(2u%JzqSp!Glc?dZOf(lYfnU1Qf0p-xoD`iKnZ0rj>M)tl zT{B-Z9p{kBh<m|` zu|K*=)zXRH5s@uEeV2L6;d44+Tf@%)sZ8&2f7Mr{+#Pi%MufCqYh8{B_p@>3-UKf% zVjZ+{i!@=!kW1+#X-gz+Cj&46HkJMf$pA%knDGS$fEy1J z8mg+UlT2ofxoP;JcC!WhWMQQ&<>o{T51$TKHq_$B`ns8x$k{ktoiP1sV0c-(Tbm9v z+mN|`tS|mwtgRpGjCJ_j7SX)yP6jw}%Ay`JQ`mm2FJli@56fL`hf}+AA~r={>J0s-g4^ObenK0k$yna;os~t4?6ZGSl|+ z9VDj{eLAU<#tZ1n|Zed8qSO$PxV*sp2({d0VgKn$N!oCDyWJ??MLV@o?@;zUgXeBQ(}>M?#j>{mqwP!oyNMRXvG(A3CbEt)54Ni!MB{WEIEexS3z zp`Pr4k2-$0!?#hO6EoBpnh0%x?#eXwUybnoVwfZ8-6cs@kK`yH%1+I*O(ZiXjl_oKK^;IIgZFvSMASZ16wWy{omN1v8~34 zCnq%1aSkT6F}pgRcTKq+dKLv&>d%UQQ>_{6qd;8`99g?&4VjoxKm0VZ?%H{BuY^vj zOs6Pj{OV$JAX)odkY)^9_NE6(@aaOgTtc65Wk%5tH1(|HVOO|d!3-rCVZ z)cSaUXd*dNQ8R38A;Jo0*W@9Y*cIqag3P-~GRj8EgPH$e;?jBzsf)SC74i9ie|NRi z{iAYA+=vgS+Vp0=8?j>0N%C*@3x0x;ruv>6v-={#0Z zP7FZ!VkgbX1R$@4Z||*^C(XTt4Y!?Z(2ei-NJ_&;Jo4~-K|6m=#1GTX#YFVeT-Sh& z$8mvBObr{BM!<%D?@X9UD$FV)OUN>dgM zuiF|QoHe%_vF>vzn>K=FVuMjdjum6KP~!s(fIrIg^>;v5B?hW>*BY{9qvAI~dX-Ij zr^U8!4^KX3$~L#Np>vn%g?o+%=JJ3qU(*p5Bna|gw;Bx5LD;J8_G^!rs~If@4bO!m zm8N*+$Rf;PJ0efH+Q7p}Uz!HsX9;b_KrT`Idp(m@9;ngXifss{wOfyO5xC#j`&@2<_Yug0O|JUP zqc4)AR|k^mW-r5Bv!9$!j5gP7USpQeIJtz@4U6(SjHm;iIiEd}tCfjt(0b|P{MdCw zlFc6+q?m#aZO^pw(-HOVW6}hvgxw{Cec2qml$SBk1=BM%2UVPGYtj3^wMX?l!*3=- z3udv;9aL3GV}qeFpQgO8IMR#)b4`)M@P?N9C6lYM5)7bMJ{medv#rnED~EVIS5uT2 z@s=MGx_sn8(}3kO7-iuB+@u>;6dIyDr&L2D@Gtc5a;l3)~cEdLr zKxqpDAY}oADFt|fV5qDE+NAdlS*i!NfJiAX{m2*MIVG4e(Y3Sh-&ynA!FZhxY+&X2 zhm~^PZuQWN$b8e{&(w!tdIGG=fPv;NL8{?Gj{EKYR1+9fyS#(r(>kez4qSaiUs_k>mE zxnRJ$&$<2Z@$#Doj&-@Lx8t3Uj4;n_&cWcq**{bDMiy&LoN4tAz3n0VXf!qf!xBIqm zZeQqoO+ggLP-|>})RQ+em}N**q8@j!bn`ew1ouEX6*gvi9o-kceE}q6GC_n1--$h+ zSxPCXCl_0p`FD@;UHLSk+i&@xu}2<8=EJ_uNQS;e5@So*E_$=2`5b%>xxxTKo`=HM zq^scz9~c13_F6cwwaox*WT#7qs45B!0Qy=17PZR-fhiJudh%vvf}hL~{ITdsZL01% z-4lB>B|tf$CW5Y1@$BQ^`^PAEZX;M*MrlLMp@S!U^)l(4&)^c%;>r86=?4*!s9EcN z_^NOQ?0~N={QFD)l9fms{_B5X6M~Yj2YyFIdm0mSNXp5WB{*i2@>LvxkxxMa&?Vd^NIpsKjFpQfFWv>I ze8VIj+)k3o0uMumov-G_!hjud5T`FqIzsFw@G+lQ#>@qtfi)KWe)=&7)f|8G`7^eY~&x%QW46y=QrPf3@GKubI9c9u97+y$#N$qZ%>-O7?OOc>U_<)L;jH2H1#P z|1S(+?V1<^_+Vc{KI}GCynrmMp+0}Y02U8P(?bOSKi!|Bp8w13-H0&x1t{C>OQpOt znZ}(grZG$|LkO`K=YoBM@mN9Iq_YEp-|+)jvRza94a4|9XMz8ki~YUdml!pP+c>yp+UVnS_`u1* zCr5ARoZItdPuBC_(!}P)6ctpf=0{OHzkMQVJgV}=`$v;LH&xobQbW#n6u=MI?WuY+euK;AP#A)2*67x$p z$jtj8res#GYdiL|s9fv%73J`cnx{AYh5MQ!a8-JSx3!CkW9;`)3^ASIeR;Bz#dW15 zt2_>>`w|~jQyhY?7%6jHS(X-4e*ZBp&1L?xGwQn0?C)T||1I(U?_FoUqmP^QP)S)l z=fdG&R2(8DKq0r%ZZhEv1JEQ0=JIav#8|9-k-XnKITPiuPqW5Jy67uv=9UH*)4V%~ z-W5J+6KddgSk- zdf%Ih9cpZJz|+$_y<{1{<#c!-A`pZH7ofw}4!E0b%7+QPvrj_%kvkEM&q26SVnRe`S}ZCRM-F%iYJ5^fiI^Cz z?y@r_C72fm3Y84XiwmC*j*=|nHr#g>AgIAyyOHduPj@C!WZq2_bsxxmg}$0yA!^(YEI9BP2-WJndbWtuSa}6R^{8X zMafDP-uBb((8}@kTD||ueWcYRqlTu`a0Z=uws?2>SDH2w8ETW!C)Ya`nqlA-n~m3SS}_(Y_!QP_CCFj%`K7KuI=hw3&i{K;_xJWqRUaFUs0kS+o&U-irEIlU{vNg*&975}#2h-8aDJ3d;DXqBi1M^CkGmp^XJtEnHUaCFJ9Z}>} z%<=wT;az^uHM$Sv{;0eRLr*>LWg5!pRWC+{vmiUvDq5AYFp> z`5JqtdGS-SwV%t*Li$6o=Lf1L$0iT8Tjx1U>mpP@6uFBR+v^US}+5qBi)0ld(k+WVqtm~oItPTLX{4?bFH`+{-FabKOJ!?2UT&{&* zH`}_w!$64A&ED*Px|MHcWDcn?IPR<&tJ&T1w!4lkM`q84{CavL^ik~B4yQa%^WE_s zPhw2>3`%pfiZ%h10E_8)Wvev6(~oOQGjd4aQo$SUJCC4MGXG9aIy0sCBZhYQKr4Nc zlbW%EU!tqmu@Ieq%Zgs6K+=~Rne;692wJWybS@_2@M2nmuiilfY-_IO(=(gFX8NsV z_)0G-7%)!B0V!xCsxz^fMs{4yeA_K=8WbkiJ_JoMEu&uu5H~QBO0QqxMRE{PZ1ax= zpAz$e)^G1}HHJZ`PTov*dmKP!27VwA-NFy7hf984LRrDMbb?&6Y)+wx=34LaNsW+(7SOkvbHqnkM!})>Msm2x!Mm!KT7-u)q zIsLJ({DCEO{qQB}lp#$x(F8?3QY`?+-9Joc07x8xUnhNu$s#~T&zADW)3m-8)xxX` z21_7~`RP6Sd^b)pLMLCH-cb&n5{FFgalK+Pb)Q{^Xs{qq@qxAriLNu3Ob|qbxV`L5 zdt5`k;#YC_^u^PMwS&^zk`13T5iU^`2ygiWdHS7J?CZ(bz%MN(U}-F5(CiiaWrIQz zN1N5yW`!6DG<38f$Eo^m2J@hpd{_G7CSFUe$?Q0E%LG?QKI*3j9*T8ag)|x~`Sovh z5Mw@!Tv$J=bML;eVF~bcx928S9Q(1-N_vROI=MG+T5jY8%-|5BzUViJ&u$W|9=7_* z^ZkgX!tT+_yxV~;PuT|ZS}F3=dU2D774CLfZFAg`uHC#(!rV2ycjAHRR|^KvkG$2z z+~EN)bgvAc#op?*WB_^DqNo=6JM(ZRUxzy!o;Wc0S{=En16QlFTVMf)YR;dBG{zaS z+LWS4;dns5nWdo0Ot8dIeLd|EYVfe3R&*yXwscnHNPsF!S+8SG4SxB{=Lkijn#Y3QgN%upJs$O49D?(fTvDzH@!wl%R^VxI1?hQ* z14H%TZXc(2(pf8=yHVCdF)k5agRodhedf03h+gDs2c35*+m-=rjUuTUmh-4WheC0B z+u(O~2B2rK8%A0NGj8#c!&9_`Vgg3ewD%AVCqxe^%&W1&@Ycl&e2G&+Z_g;tY@SyW z)Yb5orS2zu$~Q=F__|#16!s+n4DofF!92#ZyQp!TnxKb<`%4Uqij(EB!PTYFs&(K1 zl`>kq-UDpdV76{zWP6v;Xma zxm*x+6yEepek&HLrLog}O0l!c8`1Op=c)L+ZGBA;cQfyu9Dh85k zPY+O<6<`_M`$=N>7$@5E8l=44LYp{b3QoFa4&JF`6V&*0dU_r7u=4G>Zn26>r^$#x zIdHag(L0mmU+w64uYp+^RoJ+0Vq8;*3LB@ZZbqKuz-(K7*P-^?&3S{Oi-*1&N0H?fTCfZrDwPK9n|ha&F;=a53ST8 z$NQnQN-P85G|$xly!5EDBP*XOxdUi{l(`>xDsv?V`xMhHt`e^lyS#%DIszbWv@P*u0@5Mpp?U z5B77fOE2Ocm^KZkby{ysVz&CiP{ixVE5D6fe~Qu|W=4J48MnP3$w(etucPzTJa6~H zElEsXP^FeQ75d3&+Bt^!o&4O$atX_CBfU0*nEq+fgDZDT};z;Ww2B4j&b^d!x4oa?h0jUQ@ z5CY@Af`pF89WdhIQYKW?x41g83#O;A24~_qSQ8=-r>xp7nSi!YVHNt+!XX!DW{n}* zAH74Cx=7zcxa&;k8F=n92SW1~)j05%IjXwcB9+c<4PV*JLV5dmoZpVV*}v7ds_w$7 zp`vrb{?s)MHfSIJbg^TID*M3QdzgBnfvj81z|mlOnZ69j$rIeTH(umY&d&BUHEZ{; zI7}&i8eNKJzO|40s$^IdEy?$eV^wll&$6MFwNB!Vs8JavjC~h#jDgwJ+|`9fvgq|I zemF{hX|S%2oYPAUgP0oyGZ2X4IpxVR+yAQwbyII>`+&Y0!-}%=cY>2;^z{ z7vmTme4^$`+c93(@7HK?!xx8DQzhw|)o*^Ko%&P6xZi?x$JcU1z+0W7io44);~*nA+yp$g;$SAd0aoo_pbD? zwaSju^Nsi@-kikSB2_u~2$ z4!o_kQ=0-3+pAg;%t+P+3p#EM4CdtLkcGjR*ON5kt;6aT)97p^4DH!qPao5&Mt@qz z^Y@3cy>3T)r)C(UYx}(^)eJzr$4wtqC8mWNVI9>IrN;o1D_<)ehi z)=EN2g>&;UvkUH2mHP1dpBA=+_B*fl+WMB?9%XEbP6nvfk9qR5QpX~mls$G$NafCaDCAA_JCz)5LMRG#Rd0G;;z@{ z7f!L{T!(J8!>uHb3DEV+lthEEjt!lgYn+YBeO9jh2*E_dXE8*-?ib?VzYQphA%Gr8j9#Z-)0dns(I73%?d zH;a$7H4dbKHxUZ(S-~6L$H)p$%*v80v@R zsqC7hAS9(jS9(k^KbOCg;>Hw-dlFpweRkw;OPz%cL0 zJNka`Bak91`$3Vh{Rq?A!FWn$>;U1&$?vPgob1tr;{f=%-AT`5C9hMG#KJY^qtdjg z?0%a@Vm%v_H`~NBJ+XtIgH7SDlA(`gvE?Wn&ng3;0YzU>b3O3YjPXyZ{Bf6Bao>*i z5$(jm)Nz+J1eYbbn5c(Sc;u$trW)k%K#yRO@fc0{UZzuHrMI_bvD;RuK`rLOcK!!s zdMjoiK=n>abtH!90Mg>q<7Sl%pd>7Pn+3dNw!wp_soN;Z8oVh$)iQK0L>awM~C@x_gCtuC=5?sw;9%Vj927JU1y5o;;2zMAzpAmqZGi6|BMU#-`|+o_xygU0i>}zx}r!Ysh1D(B%!DqZA&j zccWUm%0ZznetO=*_aJ9W+49AEprSzaSl^V){9plR%zA~@;0fEr<42=(TF=e>x@sqP zW#@3jxPbM+Da(6(LdJq)cV{+o_!p{qFWx65;`#+NCKV; zb?9Bc6K!QDN)ou*F9reqV2tVsJE>gir2$L0^O%J-M*BFEu$M%P|+yyQN~d;uy2ED1I+O)aW=265ys9K97`7wIVIw`hUXJ}Cxp(B zU+C{3F>CSj1Z-SUsl6R1C1UeVBrYywrn7p|F7+oP{trqi|3T#Tr%)oeR`FNg9ZOiP zFtpB3hdd7SQ$7xfO?MqV+1%~uyiuGpHV3)f8 zi}iOu57z%nZ3LR$UEn}M-44p0x7pqUVvhyH2Sfn9$2%g&WZ$b)FMG?6PU9jhH60m{ znfad+24rQTeOM%`NdnA!`uf@}Fm&E-s*a~6^a}3jhYcFs+17%AN&A97GjNEf^d8un z=p2g30V7K-3}rXMZCJx%KgFNRe0VH|)RN&HcjN16DyuYjhva|$Aw(~%&>Kxsmp7)1 zWbF5U1Pbmrk+Orm@In;ziBdZ4u^v6*5 zj5)YBzWJsT=u@|-Iuh{d;5Q(DjQ@+T`aF3`=1` z9zzUc*rlr5S9|O80|N$5x1zT~7D0(&|IcIpM`k&q1634BX`Rf4T@~4ScvEhI(lQO+ z8t#oW-*k%FRZCKQi?_Pv0ciSXuz>LQu2r3)G*X0wVvjj)J7lzIb%|PR2O*^qUop%Z znR1xm;S!o*MaQJd%RY|G&cN-(-dFvhDxI1(R ztabTprQxp5@S&>6n&=!UJ-lAvMt*cwLgA3Z{%Y^73HM~^g_KHgq`|}@3z)Qt%fW2D z3qvib8#>n5NFBFuT%_$@(`s%fKH+A@m%0Hyk=*N+gG)#As{LEv&UK>(jlJN}CXIcd z)^LD)OndB8r^t$_ng_J;bp~X9SaNdPUz{{)@q%zB89o~8xVGahm=lP_Bgy>odel9( z0L3JnlmiNnK7fSbW6bqVnumOv1tGTC{Tj2<$S4z)heHH9{R6yxN~yl7H+-ncHksG; z#nzb>O!xeYG{Sfj`LXIP595+sGj2J&@B~gZ*v+o1yL_*>5ui;7=hsIGnmK!Uk0_T$ zqK*m~-y1tJunhAhH@%fac`civ=dB^j7B0Y98$5H@$9GHaG!;_KNOuul&&lkJce_m~X^sZ6&;>P^*KszP)cro;CZq@BO@haY7yuf@VcQM8SoI9roi*>P zNl0-eTm?DW9px_64!{qq;R^zJR{NY_^EkPSK{KGh*b=&bmH|;BkF*lWaccQ8@fLXYX37NT>fVJy2(g}dbz+^FxsX;D49n$i4N&VT`2-H)0rPGjohtiU!5 z|1^OvHg1*G%umPQ!pW1>>ZD;8f;#y9?(k_fL9d@US|;Q}l7uWYP(_*3!rA6Uo74Oe z6OuQ0QKhQ;yY*;i!IHL=fdKj6hd70s>@GSznr;Hu+CE#r=QvYQWDYK-w;B)2u}x5j zjr4SDUj4(Vd#oC=P|6$=^7EjA6Gg-G!V%*`Qs&M|GWGnK)Nyzk;JwMcK9EV#xy84q zM{ds}i_nVau^6{oD5dXtprL{Bo9*Cm9kFKsoxF!c=wu5un2`bU&@HM7p`-nUs&F|P zUVo4a+LO^rfHlQDI@HLY(Yf{DH7XjMv)_{>U8UtR`O%Z^fPZn22flOf4IWd>fjRNn zhbjfi-XJn~z==aHL6EJ!X8i3n~*N&uEU)I}NLBdjC3%3$ymUiKlpS81j zTV|YN(?9*=!p*@c>1Gnzfa0@#(1dS@f5zS~oS1UU`_3NjFQew)%-)QScAQ>#eYkWz zYvVs8*Z(7V6!ZATKY9fa;0>mkj;bQ0sGA8cC*P^4F@S<71Ffl)>aSqEpOwt0=R$+5 za9eBUt&gfrnnwaoW&8w`C6||Wb2{R_$w0vB$=oA)tpGNxh}FPvQc9*f#MtL!iV#^g zkY=~spb^QIfco#W4D5^Vv=kLf32t38!6T?A zLeDS*>bLUJ3A#=3IXP>jM??ViXy7{NH}R?Z%tL999_iEy=;XN=5mtib^d~9E-kytm zr}y@!f=@mI=jGWlf?%2Fp7H^=y>&}cy*2CdFV$drwy+{ZaBln2xR5k=Ev>H^>Ff6N zxMo{qQAnBSW1D#S$H$Y{o3{7Df={;Hm z7yzr~uP>`8t9;(>=5%6B5G(lt{yO6y8$Cj6er<-zK&g^vjn=CFtF7VUmdiV?aoxW6 zoGcL|<4N}EVm_~b%WP!$txrVQTfG%+oYn$T#yd`92k65hc^X$BZ4}Ki7D}}m&F(5Z%%4440nIfBc*{@OqK?>2+JaBu z!H{kwv4MJsbZt=70D=L2IPR{eEIlMq1VjM6)W05-Mhc!7I4gL(dws=+mwvx^vDi=c znud?Sg`T+^_vAPwAHjFnP0Z)p`M6n#y|!_YgVJW-yrnh*ek&TjT8{W}p5Y7*PYi-} z=*rYn_z~Mh7#G!rXeAAV!Qv^A5-zW2Ou^TWwfu zuBZuuhMnx+oy2kWTe_XC59ZhjDD?@b1lgYO(*7pDag$EV$FCg=IHwstfxs&SnmNnI z33eQUP_ve>jqsh{{Kh$MG=p*i%e~ZDNPbHG5khFlF|%$@wDv=v+(i)W-_L~Oj;}7u z(yBnjGjR`vSL5F>)}tO3gn_B!<<|@#5Co->dV-~CSJ0Bz3w$?5lrRfwJhSgbp9r-n zm6pHh{dEc1Pm%PFq-^+*tIymzT4GGA^F3EQ>B7x>NmlWiQld|9z5)raD}Jq$DLkL} zdpQG6h{3nnvvI%Gg?(E!d9C7so1zob?cr+@gQG@-@j8lVCF$)u<~g`zPrGd9562dD;}8<^t}mYfenZij@zUNI)#f#o*Vl2a;IPIHN!d>>B@f= z+NU!nd1Rq!jJx3OOLNhlyH5T5Yv<}$zgR>3!}0e?*%O}U#Twl8qFNejp5;i^p#Arh zJWJ{Db3#vsj0bIlk2u0;cy81bIX;d(a!&c?GxDnx&=hMTl(YSNt{=4Q-q`aABs^cn z#BOKdM@SivStZG7Wh|O5SGH5UH@TC#7Fd(bpFDm@#kEbXpTlMJLK!R(@bl2{HG?;- z9J-}k=$T+}ZFExc64M5RH|u~WzAE}1EA1;Rax5jS5Q zQM6p7XkMqt;lk6cVxxVoOq)sBguyy~i*gMww+y8NsU~Vp&wOMZcKSThaPdGEMLmP# zJ1x#;ACBHG zqZ>^<*JpNgBe*ns*z1zQr0m zNxf^NE0BL&@oNCBUl21;S}pGRNspKG<@=O2f7?)GRZ8aB(;;w$Yck)Q&s9l=|1mD| zO-@VQvpAut{Z8QyTuf>EYH~&<)U(GMqXJKwIc@WI1vUGhEO7&MzBxP6-&Q?Cx4c0p zYXBY}eD4uP_hiyOE;DxeG#iBXh;qR!oh31V_ZP4u zz9>TO$9e%(6nOyxoBC8)0LqxfYphoeO8ReI=}z=JcpS8wv-M!yRGfE!g*})Oa1PY(YBiXFy9n!WQWhMS>Z_h4 z_sauJO-Wmmk#?6Vd#^;jbaeD!trLz?WDT~Ic&Lj%s~R^g_v`0;{V0JJ;CbYG%~xR3 zT0Xd#=a>+pU8+=Z3wtYp821qKado&5RO3uQTd&&HS|>xT%4zSYI>HR#VvpQMEt=c` zZImW*+OP(fq5|4()nP3L5Z_a4Ud@5ZTy#DU&#qoN19T2+=GMmMFst`2av>-FVZRc=rf zvd$}Zb2wK2aI{dEvz)MH7u#k9Im%7W7 z?2KYrT4;vaD zSl>UdDioka)pgt}wkk#E?$Mx}^)wXcw2g09$kI80ZfUZHd{>g3x6>P1sB>R`ax}rX z+?>$yFi?-S8jdoVm-0VII?`=~sDB~jFl&kSqPl=A*Xe9l3wOMvoifyb58hKfT(oKx zym<7$u&2wV5Vg})C-Cgsc=@aoONKy6SAeoT7t^YJm+pg+`%m!a9?qYq*-B8F7PNb% zC#N3+HoBr8?)3Uc6nK8q_R! z!N?5lB66!X8TuGrh^?9Vf~V6INY_yRDyGI(s``2{-Jx_$@V6 zl9rig-Y$(Q$kMDKt=cZgp&$A0>2Z%uZ}+Xwtn%BY0+0=?MoNH;YbX1xw>X%TzmK-K z?;X3V{4G3;JNFm4Aw)F2`=IkJUzL)?-NqyOk>f*`lo-Gnlg+kT!uv?Ds)aeo&EYhM ziOtfz{ULMT9h7}wlg*a^l7IM%$-NE_EK3vFTrM_>YEEQB9zpT(;r~P0mR~Sre}-NA z`CJLl+>=&jT_f#60^NJl!64swknPVB%P)lWi#7#60uyK0hct&7I$45kJXyAI#njJ5-*dK3aqK z?lSb=N`~^JRKF;pB~X>}1Ko1wW8f}4FM`%2`nzr5J5@N-WD0L|_|{iVC9IPGX0S?B zq(5viFU_obWVg0Dx=@9#@DRszgf^4+{%&`#%bw2d$D z-5Pp#O5|-TUxzElc`nux@tD)I;XvkpFYf?-O;_|i7kjCHykXd(+FtsQf<;bx~3 z4^MFsNHYVKcdIx0^^%&1JLAV(#b@zCK}acI9g=zm>4H}=yNsf=-2J=fHLQG` zTDMnKXCW&-;lMh}&-3ShMH_p&7iHCfy4JHK{nEJio$jjxx1WlRzI}cM+CCT$5Xh1v z%!?y=R*4>0n+xD1;Y2?Y3a0Juh7u z)15pjwpxp9LFifGkkA{4hh~+`%D%X;zp>^h{!lPb_O2O12-XigJOM2I+s->wF6^O+T_2L z(7cu_i5ePj;sowh^au%}RUXsB?Bd(CHFo`tP{@o1%X8F7(#@E);_ zUzY}H?-L-~h=C$~=5`Kxr@5S4yH1)|;jJ^Mi*o5iFTyLn^^MrYlOS&shRp;+q^M%O z$AV{jrX+?B4_<;t^=>88fSHXvXZ)uzVUQw2C$e4-74U7>;n@zSq`aDqVN=>I_!yiV zY%xvC`!AOiCJX3lYDyIQEe{w+rI`;Ly#BR`{oXB-$fwd6zLP2nsk*}ROO|{Vn`b)! zU$}-}F_^eqsl#kY+Q3M=F}Ta9P*pZp318_nz$Z5g@AtMH3lOzZO88yCk5EyJ!)kwWku4y$=^^_!gj z9q}dK*W4(__$E}Y!e3ZJ>NBwS5{OQO3wd|?T|-r$u1V8d?2au=z$0^`4jxjZO}@f> z2Zei0;Tw8jJ%my-^-(XK0Z55ak4pk)AU#yjaD-Na{OI1Sdhyb`%?|7I#c`Yyz0i2z5N$9FwHOkh zYMD}9(yPksDRQOGhi~P^zAJqdg(PvvMqbKb?HFgF{s&Jxoy$&`{3g?Nkz)a>!nubW zSP_+12Fi^#=6xC;EW*ztA2cS<5*fg}YXUC=7%e?d4K~+)7kMGoHo)BgoKgGG%%nF@ z(fe#cp!XCMJi=B(Nf>%?2a*8*mS6;Iw+z-H;ASg1C(B-)@aG@kjg30-m;EUpNYeOh z(pIF%B7N|Hgy1*yKy?k6aJo@SORBU{Ah)_^z!%cmVYFTB59UyX50a-%5ra#2>U~?S zICY|vK94+fT69`LYJe<))(;`IlAvXIf8N>I^<)@n9zq@{epv@)GAUQKIdDrRv9`lS znD2`hQvm$JY4b=8z~zG{^wXKoxzG?fH_K_$MS~dl0a>JwXNLvyFe&hkM%3xdTaPt> zU4j<3fwS1slgCVbY^-7*N3zB)?zY28-JKn`Lu}bQTYZeV;OB7~J`iyHr*tTjhjx)t zNU_B|`1IuDSr9kb1kj7O?DwY?SL%ahd$t@}$&elYr@JeUYU14D6DeXrimf7+ZJ>g- zf?8CNLLnfVQW2FZ7A3LlA!0#5SrP)Ms1=ETVg)PuKtL2C3PiR<77@V^0a@dcu**^c zhLDhC($CX(-qGZ|zDGT6PyO>dGvCZP^WAOk{r&Ex>2tjFnKEs(>H`#0T#v z$MUI;x#__l-@m|SxzaVaOy@RG*X$c|Ey+O2Hx-EQdxA)uoKU=UnZ=59r>blc#|5Ap z_SV*Ui~d7?EE&GC@H>J&=VF2(cQ9Fx7yUW;mB&?dElF`75#R-0+974ERit4(cQ*$p zcuM>k_iOqq6xG$I0k}nui$DX31!_m63OXafbu2fhQbh{c041cc#5nLi!4fI-NF6;< z3jXycKpPu1WXX#-S8=r)7dTE$SAiQw5v18ykzNELrq2PESws8<1vCzO{O>Jl)%1Cp z!uVYF_-~g#7HnjDOQA2n73YR|21*AHyyrpnEB(hs46J;*_Q+WNT4F!}C46_W2xs zMyu4_fb#@U*rIzoo_4Zm%B@&0J5RV|OD$BuG^IS=0(vW9_ zEs;JB-a+2Rd7B@)l`UTWnA0G}kEF{%<^RlR=C6A8_3I2iaRr|w98#e7XLr_YJS3b+ zWk?|_13z&yejH>gJyq7u$6r_pm$ePWRE2113IgT+UM<$5dL-0dr4t2>3A>-{H_k0T z@c|Os$tsx~s&3j{Cb*WhXr2DybCP+<;s(mC->pE&a(ZOf3Uzdxs-rr$KJ{AKJlqe~ zkLO4BoNOeytG^10RvZ5`)ZnsJ5p~Vh5M0A1{=(KRse)Mg`H1N^N=?6|H=~&V#Cou* zqr}U440qrot8IPa<3v@ArO3SQ=sl0bE2`u97O79;mh3_NUs1f~mXQC4qy*JW1QR#E z$rf)+G0#vX2B+mpT0bQZ-=(D9cuvRZ9LT7GZS88ZFk6yGoL3@1L9RutmivrRxnojD z>E}sfGxHxC-O=gf5u=fE;SGLpn_uevsGQv5llr%()+ec0US;#x`r`XUBRO51i_?LZ ziw{+Zu=iEQ%3o?T5d5zlRqBP%tea-)O+>yZ4KDU9=ZA3 zR)=M<67&{aIbtCCVgqW@{mj8L6G`EtDWQXbi<5cJLuS2h1>(yX?fo;V9p8P*>#Y)=>!>I1t)v2bf(uVqAVqxmNOXA37&M0WjFQK*le^)#=t( zjFNLE+Ozp6i4o>3lm+d7x8_w!kKp2iOo8i|Ss#h-br7TzZ}(QlR9W^hTFL|$*JTR5 zgS4?X;8BeHDZ<~2wSbsovq^VJKOZ^&fM8rAT3hS#A&DNCB86VqXpRNQ`jvnDx)9rI zINXNl2;ze{%eokvmu7rdp|#UTj2cM+MnYpm`@upVa>)xPl|>;_$B&3(*Z^TNAP1A5 zps99ADtZ%AqW9j}N$lj zNM;E7eB`qz@&gw34#63eT`qSdH_hHc&JR3!OTEE=6AH*++(oT>y4ogOdUslvZf3d1 zuu-DGEtF45h+0fK)C~e|nxoO3_s?Zl;`wCsq&?2tDqJr_3LWUD_);=SIICTi+r-J9Eaon!3m2-xl5gPr@) z6HmiXW5qItcrHf!^}Pg!XtQHhefhpv0wY%ueT+;V#Mk3{NH|!iRU8M8u+>CT&m6>87OJs1F!x4rA}O4Hv2aQ*;(S-(``h;m_wwT_L{4?bY$D?8 z%>nmu2#j*LPD!>lD?%?ZMGfbnouOB9jE31ZHs)Lpw)PwU@LJ5a8T;9z$CajbU=2H2 zh$3|<4dU|j4wZ+~VscDZPG9*b{v9JxwRAcTAT87npGCg}wYWgjh=OR>@#Ruzc}%ht z!uJO&>Jt<&#ziy24GSBtg25_kej3>v9NzJLCfaAJ~*I45NxBcxTcQvhZD+NL>y zo=V|hj8o)*90jL^vxB@KAPc#qCxu$@Se4Fay6RFW+0GtJ&sc!wc|4w9CA(*iYuGfV z6+N{P2TyaPP>E*c?y4Jna9qh10BAx{ljODc7Ry^zxSA<6oOKcvh({|671)nXt*jY0 zxZ3=*5=ujl#8kB}G&aTGo*YsY$lHeiBeV zXW6opD5GW@T%Er7dP9))Q?iI(!etP%xbX(`5lDK0;BQ@Wl)u}#_oTu z6$U8)D&#m0M5K)jCKgP3%rJXgx1D4DD=^OKocee-y{DOtUfs@qJNkX?9(nY!q5PZ3 zCr>t%W`w0t{T#MV<&E4GZ=6pFpnz^reh>FVkoTSzc(g2&*h!&j22uY#R7r-&sV5S% zp>3_wylCjeNa2f?vqK0sYMo&Uez2&Lx{^FI`<(w{jT(Zr2v#fT+>rr}QghoSOx)%CAFChOi48LI z)TgY7ufl`W2eLcvd>)W)z!u zonZxK8FQ}|BgqJRXoruwuJCYwT4VGtu*vxFZdx1#EwJR|aGA9%`=34zA;hpg*NeZ_ W9{gq0_cqI>8BvOVo3@jr-M<3Ttaklw3G6A@66UIb|((t8O-kzS>UQUnpCiZtmUO^_;~ zBOU3GP(w?;?DOCIowL<@Pq}CBv+wtx_{@i_wPxm8V~sgSediD}hM5H@uB)i403Z+! z;DP-IU?zd900BNe1Rsw80)Y?`5)hHlkdhD+lQ2+Glhd#;LRncDnVH!*1-RMRFL5w4 z^GIC0Bq$^*DhlP6l9Lpc6%Y{>{$&slAt50NF$p~>DZTJ{=JUdT_XpDqP!iw_-~nI| zJAgw80#kx8Z2%MiKzN`(eSrV?fN;RLc=!+kLLy>phe`?n2LuM=;DYh+aB;D{{jt{p zTuMBu^Fm7a)H?Sd?9Md8LGiB$IIfhn(B2wEaEe&C1QQaSqoZeFhnm`tt!?ccou9h8zYM{LM@GlSC+6lC7MH#)udJ>icXs#o z4-QdB$G^}8!qWMlpZ|}r@93h$(uISI3&w@~LKg_f6WhR)xOnG<@Trt^AorZ9*@c4$ zXs*P+Dr+I+5V?h*wQw0EI>#wG$A$cbv_Dbyw-FZn4^j4i3Hvi$695Sqgk>I>5>NmR zk9o2KiT>UGcfSMP-08e~=DDSpi;JJRi(JoFxNW?@-PVsc#vz))IrN%u*!+V5Ia*p1 zaDS$kU=}biO;(kZQ(ZMIfE-+SLaTMQH;YdC{J^Z@CEA|!vSMs^XZPr>^qDZT)&{_z zP}#3VVv}Kh)N;x0SkxW^7{BJm04jGB5QD5D7$DPu0|S6&FhFD$`CHr4 zKcR{SH(>xe)l*T`C=9SXqlN*RJu$%i3V6+sZ>bbz8_R$J`m5qGK;Sk8XdlD?q?8K^ zM+aXN5G)t~RSO&^M;zIs896#&yPL0JvoaU}=>}`P=GBk(uZTT`z|aDL^10cKh8Q3; z44HX)vI<3!VSrN;=->8WHxdsXBVUK|!9QLvMFD@4<``yM~ z=I;1_0pfG+U6UdN0E17JrjQCPGcRzRG83!Ag@8byaj zYoRefCE$-8#L*7v*eUM9M^0hfUEuoOyo7v|Lu_awU{Id_Nu05PogM*sZ)&=JtOXRj zlSQ6yTS_tnvttpH!#&Ka)a#p*XV%^ zqRy{y41i#Pp$f=131>^U)-tuqOECbgB5Sd-x7MjBG&uaEHWLlLj6G*)=-JT^ejrkG z^|r6|y^%Ez#@Iqu1w&x(I^ShYJ$YGWbigz zX3fNleyn=l!1D41sjaryn{d$H*WRxU&-mrwNF}PBe!eF<`xibq_%28U?@>Sw;^4*@ z06*idE!*U*&9P}H)Hy4KZ+pi z6HM)gFP@CpA^Rg!@73Qfj$d&n#7>gt>_G9RIYFd6Y|(NUJ8`7V(7drIjnf-Gs7O8e z8HW@M5K&~vgVR2|G`u(M@U^F!YJq9VWizHhOUyKa2gv@%8;-A0-HVHD2Psr7!g~qa zysay$VpAyB1-htu>6V+>?mP<1Nk?|D3!m<-j?|+gfMeLl8R#C1!EEJ-!_v?rV_=Ax z9_)N-@QKBn16itHUS9?0x2!Gy5HUZkRKpeC$_JjJG{e<1nVkts!vMho)pnz-4zErQ zT+2oIU*3NL2|c6%9YoVMdqL;>pPpKgI5VVZ!TV??jMcL0%&C`No-T04bjAeN9Robs z5&!SC64mw@%2SEiPevyy`&P9OoW8F~-&WMRmzS8`W%a_mLa?%w_B63IXJTUYpf{d5 zD)$@nOXg);$xeDnxn96uj5C~yE`FE>M$HT|E~!Csf0V|ne{W*%;qsY*ZF2I)`_J){ zwo;Jwh$D_$NXM|sOu+}z-(I=IrVn;GEs?>-`+$RX3vEdK`b>p?OI+U53a?=ybQK2R zT;^6_mw2NPi6|9EDzx>}dX>98V0;-rDLCO!93I0i2Zz2u_B!urgOq80vj!fVkkC`% zU2~ylrtmL>*Ha^#OcCqtc7=6oX-@YVaxHeVk%#)#lHgaT>)rWTj zaW6APhlFf`q^{1I`YaK$pV1FCwAY#TxmBD0?2FKC*UN&Q47ZAtH#cm-V_RFB8~j|g zbs3WU^CmkQe0aLx8tz=bIVAZ)G5W1+n&;yZ&hnwEP2Y0Xu0<(x59aiIl`mxAMRyjy zep#)B87i+@RrCn_n=SqFMp>D@5(`<+0tb9?R78I8K; zb-6W0o-CY*->Kz>+VOvjvAyrL6djV2b1&&BTd*{%H2jV>WB^JkFGVu35^%}Sf9xLo zv-67Vd?yBg9xgMd9k#j0gLCk2fpD2a%s`_hexj&;?>YCUYNI46X;QrhRk9)lv8NF|HM%cw^2(OUrLp z6%7&q+tYJyCw+DxlHxi9?eYQ5sO}ur!m)qrDk0OojaV(ZhArH zlfxGZok<)H1-ogjcGpi%PozJ##R@ zB8B&-y)5!Z+tPC=BV;y<{l+m}IH#J}CEU=BxU&AhEPPJnd8y5i4X;wW-)~L*v)1nW zN(?|@7r^kv8eVDiI+y^Sp^qOIlwLr%6njs%UT?nla!c){v^RwUW1~wkoGspF@AJ2A zDv;%2wO%Ky^st|6QRUL!6aKiQ>dL$4IgDR2+u*(PmP5bP#@}wc9GTW1wVc*BqJBx# zq>Zcoq3$;`12x&@lbj`1RIhjY->Tkd_e{hYb{Cy;DZm6Yf7BvBRDKeww#c9b{XDlsH3% zDbh|1F9RrfI&x^Js8jPIv`j_qjL({1yaShzG^zf94Ci&o3J-WrYh!)GWwI%nzr z*gl@n!_}sbjffMj>eG`}4B$s3|EJ#~VKX>^@)YR4#*Tna=h)-LnK_-$_Rc`hfCjxB z@hfOw;V5ck`~t7O8!>MAFw-5U zhG~2JuqDM?P(Ih%XPyBbd+M(V_?0UAGq|2e*gZwdxqrqkjFN)9Bam+F#weL2k{C+` zmY?!EW=a^KRjf7kh#rbQjYVdmdz~pe!=UmA?051^o>D!eUNel!R{XuG-Iw-4qdfgt z73!eAfE&!QulnWqK3heoS$XBEs8ej-zZd-4Nr@#NhxfmVWgW(1-xXa+`&m<{pQ@8h zs0&AVeO&Zl6+l@dcV{7_3wJjzzzmWdD31ZM>zU?kIx5p0+{kHf;MOZU<_k5O;{(qU z51S^oXELYk`@Vf* zNK||sByl>Bx-&z(3E3Y8)vn{>UzkdcBg55MjE_&;rHslz9pKa${xzeB&-FUOGhD1v zWk{6&$~TFV_peEpGEodnFhijAtwoIbl3KQkH%o8o@il9InLF?LK`G&>2%^DoxgP>?>R;G4!LCGPbyOoADzU|duCD4tH-?z_v#xct ziu3ME(!7{c-?VxA?dO|wb=3*e^PFjfcV5STdX)r^qEMO*mSIFFghO#6n9^-NJ}?OI zwi@!-k$!oFCP4j&H8@a~C?eVRes!9fb#zX$IM2#@=q*XMkbx+-{QRG~?xl7pU1XXA z?c6}Ux=3#xOWEYtvd@z{1z;-Ja8Tl!T&LDK>~ca?)&w7n@Vzj|Nh8#jb?InHg6|M; zGne+Hk55SphZ=uG3n?XUcqzd;vQ?>JSgxS#!7a{u{g&{F& zW5Tr=O1SP>ge!k=7n?UDH{Zz4(7pF;FJ@yTMP^5}piz~0xRYZ(rIs56gtn?ka>S_h-&17vY|~v(FjG1B+mJZT@sCyEPkaetgC28226DpN`TWwv&etZ zSS^|Owj`X4z7MeBpzTl3oclaxFRz+xXm>hNwUgK}+Y07~0OaP-=ht=P;-5N7w5u3^2z}86rJxh53AggzlX*(iy_s1~<=g-p--m`B z?h^5Uw+~zi8bjWl>m<1a<1kZNF~vuWhQ10H?PdKU#Q_k9h8y1PkP=X_&&eXwYc(U6y*#I% z&G;yVFdZKc{)yGXH@(dUK~FpUJ9yJN@V!D7>yH{N*GKpY?eH0;v;~i&_T=|>tJ}1K zQYNGlZzJAo`rjMTxaFyJ&c!7QR09En`S%&b_8PE;A2kODtrc(cY{Er zUjKXp*|r9&O;2rKl7{PR4I9NQNo|SxnEGty4Uf`jd$ZPQc6dF1(bWPw zJ$}-*`}c7?KGopn1Vz1V{&bK`UNelr3&*IWB9~ZLzx2=ditrr8GoVVAX*KJ=}oL z=T5q-LiFiI|y=QT8Zgy(X z!ugU%&u@;6vQdx;8V9SHqU3@KrpXYdg$oYWGNjVyC>I&Fo~y^uZmI9@v7FV2?PGu^ zewW{%u3ibbK4d`@Cc>EtdgEtaXZcnV8i%#E$qBu(29}2X7arUiK z_FzSZXl3R14PQ_Ms*tnSgXcY)H~jOA5mC51R+%@nM!Nw2oBb`m{Qe+iz>io|*r=CN zLtzWP8eFxJTzNx82@t;0eag@=341Z#~lf7t03pOCM!r9=P22q>^#%&5qMFx1G zlFKpVmS&bKX}u|7ZuTa(wVtUvx-!=82-h%7jIFf3qD3V6Y_~weY+7r(y?nJjq^)1^ z=&LaZ8H?}+yC@QRF)vMBP?cPqb%yTcYH;?xw54FlmK4hL|wcV9+S8w*Mi_4J-V^DqwerFkbJF&wF5I^Og za}fE+cuCqi1t*)0^?seoQ7Va}i*(x5zsS_&>qm2*3co}4y&Sp{Ke;Y+aYsOquBTa2 zos5t#ai67uJWEFr3Ryc=K6qNtpZ7p~8?Q$|7i;Cu#>Z!5Erd+x>%p6tzWS{`Lq}n*39{9=xIOIDpUboEQEV@5h<;@7cTO79BcN zl+7|Z6I_TAwETys^*(0;^*7xz>D6of!m^F;0X`Pn&4>S$=Bu{Hwyo zv^xqNy?*wYlv_Dh{EDUIJMdxQ29c}{E^Ps|P zX(g{N6c?GU-6o$lnNpWo7#=G_yMb>0u-N&EQLb~`$jqos(E+-R!FXrS#Mr4q9&_m( z7vNA7v}p!9#jm{^65k8snELVppFvm-4Ub`u0695&oyOw zqAYU|>Q2SKG-pm3ZzhD*@ee2Pb1#RBei&P=cCnrp6j|(U4`%}fK8-o0j=g^DQD`DdG23A5|^!xc#P$#K@Hq*Zophib$}c?k&!C8PTUnaO)x zWP)0L(8hQT;%I-q+m&$sFr!F=1l#_ci?{*Vjb9Oc)sS#miM%z0aJ)NC9Uj|;1^$wx zoYH(FUFj>BjRF;<3hpPuC*)@7O?Fe!EJ>ftYZ(%ITak7D50w6bJUfLAFAW8-@>h_3 z8a=cJCs{OI7_nZ3vt(Hgq#YSHj2^@fKd*Fvs@^@i1$JwlD$~ILS(RS8Kdc}P5@BOa zX2Fgf4G!FE%AbW~0buQ>kKSk#(J6#H*iVQ)iMG<{9an8!{?v1wlXuSPg)6>^rW^>S z){*1USjMd_a&Z=M@`?+pI1b&^J4a!MI%c{*@Zw+LIpC2Rsh5w6)}79+@8l<@LW;izU@_CDq~~NMey?g39F6K+3e;_^P~6Ix7k7u3`Mn zQ+kHe3Ea$^x z&=()kJaEzQkogH~{pTITor#sTB#Rbhe3LNS%}ed`n%uhjpVT*RkhOSCMX7bICeWXp zHV)6<`CbbD@`8?v8V-ZDM2~W(5A<%7MJW^B(PaHOJ%ekc7`B|7)`g9^ zH!2+X9IO0cV1@F$s3Z))#n+17u(cdqo7C)DA`RK+Z(WmTtqvGm*=XGgs_a?SF;r_}M+N z@gAQ+uHi;jrc}DidB*&$Q8q%eg#kuEr+iD&CpPokr-?8s*qAiz3>a;L|G?$-%<@79 zRJ5By!<$bEJDfJhdT{rh(G4s{k&7L60@1*}f=;tre+bF>3-yq;CW<$^jT~O_ooBdt zW?i4qNxgSxqQd1RN4wVC`LNK-nU13CzgqIV-=5{}M{=2JXwgFt2MXMa=fdhSz&YCi zEFM#1g>KiK26V`hcg~6Y*t)6v&6|9pSBkT@e`+fJG%WnR$o(fDgP)_qvB001w#);v zObnnXh7|KJM^dBJo5B?~SQOBK_VW*ZMeZ*$cE5Cd27Ub+1~?$Yg4C|YH0ENFsy48r zi*(Tcd*+WJ%CMr7Jhc8E7AacQfC26?#h%d*M;e(5Vv(eirWoK|bSFCMLHnmC#AjJ^`vpZu5p*yP%~=q7ZOA#jrXdyC}%=6+;0^Oyf}4Gtglx0xMXKyzXr z*9`+4gG$4Hm~G&ZKe3A%1B^+Vosmf&CpQ|NrDK4_*IF3Bd=<7QxxQxj1Ka;u>h<_Rw@`QMWvyfb@jk8et*7jc^hkkZX@Hedq5iKuS zhdi^#ID9WCUOYug%h>GQFJ&ryqhO1=gOa$OX**RLsQ9&6sD@(?n&j92XO;UO>KCdR z(7TN0iPna}m7DgA-8U+CF~G)nLE>5UYYIVelgqLg0J}=KPS;n6{xB1MXC`(h6-{4D zeq`rOm5BwFUq8Cum~oaPa19Gdu7-Sjp>s9%9`nekPly5370kW4}&})Pgk%bHF#n0 zMbzE0lD~I|+`}RV11LQ})b2IKq@}GXP?zLjVe7AySjzhIKV$bl_>ZRjU?@VqU_mTT z-kL!kcq%)8GkXRZeP|0S_Eq*iZ1KNXQ5q_3{_s)lS2t($_@^_VROyEa^t-zo|DoFm zmZEK*%sD5y^QxB3H&Tr}>`O0saE{Y*<4{;RR~*rhq`k z)&*Y0`_Hy3VPOma zvn9m)bTj^{f_z7MoS8N;8}6NWoOA z^6WQun(ieIMfWxJVt`MjS@!(_qPD8WDEojrRvYA#dT4;j6D@5RD1YVq$1T-GK}u9} z{gmttmd06MJsjZS4!N*og}wn9sV^wClYU&QQfl?~iU|MfRpF=wE`8AQb)%L7N6w;0V0IP*JxfpgXC1-k#npxQa+_OA>C-F2NJipCyd@ zSA_ARc&>BE2B*2g_2q*0{UNglbP|q-c}a_og;cO&yw@FMH9#kWBDsS5h?K-iENT33z@qzIT3{c#LK-paF=hN0=MR?=G$ z^B2P5hj($I1H)-p=pU);O=cHD`SC4GIe-kJA*|>;%q775PN* zx!sh%wfO!WD+b`a3v2}a?t2=_R{a# zXZHdxyXLX=gOwNbN1<>h@4YcqmS}(CAMB7{g#-RFH1Jz}_rd_1pn01w^<4Pz_L4CR z+9_1|3PO*;AKbUFKqyULJil<{i*`y>$~<0km4$=b{s|Q`qTL`;a4|+d!#9uz+_&;w zvWD*iN;xlGb>1T)i{+i>K`3^sp^JjC9=U1DiHyEjXY6GGWa?&-J~etsI_MZbi#+f9 z0e&m7__vOWjGYkCRQH4CJ>bJ%&1$4%z*#Ji7Lt++T{3GM?b$!5ZZl!FZv;k)+T`7` zhnJoJUBbM{#=eV0sQlnOT=N(>@a#Kqfm-RnG8>#fw zgs9XFU!LNstkC4h5FTS_-sjF@>B=IbTOf~}N2G-2mQ|$REQ2w`i0ZYrGU4MJgX5zp z$VpaUK@;)1lJV+Z(wXMg-D7C4CANe|V%5?2*r~fY?&s)))OgFa+og zHI+9e9%$iyUAr05Q(tEu9dn%xJajVI#CueCV`zEUT|-lT_^PqVjdva7nmtY;G2>zf z+fPNkP8H@FWYnXA`T4)F&rI_I{8&8o$nX2kc>bEc0|~`Ppjzk6p3bxeC=3_%s7P8p zFX8W)0y8D3NUlgR`{+&3?jCMJ=SFtjGO0PJ>H=DL6Nk3d9+UWXz0COBX$T+~zenC4 zYaBQaCzz40`6$IbH?Q6Om^jFC$4O2&Z&z&B!4pO(dzq%-a` z-cQfQjK%r{%D4S1-%x34qom(82hY2St-VOuFow z1^O^PXjJg+nwufZd}Mu>s8w})= z)nb60WvT9Gkq6rrrsYPird58+y!e%?Xd6r+lu&dB1MuekppBr`enLp&00D$t^mu&Q z)>pjBksV?NT@`%{(9jwnHa^lq+)1a({<=R5 z_`9e#E3XiXOWKN0-s$6e0CACtpP9{xzIf^nrjPOFbC%5#9jPvmx2YgQ zYu!!=%}!X`$F=eCY~s%0n-bzVANt2O04@QdNQc8{SylN$pSFu!Y>~3ctm?YZOzs-7 zzMtSgX=nU65%yk99q%rEB7G7w`68h!$*D*Pdc&`?Y=iNG*ZG8RUbCSR$#(SYDiH?h z;mrVn9aHPiDQa_Zxe>+^+Z-@ z_Dtk1mC8=p&AD$i&p%VCp9gV1(N_N$ zHA~dI|rnHGEP2(y&8N zjQF@E&D+zfkX{BBh@z_BG0`z&!Rmqdv30tmr5%0D^t4!nC`*zGWT)_ltlST3`d?LZ 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 literal 0 HcmV?d00001 diff --git a/include/render.hpp b/include/render.hpp new file mode 100644 index 0000000..23c50d3 --- /dev/null +++ b/include/render.hpp @@ -0,0 +1,20 @@ +#ifndef OUR_DICK_RENDER_HPP +#define OUR_DICK_RENDER_HPP + +#include + +#define OPENFL_VERSION 400 +#define GLSL_VERSION 400 + +class RenderManager +{ +public: + RenderManager (RenderManager&) = delete; + RenderManager (RenderManager&&) = delete; + + RenderManager(); + bool Init(uint16_t width, uint16_t height, const char* title); // Sets up the OpenGL environment + +}; + +#endif diff --git a/makefile b/makefile index 9203e21..1892bb0 100644 --- a/makefile +++ b/makefile @@ -40,7 +40,7 @@ ifneq ($(WINDOWS),1) CC::=gcc CXX::=g++ LDLIBS::= - LDFLAGS::= + LDFLAGS::= -lglfw -ldl STRIP::=strip RANLIB::=ranlib AR::=ar diff --git a/shaders/game_board.frag b/shaders/game_board.frag new file mode 100644 index 0000000..e69de29 diff --git a/shaders/game_board.vert b/shaders/game_board.vert new file mode 100644 index 0000000..e69de29 diff --git a/src/gl3w.cpp b/src/gl3w.cpp new file mode 100644 index 0000000..6c14a06 --- /dev/null +++ b/src/gl3w.cpp @@ -0,0 +1,846 @@ +/* + * This file was generated with gl3w_gen.py, part of gl3w + * (hosted at https://github.com/skaslev/gl3w) + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#if defined(_WIN32) +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN 1 // Exclude advanced Windows headers +#endif // WIN32_LEAN_AND_MEAN +#include + +static HMODULE libgl; +static PROC (__stdcall *wgl_get_proc_address)(LPCSTR); + +static int open_libgl(void) +{ + libgl = LoadLibraryA("opengl32.dll"); + if (!libgl) + return GL3W_ERROR_LIBRARY_OPEN; + + *(void **)(&wgl_get_proc_address) = GetProcAddress(libgl, "wglGetProcAddress"); + return GL3W_OK; +} + +static void close_libgl(void) +{ + FreeLibrary(libgl); +} + +static GL3WglProc get_proc(const char *proc) +{ + GL3WglProc res; + + res = (GL3WglProc)wgl_get_proc_address(proc); + if (!res) + res = (GL3WglProc)GetProcAddress(libgl, proc); + return res; +} +#elif defined(__APPLE__) +#include + +static void *libgl; + +static int open_libgl(void) +{ + libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL); + if (!libgl) + return GL3W_ERROR_LIBRARY_OPEN; + + return GL3W_OK; +} + +static void close_libgl(void) +{ + dlclose(libgl); +} + +static GL3WglProc get_proc(const char *proc) +{ + GL3WglProc res; + + *(void **)(&res) = dlsym(libgl, proc); + return res; +} +#else +#include + +static void *libgl; +static GL3WglProc (*glx_get_proc_address)(const GLubyte *); + +static int open_libgl(void) +{ + libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL); + if (!libgl) + return GL3W_ERROR_LIBRARY_OPEN; + + *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB"); + return GL3W_OK; +} + +static void close_libgl(void) +{ + dlclose(libgl); +} + +static GL3WglProc get_proc(const char *proc) +{ + GL3WglProc res; + + res = glx_get_proc_address((const GLubyte *)proc); + if (!res) + *(void **)(&res) = dlsym(libgl, proc); + return res; +} +#endif + +static struct { + int major, minor; +} version; + +static int parse_version(void) +{ + if (!glGetIntegerv) + return GL3W_ERROR_INIT; + + glGetIntegerv(GL_MAJOR_VERSION, &version.major); + glGetIntegerv(GL_MINOR_VERSION, &version.minor); + + if (version.major < 3) + return GL3W_ERROR_OPENGL_VERSION; + return GL3W_OK; +} + +static void load_procs(GL3WGetProcAddressProc proc); + +int gl3wInit(void) +{ + int res; + + res = open_libgl(); + if (res) + return res; + + atexit(close_libgl); + return gl3wInit2(get_proc); +} + +int gl3wInit2(GL3WGetProcAddressProc proc) +{ + load_procs(proc); + return parse_version(); +} + +int gl3wIsSupported(int major, int minor) +{ + if (major < 3) + return 0; + if (version.major == major) + return version.minor >= minor; + return version.major >= major; +} + +GL3WglProc gl3wGetProcAddress(const char *proc) +{ + return get_proc(proc); +} + +static const char *proc_names[] = { + "glActiveShaderProgram", + "glActiveTexture", + "glAttachShader", + "glBeginConditionalRender", + "glBeginQuery", + "glBeginQueryIndexed", + "glBeginTransformFeedback", + "glBindAttribLocation", + "glBindBuffer", + "glBindBufferBase", + "glBindBufferRange", + "glBindBuffersBase", + "glBindBuffersRange", + "glBindFragDataLocation", + "glBindFragDataLocationIndexed", + "glBindFramebuffer", + "glBindImageTexture", + "glBindImageTextures", + "glBindProgramPipeline", + "glBindRenderbuffer", + "glBindSampler", + "glBindSamplers", + "glBindTexture", + "glBindTextureUnit", + "glBindTextures", + "glBindTransformFeedback", + "glBindVertexArray", + "glBindVertexBuffer", + "glBindVertexBuffers", + "glBlendColor", + "glBlendEquation", + "glBlendEquationSeparate", + "glBlendEquationSeparatei", + "glBlendEquationi", + "glBlendFunc", + "glBlendFuncSeparate", + "glBlendFuncSeparatei", + "glBlendFunci", + "glBlitFramebuffer", + "glBlitNamedFramebuffer", + "glBufferData", + "glBufferStorage", + "glBufferSubData", + "glCheckFramebufferStatus", + "glCheckNamedFramebufferStatus", + "glClampColor", + "glClear", + "glClearBufferData", + "glClearBufferSubData", + "glClearBufferfi", + "glClearBufferfv", + "glClearBufferiv", + "glClearBufferuiv", + "glClearColor", + "glClearDepth", + "glClearDepthf", + "glClearNamedBufferData", + "glClearNamedBufferSubData", + "glClearNamedFramebufferfi", + "glClearNamedFramebufferfv", + "glClearNamedFramebufferiv", + "glClearNamedFramebufferuiv", + "glClearStencil", + "glClearTexImage", + "glClearTexSubImage", + "glClientWaitSync", + "glClipControl", + "glColorMask", + "glColorMaski", + "glCompileShader", + "glCompressedTexImage1D", + "glCompressedTexImage2D", + "glCompressedTexImage3D", + "glCompressedTexSubImage1D", + "glCompressedTexSubImage2D", + "glCompressedTexSubImage3D", + "glCompressedTextureSubImage1D", + "glCompressedTextureSubImage2D", + "glCompressedTextureSubImage3D", + "glCopyBufferSubData", + "glCopyImageSubData", + "glCopyNamedBufferSubData", + "glCopyTexImage1D", + "glCopyTexImage2D", + "glCopyTexSubImage1D", + "glCopyTexSubImage2D", + "glCopyTexSubImage3D", + "glCopyTextureSubImage1D", + "glCopyTextureSubImage2D", + "glCopyTextureSubImage3D", + "glCreateBuffers", + "glCreateFramebuffers", + "glCreateProgram", + "glCreateProgramPipelines", + "glCreateQueries", + "glCreateRenderbuffers", + "glCreateSamplers", + "glCreateShader", + "glCreateShaderProgramv", + "glCreateTextures", + "glCreateTransformFeedbacks", + "glCreateVertexArrays", + "glCullFace", + "glDebugMessageCallback", + "glDebugMessageControl", + "glDebugMessageInsert", + "glDeleteBuffers", + "glDeleteFramebuffers", + "glDeleteProgram", + "glDeleteProgramPipelines", + "glDeleteQueries", + "glDeleteRenderbuffers", + "glDeleteSamplers", + "glDeleteShader", + "glDeleteSync", + "glDeleteTextures", + "glDeleteTransformFeedbacks", + "glDeleteVertexArrays", + "glDepthFunc", + "glDepthMask", + "glDepthRange", + "glDepthRangeArrayv", + "glDepthRangeIndexed", + "glDepthRangef", + "glDetachShader", + "glDisable", + "glDisableVertexArrayAttrib", + "glDisableVertexAttribArray", + "glDisablei", + "glDispatchCompute", + "glDispatchComputeIndirect", + "glDrawArrays", + "glDrawArraysIndirect", + "glDrawArraysInstanced", + "glDrawArraysInstancedBaseInstance", + "glDrawBuffer", + "glDrawBuffers", + "glDrawElements", + "glDrawElementsBaseVertex", + "glDrawElementsIndirect", + "glDrawElementsInstanced", + "glDrawElementsInstancedBaseInstance", + "glDrawElementsInstancedBaseVertex", + "glDrawElementsInstancedBaseVertexBaseInstance", + "glDrawRangeElements", + "glDrawRangeElementsBaseVertex", + "glDrawTransformFeedback", + "glDrawTransformFeedbackInstanced", + "glDrawTransformFeedbackStream", + "glDrawTransformFeedbackStreamInstanced", + "glEnable", + "glEnableVertexArrayAttrib", + "glEnableVertexAttribArray", + "glEnablei", + "glEndConditionalRender", + "glEndQuery", + "glEndQueryIndexed", + "glEndTransformFeedback", + "glFenceSync", + "glFinish", + "glFlush", + "glFlushMappedBufferRange", + "glFlushMappedNamedBufferRange", + "glFramebufferParameteri", + "glFramebufferParameteriMESA", + "glFramebufferRenderbuffer", + "glFramebufferTexture", + "glFramebufferTexture1D", + "glFramebufferTexture2D", + "glFramebufferTexture3D", + "glFramebufferTextureLayer", + "glFrontFace", + "glGenBuffers", + "glGenFramebuffers", + "glGenProgramPipelines", + "glGenQueries", + "glGenRenderbuffers", + "glGenSamplers", + "glGenTextures", + "glGenTransformFeedbacks", + "glGenVertexArrays", + "glGenerateMipmap", + "glGenerateTextureMipmap", + "glGetActiveAtomicCounterBufferiv", + "glGetActiveAttrib", + "glGetActiveSubroutineName", + "glGetActiveSubroutineUniformName", + "glGetActiveSubroutineUniformiv", + "glGetActiveUniform", + "glGetActiveUniformBlockName", + "glGetActiveUniformBlockiv", + "glGetActiveUniformName", + "glGetActiveUniformsiv", + "glGetAttachedShaders", + "glGetAttribLocation", + "glGetBooleani_v", + "glGetBooleanv", + "glGetBufferParameteri64v", + "glGetBufferParameteriv", + "glGetBufferPointerv", + "glGetBufferSubData", + "glGetCompressedTexImage", + "glGetCompressedTextureImage", + "glGetCompressedTextureSubImage", + "glGetDebugMessageLog", + "glGetDoublei_v", + "glGetDoublev", + "glGetError", + "glGetFloati_v", + "glGetFloatv", + "glGetFragDataIndex", + "glGetFragDataLocation", + "glGetFramebufferAttachmentParameteriv", + "glGetFramebufferParameteriv", + "glGetFramebufferParameterivMESA", + "glGetGraphicsResetStatus", + "glGetInteger64i_v", + "glGetInteger64v", + "glGetIntegeri_v", + "glGetIntegerv", + "glGetInternalformati64v", + "glGetInternalformativ", + "glGetMultisamplefv", + "glGetNamedBufferParameteri64v", + "glGetNamedBufferParameteriv", + "glGetNamedBufferPointerv", + "glGetNamedBufferSubData", + "glGetNamedFramebufferAttachmentParameteriv", + "glGetNamedFramebufferParameteriv", + "glGetNamedRenderbufferParameteriv", + "glGetObjectLabel", + "glGetObjectPtrLabel", + "glGetPointerv", + "glGetProgramBinary", + "glGetProgramInfoLog", + "glGetProgramInterfaceiv", + "glGetProgramPipelineInfoLog", + "glGetProgramPipelineiv", + "glGetProgramResourceIndex", + "glGetProgramResourceLocation", + "glGetProgramResourceLocationIndex", + "glGetProgramResourceName", + "glGetProgramResourceiv", + "glGetProgramStageiv", + "glGetProgramiv", + "glGetQueryBufferObjecti64v", + "glGetQueryBufferObjectiv", + "glGetQueryBufferObjectui64v", + "glGetQueryBufferObjectuiv", + "glGetQueryIndexediv", + "glGetQueryObjecti64v", + "glGetQueryObjectiv", + "glGetQueryObjectui64v", + "glGetQueryObjectuiv", + "glGetQueryiv", + "glGetRenderbufferParameteriv", + "glGetSamplerParameterIiv", + "glGetSamplerParameterIuiv", + "glGetSamplerParameterfv", + "glGetSamplerParameteriv", + "glGetShaderInfoLog", + "glGetShaderPrecisionFormat", + "glGetShaderSource", + "glGetShaderiv", + "glGetString", + "glGetStringi", + "glGetSubroutineIndex", + "glGetSubroutineUniformLocation", + "glGetSynciv", + "glGetTexImage", + "glGetTexLevelParameterfv", + "glGetTexLevelParameteriv", + "glGetTexParameterIiv", + "glGetTexParameterIuiv", + "glGetTexParameterfv", + "glGetTexParameteriv", + "glGetTextureImage", + "glGetTextureLevelParameterfv", + "glGetTextureLevelParameteriv", + "glGetTextureParameterIiv", + "glGetTextureParameterIuiv", + "glGetTextureParameterfv", + "glGetTextureParameteriv", + "glGetTextureSubImage", + "glGetTransformFeedbackVarying", + "glGetTransformFeedbacki64_v", + "glGetTransformFeedbacki_v", + "glGetTransformFeedbackiv", + "glGetUniformBlockIndex", + "glGetUniformIndices", + "glGetUniformLocation", + "glGetUniformSubroutineuiv", + "glGetUniformdv", + "glGetUniformfv", + "glGetUniformiv", + "glGetUniformuiv", + "glGetVertexArrayIndexed64iv", + "glGetVertexArrayIndexediv", + "glGetVertexArrayiv", + "glGetVertexAttribIiv", + "glGetVertexAttribIuiv", + "glGetVertexAttribLdv", + "glGetVertexAttribPointerv", + "glGetVertexAttribdv", + "glGetVertexAttribfv", + "glGetVertexAttribiv", + "glGetnCompressedTexImage", + "glGetnTexImage", + "glGetnUniformdv", + "glGetnUniformfv", + "glGetnUniformiv", + "glGetnUniformuiv", + "glHint", + "glInvalidateBufferData", + "glInvalidateBufferSubData", + "glInvalidateFramebuffer", + "glInvalidateNamedFramebufferData", + "glInvalidateNamedFramebufferSubData", + "glInvalidateSubFramebuffer", + "glInvalidateTexImage", + "glInvalidateTexSubImage", + "glIsBuffer", + "glIsEnabled", + "glIsEnabledi", + "glIsFramebuffer", + "glIsProgram", + "glIsProgramPipeline", + "glIsQuery", + "glIsRenderbuffer", + "glIsSampler", + "glIsShader", + "glIsSync", + "glIsTexture", + "glIsTransformFeedback", + "glIsVertexArray", + "glLineWidth", + "glLinkProgram", + "glLogicOp", + "glMapBuffer", + "glMapBufferRange", + "glMapNamedBuffer", + "glMapNamedBufferRange", + "glMemoryBarrier", + "glMemoryBarrierByRegion", + "glMinSampleShading", + "glMultiDrawArrays", + "glMultiDrawArraysIndirect", + "glMultiDrawArraysIndirectCount", + "glMultiDrawElements", + "glMultiDrawElementsBaseVertex", + "glMultiDrawElementsIndirect", + "glMultiDrawElementsIndirectCount", + "glNamedBufferData", + "glNamedBufferStorage", + "glNamedBufferSubData", + "glNamedFramebufferDrawBuffer", + "glNamedFramebufferDrawBuffers", + "glNamedFramebufferParameteri", + "glNamedFramebufferReadBuffer", + "glNamedFramebufferRenderbuffer", + "glNamedFramebufferTexture", + "glNamedFramebufferTextureLayer", + "glNamedRenderbufferStorage", + "glNamedRenderbufferStorageMultisample", + "glObjectLabel", + "glObjectPtrLabel", + "glPatchParameterfv", + "glPatchParameteri", + "glPauseTransformFeedback", + "glPixelStoref", + "glPixelStorei", + "glPointParameterf", + "glPointParameterfv", + "glPointParameteri", + "glPointParameteriv", + "glPointSize", + "glPolygonMode", + "glPolygonOffset", + "glPolygonOffsetClamp", + "glPopDebugGroup", + "glPrimitiveRestartIndex", + "glProgramBinary", + "glProgramParameteri", + "glProgramUniform1d", + "glProgramUniform1dv", + "glProgramUniform1f", + "glProgramUniform1fv", + "glProgramUniform1i", + "glProgramUniform1iv", + "glProgramUniform1ui", + "glProgramUniform1uiv", + "glProgramUniform2d", + "glProgramUniform2dv", + "glProgramUniform2f", + "glProgramUniform2fv", + "glProgramUniform2i", + "glProgramUniform2iv", + "glProgramUniform2ui", + "glProgramUniform2uiv", + "glProgramUniform3d", + "glProgramUniform3dv", + "glProgramUniform3f", + "glProgramUniform3fv", + "glProgramUniform3i", + "glProgramUniform3iv", + "glProgramUniform3ui", + "glProgramUniform3uiv", + "glProgramUniform4d", + "glProgramUniform4dv", + "glProgramUniform4f", + "glProgramUniform4fv", + "glProgramUniform4i", + "glProgramUniform4iv", + "glProgramUniform4ui", + "glProgramUniform4uiv", + "glProgramUniformMatrix2dv", + "glProgramUniformMatrix2fv", + "glProgramUniformMatrix2x3dv", + "glProgramUniformMatrix2x3fv", + "glProgramUniformMatrix2x4dv", + "glProgramUniformMatrix2x4fv", + "glProgramUniformMatrix3dv", + "glProgramUniformMatrix3fv", + "glProgramUniformMatrix3x2dv", + "glProgramUniformMatrix3x2fv", + "glProgramUniformMatrix3x4dv", + "glProgramUniformMatrix3x4fv", + "glProgramUniformMatrix4dv", + "glProgramUniformMatrix4fv", + "glProgramUniformMatrix4x2dv", + "glProgramUniformMatrix4x2fv", + "glProgramUniformMatrix4x3dv", + "glProgramUniformMatrix4x3fv", + "glProvokingVertex", + "glPushDebugGroup", + "glQueryCounter", + "glReadBuffer", + "glReadPixels", + "glReadnPixels", + "glReleaseShaderCompiler", + "glRenderbufferStorage", + "glRenderbufferStorageMultisample", + "glResumeTransformFeedback", + "glSampleCoverage", + "glSampleMaski", + "glSamplerParameterIiv", + "glSamplerParameterIuiv", + "glSamplerParameterf", + "glSamplerParameterfv", + "glSamplerParameteri", + "glSamplerParameteriv", + "glScissor", + "glScissorArrayv", + "glScissorIndexed", + "glScissorIndexedv", + "glShaderBinary", + "glShaderSource", + "glShaderStorageBlockBinding", + "glSpecializeShader", + "glStencilFunc", + "glStencilFuncSeparate", + "glStencilMask", + "glStencilMaskSeparate", + "glStencilOp", + "glStencilOpSeparate", + "glTexBuffer", + "glTexBufferRange", + "glTexImage1D", + "glTexImage2D", + "glTexImage2DMultisample", + "glTexImage3D", + "glTexImage3DMultisample", + "glTexParameterIiv", + "glTexParameterIuiv", + "glTexParameterf", + "glTexParameterfv", + "glTexParameteri", + "glTexParameteriv", + "glTexStorage1D", + "glTexStorage2D", + "glTexStorage2DMultisample", + "glTexStorage3D", + "glTexStorage3DMultisample", + "glTexSubImage1D", + "glTexSubImage2D", + "glTexSubImage3D", + "glTextureBarrier", + "glTextureBuffer", + "glTextureBufferRange", + "glTextureParameterIiv", + "glTextureParameterIuiv", + "glTextureParameterf", + "glTextureParameterfv", + "glTextureParameteri", + "glTextureParameteriv", + "glTextureStorage1D", + "glTextureStorage2D", + "glTextureStorage2DMultisample", + "glTextureStorage3D", + "glTextureStorage3DMultisample", + "glTextureSubImage1D", + "glTextureSubImage2D", + "glTextureSubImage3D", + "glTextureView", + "glTransformFeedbackBufferBase", + "glTransformFeedbackBufferRange", + "glTransformFeedbackVaryings", + "glUniform1d", + "glUniform1dv", + "glUniform1f", + "glUniform1fv", + "glUniform1i", + "glUniform1iv", + "glUniform1ui", + "glUniform1uiv", + "glUniform2d", + "glUniform2dv", + "glUniform2f", + "glUniform2fv", + "glUniform2i", + "glUniform2iv", + "glUniform2ui", + "glUniform2uiv", + "glUniform3d", + "glUniform3dv", + "glUniform3f", + "glUniform3fv", + "glUniform3i", + "glUniform3iv", + "glUniform3ui", + "glUniform3uiv", + "glUniform4d", + "glUniform4dv", + "glUniform4f", + "glUniform4fv", + "glUniform4i", + "glUniform4iv", + "glUniform4ui", + "glUniform4uiv", + "glUniformBlockBinding", + "glUniformMatrix2dv", + "glUniformMatrix2fv", + "glUniformMatrix2x3dv", + "glUniformMatrix2x3fv", + "glUniformMatrix2x4dv", + "glUniformMatrix2x4fv", + "glUniformMatrix3dv", + "glUniformMatrix3fv", + "glUniformMatrix3x2dv", + "glUniformMatrix3x2fv", + "glUniformMatrix3x4dv", + "glUniformMatrix3x4fv", + "glUniformMatrix4dv", + "glUniformMatrix4fv", + "glUniformMatrix4x2dv", + "glUniformMatrix4x2fv", + "glUniformMatrix4x3dv", + "glUniformMatrix4x3fv", + "glUniformSubroutinesuiv", + "glUnmapBuffer", + "glUnmapNamedBuffer", + "glUseProgram", + "glUseProgramStages", + "glValidateProgram", + "glValidateProgramPipeline", + "glVertexArrayAttribBinding", + "glVertexArrayAttribFormat", + "glVertexArrayAttribIFormat", + "glVertexArrayAttribLFormat", + "glVertexArrayBindingDivisor", + "glVertexArrayElementBuffer", + "glVertexArrayVertexBuffer", + "glVertexArrayVertexBuffers", + "glVertexAttrib1d", + "glVertexAttrib1dv", + "glVertexAttrib1f", + "glVertexAttrib1fv", + "glVertexAttrib1s", + "glVertexAttrib1sv", + "glVertexAttrib2d", + "glVertexAttrib2dv", + "glVertexAttrib2f", + "glVertexAttrib2fv", + "glVertexAttrib2s", + "glVertexAttrib2sv", + "glVertexAttrib3d", + "glVertexAttrib3dv", + "glVertexAttrib3f", + "glVertexAttrib3fv", + "glVertexAttrib3s", + "glVertexAttrib3sv", + "glVertexAttrib4Nbv", + "glVertexAttrib4Niv", + "glVertexAttrib4Nsv", + "glVertexAttrib4Nub", + "glVertexAttrib4Nubv", + "glVertexAttrib4Nuiv", + "glVertexAttrib4Nusv", + "glVertexAttrib4bv", + "glVertexAttrib4d", + "glVertexAttrib4dv", + "glVertexAttrib4f", + "glVertexAttrib4fv", + "glVertexAttrib4iv", + "glVertexAttrib4s", + "glVertexAttrib4sv", + "glVertexAttrib4ubv", + "glVertexAttrib4uiv", + "glVertexAttrib4usv", + "glVertexAttribBinding", + "glVertexAttribDivisor", + "glVertexAttribFormat", + "glVertexAttribI1i", + "glVertexAttribI1iv", + "glVertexAttribI1ui", + "glVertexAttribI1uiv", + "glVertexAttribI2i", + "glVertexAttribI2iv", + "glVertexAttribI2ui", + "glVertexAttribI2uiv", + "glVertexAttribI3i", + "glVertexAttribI3iv", + "glVertexAttribI3ui", + "glVertexAttribI3uiv", + "glVertexAttribI4bv", + "glVertexAttribI4i", + "glVertexAttribI4iv", + "glVertexAttribI4sv", + "glVertexAttribI4ubv", + "glVertexAttribI4ui", + "glVertexAttribI4uiv", + "glVertexAttribI4usv", + "glVertexAttribIFormat", + "glVertexAttribIPointer", + "glVertexAttribL1d", + "glVertexAttribL1dv", + "glVertexAttribL2d", + "glVertexAttribL2dv", + "glVertexAttribL3d", + "glVertexAttribL3dv", + "glVertexAttribL4d", + "glVertexAttribL4dv", + "glVertexAttribLFormat", + "glVertexAttribLPointer", + "glVertexAttribP1ui", + "glVertexAttribP1uiv", + "glVertexAttribP2ui", + "glVertexAttribP2uiv", + "glVertexAttribP3ui", + "glVertexAttribP3uiv", + "glVertexAttribP4ui", + "glVertexAttribP4uiv", + "glVertexAttribPointer", + "glVertexBindingDivisor", + "glViewport", + "glViewportArrayv", + "glViewportIndexedf", + "glViewportIndexedfv", + "glWaitSync", +}; + +union GL3WProcs gl3wProcs; + +static void load_procs(GL3WGetProcAddressProc proc) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(proc_names); i++) + gl3wProcs.ptr[i] = proc(proc_names[i]); +} diff --git a/src/main.cpp b/src/main.cpp index a3cf2cb..5eedc9d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,8 @@ #include #include +#include "render.hpp" + // 0 | 1 | 2 // --------- // 3 | 4 | 5 @@ -83,6 +85,10 @@ int exists_empty_tile(const game_state& gs){ int main(){ srand(time(NULL)); game_state gs = {}; + + RenderManager manager; + manager.Init(640, 480, "Tic-Tac-Gugh"); + while(exists_empty_tile(gs) && gs.turn != -1){ game_turn(gs, get_player_input()); } diff --git a/src/render.cpp b/src/render.cpp new file mode 100644 index 0000000..df62811 --- /dev/null +++ b/src/render.cpp @@ -0,0 +1,33 @@ +#include "render.hpp" + +#include +#include +#include + +RenderManager::RenderManager(){} + +bool RenderManager::Init (uint16_t width, uint16_t height, const char* title){ + if (!glfwInit()) { + printf("[EE] failed to initialize GLFW.\n"); + return false; + } + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + auto window = glfwCreateWindow(width, height, title, nullptr, nullptr); + if (!window) { + printf ("[EE] Could not create window\n"); + return false; + } + + glfwMakeContextCurrent(window); + if (gl3wInit()) { + printf("[EE] failed to initialize OpenGL\n"); + return false; + } + + printf("[DD] OpenGL %s, GLSL %s\n", glGetString(GL_VERSION), glGetString(GL_SHADING_LANGUAGE_VERSION)); + return true; +}