From ad9344f3f8b3601bae5239f1549ef4484647101f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9au?= <theau.baton@etu.univ-amu.fr> Date: Wed, 13 Nov 2024 19:21:27 +0100 Subject: [PATCH] Add vertexArray --- assets/shaders/FrameBuffer-Instanced.frag | 7 +- assets/shaders/Grid-Instanced.frag | 10 ++ assets/shaders/Grid-Instanced.vert | 19 ++++ assets/textures/Test.png | Bin 37257 -> 0 bytes assets/textures/Tile_Test.png | Bin 0 -> 1202 bytes assets/textures/Tile_Test_2.png | Bin 0 -> 2079 bytes assets/textures/Tile_Test_3.png | Bin 0 -> 604 bytes .../graphics/back/geometry/Geometry.hpp | 3 +- .../engine/graphics/back/shaders/Program.cpp | 11 ++ .../engine/graphics/back/shaders/Program.hpp | 2 + .../engine/graphics/front/engine/Engine.cpp | 9 +- .../engine/graphics/front/engine/Engine.hpp | 1 + .../engine/graphics/front/geometry/Plane.hpp | 1 + .../engine/graphics/front/geometry/Quads.cpp | 4 +- .../engine/graphics/front/geometry/Quads.hpp | 1 + .../engine/graphics/front/geometry/Vertex.hpp | 10 ++ .../graphics/front/group/FrameBufferGroup.cpp | 5 +- .../graphics/front/group/FrameBufferGroup.hpp | 2 + .../graphics/front/group/ImageGroup.cpp | 14 +-- .../graphics/front/group/VertexArrayGroup.cpp | 42 ++++++++ .../graphics/front/group/VertexArrayGroup.hpp | 33 ++++++ .../graphics/front/object/VerticesArray.cpp | 20 ++++ .../graphics/front/object/VerticesArray.hpp | 37 +++++++ .../graphics/utility/texture_comparator.hpp | 11 ++ source/main.cpp | 94 +++++++++++++++++- 25 files changed, 316 insertions(+), 20 deletions(-) create mode 100644 assets/shaders/Grid-Instanced.frag create mode 100644 assets/shaders/Grid-Instanced.vert delete mode 100644 assets/textures/Test.png create mode 100644 assets/textures/Tile_Test.png create mode 100644 assets/textures/Tile_Test_2.png create mode 100644 assets/textures/Tile_Test_3.png create mode 100644 source/engine/graphics/front/geometry/Vertex.hpp create mode 100644 source/engine/graphics/front/group/VertexArrayGroup.cpp create mode 100644 source/engine/graphics/front/group/VertexArrayGroup.hpp create mode 100644 source/engine/graphics/front/object/VerticesArray.cpp create mode 100644 source/engine/graphics/front/object/VerticesArray.hpp create mode 100644 source/engine/graphics/utility/texture_comparator.hpp diff --git a/assets/shaders/FrameBuffer-Instanced.frag b/assets/shaders/FrameBuffer-Instanced.frag index 2db481d..736ee8a 100644 --- a/assets/shaders/FrameBuffer-Instanced.frag +++ b/assets/shaders/FrameBuffer-Instanced.frag @@ -6,20 +6,21 @@ in vec2 Texture; uniform sampler2D uSampler[32]; uniform uint uTexturesCount; +uniform vec3 uClearColor; void main() { vec4 color = vec4(0.0, 0.0, 0.0, 1.0); for(uint i = 0; i < uTexturesCount; ++i) { vec4 tcolor = texture(uSampler[i], Texture); - if(tcolor.r != 0.0) { + if(tcolor.r != uClearColor.r) { color.r = tcolor.r; } - if(tcolor.g != 0.0) { + if(tcolor.g != uClearColor.g) { color.g = tcolor.g; } - if(tcolor.b != 0.0) { + if(tcolor.b != uClearColor.b) { color.b = tcolor.b; } } diff --git a/assets/shaders/Grid-Instanced.frag b/assets/shaders/Grid-Instanced.frag new file mode 100644 index 0000000..6860880 --- /dev/null +++ b/assets/shaders/Grid-Instanced.frag @@ -0,0 +1,10 @@ +#version 450 core +out vec4 FragColor; + +in vec2 Texture; + +uniform sampler2D uSampler; + +void main() { + FragColor = texture(uSampler, Texture); +} \ No newline at end of file diff --git a/assets/shaders/Grid-Instanced.vert b/assets/shaders/Grid-Instanced.vert new file mode 100644 index 0000000..f9d3622 --- /dev/null +++ b/assets/shaders/Grid-Instanced.vert @@ -0,0 +1,19 @@ +#version 450 core +layout (location = 0) in vec2 aPos; +layout (location = 1) in vec2 aTex; + +uniform mat4 uProj; +uniform mat4 uView; +uniform mat4 uModel; + +uniform vec4 uData[254]; + +out vec2 Texture; +out vec2 Color; + +void main() { + vec4 usedData = uData[gl_VertexID]; + Texture = usedData.zw; + + gl_Position = uProj * uView * uModel * vec4(aPos.x + usedData.x, aPos.y + usedData.y, 0.0, 1.0); +} \ No newline at end of file diff --git a/assets/textures/Test.png b/assets/textures/Test.png deleted file mode 100644 index 5900cdb901de8ec21b580869c01c70d32e764dae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37257 zcmeAS@N?(olHy`uVBq!ia0y~y;M@Sh9Bd2>430_jIT#oiI14-?iy0X7ltGxWVyS%@ z1A_vCr;B4q#jQ8D3>g_1c$zo-GCv#h=9D1woi$PnFi<1R2xBrZOT(FLW^ks#2DplZ z1ZKD}6%_O2D8Y?GGWx&)kjEf0Nbcatfe0}$Fi=5pLnANTI3$xLZooy6oIz#9NFj=B zGE#^lIfKfIkpdLSWTXJ4T`E8dPzEGtAca1XGpMW>DL|1-Mh<->XHZ!&UE;L^o^Fvn zMHj2t%mm?<kESW);2+{?3Mn7ZJ6>^=LP!BhyRrhi$@Ga=7kEyhe=#*1)R2JKk3Hs* zgMhjv3sR8dh<Vy2z+s=JkUU85c*T)okZOP0#VdA`k+KyH8zBSPuJvVs<Y5K|2JA79 z6a>ieLj}c1L5^%Pb;}AICJ*~Gh2%jhL=`m>0bSx1dyz$-3S%JKwQ5Z8Y>YkTk%9mz zGO1ChAq6>-$;kPRb_sCUrzs>4(mP(Urx^OgEA|vaN`>*@##U!=o^bphU)*wlar4#2 zwX0x&FDDcRWN*L(SG_tA1`|bA?6v}?0*3;UOe0A#^KA~8i$akcYPA6_itJG4Xt*#H z6qhEfhWUFHlF97b;G#&*pt545KteJZDfmN?oIzd1$N`FEGE#sdIfKfIkpdLiWTenX zat4(ZBLygu$w;A3yF`E#ptOtEP~{L<?m+SsU97&^nA-x+G^1$>DfowannKDn^p01g zluP%r0(&V$mv~(z2+v9MFQ&|#U_}TG%c;>cMem5kQ3@gDXr!c#l<#Pl2#|9$k~5I< z9g;JstQaZukxiy@BV-`kwbBdWWeAe5kn$Z;5Fo`oj$}fTVx-7KG8ri{2RcnXe>;B) zY%Kt^utQD-NbV;$F(QQ*vdKs>fn+k371Je-k=#u0IL48BkOCAbsUe3x72-8(AltaT z0no%6itMY=G)21vNS8E)Bel{cUXeVAJx5ccJ|M+ptv7csPMz&>tKp%@j_)5WTO2sJ z8U;8S1w@z>1(*~ySez7CjApc!e(gDaId^rmkZY)|`1z;%|G$$Eo&WP5BMV|ZlmcR1 zmIKn_DJH}sE^-w=kOvRBfrp~0U>r#f<+$<38Ei3#K=M~Z17hhGlD{|*OSh<@m=UoU z4#{Kz#9}yPXHZu$QYbMXnT!<vNY0?LVx#~?G8rjA8IYVoUB$=&iexfU=p#9U%8HQ! z6xn2?&_{9xl@%ieD3ZxYp-+uO@PQw`ijx|~k>pU8oPUa-JPgK2{z8h*(Nx8N6r|Kh zf^<n$NN%Qgyy8ePNZAxAc_9ZV?TQvEmKOcL|NV{Lyp!ebvtN@li+>;8^Yb<Lweo+P z%MR=Rx4-{ycg&xk3=9m=FmEV%yv6EBLT$(4W9-UXBBp(~U(NO3`qzj3t3N*HVPJrH z{*i0eRsV^%1f15ZZghAX*?9YY;p}YCg6{tU;GFqj=f)^uyU#zxR;_Jq&FXK-ef!VN z>bfApfFH$c!u|`b=DajdeCyuYt}l<Gm>FQnwjtr|@!MB_34~W}zO^y03Doj{1_#GA zi{J~_c7!o9FtFqt_$=RbmqF>}oTCT2)8-tM<X&>@CvU)$J5jCvO?^#Um#lesKIi}D z)iI|T%3>Mz^wc-9FiMLUU8pu-J5o|A$E-iAIPYA9g6X;ZhDGyEzRmwM>+b(ehOOq$ zudXX>(D;6>yIRm;+8z#OMrn~x`Q=^L85pG%5|{-xFc$c1*|uM`qVW9bdooF8`Dq|A zg*fK}Y=0EvKId03F_}3WU{gq7cGz+(`~I0{#*0D8>qs`o4Tg_W3JJ_CIUqjYOy}&2 zQtxl<Z!vt=*m|E66tEwqn9Ky$cOq>1@FqQP?(@7mnIAg?K_%^bsXNyNHZ)f7Ivil* zxWT}Z!%&kKX}7EWBSU^F$Q1%<$=^*_aunh~940f6mhZOduWOa2sL!s|;siM>j+s%q z<2nONPD2C8lmqUcQ)TZ>+qx_L;paslcOl#<uz``ujG-^8W45m4Ejh2aR<OH2N^#t9 z*aPw&*dGl>&rhD)Y}x{r!_dojUF^FmLayOB+t-V}{9uEh>wrRNN81FDD;g?zQC!_n zz&lTJ)7QGgAQz$8$na3=$fo$i;`=iX)W#lQo6vC5mK()O34VVzJ}}dsH2d$Yb$^dB zGD<V3o91hM*Fmwt;pFGUT(>1H&vnF_AwiGot<Ps#ucj5uU%26X*S5O<*i`H=PTU@O zH(BG#lg*2;$v;j%c+7_5|918{dy5$bHZUrng?z!8=T7V2X?~D5&rb%WiH_?I2iVTb z9I7_A1;rCMo%~5J+`D7`f&BZ&u374XV)KzHsQx>!n7QKlGInqZXlUSVsNY+fTOi-K z+jm+Q#3f8-NKwR)AKM)9?f%)LmP{Ns7zEZUCNLk#W`HHqAGh|Dm%e8>p9)G%%YTH_ zKCWwN;60MfAU6f1oKf0Avp7!p-`l$Hd=-7Ox2J+)1SOt1ZZN#74%@aXz2T^GLj&&t z9!^jqX5_fRz$o3&!24ju&2_hW-idxFnrqAs4hH7~Y#pE^-q64+uz~Tx<b?vKU%UbJ zKsrEaTQPbMBx!@p^7;NZ`t{_60!QU~!_Fx>9AImx;ANDa@;l&MFDMm(?QnSc`Oek7 zjEkal)Io6#3ZZ~!&jtQSFNLIVjvEYK^B%7{`(z)(v?(Ch7b~JhwQ~9ntD0RGY8lTh zEp`JXc|?K(r&NaXCm005UhxqBF2$1b;GhiL<f8d^qt2f=P%H!TY<(vqIE{UHAS|!} z6aanmZd-k4@HqA24HHWa!y{8z)`b)TmS=MIewKFu=NyEUkX*I+`PPd!`ISI97$a{~ z@Cs}MITI8MkZ6WD^P`kP5-8t85|aF!)o0%<V~1D;P7fX60t4X+aPnbzWct98EnOB= zvaN3fM?ARP0P`8A&2MPnW%w+O5?~A;r6QU@X`_Zs4(wlu^^DREJu}x7?{l80cg_Kn zf|1huSxIh=8w^LX9e7?ZD->g5GGjpVFoSoBLR)Hm+&dqZGjd2F1#zSMxkTTJ-;*}W z&Ts`6TYK10lh}#$lx}0$4H~R0ISgq=0vj4xH5(du4dz=WGcrmaxM)11{-AJ$|N9;m zXe=DeZhv&qmmgM$Hl(MVD|+B8o~{b^bz=js%?waLf&=1!cG~)LmVAE>?y66_F_RPQ z4TS{ek5Z82%W;EYo@Ke|xq=6Nn~OowK4Z7T0k%h`@XEp_``Ie9Zey7bIvfHU80V<R zeSQ`#ut717`GB)GD3lVI&%`ju@3wGeWRymV>S-$(n9Lg7pRK)jlegw#)<!NY7Vopl zHa(a7z;W_t5rGYi;Als(xTfsfszXIbZt~i!Dqn{s$Q#a|iEK8Ou6VTEB|BXk=JPuH z4`q2(@X}#}3|rizXEm&6G%zCNdyQ2|VH~raDyq{Uf!a53{kn5m4_fC7ZEXO>%J;}K zehLZBd)Q#1)^I6p^)XA{JvW~00m+xQ{_ou^&yv$|9n=N@2YkXdriy*t#^O+~wN;!2 z$5_NBP|~w8W?odocX}rzSt%qOZnl6|X&=mjLlXlZ&0(|AM#^>voIN3NVo|bem(~16 z4(?mGBzd5ritMmW&sW~M$>U;V)eei1DMn|^kiw**e4f<Yvkore>4plRqV!yaz=lAl zJ==DD1m$^fp?5$?!eZ|1&k_c^86KHB9B8ZHh1e~yfiX>!AwLmR-Xk(%!b?yP>NGSi z(m9uU;183?vf_2k4ZI(v;L&g<@Lb9PAy81vsD>r4hNGZJ+wg~VPwUyAJTnr(jSFOt z2&Jt!S;-Ue0u=X~`CwTXoLL(dKVN<;lBa?j+@e9t_Z^1zz2}l19EnOd1^cg|p;zR8 zZy-{N|7T+zdM@$7le}};4$#7UrES6NyI<gOP;mWCNhu#Q=MIa_jEvF>am*-DJK_GD zEf(#KEIsFPVEP}K!u38eHQ#zJK|yirW@&*9jAcm;;Gk$LbpSW2KFyr1mTpiUb!d)l z+xc^G&ITWr{W`Mw&iw!H@BQ1H_pIWbfyHh{M(GE>n;`mN_1vc!GqaxSzn|fJ<A>M^ z(~0ZOZr_pn|NW+4#flMg?}Jk1dPXL*BiRh#I;Ek3_e65qtGWA=7R*oH%F=XNZx5s2 zg|KbsB>AANIOKr-lCF0C+9{LPijAIse&v2U@7d-*`&Y5<>9g2WGtB2#ox6R_+kD+@ z<9+jv<~&_F_bC?ZJ<8*x=InKK$)3)%{;k=b)N`d1wjYdy*{=Ldz-re^P;vve;|@G` zuKfOa!QAXW@3-^xDLyOCeUe@{ml<5@bKDSE&j_mp4m@|ZJbwEc+x(C}Z^dobIc?L4 zjd_gC_WZC{b9YznY1H}?8Mf~AZfCRk=eDY_vE(p36B5|)v%LX1L95E~T(434ve8_? zZ{1>>dv-5ov9aVF;5_qhsgS@1#y#J~MVluna58*uSej#FeqDiK&OhCdv}q;wqOW$I zE>3PgS~_*lwXZx44=(Bnf(s9W5+;QN=L2jEFVA?ctyJ}F-fp!==f#)E!1=G491gU_ zDuK$X4U$%j4hPf{m>KwHO+I4vvbOKVqg!9i%<TRxS(h!rz&JZr3FNO0i7!|j4zxA! zGF+ND*~Mz!#t$EF-%z_AJ4x!g0Rxj+u^y_TbN0$t)26DdxwlK~Yx$+!Y_|O%-PPu( zHqNtG-kLU5#ZEG6XPp1W8*#DyFaPAlY-ixO@kWRd93jr?3`}M$ISd8=Br^?G&$;!& z%J%B}rJRlnvyFKV`7^NOly!phcH2T>21aQnGX?|YkFL$xU#9Gz>2+jU&oxu-hK93< z;7G9SZs29GF@E^j>iY5yUO^28CbQix42;qb5_Q`A7+7*RZZIf3|GC0&c}JeW#?+j$ zwM+^Lo4r}Ud7Wo21IG=44U7jWpD#W)r^sq?cJPs7!J+Fyu{guxc}<Dw@``8?|IQm? z*WYJuT^Ec+m4W=n>etK4V%2^}XC0cqF#Be)Cj(2)j&x>FxjlQKFoRA8YYxMKxt}L) zcbn_}e%6*B$L_l_6v%H!cF_hCCWiCg2HGF5-k);*)4U1U!mvpD;2;JLKb=&@1C#pt zV`C=&yLZsrbe%85nPW)d)~&)g`?Uar&PxOJsUL2yGFzSfJ0$A58bew#IA|0S4qxDG zXgHg6t(1e|`K;cWR~K$yuekeub!l$38K}4Q9aMHHBp8=4H8l7hU}NC8aW1D&H|?+V z?3l;@?3fxFcz3&iiyW|uvxhhs1g_7y`XK7eFY~b7$Br&y;JC5D8`Pp;GILgE;JCq( z!_aW^#Tu#Wi_B$<c&;nM;t1jp)wK<0OF0<Qlvzxd{yn$q?5isA9wvo^!+L_?rXtT= zh6GRT1ZD;sZA1Box;amG?T}*>*l<%7RN3*T^3Gl7%D|E%wuPY~UG<N_F2233yyw*! z1vWg4<K?))z@KUe%QN$)K8WO8|8Fnvy2|~QpjZiKW->eQAoGK92~&cczy{763=HSJ zY_t`Ry<b~)*4=!k7^A?3nf;(-+rFvI@46BLlNqBlLqXrp6^8RG!kYH?|FGs{;J9(- zI5@$ky<lPBRz9u7aG>ejW}#C*?v}3my&~<pBEz%f&xYW<Bxx1f4Gj%e*?Ci^{Mx-b z=6m5zK1Kui*<foL&R%#K#RAE@Ixh_5r~bJ;JN7q|8N-?5H&nrWXGpFP+rp6Gm~PjZ zTdFJe^Y-pt-&k`PX7q0a1$jdQFF1v;<bah}HXr*MaVLL$>D}LF858V|fy0!^43_X4 zSm*vc@>wY9&o`~>wISkQ$8Lr>7Fvkty!eq=Xj|pi32N>dmUT8X@P0_(Kv?3gGdKIv zeQ$vcsOCqAC?+s7a9izZ<*nBjL`ZVn07Yn^3OGVP-eIZNcRaw>&~Vm=M<IdPX3EhE zoDHsmOlAxp*0d;_tUH}lR~`FfH|O!s*31qE(x!8O6`8^kW<}T`>ubJGZ?P~S5(H9w z3mn!-V#X$wrtFf#z`$hoMhMi9X*hd<lVRExCNqWuIUy-WuI=z+M9tdXQ7kzO6JF<- z%nbC)y}M;yC<81*3Lr|+qB*_m(x#~JtP5wT-)npUwiW=J%GteD#$EnhObm#k2%b+= zWy|;W<_7PqV?@o<;Ih!8)-3CchG*3G?az0%p*a$);KQDlh-tpht=JI0PJsu=%5(0U zEnQErF(l}Tf$|TN*?$2B#@P#n8CY_d%or4o)tJl--o$nDm+#YC2m=_U;pJ%S&lg#K zC(rGYG~1dj!vKp9mK+HyMu82A3Cs<~=iS#@s=k*z^V}7i>nvW^gv<`^s?v^ryo(*~ zLWBz*_!wVG3e!Bb=cW17*YZdfwD~cB^Jl{i<4Y-Fn%DlN-|xK1z+k))R26_~T?TNn zQb-Wqz{s#MZOOegO*42I1UAg%e2a)-aPAdIcFQ`W)o~LPgO(S-*#TMWvn5ye9C9y? zsql_}yPXM3Id(w%*^-NU4#_?{yJ7#<^Y1~ylsKIO+!up8GX1RQ+{#w}DCZwHeqGUE zKq<-~PV7J9Ikl2?z7#71OAa_^BS*uvH72toD<-MdWNrC+n+c1G2lFCVns5H_X!~Z< zx@^#}Be*o?xB+h+>@nBAnkL3qWqo_c%WwYIf4yadrFBS&+rY~x&G5lY|7VYe`|QKd z-Sq348Bl6fNFyWly!YIltsU3SJ}F*|RsNj!)SayJrLp_sjLEE6i=WTkqW6a)#Uw1L zFr2pTuuA@QM}r}OZ5wjsx8r-Rq_{_it3|-CJ6mSNdz{%d^U!m*?ET5;hA`ff;+XL6 z&Xt|w6LzT9@NK^vQg<EQm7vZ<=2^ehzZqxl75uSFfBD~ijED>gZYP08RL<F3$KK^X zapT|4i}%tGV^v{k9eVFj+xcE5SV%U2OAT-n`hjjv!Jp@Dd*||^M;2(HCi;fLEYm%6 z*M2TDV-VPYl2|}P75RzG`RUB4<qdc=^@Et%hq7(HuixgNry!88*3VvC^_}g<V$DBc zS<gW=G)jfbz$ks7IDO^Ozl=3mBG?=i#D8hy@%ha&cp1*@0w+MEdXSOHtl{{xl_zbP z<Tm9U^L_2Z$iOHKF886O9cYB}#~qu{c8247nT}v}Ui<lwy}w!ZsHA<K8HmW}kdg#E z&?M@zwc{pgly1miWyv|`*U<l5Yrarx@|lNg+qZ6J#}YCR=HEQE+~r}!<z>bHu*LYF z8SB-)^H|(@CA=7^gay}mps}c*uYPaO+Pov*;fjAx+3);|Gg(mEBjB;ODHh45@1zU5 zwr}dacZv<Gg7mNNWDDk5rqyfD-pq-`nHrhbr0&{32>EvYcU)~8C>oHOXy7Q;NW8Yn zY;!fooJ(>uuAS3D1Qeu9ZfM|D_}-CQD&H7fANS?a9wsbFw`lH8DM9Hu_x^1=a&9Io z!kyrj8E6pkiADL=cd8RwK;=HPX$)=IL1e2-->EC4FvFtQ;Q*)|19qLjMn)%4l7+Oi zprv#}1Mh+zl5bw^V*<-Tl5_L&h37ADHdKQ9C=5ww6Bk!=FR>JU%U%0i0!w~TNMcTE z%h|e_2aBa1m2%Q|k`*$mJEAPlW63WKA?cgW)v`_6mRI#$5{KC{zo+gu1`R8K6D^XD zJWP|K?-n0OcV&cimY{VPsJobSCcU?Vchk=`8P8*wVe$fy&J?JS2<o|!_Fe8oa@(yd z=ghF=DTSq$YmHVrhUF)}o|}tab1*PUJ7j&n^+1m0-Z3nx$<mxL>1<AHMf2p}f=@o0 zZM$|8G#Ugh){!D>iOF`;*+>6!Y%+W|pQ~&iBdlV9w&(6lW@MCh(Apfmb>^MP3eunD zmRsG2haj{TXJ9gGn3A^RUM=UQUrREc=fFLR6c9nP9?$ylP3^nJi6@g6A-w8v0Mhsb zrOKs|dH<KZcp%3bSsS#a2*V|y@$!|r;^N=6PCT2usCP3wE|3b44`yZxVMnf6-Ug@o zU1FfI5J<lSH0$voH^)I|Z!s?-#e;jRppwVqV{T6PcfAvbUVx$r(j-K7{hY5-pXEAk zpq4G*?jA$ZxthCarTWcF&i=kFIyV!&SL$$p&7rIK{=dkJ2mkW8fXX$Ljv{E1VdJy? zw|F>|kg^4&Oao0d+~7WW^e-=pK5(lJqVJ&J2{vSX@GRaiqxfOz=3Vz4qXcJv=0^80 z#|?%Psb*_hawg2V_>&c_k_J@-95)#RrLkm$h6%h~m#w#hLl@Ljf+hfvL+3beJNj3^ zZ*6HBqe8-O`Reaw(yOPj2AHt^i`EqcuZa?HY7GFbjS@J-30^5xb$L;VZv5>}8&}_0 z|Iu*Y?^Er^wXWrCK(4nzzEnNmzjy-gq|!aQ8;jR6p|uY|m7UjoW%kV~Dla*Fq_1mY zDKZzdRc_)=`|fG59iF(MtutmFC&mubaI@o^`R0qWo(J^+AJ&1!d{}b8?Jkh%N#|xP zwiKRpVYeD1qG1gy_8GRGo0V(8y8E|=OW~aA-q(VNvJ%`I29<^n*5;)7cO(|_VsrbC z=WBDmClu$mp5|F+k0t3a{EzE8XJ^P|r^?j;?I1&&WS{|afo!$hbN)Sg@3ub(hWC$Q zoi$L{ZA{*Fb+34hmk1~YEJ_CTeWCdpl$(ys3cdY6Ev<R^O{fZ_AskTQ<Zy;<o+qf& zTnic)l=#In7c^<jlEaW9vw3Ff!}O@@LRf;k;r{u}z6NaF)uuJKAN^v)lDa<p`B}#C zETQ;)oBr2zlGuE`es<~Z$3ML{?CNj6$p>;fvdbchm>kyZ{Qhy}#m8@RcK^1j;07gC z<Ut5fus3Yq-1w6ZRvEy`h=hZj4p;NjrO$2Oocr!4NGE&{3DjQ$x4alOradv+!P<Sk zH|ZF>D1(*R5qV4wXJ+oK7Tz+GQzP(s3_Bu0!jsI2^qJM>-oX=Y?&L-I9v*lK8O;$= z&y5i&1zfAH)%*SPdwYz}y4eg08HYD}frb+7nPCGwEIIemSQ#AbjLXIEG(G)eZ#bjX z^Ww7_Ry4~&gAFURGj5+bs*+OBhcqSyE;2xCC$5-I-hNQxOp}???75Q>ArJ98XwJWB zoBM@rvu5v%cx=Oh#q<Y;o6V0emu>dEaE#UMxh$F|K*Kr=O=d|EbJDSyT~ofS{`bj? zXXo^u??7@KI5UA3qX-yh?3T^H#8p;oZl}zJ2s(Hd#9__M{nqoGf8No+A%EuQ{>slg z1M|}#8}I(i3Q0KjOwig6?7DEBWy=$c=YRHlFT-e{zC->NXb1$Uqr|Y|)pkeqw8NXd z8CY`OAqHU>XM+|l9?AK!7d}!2&4`DcI2afVZ%b}|oAzUu#Xm-toOkWWZ3M8!pkIFt zSh^$kN$q_sht>=Ljj1+VsdL|Qe6wzT>gPW~42;t6j)G@A!L25+{-l4)B$}_*#4kB& z$Oo&TIc|W{6sULVpy!>pU;or5>urpfeZK?76O%0dwdABMFO6Y_4Wh|ilY$NC+6W6C zR!C89yZ4a?W^_eF_6rsUu%AEpED>o=-mvR)E{ECied#k8IBpckv$5nbpqS8^Tf`Gq zdCv6sW`pDP)6$L`z)GtJiECj)0SAl)jRjQaRL5?x;-9k_-k5=!lP1W*Ft1afHCZ4( zx%eEY)B*RSkzA5BuW=8f*1Cg*Cw7Y5pUWSaA+s61iei*zNMO@C`o!Xijd-+UrdZW+ zZJ0wKiQwtl23`gO=BY`=GM}E+<jk3TZx#nk1vowvDnUcPXB=Wymg;<Zw`a~=@p;K0 z$Jk1MYkQu#3=#K~5||sL(iZHFRM|B<c_RP0vqyJ6v{YkYGP~1^)Zk#0X5hF{vGwZ4 z6YS5QeYCuI_2<MnM?Z4Hf*2|G&d+YlOB0+gsQR)ax4iDhTZ|MY#KEBRxMJzaj~&HV z^2HhMppMFYPxV${*wCZgcJ|{5@#im}$ao%mH-p8%I2mmSf#JNXmx+bk&nGgrcB;E9 z-7h_u!2;_$+N^*Nf7z7t-8!r686neOQ#h~hoFF4c>B=b0Fr&F*={3WX;?GxY2Muw; z2Fk$g0i8U-4U7(j#TRnqJdeGZaU>cvR0~aau*!)ghaupyOo@5F%Htn%vLEkw(*60W zdi`EaK}enj^_IYGGtf*z*Q{o?&mGTIQi}IgB`4MFO%`-G&?YG<0GjfL=YaFGo2@=~ zY~P@0;R+u4gAV4y<>&Q2h~$i)ySn$YGg!U`JTkZhG%^StxR}xULCh>^?)ufmE?{}6 zeuEOGgiKJ1@S4?{X6#v%c3f@#ob}yMLlBA}V;ibxoy?6rCs`d=m!Gq~{5i<+j2IIm zUb9-Qj5{qk!9#2CnF&Z%KdQs<;3r3ZZ=e6YxvQH$E6E*KfThj{jEIb66EfL0LuPTr zBJLXu1@E^aT1*i)KxuQ*bH(|pKGz>f92JT^z}8T`9(``cYhHWJG=tpc$5TGX?6s6< z$w8FX@PXcdTQ*l_c-MGM(K#2I?=7+cz4arofze^2@x?4NL-UD$Dy^)=7e&f8qvyx& z2!;ox#urn}KFYA}kNt2PR3uAEfO~YH0b9-#P8NoUb023O{P-$Tt!_6%f*WMmM($Sv zcpgbrfT6<AiKqI4W!!2Td+X!%A)6lyz{<}L3D+)gLWa*j+}fF8I6ozkSL%39>GS7j zH@*kw$L|T?X<$fGj8U3lij8>hv&l6|W?)sXc6^rsO@dT|3M*&>0Tg9k^SYxxclt{` zy7R;tlGxCv!1g@l6pZeD{`5(NIM#6C-F)$Ek5ZEI%HmC&WydRH`dne{5NN*<RHpAp zGyAmCNl-d-?&R|0<t4kp$r|0Jb+h|x+(M4DZD0SeoV%eKHZ%#E>;Tv4I!z1>8lNYg z??{u`D0^}8;~g`K3(I`EoxyV%R${2d(G@fKpFJ7(!USixTFy&kdQkVq4wMU^{T$Fx z>zs6z`GRNdlU~c5zB#YnPIlI`dxh9atn24I7DuX9yEB+t%=_#1@cN#M@K^yilnxYm z9AIN`sbHQ`xs+#eveoM1{IWC4M4PPiu+&cu9*5uCYu>V2xA&*O{z&w`MFbmTL#ymY zJI$)%obKx%{s=LA-cSvhO@NmWMKh<G8GBb6&)B|EwS3-P+36==$$}OEB8|i|ZQFF8 z=@a{p>UH-Iv~Iq1_Ds+lnP)qFq@K_4|GI2#;T$Gt0mT5FU1GRb_?Jy@&Qz)EcNgW} zGZ1}yC#(6Y;fyU;H*zT?6x(kBO^d+Qvg9<FyA+;HceOtLJN5aMf_<##H%{Mn@*`HI z4u2|F7QbD4Oi+7U-|y-BN^=Y6q$U^KVdA)PhaY8NnSoI{Ax+8e#5L=0^Q-vo?k&}| z?oAeVIPk1415vVX=wTJuz&Ne^$lon1wg>!ucSo}M?8Yf`uYTliki4NMctD;J93kL| zHRemRX1iE?y>-sKW9vEAhqInf16Ah!pvoNPYsT5x76RHQ3T4wQ`&s9Q|M_lt=~qaG zq1AB{NK>yK)F=cs4M6L&K8Tqe$yqsH`0P*f2pRsTdkQanl|z)@kbzKz1m-=hy?fR? zzkPfc*SY4fEn!<u;!;)f_W7JzmfTv!{7C7(4KI1V{*j)(wtOu{6Px1(Lw@4oJ?2}^ z_OEzb(H(gxKm7Ii|L0scy!^Zn-mHN6h$W|C`-Z@>8{aCTZ~v{i9Ql8h|HOTqSALoQ zpWS_*^+yeSZWq!(058(4;FhlWmA0n1>_2C{{l3-3y;z*kVDoInRa40iKLfA~+Z=G> ze^8#c?k&TN^0$yFYDfzk6s6OcIu;hjqMEp&1Qd&vXM@(hHVSCCX)22)7(dNfu68|5 zp?L3WOGsRR#?!!k2hiBY6H9;7gYSOvq+}KAqM8k^CmZ&pue$hE^2C)FR(yztHMn*J zbtIo@HLQNS?mnU#ID6q`1j~U%q7DbxrWl5ouDjUq9MoMXSdWreq#f4W%qp78R#f>r z>cWmPW<&?sd3mxRXjrs?S0jB}R@2$7QXg`_4cqI8hAn6<%!U`tAHJC~oY{&pirLV> zyCUn@C(XbE=ri5m*?xsnJx_xdHEaj1vp|~Ag)F)dt7Dkw$&@g!^gbJ`#Ri^8aj4xq z&A*dL^JdI!aN&qFe8IqEwqRXlcIjI-A;VpINWK8~Oc+>l9AZC*iN9HQ-yx+wW->P2 z=VoS?{AE*m9n+6Z_TJ9yGG2D2nKA9yWZ&&v%^7yR@Ilh;!oP*GY=}-5cvb^6h`2di z{LQ+j2U^*#$D{YRK?^<&>v`8bJ>V*KJr<knU!JmZTlTn|?=L|K6+M_AY_`lP^kuKH z5`ooF(2DTcJkVOLq%(=W8+NT@);HJ*YLcUlT(RUZ-0!?mcD?LDXV`o`q`oNJ;rp!n zOO?zXc=ly`KEH+Dp#!D6KWBZ+cI;#JH`uidy+a5Zps=5L+U<J91M#%$LD;-zzWL_a zQn??ErWrBrSVFep{<-wc*|s0Vzbz>J3o5t36TQ&d4iv5~IR~y<UH8Rew8Ig$nB0=R z*flkzgC^Vy_OpYRj)JRUP*U&U)wuWO7Y8DDfxE3BUv}JJ0Iw}Wu8zP<){~gKwzKtS zgVq3`3}1js>m+9I;;0QM6%C`bL+Iz*PvRIJnWEQ|ph4IO<2x_vu*)$Bf>wpWnoh7f zf#U|ls@YF>C6wobTnHZufiwa^!^>+ra!czQ7M%ev7X#1fAdlEipSjNPx})XCS+7A$ z=fK{B%>_CfV4Ltb$9%Vc!}C@Kg#=?zXNUpZJphMVL&WF1FX9*@rD6|b8%-8U+oN~m zj<Evw@4|Dt%HYFxNMl#3XDfRn`6q2>TbnHgYjq;o9q?*TdHMSWm9y>{udG;MZD?>0 zPa&ZgT;-YS$d`W?@HlpMD<>@NLtAH{f@wwOJ8L`5T|4?6Lfk!Wfd~IEikhwG>do_$ zn>EDd^RQwG*)t9Q|N3Y1wRqp(^=vX`#l$GhaPJt~^r+@@U)iuY;K1!02R7S-rkm9v zEA_yOBR~ml`^HA@4~?r}YXP>eV}$un!iKlD&5z*>XeHVKwgdK?6NS&bGks7g4_Z(n z#_$i6IKfS3P}H7Defn%3^Zl|v>#|}&_CRJ`kVZb|nQQ-Aqfzsg!<PLzH<n7S;rf~G z<LR#I-{pUN-@NznpMtpzSVE!V@0}a7WFP()o6n6ckUF-XFmVoA{CLOvSkUA>x+AU^ zG?<9ZTK!u{^hOJ4tsrW4V98;~JU98V<c}Thfk`{etj;sS`m-=^aNJ<{6j3lsR}c|M zuzDV}Ha?|!e~HZY=Fbv{G638W1GR1x{#$P5PW!HFv_Xcu>bWj*-3aP+fP%2{b6T|x zGiTX%1EEdx8&hA~fciJk&KA7+vm*JM%-Q)a+gP_RDD-2(QaoI-Y?hlZK6lU5UhcDY z!d!^T9nx=cIKXzmJwG-2&i#tUuQvPk<bo!I(aZ4${pXjy{n_&PRoroXd%>zbch{H3 zVGO+rY+(Fwc}A{PvdVY6ebQ@7&&gvcL>T5-t}i=oERvt*yoC*mTO8h)Z<d`e8GDC+ z^_F@6|1H8+5HTz|x6#*tWwU>;ShoHD+T)M!-!9~bnHBKvfv3&d#{vy3&l=C!N}lL_ zZO$-%&)i&_`{%Yrm!(Os(Y?2cjluJ;Jey5BB)UNxoDT5+@0VI^zC|@xcnu>1Xw@i4 zbV1vKw;xYltp0F3`qrW!#sB`Y=Yy`q01YNGFfcg04UGP+m-Ttsw&!~z-{!7)_BM-w z0W?tz()wU_Vsw37-50@aYZq<dUz_i=_3`_w)^!Y^jZPqWh6CA$wtb7eV<!IZ*|y`e zuRPm6an|{ICb-oNCd%9YefeSXGSSL;gZ;$&FShOb{eH&1KjwV>|I7aOF~AirxcB4j z^*^?Z@ZDA*)1jNcKupj$J(xzg4a9}|0mMX7jI=Ed<`Iwz(9kZ3Mr<ns@u;kLnC#AD zK<tSF1rlh`8$=@_48+48`XogaH5Ah&Ua==H&_)zcNPsYsGpL*h7-!oL<QWAZ&w(*g zR-u!}M^7lA*|`@3nV_*}6{O+>Ie8H*d#It9E_=yYa{eJMpg<}k=;Cpt_@+joi{xg) zCL_f+l47Ldgm%?5a^gU822$uFIfKfIk-`Ys<UyIB{~cc^D+DU#Iez`0rOd)N19tK> zj`NI2I(=)nAAa=e!00iX*w3D#-O*;Hqi21Sln1Gx80q9M+Qlmllj(8{B45rxp12Jw zaaXOPLR^tlY!Ca0Me-n0xq%c$p-AZqDfDTl7^%2Kat3nZM{)+06^~ZOp`#Itd=w;7 z`a;Sn$cd3)l0gbkWRsDy6_UwRR*aNWkW5C(R<z6A$YF%!45R=>at4(ZBLyh3$poW{ z8j9%@ucOs5(hWevCt{IOF1<4>j-r4r85T!TK$mz$@*wumr(LN%+B*&%y$Nd-QsT#v z2dPjLfU34jh=HtIib56%VxUp2wcZ;v85jh)JzX3_7#J9kZe>HdGLCi^^CDd`NR8_Y zk=#t!WV+mSXt1FZ6wF|ZeBB<>U4TgLKni|pC`P(v5XoeuKpKr$2BgqON;1fykNy5a z9E#}@uSjmDcf8_AF-T#Al)R9_h<3S~?5IL=Gg5#exf$7H=FuzChiAlMPX$QX3MCaF z=G~E!43!m+mfAS-Aoi#tN%3fP%s{)67>CJ7IfbOSqK4wp>UemT+N0Gm!|;q)>}5Qa tYgnWbiLl9|)iE^+VqEb$=z7N+1e%^_{V~XV(hushd%F6$taD0e0stKDDZc;! diff --git a/assets/textures/Tile_Test.png b/assets/textures/Tile_Test.png new file mode 100644 index 0000000000000000000000000000000000000000..d25e9e0324403cbccc67e1a0eed3fdbb9b63e694 GIT binary patch literal 1202 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}jKx9jP7LeL$-HD>U|>mi z^mSxl*x1kgCy|wbfq}EYBeIx*f$snaGiF`u<YZuAarbm_42f{xJH0w5#8srdK76Al zE3bm?ja4=}N`b<QU4FOsuMiYw;n9kk@3JE5f<&^CoAS1Oi`0&-QkW6o5g;h-%Bz&w zV#3AsQLtG}&2?hXkyWBmky}MpthxW@%%<IYH@|*+?N_S*vwJ%?7uOpXKby1Du~%e$ zXdO$ZyiVV7;neuZ_|*;dX@5V<-%y@Wd769KA?FP@K7YS|drAJi$=`Aoe^<Wr!t;{r z=cP>t*Ex2rVTwC0cjSfF@}#vh`X@A;^<LVxd*_0E2^}Rb^rP)-dP4s03n|;Sw_N7& zsl_r!)*a6~>SrkWVY{~S#f{Nc^Xv701Xca>U-_=V<gMq*$%=a_r)N)5GGX?a)$`AN zqqd>(U-iT^wVI0Q2aYozUMklXe*LMI&O%8G_TM7L`u>-eOP+8OWMUKDHCsfH(e9V7 z!nf`%>sw82uZJ%AQO}YSm2}#8`7NW~M)3`=jaPo;%sjO8($nv|Pl-%q*)aL@V&?Pl zfttK&f7ACq(K43YA^GCflxg=HI$|%)VO#k{=exq>M!|v!fB&E2StNcreyiK8lGbX0 zXZytqX6((2+xJ;G^VsD#ue0wk+usY=!(q&LWzUT#OwA`*k0%~aR`XKhWL@+t(q;4Z zr4yfCy1{+p|KTNvgzq?O%+v@yQ)Vv5$Py&Db#oE-w^@6A1cU<0H-0&sR{r?mp~|48 zx2H|;SiaZw$){gmOkbB<?NjGi)9~zrk&B|mVa|^J)BX+@gjn`X-~LZ!@9w}~->Nsg zOq{mKXI8m#=H45o9?CN;&c#+{sC+ajz5P0CPx_vZi+r4zraiU~J@?s9Uc2_VnVE># zgjeC7lZ`J|<}p4uoV1?r=Ih?Yoh=WUJu{^1?)qrW*M56fD>vUqr(bSY@T+C>TlIIj z1+KWAA0Jn?X7Brt>nD|SR$cz4{Ws<i&%B=I%_c7^(jS<c75wbK6mTrOsUepm(%fs; zsuQLjf|>%Q$8su_qOF8XTOLY0z7=)qR;2w|Hx<V7dYhlVnYr!ENwGP3n#XV6ZZDc4 zGi83m^uleo#XO8HXZy}@dJw5?Tc_{7b#`oX%oU@m!(7`_KM7vw{GaojVRQ3_j58lT zJ`eirS3P%Xxa3c^w1k@;;f(*46ebB@+pl_e<Ak0lrP_m~n*XLeSs^U9aP}u#vt`>< z&R;GF-o0hknM?BOYn1lSP|aAp-c)|qse3wyf}^XJ2$onrP0zG?ejxj%UGy18`FY7v ztG|ERI$83CGN(b$!G*l+G4+a8FLum$S0-R(zLDqk54nnVj~iVYhuyF2J!rYm)_7+- zOO8Q$5r41VLEmrkIZKXPlx>~t{$1E^cjUAkn=Rk4ISWrTIJWt+(cwZ52i51txa@k@ zJquo!XnW2lV_)CP_`i(Cr}}oRIb_=7b%}HHk0g%+!QTxTmR06X7B!x}Cn4==;=Wa3 zc8{gLwkqxnw_Gvv{Buj?H)r$q9Zk}S{K%0Ra%-KJdXd$;L-t)ZPFdey%7-S~xkjuj S7iM5!VDNPHb6Mw<&;$T@R5i;0 literal 0 HcmV?d00001 diff --git a/assets/textures/Tile_Test_2.png b/assets/textures/Tile_Test_2.png new file mode 100644 index 0000000000000000000000000000000000000000..6193471ba9f044adff524fb9b3afa01ee664c806 GIT binary patch literal 2079 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 FngB(@+Qa|= literal 0 HcmV?d00001 diff --git a/assets/textures/Tile_Test_3.png b/assets/textures/Tile_Test_3.png new file mode 100644 index 0000000000000000000000000000000000000000..5b6bb5cbd73647990fa99bac0513a38665b877c3 GIT binary patch literal 604 zcmeAS@N?(olHy`uVBq!ia0y~yU{C;I4mJh`hT^KKFANL}jKx9jP7LeL$-HD>U|>mi z^mSxl*x1kgCy|wbfq}EYBeIx*f$tCqGm2_>H83zRe)M#442f`mJJm3c$xy&m+;769 zqSLlcr>0DiQB+k`bziV#$r(Y7;Aaw=+n1c-?bv_)ehvRN))PT0Q`94Of1CBU{+RLU zoXUuKyX{lt)}6Jeo&RUUlxwr4BY3#$Lk;hJo_XmA!{XDf85^r-OI$ed;Ze+zh~VZs zm)~%#S#d7={Jizt@19ojWTal-@OzfT1Mb|7PanwrTlQ1Xz^T`0yW1>DhZL;^H!oDb zxmYR8{L3lf`GPIa|65N;Nsy`E_3i~*<X)ff&DXvs?q$5laP+tDdwG>Kmy$dEuEMXc zs@*BQ`)~(;xv)+^H1|J_Ju?!XFWBbZD!Oj^k%Kum_RX6t!aV!eoxp|(oLsdsc7H|p zte^g`%V!1S?N!Cg?k<;ek`OqgaprN|8q007YuHL`)%lXdRW#csFkd{nnJ-(R+(p3o zicDC{#h*D6Z7aE54m@7e%__;Iujq2#HsMdvZ>GPuQ}?><W8-kuKEG93&N$$t!y#VD z3YK{0aQ%fAF5HnCoQp4Pxgk=*&EDxM5xnxzkr@}ZL`NiKIkAeaiSIiQ<gt@==7zUN zEze$XcxP?6zsux|>8T~6Z|mB(i5@BC%evpWlDnZ>;NlOt^i_u~f19!R38Zb&y}F`z z&IaqU->3gG`~I|77Tr5D;h9`f?yP^(Q5jyB<#vS2#7Mu`6(6c$?Dx9;TLl9H1B0il KpUXO@geCwG!3CKB literal 0 HcmV?d00001 diff --git a/source/engine/graphics/back/geometry/Geometry.hpp b/source/engine/graphics/back/geometry/Geometry.hpp index c34f8fd..2ba0d91 100644 --- a/source/engine/graphics/back/geometry/Geometry.hpp +++ b/source/engine/graphics/back/geometry/Geometry.hpp @@ -59,7 +59,8 @@ namespace megu { const Vertices_t & vertices() const {return Static_Geometry<T, P>::Vertices();} static Layout_t Layout() {return Counter<megu::layout::Value>::Count<L...>();} - static const Vertices_t & Vertices() {return T::Vertices();} + static const Vertices_t & Vertices() {return T::Vertices();} + static const size_t & Count() {return T::Count();} }; template <class T, Primitive_t P, layout::Value ... L> diff --git a/source/engine/graphics/back/shaders/Program.cpp b/source/engine/graphics/back/shaders/Program.cpp index 71a3e77..a06d4f3 100644 --- a/source/engine/graphics/back/shaders/Program.cpp +++ b/source/engine/graphics/back/shaders/Program.cpp @@ -181,4 +181,15 @@ namespace megu { void Program::setUniform(const std::string & name, const std::set<std::reference_wrapper<const glm::mat4>> & value) const { glUniformMatrix4fv(this->_locations.at(name), static_cast<GLsizei>(value.size()), GL_FALSE, glm::value_ptr(value.begin()->get())); } + + void Program::setUniform(const std::string & name, const void * data, size_t size, GLenum type) const { + switch (type) { + case GL_FLOAT: + glUniform4fv(this->_locations.at(name), static_cast<GLsizei>(size), static_cast<const float*>(data)); + break; + + default: + break; + } + } } \ No newline at end of file diff --git a/source/engine/graphics/back/shaders/Program.hpp b/source/engine/graphics/back/shaders/Program.hpp index cd005dd..42e0011 100644 --- a/source/engine/graphics/back/shaders/Program.hpp +++ b/source/engine/graphics/back/shaders/Program.hpp @@ -71,5 +71,7 @@ namespace megu { void setUniform(const std::string &, const std::vector<std::reference_wrapper<const glm::mat4>> &) const; void setUniform(const std::string &, const std::set<std::reference_wrapper<const glm::mat4>> &) const; + + void setUniform(const std::string &, const void *, size_t, GLenum = GL_FLOAT) const; }; } \ No newline at end of file diff --git a/source/engine/graphics/front/engine/Engine.cpp b/source/engine/graphics/front/engine/Engine.cpp index 46822d9..7551656 100644 --- a/source/engine/graphics/front/engine/Engine.cpp +++ b/source/engine/graphics/front/engine/Engine.cpp @@ -57,7 +57,6 @@ namespace megu { if(this->_window.isOpen()) { // Draw Layers TextureArray textures; - for(auto & [priority, layer] : this->_layers) { if(!layer.get()->empty()) { const glm::vec2 & dimension = layer->renderer().dimension(); @@ -73,4 +72,12 @@ namespace megu { this->_window.swapBuffers(); } } + + void GraphicEngine::setClearColor(float x, float y, float z) { + this->_renderer.setClearColor(x, y, z); + this->_group.setClearColor(x, y, z); + for(auto & [priority, layer] : this->_layers) { + layer.get()->renderer().setClearColor(x, y, z); + } + } } \ No newline at end of file diff --git a/source/engine/graphics/front/engine/Engine.hpp b/source/engine/graphics/front/engine/Engine.hpp index b9a88bc..aa721f0 100644 --- a/source/engine/graphics/front/engine/Engine.hpp +++ b/source/engine/graphics/front/engine/Engine.hpp @@ -30,6 +30,7 @@ namespace megu { inline const std::map<Priority, std::unique_ptr<Layer>> & layers() const {return this->_layers;} void step(); + void setClearColor(float, float, float); private: std::map<Priority, std::unique_ptr<Layer>> _layers; diff --git a/source/engine/graphics/front/geometry/Plane.hpp b/source/engine/graphics/front/geometry/Plane.hpp index 373e367..023e399 100644 --- a/source/engine/graphics/front/geometry/Plane.hpp +++ b/source/engine/graphics/front/geometry/Plane.hpp @@ -6,6 +6,7 @@ namespace megu { class Plane : public Static_Geometry<Plane, QUADS, layout::FLAT, layout::TEXTURE> { public: inline static const Vertices_t & Vertices() {return Plane::_Vertices;} + inline static const size_t & Count() {return 4;} private: static Vertices_t _Vertices; diff --git a/source/engine/graphics/front/geometry/Quads.cpp b/source/engine/graphics/front/geometry/Quads.cpp index fccb887..e4550c4 100644 --- a/source/engine/graphics/front/geometry/Quads.cpp +++ b/source/engine/graphics/front/geometry/Quads.cpp @@ -5,6 +5,6 @@ namespace megu { 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 1.f, 1.f, 1.f, - 0.f, 1.f, 0.f, 1.f - }; + 0.f, 1.f, 0.f, 1.f + }; } \ No newline at end of file diff --git a/source/engine/graphics/front/geometry/Quads.hpp b/source/engine/graphics/front/geometry/Quads.hpp index 2e70bc6..f36888a 100644 --- a/source/engine/graphics/front/geometry/Quads.hpp +++ b/source/engine/graphics/front/geometry/Quads.hpp @@ -6,6 +6,7 @@ namespace megu { class Quads : public Static_Geometry<Quads, QUADS, layout::FLAT, layout::TEXTURE> { public: inline static const Vertices_t & Vertices() {return Quads::_Vertices;} + inline static const size_t & Count() {return 4;} private: static Vertices_t _Vertices; diff --git a/source/engine/graphics/front/geometry/Vertex.hpp b/source/engine/graphics/front/geometry/Vertex.hpp new file mode 100644 index 0000000..4c3eed9 --- /dev/null +++ b/source/engine/graphics/front/geometry/Vertex.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include <glm/glm.hpp> + +namespace megu { + struct Vertex { + glm::vec2 _position; + glm::vec2 _texture; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/group/FrameBufferGroup.cpp b/source/engine/graphics/front/group/FrameBufferGroup.cpp index 6653a7c..c9052ed 100644 --- a/source/engine/graphics/front/group/FrameBufferGroup.cpp +++ b/source/engine/graphics/front/group/FrameBufferGroup.cpp @@ -6,7 +6,7 @@ namespace megu { FrameBufferGroup::FrameBufferGroup() - : _vbo(this->_vao, Plane::Layout(), Plane::Vertices().size(), megu::EditMode::STATIC) { + : _vbo(this->_vao, Plane::Layout(), Plane::Vertices(), megu::EditMode::STATIC), _clear(0.f) { megu::Source vert("assets/shaders/FrameBuffer-Instanced.vert", Source::Categorie::VERTEX); this->_program.attach(vert); @@ -15,8 +15,6 @@ namespace megu { this->_program.link(); - this->_vbo << Plane::Vertices(); - vert.release(); frag.release(); } @@ -33,6 +31,7 @@ namespace megu { this->_program.setUniform("uSampler", uSampler); this->_program.setUniform("uTexturesCount", static_cast<GLuint>(textures.size())); + this->_program.setUniform("uClearColor", this->_clear); glDrawArrays(Plane::Primitive(), 0, static_cast<GLsizei>(Plane::Vertices().size())); } } \ No newline at end of file diff --git a/source/engine/graphics/front/group/FrameBufferGroup.hpp b/source/engine/graphics/front/group/FrameBufferGroup.hpp index c4ee336..40858d4 100644 --- a/source/engine/graphics/front/group/FrameBufferGroup.hpp +++ b/source/engine/graphics/front/group/FrameBufferGroup.hpp @@ -13,10 +13,12 @@ namespace megu { ~FrameBufferGroup() = default; virtual void draw(const Window &, const Camera &, const TextureArray &) const; + inline void setClearColor(float x, float y, float z) {this->_clear = {x, y, z};} private: VertexArray _vao; VerticeBuffer _vbo; Program _program; + glm::vec3 _clear; }; } \ No newline at end of file diff --git a/source/engine/graphics/front/group/ImageGroup.cpp b/source/engine/graphics/front/group/ImageGroup.cpp index 8730cb9..32db991 100644 --- a/source/engine/graphics/front/group/ImageGroup.cpp +++ b/source/engine/graphics/front/group/ImageGroup.cpp @@ -37,12 +37,16 @@ namespace megu { this->_vao.bind(); this->_program.use(); + this->_program.setUniform("uProj", camera.projection()); + this->_program.setUniform("uView", camera.view()); + std::vector<std::reference_wrapper<const Texture>> textures; std::vector<glm::mat4> uModels; std::vector<GLint> uTextures; - static auto uSampler = array_generator<GLint, 32>().array; + static auto uSampler = array_generator<GLint, 32>().array; + this->_program.setUniform("uSampler", uSampler); for(auto & image : this->_images) { @@ -53,9 +57,6 @@ namespace megu { } else { if(textures.size() >= 8 || uModels.size() >= 124) { - this->_program.setUniform("uProj", camera.projection()); - this->_program.setUniform("uView", camera.view()); - this->_program.setUniform("uSampler", uSampler); this->_program.setUniform("uModel", uModels); this->_program.setUniform("uTextures", uTextures); @@ -74,11 +75,6 @@ namespace megu { } if(!textures.empty()) { - this->_program.setUniform("uProj", camera.projection()); - this->_program.setUniform("uView", camera.view()); - - - this->_program.setUniform("uSampler", uSampler); this->_program.setUniform("uModel", uModels); this->_program.setUniform("uTextures", uTextures); diff --git a/source/engine/graphics/front/group/VertexArrayGroup.cpp b/source/engine/graphics/front/group/VertexArrayGroup.cpp new file mode 100644 index 0000000..26c5bda --- /dev/null +++ b/source/engine/graphics/front/group/VertexArrayGroup.cpp @@ -0,0 +1,42 @@ +#include "VertexArrayGroup.hpp" + +#include <engine/graphics/utility/array_generator.hpp> + +namespace megu { + VertexArrayGroup::VertexArrayGroup() + : _vbo(this->_vao, Quads::Layout(), Quads::Vertices(), megu::EditMode::STATIC) { + Source vert("assets/shaders/Grid-Instanced.vert", Source::Categorie::VERTEX); + this->_program.attach(vert); + + Source frag("assets/shaders/Grid-Instanced.frag", Source::Categorie::FRAGMENT); + this->_program.attach(frag); + + this->_program.link(); + + vert.release(); + frag.release(); + } + + void VertexArrayGroup::add(const Texture & texture, const VerticesArray & grid) { + this->_objects[texture].push_back(grid); + } + + void VertexArrayGroup::draw(const Window &, const Camera & camera, const TextureArray &) const { + this->_vao.bind(); + this->_program.use(); + + this->_program.setUniform("uProj", camera.projection()); + this->_program.setUniform("uView", camera.view()); + + for(const auto & [texture, grids] : this->_objects) { + texture.get().bind(0); + for(const auto & grid : grids) { + this->_program.setUniform("uModel", grid.get().transformation().model()); + this->_program.setUniform("uSampler", 0); + this->_program.setUniform("uData", static_cast<const void *>(grid.get().vertices().data()), grid.get().size()); + + glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(grid.get().size())); + } + } + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/group/VertexArrayGroup.hpp b/source/engine/graphics/front/group/VertexArrayGroup.hpp new file mode 100644 index 0000000..65efa65 --- /dev/null +++ b/source/engine/graphics/front/group/VertexArrayGroup.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "DrawGroup.hpp" + +#include <map> +#include <optional> + +#include <engine/graphics/back/textures/Texture.hpp> +#include <engine/graphics/back/buffers/VertexArray.hpp> +#include <engine/graphics/back/buffers/VerticeBuffer.hpp> +#include <engine/graphics/back/shaders/Program.hpp> + +#include <engine/graphics/front/object/VerticesArray.hpp> + +#include <engine/graphics/utility/texture_comparator.hpp> + +namespace megu { + class VertexArrayGroup : public DrawGroup { + public: + VertexArrayGroup(); + ~VertexArrayGroup() = default; + + void add(const Texture &, const VerticesArray &); + void draw(const Window &, const Camera &, const TextureArray &) const override; + + private: + std::map<std::reference_wrapper<const Texture>, std::vector<std::reference_wrapper<const VerticesArray>>, texture_comparator> _objects; + + VertexArray _vao; + VerticeBuffer _vbo; + Program _program; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/front/object/VerticesArray.cpp b/source/engine/graphics/front/object/VerticesArray.cpp new file mode 100644 index 0000000..3a576ed --- /dev/null +++ b/source/engine/graphics/front/object/VerticesArray.cpp @@ -0,0 +1,20 @@ +#include "VerticesArray.hpp" + +namespace megu { + VerticesArray::VerticesArray(Primitive_t primitive, size_t size) + : _primitive(primitive), _vertices(size) {} + + VerticesArray::VerticesArray(const VerticesArray & src) + : _transformation(src._transformation), _primitive(src._primitive), _vertices(src._vertices) {} + + VerticesArray VerticesArray::operator=(const VerticesArray & src) { + this->_transformation = src._transformation; + this->_primitive = src._primitive; + this->_vertices = src._vertices; + return *this; + } + + void VerticesArray::append(const Vertex & vertex) { + this->_vertices.push_back(vertex); + } +} \ No newline at end of file diff --git a/source/engine/graphics/front/object/VerticesArray.hpp b/source/engine/graphics/front/object/VerticesArray.hpp new file mode 100644 index 0000000..bbceaa9 --- /dev/null +++ b/source/engine/graphics/front/object/VerticesArray.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <array> + +#include <engine/graphics/back/geometry/Transformable.hpp> +#include <engine/graphics/back/textures/Texture.hpp> + +#include <engine/graphics/front/geometry/Quads.hpp> +#include <engine/graphics/front/geometry/Vertex.hpp> + +namespace megu { + class VerticesArray { + public: + VerticesArray(Primitive_t, size_t); + VerticesArray(const VerticesArray &); + VerticesArray operator=(const VerticesArray &); + ~VerticesArray() = default; + + inline size_t size() const {return this->_vertices.size();} + + void scale(float x, float y) {this->_transformation.scale(x, y);} + + void append(const Vertex &); + + const Transformable & transformation() const {return this->_transformation;} + const Primitive_t & primitive() const {return this->_primitive;} + const std::vector<Vertex> & vertices() const {return this->_vertices;} + + Vertex & operator[](size_t index) {return this->_vertices[index];} + const Vertex & operator[](size_t index) const {return this->_vertices[index];} + + private: + Transformable _transformation; + Primitive_t _primitive; + std::vector<Vertex> _vertices; + }; +} \ No newline at end of file diff --git a/source/engine/graphics/utility/texture_comparator.hpp b/source/engine/graphics/utility/texture_comparator.hpp new file mode 100644 index 0000000..cdb9f9a --- /dev/null +++ b/source/engine/graphics/utility/texture_comparator.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include <engine/graphics/back/textures/Texture.hpp> + +namespace megu { + struct texture_comparator { + bool operator()(const Texture & t1, const Texture & t2) const { + return t1.identifier() > t2.identifier(); + } + }; +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index c4abc5e..67c44ff 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -16,6 +16,7 @@ #include <engine/graphics/front/group/ImageGroup.hpp> #include <engine/graphics/front/engine/Renderer.hpp> #include <engine/graphics/front/engine/Engine.hpp> +#include <engine/graphics/front/group/VertexArrayGroup.hpp> #include <engine/graphics/errors.hpp> const float i_x = 1.f; @@ -30,6 +31,12 @@ glm::vec2 to_screen_coordinate(const glm::vec2 & tile, float w, float h, float l }; } +megu::Vertex to_screen_coordinate(int x, int y, unsigned int u, unsigned int v, const megu::Texture & texture) { + return {{x, y}, {static_cast<float>(u) / static_cast<float>(texture.width()), static_cast<float>(v) / static_cast<float>(texture.height())}}; +} + +//* Isometric : +/* int main(int argc, const char * argv[]) { try { //? Window @@ -201,4 +208,89 @@ int main(int argc, const char * argv[]) { } return EXIT_SUCCESS; -} \ No newline at end of file +} +*/ + +int main(int argc, const char * argv[]) { + try { + //? Window + megu::Window window; + window.open("Isometric Window", 360, 360); + megu::error::opengl_error::check(); + + std::cout << "Window Inited" << std::endl; + + //? Group + megu::VertexArrayGroup group; + + std::cout << "Group Inited" << std::endl; + + //? Grids + + megu::Texture texture_1; + texture_1.store(megu::TextureBuffer("assets/textures/Tile_Test_3.png")); + + megu::VerticesArray grid_1(megu::Quads::Primitive(), 4); + + /*grid_1[0] = {{0.f, 0.f}, {0.0f, 0.0f}}; + grid_1[1] = {{16.f, 0.f}, {0.5f, 0.0f}}; + grid_1[2] = {{16.f, 16.f}, {0.5f, 0.5f}}; + grid_1[3] = {{0.f, 16.f}, {0.0f, 0.5f}};*/ + + + + grid_1[0] = to_screen_coordinate(0, 0, 0, 0, texture_1); + grid_1[1] = to_screen_coordinate(16, 0, 16, 0, texture_1); + grid_1[2] = to_screen_coordinate(16, 16, 16, 16, texture_1); + grid_1[3] = to_screen_coordinate(0, 16, 0, 16, texture_1); + + + grid_1.scale(1.f, 1.f); + + + + group.add(texture_1, grid_1); + + std::cout << "Grid created" << std::endl; + + //? ImGui + //ImGui::CreateContext(); + //ImGui_ImplOpenGL3_Init(); + //ImGui_ImplGlfw_InitForOpenGL(window.ptr(), true); + + //? Engines + megu::GraphicEngine engine(window); + megu::Renderer basic_renderer(100, 100); + + engine.push(0, basic_renderer); + engine.push(0, 0, group); + + //? Render Loop + std::cout << "Render Loop Begin !" << std::endl; + + double previousTime = megu::Window::Time(); + int frameCount = 0; + + while(window.isOpen()) { + double currentTime = megu::Window::Time(); + frameCount++; + + if(currentTime - previousTime >= 1.0) { + window.setTitle(std::to_string(frameCount)); + + frameCount = 0; + previousTime = currentTime; + } + + window.pollEvents(); + engine.step(); + } + std::cout << "Render Loop End !" << std::endl; + } + catch(std::exception & error) { + std::cerr << error.what() << std::endl; + } + + return EXIT_SUCCESS; +} + -- GitLab