From 366300aafee6270ed94e99b3a67d9085353012fa Mon Sep 17 00:00:00 2001 From: JordSant <77529699+JordSant@users.noreply.github.com> Date: Tue, 9 Dec 2025 19:13:05 +0100 Subject: [PATCH] [examples] Add `shaders_game_of_life` (#5394) * [examples] Add `shaders_game_of_life` * Declaration hides another variable same name --- .../shaders/resources/game_of_life/acorn.png | Bin 0 -> 218 bytes .../resources/game_of_life/breeder.png | Bin 0 -> 1919 bytes .../shaders/resources/game_of_life/glider.png | Bin 0 -> 216 bytes .../resources/game_of_life/glider_gun.png | Bin 0 -> 291 bytes .../resources/game_of_life/oscillators.png | Bin 0 -> 463 bytes .../resources/game_of_life/puffer_train.png | Bin 0 -> 1378 bytes .../resources/game_of_life/r_pentomino.png | Bin 0 -> 213 bytes .../resources/game_of_life/spaceships.png | Bin 0 -> 828 bytes .../resources/game_of_life/still_lifes.png | Bin 0 -> 615 bytes .../resources/shaders/glsl100/game_of_life.fs | 44 ++ .../resources/shaders/glsl120/game_of_life.fs | 42 ++ .../resources/shaders/glsl330/game_of_life.fs | 45 ++ examples/shaders/shaders_game_of_life.c | 350 +++++++++++ examples/shaders/shaders_game_of_life.png | Bin 0 -> 13793 bytes .../examples/shaders_game_of_life.vcxproj | 569 ++++++++++++++++++ 15 files changed, 1050 insertions(+) create mode 100644 examples/shaders/resources/game_of_life/acorn.png create mode 100644 examples/shaders/resources/game_of_life/breeder.png create mode 100644 examples/shaders/resources/game_of_life/glider.png create mode 100644 examples/shaders/resources/game_of_life/glider_gun.png create mode 100644 examples/shaders/resources/game_of_life/oscillators.png create mode 100644 examples/shaders/resources/game_of_life/puffer_train.png create mode 100644 examples/shaders/resources/game_of_life/r_pentomino.png create mode 100644 examples/shaders/resources/game_of_life/spaceships.png create mode 100644 examples/shaders/resources/game_of_life/still_lifes.png create mode 100644 examples/shaders/resources/shaders/glsl100/game_of_life.fs create mode 100644 examples/shaders/resources/shaders/glsl120/game_of_life.fs create mode 100644 examples/shaders/resources/shaders/glsl330/game_of_life.fs create mode 100644 examples/shaders/shaders_game_of_life.c create mode 100644 examples/shaders/shaders_game_of_life.png create mode 100644 projects/VS2022/examples/shaders_game_of_life.vcxproj diff --git a/examples/shaders/resources/game_of_life/acorn.png b/examples/shaders/resources/game_of_life/acorn.png new file mode 100644 index 0000000000000000000000000000000000000000..58ea0b4d1c588535bc857e5ef7cb3b474260c014 GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^AT}!p8<4C?sm%aVjKx9jPK-BC>eK@{Ea{HEjtmSN z`?>!lvI6-E$sR$z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a z5n0T@pr;JNj1^1m%YcIHC7!;n>@Rs(c=SYXob8hb3K@91IEHXsPyX}k>+5z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Rk3B4{fu`^gtNa30(F0Z`0uWkbu*WX7 zYKRJmkOt)QJpUPrEnp%7qFA4_(}`&(zWq$8hP;dUpp#@YF=A|?mRn7TJa*Nxb&Ct`$Kf?}c;Bj~r(d`E{W@ralBC-g1{x9$p(Zw{E&p@#f zdjX|gz-2yzaTgOZG1$05x|oX0ush(;WD|-B%s7K#Mwm@fFO1y#zomDv3O3Vf0urRc z2C}$~)3z_GzlZfEFm$~#{Cd{Elqc|GAV^Y-WiQ25LM(=6HB^Py_(kyq1jx$MSaB^I ztqk0>84T&~6sO*VW!La)@rdGawR;N@d&#XV9#^}C4C&T}8TF_Bo^?RDWCknXY-1eI zjj#}4;5^{+8*Iyz+XAAu`)S#}AonItURookfl_7kHpx7BH8A8FaKsL{;v5vu-nB_~awSex)aQ0BxtPa_mqGD^6JZT2kv5K?-@NqS?82Tbg2<7xVkbN9xqTFdFQ7M^b|_ zwV46?-qd4OMje|C*hvRQ2VqX#rYe3Fc2-WJ@IXj8%%POA$ zdk&KlFcJrapuZo2L1KmM48&=`rDwGE_C+ATk{%^{8FZpbLXiN(Zuz5=LMX-J zWOD1r(SXdn393HrKBu;&MmAN;urs^NWYEc?uMbfb82?>M4e!b)E4Og9eOgD-dek-V zn-FH56(F!h&1c^ayK8A33@adDJeFMpSbf(r+Qio@6}rNy0&cx46kOR1TKbeDh%|Cr zN7YOl8=w$ucdrN8ony|g=``PK8a4d-n&@s*V;)o%TJOlcpDol`I~aQpw# ztiaLkD6<+{eNK8Iq&H#2lQ{7vsN~M6;ulQeQw>QlI0cTX0h#iBNid`&7*f(^aOZ(Y z+7bx{CoZN*HNl;U#FdpT+3qM)3VJp~%cDTq3|#(jFOA)MyFE65r1Oth!W0;^0wZ4A z-Khuz0S>2_%z@0U?6cc+AZJZ_eaXEEA&=nXfHCI45#-QN`#Iwb%qpf%UEj%z;P6^j z?I#$R7~$mXB(^m2%GOvJrl}?r;t5vEBHvyIRC_XaSEYqG0!y61oAI_w@2g{WtK)83 zUK2z$&AxM6U7?yMoM-P$)i12OIC}=hnDJ^{hg}Ms&yb|bWRO4 zC>S-Z{?nqLr~NI~fFN0k6;rgsqR~t>X6kW<9(_}w9P@immy2ao8y zJHveike2S}UNk4R#mq($2ZQ9qeCeuz-i^PzeQ>jDNqq$Yb+AmkzBEO9W_K;~dLnz* z6BSJ$KnhY>ocz=H2bN(dHptAY32P<&M_}a$KU-o)Gs!KME<2Sf0c=f8vV!5XCXxlV ziWCDWmR4A+N40OjjTQ_moP!xnMj*ykeGO|fXu5eEEI5i7T2?>BBM>;#v zggY=;0{}Kb$0Cs3sR@b=8!gYnx`%RmW(G_s*YbT9$qWGv&Ty`!8nWJ4ydHUwuUkVmEUW*2&$UIUn}B_j}4 z1|k(buO@qkkrE6-0HJjGc481;X9H6Pq!oh-TRSnqKq73hzESK3*I?kBpop=LtSX-p$AF~rMn;}Tf+3LPu4PIXHmK!}Hkp_* z0Z{;Pe;o)E*9d3O>0|mnB{&!&297e$kdn-hl3++-l7HVm^}8B2ZLa_T002ovPDHLk FV1l3@Y~}y} literal 0 HcmV?d00001 diff --git a/examples/shaders/resources/game_of_life/glider.png b/examples/shaders/resources/game_of_life/glider.png new file mode 100644 index 0000000000000000000000000000000000000000..921adb8ed5e4361628af0df83a7000b078b0ee15 GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0vp^tRT$61|)m))t&+=#^NA%C&rs6b?Si}mUKs7M+SzC z{oH>NK`IrJJ%W507^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10g0sLQ zvY3HEPZ@+6E0)@q0R`DhJbhi+U-Gc9v$Cm$-Sq?t>3O<1hHzYu?Kb3NP!Kru;nA`G z^KV6}cWexHKFri-w@u~dJBAD;hr=#8=4Yz8#o1Mb+BF2lb^~=Xc)I$ztaD0e0swAE BH=h6i literal 0 HcmV?d00001 diff --git a/examples/shaders/resources/game_of_life/glider_gun.png b/examples/shaders/resources/game_of_life/glider_gun.png new file mode 100644 index 0000000000000000000000000000000000000000..29b65d3de8ae04baa7be9ae31a29d9704cc1eab5 GIT binary patch literal 291 zcmeAS@N?(olHy`uVBq!ia0vp^YCz1*!3HFS`Tx5CDaPU;cPGZ1Cw1z99F}xPUq=Rp zjs4tz5?O(Kg=CK)Uj~LMpst1%28Lfip@tU>45bDP46hOx7_4S6Fo+k-*%fF5l;AAz zh%9Dc&{GCs#)_r(Wk5mp5>H=O_Ln>?JZ6HiyD!B9g(^K=978NlpAB*3YcSxDKArdX ze{l6RVK&}loEg_H8;NDy;#1tYmG$C(38n@3*@#~6Qc9G}iX027_oA<62Uil&V>mC``O-mQ!T eYlqfvV6I_vynNnt{d}M!7(8A5T-G@yGywpkz@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Rk3-1z@fecnz{5u#ZNG@)v8+!P=#7|agfyREZ*vIj^+8xbua zMxBy9KmhLsLY9LSkZK3OX^8EXSt@6b5M5`aHj?a?*2o5g zti=(EFrN4&l<6{ zV7>c;JH^&15MC$ReUD9fN8_4Q?Nj3fZIGJTN;TiwZzYPzv^m0>A+4@s$*N3c002ovPDHLk FV1jQ-vg`l= literal 0 HcmV?d00001 diff --git a/examples/shaders/resources/game_of_life/puffer_train.png b/examples/shaders/resources/game_of_life/puffer_train.png new file mode 100644 index 0000000000000000000000000000000000000000..8d77219b024579726c05be0bb520d0193da6e920 GIT binary patch literal 1378 zcmV-o1)chdP)z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Rk3GuBrQ+=K}xk{zd0!_1IYJ82AAPh}|F!?;s^XKOaulDn$ zSDN6zzrUvSJyUC=@XzzaYy1^Jqs8ZW)WW)%%JV#G6Bsw3S=(6x&rd+AP1M#uUT~-p z9$D8s1lHL6c#mdX_tx@FgDd+E*Er&2^IEBSrQ!JdBv34OiJYV6Pr|&PBTh^~m6i4+ z8ni^to}p>Y=3Gr>{BcBR#F-n@*&-R@r%EEBjkJyZ<74F1u*wu#i#l2vTC26$_kLsp zJyYWr;pwQNweL4_YM)lm)HWipOURE(BHZB6;;7Pft^r7*!SNmq>1tjAOKo@*P?Jog z7KB!&k!Issgn8jm>&$c;N0W(Et}<%yCd`hENztWyI;JIPy^g)Rr$w8G24zn7)18x< zYo2&aSO&BTG@2^Fe1B)yvP9F`;?J#|*BI!b@d4?&TLqw5HLg8{U|nW7)Y>Vl$kb6M z+X-wfW=hL>4bi|(i}R0K4ybMsxM^+L`b0FQ2SrXvVP|y=!f-%|lG;scnsXc$YDh?0 zx4@S6_yg6t$i_ABHDb9H_O!~Q*2hn1v-=#a3N)5hX5m*)VfL9FACWvkw`6&>sU2jF z8;~ByG?oLMkmW?Ob^_kauQL$<;Vn1n;9@E#I9!E&ZQ0_)_q$coGdDSfZbaid&C~i- zUL=q-97s&U6~|9-cp^@-v!3wXwLEbnX*+JcDvr+UT*?zCI9yTN*(`PmgM=2h2sk{U z3QE-6;Lw|syTRcI@hA%IzKaroyoy4n!e7LM*nagxf zNK?0R-4nNlgYw-IyH>sO-4i#=_2`}`c_c3Rp7N<%$eUNJGP8s+mQ3Bkx+j>aTWI%$ z$B}qQ_XIO_3+QwU;SL)rjSk%1B_Jt7rO~on%1~(p8OjWmMhEVu4wYtXHg%{pB1q~` zX;g?3L!}V`{tuP*&Vo*B(r7I@aJNLxiKcJJ2GR%aqUDOTfxEM|QzyQ!gu10~sK(P0 zi4_}69V(4FTl!FGWZ*86OnmJh8Kn-~MV^pb0Mgnx`hs7}HjfbwHEXFkXXNQbYC)*X kKX*h4ohrEX`dY#N0tbz~VkKQve*gdg07*qoM6N<$f;TL9mH+?% literal 0 HcmV?d00001 diff --git a/examples/shaders/resources/game_of_life/r_pentomino.png b/examples/shaders/resources/game_of_life/r_pentomino.png new file mode 100644 index 0000000000000000000000000000000000000000..1707f3c12d561bf0aad93a9de91a60aa452f6829 GIT binary patch literal 213 zcmeAS@N?(olHy`uVBq!ia0vp^tRT$61|)m))t&+=#^NA%C&rs6b?Si}mUKs7M+SzC z{oH>NK`IrJJ%W507^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10g0sLQ zvY3HEPZ@+6E0)@q0R`DhJbhi+U-Gc{uKbLh*2~7Y$eLAE7 literal 0 HcmV?d00001 diff --git a/examples/shaders/resources/game_of_life/spaceships.png b/examples/shaders/resources/game_of_life/spaceships.png new file mode 100644 index 0000000000000000000000000000000000000000..867f6fea32e5dbc5a62f3b52c78a2b762dae507c GIT binary patch literal 828 zcmV-C1H=4@P)z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Rk3#Z zM+~5~_5vx)s^hCNt5N_RWQ!6L;8!wHV_xZxO8a#{}#kLwP6<{^RhPE&&tV?1^ksV6{B*3ClwMKwTfY}4B z*x>fY8N49*P@1Xr&)n5IB!RS7*Az#Ji*GwNuGSWi2wj}6J=Et&j$ znnqnslIGjFGg8V~MHhW|?-~PHl&0p&q1k$9j`T-@YG&sINPwRJKn0Z5j5)l8@QtX7 zewq690CJhfwS_H5=X7S$B%vl4TMq9j9nh(5*1r2z7&QV}**_$~Rwagif>Bu(hPFWa zg8S0KiqJf9t2b(*yDL@AE588uc^zQ;kKAJb0000z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vG?BLDy{BLR4&KXw2B00(qQO+^Rk3kvdguYs+#Ud#*;>d(|Lm}J_;%nX4;!J>rPb4M7YQLIBfn^`1~y(GdYhBAtZwt;lu z2&^=35sL=!Uae*`H|$+oRx3uU`PNw1y~{_su^;qMRpWz@&V(Gh75AeJCjq%WLxpCk~y8kGd=*+rb4e&i@pE=002ovPDHLkV1ksY B1pEL1 literal 0 HcmV?d00001 diff --git a/examples/shaders/resources/shaders/glsl100/game_of_life.fs b/examples/shaders/resources/shaders/glsl100/game_of_life.fs new file mode 100644 index 000000000..70c12ac2c --- /dev/null +++ b/examples/shaders/resources/shaders/glsl100/game_of_life.fs @@ -0,0 +1,44 @@ +#version 100 + +precision highp float; + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Input size in pixels of the textures +uniform vec2 resolution; + +void main() +{ + // Size of one pixel in texture coordinates (from 0.0 to 1.0) + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + // Status of the current cell (1 = alive, 0 = dead) + int origValue = (texture2D(texture0, fragTexCoord).r < 0.1)? 1 : 0; + + // Sum of alive neighbors + int sumValue = (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top + sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right + + sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right + + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right + + // Game of life rules: + // Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise + // Current cell goes from dead to alive when exactly 3 neighbors are alive + if ((origValue == 1 && sumValue == 2) || sumValue == 3) + gl_FragColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black + else + gl_FragColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE +} diff --git a/examples/shaders/resources/shaders/glsl120/game_of_life.fs b/examples/shaders/resources/shaders/glsl120/game_of_life.fs new file mode 100644 index 000000000..611f961bc --- /dev/null +++ b/examples/shaders/resources/shaders/glsl120/game_of_life.fs @@ -0,0 +1,42 @@ +#version 120 + +// Input vertex attributes (from vertex shader) +varying vec2 fragTexCoord; +varying vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Input size in pixels of the textures +uniform vec2 resolution; + +void main() +{ + // Size of one pixel in texture coordinates (from 0.0 to 1.0) + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + // Status of the current cell (1 = alive, 0 = dead) + int origValue = (texture2D(texture0, fragTexCoord).r < 0.1)? 1 : 0; + + // Sum of alive neighbors + int sumValue = (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top + sumValue += (texture2D(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right + + sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right + + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom + sumValue += (texture2D(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right + + // Game of life rules: + // Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise + // Current cell goes from dead to alive when exactly 3 neighbors are alive + if (((origValue == 1) && (sumValue == 2)) || sumValue == 3) + gl_FragColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black + else + gl_FragColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE +} diff --git a/examples/shaders/resources/shaders/glsl330/game_of_life.fs b/examples/shaders/resources/shaders/glsl330/game_of_life.fs new file mode 100644 index 000000000..cc80861d6 --- /dev/null +++ b/examples/shaders/resources/shaders/glsl330/game_of_life.fs @@ -0,0 +1,45 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// Input size in pixels of the textures +uniform vec2 resolution; + +void main() +{ + // Size of one pixel in texture coordinates (from 0.0 to 1.0) + float x = 1.0/resolution.x; + float y = 1.0/resolution.y; + + // Status of the current cell (1 = alive, 0 = dead) + int origValue = (texture(texture0, fragTexCoord).r < 0.1)? 1 : 0; + + // Sum of alive neighbors + int sumValue = (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Top-left + sumValue += (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Top + sumValue += (texture(texture0, vec2(fragTexCoord.x - x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Top-right + + sumValue += (texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Left + sumValue += (texture(texture0, vec2(fragTexCoord.x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Right + + sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y - y)).r < 0.1)? 1 : 0; // Bottom-left + sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y )).r < 0.1)? 1 : 0; // Bottom + sumValue += (texture(texture0, vec2(fragTexCoord.x + x, fragTexCoord.y + y)).r < 0.1)? 1 : 0; // Bottom-right + + // Game of life rules: + // Current cell remains alive when 2 or 3 neighbors are alive, dies otherwise + // Current cell goes from dead to alive when exactly 3 neighbors are alive + if (((origValue == 1) && (sumValue == 2)) || sumValue == 3) + finalColor = vec4(0.0, 0.0, 0.0, 255.0); // Alive: draw the pixel black + else + finalColor = fragColor; // Dead: draw the pixel with the background color, RAYWHITE +} diff --git a/examples/shaders/shaders_game_of_life.c b/examples/shaders/shaders_game_of_life.c new file mode 100644 index 000000000..daeb4d789 --- /dev/null +++ b/examples/shaders/shaders_game_of_life.c @@ -0,0 +1,350 @@ +/******************************************************************************************* +* +* raylib [shaders] example - Conway's Game of Life with shaders +* +* Example complexity rating: [★★★☆] 3/4 +* +* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support, +* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version +* +* Example originally created with raylib 5.6, last time updated with raylib 5.6 +* +* Example contributed by Jordi Santonja (@JordSant) and reviewed by Ramon Santamaria (@raysan5) +* +* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, +* BSD-like license that allows static linking with closed source software +* +* Copyright (c) 2025 Jordi Santonja (@JordSant) +* +********************************************************************************************/ + +#include "raylib.h" + +#define RAYGUI_IMPLEMENTATION +#include "raygui.h" // Required for GUI controls + +#if defined(PLATFORM_DESKTOP) + #define GLSL_VERSION 330 +#else // PLATFORM_ANDROID, PLATFORM_WEB + #define GLSL_VERSION 100 +#endif + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// Interaction mode +typedef enum { + MODE_RUN = 0, + MODE_PAUSE, + MODE_DRAW, +} InteractionMode; + +// Struct to store example preset patterns +typedef struct { + char *name; + char *fileName; + Vector2 position; +} PresetPattern; + +//---------------------------------------------------------------------------------- +// Functions declaration +//---------------------------------------------------------------------------------- +void FreeImageToDraw(Image **imageToDraw); + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + const int menuWidth = 100; + const int windowWidth = screenWidth - menuWidth; + const int windowHeight = screenHeight; + + const int worldWidth = 2048; + const int worldHeight = 2048; + + const int randomTiles = 8; // Random preset: divide the world to compute random points in each tile + + const Rectangle worldRectSource = { 0, 0, (float)worldWidth, (float)-worldHeight }; + const Rectangle worldRectDest = { 0, 0, (float)worldWidth, (float)worldHeight }; + const Rectangle textureOnScreen = { 0, 0, (float)windowWidth, (float)windowHeight }; + + const PresetPattern presetPatterns[] = { + { "Glider", "glider", { 0.5f, 0.5f } }, { "R-pentomino", "r_pentomino", { 0.5f, 0.5f } }, { "Acorn", "acorn", { 0.5f,0.5f } }, + { "Spaceships", "spaceships", { 0.1f, 0.5f } }, { "Still lifes", "still_lifes", { 0.5f, 0.5f } }, { "Oscillators", "oscillators", { 0.5f, 0.5f } }, + { "Puffer train", "puffer_train", { 0.1f, 0.5f } }, { "Glider Gun", "glider_gun", { 0.2f, 0.2f } }, { "Breeder", "breeder", { 0.1f, 0.5f } }, + { "Random", "", { 0.5f, 0.5f } } + }; + const int numberOfPresets = sizeof(presetPatterns) / sizeof(presetPatterns[0]); + + // Variable declaration + //-------------------------------------------------------------------------------------- + int zoom = 1; + float offsetX = (worldWidth - windowWidth)/2.0f; // Centered on window + float offsetY = (worldHeight - windowHeight)/2.0f; // Centered on window + int framesPerStep = 1; + int frame = 0; + + int preset = -1; // No button pressed for preset + int mode = MODE_RUN; // Starting mode: running + bool buttonZoomIn = false; // Button states: false not pressed + bool buttonZomOut = false; + bool buttonFaster = false; + bool buttonSlower = false; + + InitWindow(screenWidth, screenHeight, "raylib [shaders] example - conway's game of life"); + + // Load shader + Shader shdrGameOfLife = LoadShader(0, TextFormat("resources/shaders/glsl%i/game_of_life.fs", GLSL_VERSION)); + + // Set shader uniform size of the world + int resolutionLoc = GetShaderLocation(shdrGameOfLife, "resolution"); + const float resolution[2] = { (float)worldWidth, (float)worldHeight }; + SetShaderValue(shdrGameOfLife, resolutionLoc, resolution, SHADER_UNIFORM_VEC2); + + // Define two textures: the current world and the previous world + RenderTexture2D world1 = LoadRenderTexture(worldWidth, worldHeight); + RenderTexture2D world2 = LoadRenderTexture(worldWidth, worldHeight); + BeginTextureMode(world2); + ClearBackground(RAYWHITE); + EndTextureMode(); + + Image startPattern = LoadImage("resources/game_of_life/r_pentomino.png"); + UpdateTextureRec(world2.texture, (Rectangle) { worldWidth / 2.0f, worldHeight / 2.0f, (float)(startPattern.width), (float)(startPattern.height) }, startPattern.data); + UnloadImage(startPattern); + + // Pointers to the two textures, to be swapped + RenderTexture2D *currentWorld = &world2; + RenderTexture2D *previousWorld = &world1; + + // Image to be used in DRAW mode, to be changed with mouse input + Image *imageToDraw = NULL; + + SetTargetFPS(60); // Set at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + frame++; + + // Change zoom: both by buttons or by mouse wheel + float mouseWheelMove = GetMouseWheelMove(); + if (buttonZoomIn || (buttonZomOut && (zoom > 1)) || (mouseWheelMove != 0.0f)) + { + FreeImageToDraw(&imageToDraw); // Zoom change: free the image to draw to be recreated again + + const float centerX = offsetX + (windowWidth/2.0f)/zoom; + const float centerY = offsetY + (windowHeight/2.0f)/zoom; + if (buttonZoomIn || (mouseWheelMove > 0.0f)) + zoom *= 2; + if ((buttonZomOut || (mouseWheelMove < 0.0f)) && (zoom > 1)) + zoom /= 2; + offsetX = centerX - (windowWidth/2.0f)/zoom; + offsetY = centerY - (windowHeight/2.0f)/zoom; + } + + // Change speed: number of frames per step + if (buttonFaster && framesPerStep > 1) framesPerStep--; + if (buttonSlower) framesPerStep++; + + // Mouse management + //---------------------------------------------------------------------------------- + if ((mode == MODE_RUN) || (mode == MODE_PAUSE)) + { + FreeImageToDraw(&imageToDraw); // Free the image to draw: no longer needed in these modes + + // Pan with mouse left button + static Vector2 previousMousePosition = { 0.0f, 0.0f }; + const Vector2 mousePosition = GetMousePosition(); + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && (mousePosition.x < windowWidth)) + { + offsetX -= (mousePosition.x - previousMousePosition.x)/zoom; + offsetY -= (mousePosition.y - previousMousePosition.y)/zoom; + } + previousMousePosition = mousePosition; + } + else // MODE_DRAW + { + const float offsetDecimalX = offsetX - floorf(offsetX); + const float offsetDecimalY = offsetY - floorf(offsetY); + int sizeInWorldX = (int)(ceilf((float)(windowWidth + offsetDecimalX*zoom)/zoom)); + int sizeInWorldY = (int)(ceilf((float)(windowHeight + offsetDecimalY*zoom)/zoom)); + if (offsetX + sizeInWorldX >= worldWidth) + sizeInWorldX = worldWidth - (int)floorf(offsetX); + if (offsetY + sizeInWorldY >= worldHeight) + sizeInWorldY = worldHeight - (int)floorf(offsetY); + + // Create image to draw if not created yet + if (imageToDraw == NULL) + { + RenderTexture2D worldOnScreen = LoadRenderTexture(sizeInWorldX, sizeInWorldY); + BeginTextureMode(worldOnScreen); + DrawTexturePro(currentWorld->texture, (Rectangle) { floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), -(float)(sizeInWorldY) }, + (Rectangle) { 0, 0, (float)(sizeInWorldX), (float)(sizeInWorldY) }, (Vector2) { 0, 0 }, 0.0f, WHITE); + EndTextureMode(); + imageToDraw = (Image*)RL_MALLOC(sizeof(Image)); + *imageToDraw = LoadImageFromTexture(worldOnScreen.texture); + UnloadRenderTexture(worldOnScreen); + } + + const Vector2 mousePosition = GetMousePosition(); + static int firstColor = -1; + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT) && (mousePosition.x < windowWidth)) + { + int mouseX = (int)(mousePosition.x + offsetDecimalX*zoom)/zoom; + int mouseY = (int)(mousePosition.y + offsetDecimalY*zoom)/zoom; + if (mouseX >= sizeInWorldX) + mouseX = sizeInWorldX - 1; + if (mouseY >= sizeInWorldY) + mouseY = sizeInWorldY - 1; + if (firstColor == -1) + firstColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1; + const int prevColor = (GetImageColor(*imageToDraw, mouseX, mouseY).r < 5)? 0 : 1; + ImageDrawPixel(imageToDraw, mouseX, mouseY, (firstColor) ? BLACK : RAYWHITE); + if (prevColor != firstColor) + UpdateTextureRec(currentWorld->texture, (Rectangle){ floorf(offsetX), floorf(offsetY), (float)(sizeInWorldX), (float)(sizeInWorldY) }, imageToDraw->data); + } + else + firstColor = -1; + } + + // Load selected preset + //---------------------------------------------------------------------------------- + if (preset >= 0) + { + Image pattern; + if (preset < numberOfPresets - 1) // Preset with pattern image lo load + { + pattern = LoadImage(TextFormat("resources/game_of_life/%s.png", presetPatterns[preset].fileName)); + BeginTextureMode(*currentWorld); + ClearBackground(RAYWHITE); + EndTextureMode(); + UpdateTextureRec(currentWorld->texture, (Rectangle){ worldWidth*presetPatterns[preset].position.x - pattern.width/2.0f, + worldHeight*presetPatterns[preset].position.y - pattern.height/2.0f, + (float)(pattern.width), (float)(pattern.height) }, pattern.data); + } + else // Last preset: Random values + { + pattern = GenImageColor(worldWidth/randomTiles, worldHeight/randomTiles, RAYWHITE); + for (int i = 0; i < randomTiles; i++) + { + for (int j = 0; j < randomTiles; j++) + { + ImageClearBackground(&pattern, RAYWHITE); + for (int x = 0; x < pattern.width; x++) + for (int y = 0; y < pattern.height; y++) + if (GetRandomValue(0, 100) < 15) + ImageDrawPixel(&pattern, x, y, BLACK); + UpdateTextureRec(currentWorld->texture, + (Rectangle){ (float)(pattern.width*i), (float)(pattern.height*j), + (float)(pattern.width), (float)(pattern.height) }, pattern.data); + } + } + } + + UnloadImage(pattern); + mode = MODE_PAUSE; + offsetX = worldWidth * presetPatterns[preset].position.x - windowWidth/zoom/2.0f; + offsetY = worldHeight * presetPatterns[preset].position.y - windowHeight/zoom/2.0f; + } + + // Check window draw inside world limits + if (offsetX < 0) offsetX = 0; + if (offsetY < 0) offsetY = 0; + if (offsetX > worldWidth - (float)(windowWidth)/zoom) + offsetX = worldWidth - (float)(windowWidth)/zoom; + if (offsetY > worldHeight - (float)(windowHeight)/zoom) + offsetY = worldHeight - (float)(windowHeight)/zoom; + + // Rectangles for drawing texture portion to screen + //---------------------------------------------------------------------------------- + const Rectangle textureSourceToScreen = { offsetX, offsetY, (float)windowWidth/zoom, (float)windowHeight/zoom }; + + // Draw to texture + //---------------------------------------------------------------------------------- + if ((mode == MODE_RUN) && ((frame % framesPerStep) == 0)) + { + // Swap worlds + RenderTexture2D *tempWorld = currentWorld; + currentWorld = previousWorld; + previousWorld = tempWorld; + + // Draw to texture + BeginTextureMode(*currentWorld); + BeginShaderMode(shdrGameOfLife); + DrawTexturePro(previousWorld->texture, worldRectSource, worldRectDest, (Vector2){ 0, 0 }, 0.0f, RAYWHITE); + EndShaderMode(); + EndTextureMode(); + } + + // Draw to screen + //---------------------------------------------------------------------------------- + BeginDrawing(); + DrawTexturePro(currentWorld->texture, textureSourceToScreen, textureOnScreen, (Vector2){ 0, 0 }, 0.0f, WHITE); + + DrawLine(windowWidth, 0, windowWidth, screenHeight, (Color){ 218, 218, 218, 255 }); + DrawRectangle(windowWidth, 0, screenWidth - windowWidth, screenHeight, (Color){ 232, 232, 232, 255 }); + + DrawText("Conway's", 704, 4, 20, DARKBLUE); + DrawText(" game of", 704, 19, 20, DARKBLUE); + DrawText(" life", 708, 34, 20, DARKBLUE); + DrawText("in raylib", 757, 42, 6, BLACK); + + DrawText("Presets", 710, 58, 8, GRAY); + preset = -1; + for (int i = 0; i < numberOfPresets; i++) + if (GuiButton((Rectangle){ 710.0f, 70.0f + 18*i, 80.0f, 16.0f }, presetPatterns[i].name)) + preset = i; + + GuiToggleGroup((Rectangle){ 710, 258, 80, 16 }, "Run\nPause\nDraw", &mode); + + DrawText(TextFormat("Zoom: %ix", zoom), 710, 316, 8, GRAY); + buttonZoomIn = GuiButton((Rectangle){ 710, 328, 80, 16 }, "Zoom in"); + buttonZomOut = GuiButton((Rectangle){ 710, 346, 80, 16 }, "Zoom out"); + + DrawText(TextFormat("Speed: %i frame%s", framesPerStep, (framesPerStep > 1)? "s" : ""), 710, 370, 8, GRAY); + buttonFaster = GuiButton((Rectangle){ 710, 382, 80, 16 }, "Faster"); + buttonSlower = GuiButton((Rectangle){ 710, 400, 80, 16 }, "Slower"); + + //------------------------------------------------------------------------------ + + DrawFPS(712, 426); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + UnloadShader(shdrGameOfLife); + UnloadRenderTexture(world1); + UnloadRenderTexture(world2); + + FreeImageToDraw(&imageToDraw); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} + +//---------------------------------------------------------------------------------- +// Functions definition +//---------------------------------------------------------------------------------- +void FreeImageToDraw(Image **imageToDraw) +{ + if (*imageToDraw != NULL) + { + UnloadImage(**imageToDraw); + RL_FREE(*imageToDraw); + *imageToDraw = NULL; + } +} diff --git a/examples/shaders/shaders_game_of_life.png b/examples/shaders/shaders_game_of_life.png new file mode 100644 index 0000000000000000000000000000000000000000..8ebc2c12e6920fdab2ba0a85139fb4531b4180c6 GIT binary patch literal 13793 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 literal 0 HcmV?d00001 diff --git a/projects/VS2022/examples/shaders_game_of_life.vcxproj b/projects/VS2022/examples/shaders_game_of_life.vcxproj new file mode 100644 index 000000000..0ede87cda --- /dev/null +++ b/projects/VS2022/examples/shaders_game_of_life.vcxproj @@ -0,0 +1,569 @@ + + + + + Debug.DLL + ARM64 + + + Debug.DLL + Win32 + + + Debug.DLL + x64 + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release.DLL + ARM64 + + + Release.DLL + Win32 + + + Release.DLL + x64 + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {071E64F3-1396-4A97-97CA-98CAC059B168} + Win32Proj + shaders_game_of_life + 10.0 + shaders_game_of_life + + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + true + $(DefaultPlatformToolset) + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + Application + false + $(DefaultPlatformToolset) + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + true + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + false + $(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\ + $(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\ + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + $(SolutionDir)..\..\examples\shaders + WindowsLocalDebugger + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + /FS %(AdditionalOptions) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions) + CompileAsC + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + + + Console + true + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + Copy Debug DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP + $(SolutionDir)..\..\src;%(AdditionalIncludeDirectories) + CompileAsC + true + + + Console + true + true + true + raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + $(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\ + + + xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)" + + + Copy Release DLL to output directory + + + + + + + + + + + {e89d61ac-55de-4482-afd4-df7242ebc859} + + + + + + \ No newline at end of file