From d79216555b64838dd008b8a3c9ab1011a51b1e29 Mon Sep 17 00:00:00 2001 From: justin Date: Tue, 11 Apr 2023 14:55:57 +0100 Subject: [PATCH] Try to add compute shaders --- appDodge/Main.hs | 17 ++- data/normalMaps/diffuseArray.png | Bin 144206 -> 150830 bytes data/normalMaps/normalArray.png | Bin 83506 -> 83656 bytes package.yaml | 28 ++-- shader/compute/multiplyArray.comp | 7 + shader/compute/shadow.comp | 40 ++++++ shader/shadow/light.frag | 2 +- src/Color.hs | 39 ++---- src/Color/Data.hs | 37 +++++ src/Data/Preload/Render.hs | 3 +- src/Dodge/Data/Config.hs | 1 + src/Dodge/Floor.hs | 9 +- src/Dodge/Placement/Instance/Wall.hs | 2 +- src/Dodge/Render.hs | 197 ++++++++++++++------------- src/Dodge/TestString.hs | 1 + src/Picture/Base.hs | 3 +- src/Preload/Render.hs | 116 ++++++++++------ src/Render.hs | 32 ++++- src/Shader/Compile.hs | 9 +- src/Shader/Poke.hs | 157 ++++++++++++++------- src/Shader/Poke/Cloud.hs | 3 + 21 files changed, 457 insertions(+), 246 deletions(-) create mode 100644 shader/compute/multiplyArray.comp create mode 100644 shader/compute/shadow.comp create mode 100644 src/Color/Data.hs diff --git a/appDodge/Main.hs b/appDodge/Main.hs index 0d8f79d43..d77d5ab2f 100644 --- a/appDodge/Main.hs +++ b/appDodge/Main.hs @@ -20,7 +20,7 @@ import Dodge.Render import Dodge.SoundLogic.LoadSound import Dodge.TestString import Dodge.Update -import qualified IntMapHelp as IM +--import qualified IntMapHelp as IM import Loop import Music --import Picture @@ -30,7 +30,7 @@ import Preload.Render import SDL (($=)) import qualified SDL -import qualified SDL.Mixer as Mix +--import qualified SDL.Mixer as Mix import Sound import System.Directory @@ -59,7 +59,7 @@ winConfig x y winpos = { SDL.windowGraphicsContext = SDL.OpenGLContext $ SDL.defaultOpenGL - { SDL.glProfile = SDL.Core SDL.Normal 4 3 + { SDL.glProfile = SDL.Core SDL.Normal 4 5 , SDL.glColorPrecision = SDL.V4 8 8 8 8 } , SDL.windowPosition = theWinPos @@ -128,13 +128,18 @@ doSideEffects u = do doPreload :: IO PreloadData doPreload = do + putStrLn "Start Render preload" rData <- preloadRender + putStrLn "Start sound preload" lChunks <- loadSounds - lMusic <- loadMusic - Mix.playMusic Mix.Forever (lMusic IM.! 0) + putStrLn "Skip music preload!" +-- lMusic <- loadMusic +-- Mix.playMusic Mix.Forever (lMusic IM.! 0) + putStrLn "Return PreloadData" return PreloadData { _renderData = rData , _soundData = SoundData{_loadedChunks = lChunks} - , _musicData = MusicData{_loadedMusic = lMusic} + --, _musicData = MusicData{_loadedMusic = lMusic} + , _musicData = MusicData{_loadedMusic = undefined} } diff --git a/data/normalMaps/diffuseArray.png b/data/normalMaps/diffuseArray.png index 367469a0b99f8881d6cc3892c2e4d574c0b02a8e..428060a29447aa8f0c5e6c6eea3da16dea688881 100644 GIT binary patch delta 9013 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 BUvB^a delta 2310 zcmeH`doyt*kgg~qZLR}0M-mW|z3`Yo=XW_0nXJ~*L z0+{(D(M2$wKJ`*Hn{>a9gfsHDALxVW5v{us8iY?g(5pN%s7+uwmJuj1BFH6DnKk!C z=kV6CFZZv%0hMD;3?#okEP&Dl?ButK9^G>#5Fu5Vm}QOG>`R%Lb9if>t4=>?^St!3 zP_ya0h{!1jp76iP$g9q;59qp04gLgl_6D;?gBA46oXYDh&j(W;nPG^!Sd3eC;c*1> zm22U-B8c8WKJLjYvZkp?Q8gGd_7$jFr)5@JT(E_Ct&BkOJv=^c6?R$b zd?x^B#Ku#^8Bd%+!6HP8s*w>m(!3upzm!Hvqioa3a=EI%cT#DHi1`x;1kxa4z1%_O zU-#FbP^%W&qB>ObfVPg=c)0dL7DOW#qM_0X(EzVP!TUm5wJg9;E#SqZr@lI9-O+?s zOk-ys@jVOUtGg0)VeQPIa~R3~#eKs)>Ch6ZeNG27;mrNaT9!W)rgnzm>$*5jeXQIAm4g9HdCl} zT^kz_K?oVs+|83Qtt1mJbQn5Kch7K#oOA>7=O&I20gS9o3Pmfw)UhSD@K!Vq1=A9=U3QA^Rs>j$B_ZEY8-nqrXcO=UL1?iTj?Pu2IbT%@;?gmM zYfe?{@uC>=;Ms~c`=_mvjjOQ?l4aF>bdjz1Q`{ixdtcJrX$oUJa~XvLE{HEK&_0v7t~1ETbysd7he-4hKl^#4?j3qp z7%rxn==a=P)EJ=OXz`)4X`Fk%ylG0ICrPC+tOzErP%&>gSV-(#+gRBf<7$*$o`O!NGuOwUv76VQm%=LB-pOm+Xno_9Us6(DbFbWpp7 zn_9AQU?Z*&d6{x5nOYq|gc diff --git a/data/normalMaps/normalArray.png b/data/normalMaps/normalArray.png index e4f7c40f96aecdf611fd75b1dd9b9d90bef4746a..85ebb0c90b5c7b21e1784f8c0f389a94f319774e 100644 GIT binary patch delta 15438 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 x{{Qy>FJ1osZ~yzq delta 15300 zcmeIZQ;gt2*Y4Z4ZQC}cr>AY(wvB)HG^cIbnzn7*wtL$4c@L74d?!2E7dzj%*{O9? zb+MkR-^I$as#2rTko8fJaTK7!@sz}XUi~2zLdcGmSV{mz@SyXHikf@e(TQOPzn_B~ z6+5O1R0~4FEcKlHdyO#pXJ8~ns_J5Avo?G6y!1f~^vv^8O^$Qh+XdYW{l^!X!nGMf zykXLN$cjZ@XclWO@vHBH>*%AX(#A~W?V}igQ6~&V^g0nYYe!Nep#)&S3a0?XJ0m7- zTrD$i>paU~gVyc+Hde zX%-L{i)_W}cF$E_-zJn^GfM(M)VuN9UVL(k(bv9`&NbyL`b8Ugio`!3k1kc)Hla-K z%i#GCwq+hEN5)FaP@P*_4I9fC=k(FKWD6q8L_Ag$XiV)zTC~dxqxs<25N>?&<1yzk z0tP$<-q{H&4BL5AP@#!m6);5v@k9ov^&3n+i3BOwMs(;&*`2R5DgJ=j{EYTsIc33v z68lZ00&ah_=+#3S6d8ts;v?KmrJvj=G(!xPEWeSvZS9FuC64s>VTx`ZQngCq#p zWI8A=IX=VWf>C1n7y{s&PFuC9qTFUdzc?iru5#&|*S_Nqrb?yx@p4s%r_i z0ToYlQ$9gv%d&Ua6w*{zNz5x@LZ7HOF5h|WUSYIQyikK|w%hu{nz=!zX?~1`UbAo0 z61QE^Jd@5s^+xk`vk%G2&w^laMEF>&Pr2xv`p<3uAUwgv7c#)@cr6pJ$ox62+BYy^ z0Aa8dC47T4AozHIfj_xFY||)ZgO@FNuZV~%(z$e;Qfh4w@4@^Txou}Z#rl<&`%BIF zEbl${kjdWa0=k7*QRl?LM}P2&PJnd^?Sy#xSv$~#N>d_1oVD1J2m_@?tfNWKn3O|B z3f!p7u94F^DiAQ4=WN;QD!39^D!MA8vESV(blKo3#%l{}WY5>&KdDsKsywCJh;s?l zOdMR?gCHAr(Uz5nI!IgfUrci_gM>xbcF=%jeUgq1!K0qxl)4oR|Ya2ORV{32$%tY<7VMnD-bAhPK;8Z8#DFLK^g3g zfb@rxld!7f%9N_y5Ewk)+&(f5H+0T?^1dbi9s|jh6qs-wAloL%*=}^5ejh|tPr=xC z*>?(JlKdETTRY;OrVNA3!DX#a_u7Z4(>ynBi_}_E{8JiU7*V0r9p|F82Xqc;{ax02 z&-n<+|J__a>6Sq*X^bi(DHMuZ8JUP~uS^39p>O+cf&p^{_BYfHAl`7lfVdF`*U%m@umNMwE#l_Wet>~-0LNY- zl-mYp@(9SM)?=fPxLd%85EI+|jOwOEM%V`Pv$1!$^ve-Mflc34|dc;*4TW%me8T*Z#w)IGodH}`-IE!;)z95D|l=F^Sed@vVKAM(r}Y&Ho7nK1w3^uk!dd-%{a#5T*+N+>-nR40FBzuphOpolQj94% zy$49(&3U4@xScNRFa_LRwPQB((ml3))pM7EUt8GjoQ-}R=jLq<;ULWVR+&GdFUcaM zMO}>>9SVx+KKo|%;o?r}g9sX|%8$(zDyDKd4l}>MCKJi2oeA#B?7I!J8Xu?t1a-$| zIqg-^2C>%%7duk%`F90+Nf4#)R{gh2>Cb|5?7w#US=d>;jW6IZ904OiMu$*?b`Fxp3F z%x8=iwCs2Q%Ol?Gf$B zs%889X8sZV^^VX^cXMr^rXHX7GeO*btsV54n=%WvqOjN%oI1AzXDj{}WMW=)zFgWA znw;kqOm%lt?hb+81oL;+?nd#2Vc3WV^0kqy7kv+7waLac-OJ{xJ5C2c7)!G4t|*0m zxt=uK>@x3Bp(!**a>dAW-}C!W(vowyOL*6CHbzn^Q>{qO)|pQWX6aY-uOLrB#qfZakJ;62g1YLxc@ zWiLXEy=gEg(xcNCdrb@s<9exae2kKLdM2Gy%V^eVC92H!;oe7{MvJ$(9D}So6!-+_ zvTSn2ma@@#)f);J_*DK;vA=&&e^Z5vuW^6Sx_tJSP|HAIleKZ%Jt}sEheMCXkQ{l=nfg-g9&_TQ|YS~s)8*Q z-W;Xl$k2OzRwin?Ow&xesNc?mv%f5-gUU}b9FChQ`P)wI4^3TWeHWsc_h5;Oi4+IT z;fhCVdnA5MhrP?nI6jJ-&w*XAW&FGR>T4EyIH zsFNTpT@XVvnYiGfqsxP61gsMx2>s=lvGnMqTWlPstTPKn7{N$~f)_X=!*HwQ@SDEUP6bn+AK|e?*Z@$4Q#-#InFK&3v+gU2~;ja1Y9A|md<^p0!UINtfvaIhLkL>AW4zP$SOJybeRYo z&$(VS)VYdMAB{bAQ-p`VFsfNGa6l0(iA$Vs8l{?@VXRKouxPXLy<)tm6J5ly&iU@m zw~T{ts#qY)iIUjXSUxSufGBp`y9-Y~F@7eIzqG)wg%XDOMlzW-+m#4;6{YHW8uoo# zSxOdGn%bY6pJ4;1gv-7ALw>UCKIOzw^8o{ncDs3!yYY5rwXo0&(Fvvft@Z>fF!j4b zR;LCQcMk)x=!TXYrD9%(hVfx?gxN>_fRQ03VAmkjv5#ml;1WXrr1B|H_ELY)T5Z8_6*}{ph103?% zW0{-_UXS!@o!Rv`kDipJ2#vdTY9AcNv+R8mm)9q?=6gH^$u5q7RydOY#xrty8hr`M z`x1xw7yUSEsoY6PPdi5sZ#+KJO+4VPPF$W~`$c_>#y@I!^N$?%%M<5>DafuzFe39F z!CnXBaAIEmkqiXLkQQU+W{V2KEMbiTL?p+`i_mayy;*T|G;jcLlM`W9VF5e06%wk|ce=ltV z?zO)HDu$P9lKxf}$)G9v`l~K;!`qKTP)oj^(eIR&H8gN(?_`siy1b(!EK&Fwsx63g zTe1;#?DVMZHBJ+AA31fBswF>%SD)2Q*t$QQ7b185r2xs4*U(E>h)ZnZ{3jE?8{AOp z-^1X@`xm=s)T~aBsH+xTxN9JHJgHH6|M@TJNivT-08umAXU+M#r@-&|9{96+tH$ef z8YM84q5*2&>-72nCwFr?!7S11Z+FOAB>kG>PyRj~55uaUMfK=y!yjSdfDx9&2!5;C z0)fA$4L-9_ylG#%)aHYm*vF;7vVU7>7&GC_>W&)<4N*XC^t9yO;Sk{Y(Qi%UU{&~1 zjkL)JR_J;Zx~Z9QrM1e>_pq}UyW$+0y@DxVr+S! zEJ8!BFZU?Y0C}~pyC;*@xI%HW6{lesv{>lalPMHrpwM)6B&)AhfF$%J&&pAmKxC+D zxY8Gf+;Ml*h#GuC()sCJ1kPZTf*_jJuY3yEON1{;hG0shj$=8508cm7 zC?$;dC@iwN+5@}@pM?+iFrFdRLW60~M+U8|Q$FcwArDZoJ*7ALnU@R3A6*MOeiKdy zX^$6^ZW?w_I7wXm!)E#DrS+oTg!ix*jLNSe2(yj^GoJ_D1nY&9Kfqf7mDMQ8WdFH? z#^hARtj0Wjvwh!1_t`OS-k}Lyg-9m>OT-`owOS^({LEeMMofw}Q}#&t*z!ENK$JQh zhiI;fWDmeLk8fxV&8o-Z@Q-L3$y6d%msG->pui(2QnXoITF!Mv3D-GGb0^MW8yhT? z>EN;a{i6^zxerb{L9WVCP&%6Bj5oQ{|4eoG^F`qyAI31=EX|hv!_or;S#kv`xrA!Z z>O2Z1-97;YWrW;!d$1H?z6zvLP_6^lBn#b0K1ISy8(rx`>d29eCA1GdlRA9>}LcOri`()wdcUfxue?S-w0pFgoDG8Ew{kZ zMd$+d*`BrqUY&QCss`9|OLprH6XnG1=@Y)DgT3j$+iOD%>b_eg;hk8w5vO2vjJSmo zEBpBe-T6N*3PPnw4>#x5Vbh^*sze?%g>(e^zMNy+4Oau>*TWY|I4_7fS=XgEhp-Sx z_xBf&F0Ue=3#yGV`!zM4QzseLr!+u|mWK{&Y|YkmLfu3kOI>dLtw!L&_C%73sBU~y zV8y`1>)Q%`dP{vey~g6*%85n8(LC6B7Sy!gqZ(3WZl9gY4y1`CirOnipA@XKJ4b`< zw&T7{i__Wb*@J#N6u+r+U%$vl$;d#WwqlPh`CmTCBg7+|0bLfvMjO%Q*mA&WXvb&$ z)nf5DDg;06&6a5Hx_j^*-P!BdIW_{{0-ea@CgH$DmkVOVGCb3;GT+Xyl-X*K5L5(v zny)C3Q4D?6^;Dcn|Dx~+H0`TG=8m6h#1!kccin2RITTi*$!Yoh*4YkWU>9i^t#W5H zawf&;SqW12xl&GcXR+7m0v{Oj6%0B-%9XpevMFmC`8|*FP&-O8mxmL7qP*IWZPA@J z1M6|TI6 ziUS30dqr|@O{C}3wz_(vz)OeTWTn>f4-Z z>{gki3`;)nc~SEh=9=t{#pw2(GWtT{WyDe$2(n}bfjq;p2jMKaqVik5fhkmhZD$NB zwZ*|-{H6HNfhx-`t~vl?H*3A>>g{-hl^U_J@W(QiH8s+_ zSJJ;lwkzSAFI7Yk94w(KPivSi-raL$)7F))Ikk|ACI;6`zEMF9pqnXNaP%|n>967KoHlF$mlSCuYsIr6+5amKlSG@m8Jh;}8)r#r+sGfQ=u%>v~E7?mi7x9alY2IjKI1sW$x zj#pR&160OCk|<?pQ|^GnkMI%mX->#WGNP zyB%0t1cA=N+#Awf0<-4 zVwN9oz-0kTYNK*tV`xSmE|ZGAecjU|@Y%%D-U(;-o`o<&Q}U0{jTABf%`V5$3eB}z z1zI6I|3Hw=2`v#pl3*)32c+-Ro4-NB?X6TfMcXsdVPv{fcb$6Le{esraQ z7*5c*N$1iKsKu<*LcftkxIDoh<`t+lVx-RDOBha&KPGO7dEG3_BD(xW~Rt><-scZMRhhOXRR>a=UW~ z^IP#IhQ6nBF;8O0`Xj1=#-l}diQR70Ae^*b$h_vLiKdva7LVk=Lf15$PvchETbYl2 zN)7AkP4`qJ+G?WjS73I@j{1WR)Wcd4=U|ow&24sb^fTwgIL&nuOv;R(5)v8>0^I6G z0<(>wHBViGUX>;St^+ul*nJaEfzFDUO4jenoA=pN#~W$0g*+8>jI z7N=L{)$ixICp=jN2kZ#f9mkL8P;LR101<%eD$g9xQT{>f8ndO*i#)$^2Jp7#D7GV-d_o) z)HT*d1kKPbIGu(ZXlAWR0-`LVuc?&0 zuG-|tdK@XM5u60M4EeA8nK*zXZ~NGQEFyxPW)a$ll^yNy$aez-~SOJB_j+GJxH zk(J}hq_n-=U-L6qLWY+ooPPx1%;(_5Jc0gqz$1YHJmYRr!#qssv(rr{T1Jk+G$rMiqnsgdR-k4825c@NC_=aC|imKi5RLO55bjkU~6#w}|O~Cy-lA(*@SM6Mh z-5$yCnT+uVgB@SIB44TRp5+4qIN{SChEUv2(gOPFA-IKhzng9?J^>C-KmV3nL-ZU)u7^HtF{*VEX6RdwuC$RjpjpRk*MTQ*d@#G`8W^y?s3Hn9t=>jRHNt z!%9-o=q)V*XN)E{0qw=q%go1s(sB+tIDuHvW=h=GSOhZIpm{Mr0_97K#xrsvM(Vic z5a$h&a`MjO^eA|Q*%E^04XQ$4#WjQeeN)4^CD&rsjZaxl;jnka? zbcqL&$O`l_5al*i4)HSBR!sKb!ZuIpVMhv8nWdb)ywZ~PfZFlL{4Erd&(Burg+o(C z<5dJ2=v-&eSbYxM^%-8bpr}^*XhnwzFX7v?#61(0`2s3Kb|EZ77sZ7#PINUiwLo zGH9~Vb4W%U|6Js&*{ZFRR_`8phM&hxEJ9Qvd$oF|@jur$%z4smXS1Z6d}o9Sen~A; z-<83*H!R)LaALH{r!g($_s^Am-+qfB^C=+=#Lm+y1LG2@(n=Md2$rc_J-H#{lpVDR zD|p-}ilFWP@o*Dot}lfI&ga53$S+>18;3kt4U-sl%_2RhgEwdt0eQ9Jc}=tLmMZN^V%)OQKibQ1mqkCH#vR()}*WPM6H?c;)#sQW&ZIG z!%mJBrraD6uG`8{W9d%A67jf?LVsND~b@ zsoh#gGD$GQY4m~GU=;S}?(;IE#hR%xSyl~c@<-ZqJ-l6&1C{?{x4&)iyNcJ0Y(>s9 z8?e!kx7ho<*hLy5FQwGU zU;WY!#%Vp*$9qpE_b9|=`4FHGY z*RV)j?z%{eT*jh#2WMv3JA2(>Co#$-Ap3z#zw{3t>*)C_seDx@NPsouiH5+))_2;_ zKs?`sPtdCc6WF_u0VdhcszdAO@tk&{aWJercx|$V`yPsgO`E3=#R8Zgq@2kmp}D z@qA6+XRmND7p>G^iFq;upc643A7-d;A`#QA^jeti*}~pMHm;0yToKyiIXF$VaOj9f z9~Q*(znmz5*;-$i8cHYKX8TJoLzM&h=v&~SxR4{g)vi3H*1Xoi16|(a+^&Sv9W{(6 z7uYFxr+N`%$RoTqeQ?X)wh+<4jGf6pndDvYCMk5EjR6*TGS`1JCwu93NyJJ~*&J=aZ9?t!jVjp?Ehsh~K=8zRUCx;LRZwa2L@RwR;zUU2Lp~SdDbWLk>X9r=Im9JMn z$WwPpUvE1$V3#0xuOrk12pLQ!vgvtRJmAdZBQ*}uh<79mL*(|9xKzG?(^7Y{-^(uG z90b_MZDf(4)I*#W4=T-EgQza+Jl9r<7Y@>UF>r+#t#){5P|PcG#uwcB7J=LmAL>(1 z-*9!s%`qqDyp#NOabeOUCcjJ=P8kYa+`$+i*PzDlOwN!p5li_^W2Oz84{G~@tX%BW zPm<=G0c170pq!eR!wq$S9vQ3YR$haadRR}jc{n#-ykP4%|5*JTELpbI5WfehO;e?# zjf?!3qdY05guUrRS7O^^QwvR-BZ3$`2Zm1?BbGiz%#m2@#ig{r_0jBWDP!=v&#O$s zMAr_zh?-{SohzzN&Z_KQBbmJ)b&!J_MIBRY{^RTuUa-LVhY%fbOg!jHJ`7>PKGwnB zRv;j5>?^2mA8<~TdSRi?@_LD5a84i8DvoXafP~NKJ`w#EY^3!onr3O8qFf+DF-;nM z-oJlb+)AwOqHep<(plNJWv%$lDseUjTx((IDOBi}o;kGT9dBdN z�R#wT?z=Zl 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 Vds>b9&qp&5DKYt9)jth?{~y387}x*+ diff --git a/package.yaml b/package.yaml index 265894045..0c1c30453 100644 --- a/package.yaml +++ b/package.yaml @@ -21,31 +21,31 @@ description: Description text, TODO link to README.md dependencies: - base >= 4.7 && < 5 +- aeson +- aeson-pretty - containers -- unordered-containers +- deepseq +- dlist +- directory +- extra +- foldl - graphviz -- template-haskell -- sdl2 -- sdl2-mixer - OpenGLRaw - text - bytestring - lens - mtl - fgl -- random - JuicyPixels -- vector -- dlist -- deepseq +- random +- sdl2 +- sdl2-mixer +- template-haskell - transformers -- foldl +- unordered-containers +- vector - linear -- aeson -- aeson-pretty #- store -- directory -- extra - primitive - monad-parallel - parallel @@ -71,7 +71,7 @@ executables: #- -eventlog - -rtsopts - -with-rtsopts=+RTS - - -with-rtsopts=-N2 + - -with-rtsopts=-N #- -with-rtsopts=-l - -flate-dmd-anal - -fno-liberate-case diff --git a/shader/compute/multiplyArray.comp b/shader/compute/multiplyArray.comp new file mode 100644 index 000000000..ae4d413c1 --- /dev/null +++ b/shader/compute/multiplyArray.comp @@ -0,0 +1,7 @@ +#version 450 core +layout(local_size_x= 1, local_size_y=1) in; +uniform sampler2DArray screenTexture; +layout(rgba8, binding = 5) uniform restrict writeonly image2D img_output; +void main() +{ +} diff --git a/shader/compute/shadow.comp b/shader/compute/shadow.comp new file mode 100644 index 000000000..404d913f2 --- /dev/null +++ b/shader/compute/shadow.comp @@ -0,0 +1,40 @@ +#version 450 core +layout(local_size_x= 16, local_size_y=1) in; +layout(rgba8, binding = 5) uniform restrict writeonly image2D img_output; +layout (std140, binding = 1) uniform LightsBlock +{ + vec4 posBool[20]; + vec4 colRad[20]; +} ; +layout (binding = 0) uniform sampler2D posTexture; +layout (binding = 1) uniform sampler2D normals; +void main () +{ + shared vec3[20] larray; + uint i = gl_LocalInvocationID.x; + vec3 lightamount = vec3(0,0,0); + ivec2 pixel_coords = ivec2(gl_GlobalInvocationID.xy); + vec2 tex_coords = vec2((4*pixel_coords.x+4)/800.0, (4*pixel_coords.y+4)/835.0); + vec3 pos = texture(posTexture,tex_coords).xyz; + vec3 lightPos = posBool[i].xyz; + vec4 lumRad = colRad[i]; + vec3 distVec = lightPos - pos; + float dist = dot (distVec,distVec); + if (dist > lumRad.a) { } + else + { + float x = 1 - dist / lumRad.a; + vec3 norm = texture(normals,tex_coords).xyz; + float y1 = dot(normalize(norm), normalize(distVec)); + float y = float(y1 > 0 ? 1 : 0); + lightamount = y*x*lumRad.rgb; + + } + larray[i] = lightamount; + if (i == 0) + //{ vec3 inverselight = 1 - lightamount; + { vec3 inverselight = vec3(0,0,0); +// for (uint j=1 ; j < 20; ++j) {inverselight = inverselight * (1 - larray[j]);} + imageStore(img_output, pixel_coords, vec4(inverselight,1)); + } +} diff --git a/shader/shadow/light.frag b/shader/shadow/light.frag index 7ea159f59..6b38fe6ed 100644 --- a/shader/shadow/light.frag +++ b/shader/shadow/light.frag @@ -32,5 +32,5 @@ float rad = lumRad.a; float y = y2; float x = 1 - dist / rad; vec3 c = y* (x * x * x) * lumRad.rgb; - fColor = vec4(c, 0); + fColor = vec4(c, 1); } diff --git a/src/Color.hs b/src/Color.hs index 444b8cd07..e5cf9ff67 100644 --- a/src/Color.hs +++ b/src/Color.hs @@ -1,35 +1,11 @@ ---{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE StrictData #-} +module Color ( + module Color, + module Color.Data, +) where -module Color where - -import Data.Aeson -import Data.Aeson.TH +import Color.Data import Geometry - -data PaletteColor - = RED - | GREEN - | BLUE - | YELLOW - | CYAN - | MAGENTA - | ROSE - | VIOLET - | AZURE - | AQUAMARINE - | CHARTREUSE - | ORANGE - | WHITE - | BLACK - deriving (Eq, Ord, Enum, Show, Read) --Generic, Flat) - -type RGBA = Point4 - -type Color = Point4 +import Control.Lens withAlpha :: Float -> RGBA -> RGBA {-# INLINE withAlpha #-} @@ -165,4 +141,5 @@ numColor _ = toV4 (1, 1, 1, 1) light4 :: Color -> Color light4 = light . light . light . light -deriveJSON defaultOptions ''PaletteColor +toColor256 :: Color -> Color256 +toColor256 = over each floor . (255 *) . normalizeColor diff --git a/src/Color/Data.hs b/src/Color/Data.hs new file mode 100644 index 000000000..9b9c2b7f3 --- /dev/null +++ b/src/Color/Data.hs @@ -0,0 +1,37 @@ +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE StrictData #-} +--{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE TemplateHaskell #-} + +module Color.Data where + +import Data.Aeson +import Data.Aeson.TH +import Data.Word +import Geometry + +data PaletteColor + = RED + | GREEN + | BLUE + | YELLOW + | CYAN + | MAGENTA + | ROSE + | VIOLET + | AZURE + | AQUAMARINE + | CHARTREUSE + | ORANGE + | WHITE + | BLACK + deriving (Eq, Ord, Enum, Show, Read) --Generic, Flat) + +type RGBA = Point4 + +type Color = Point4 + +type Color256 = V4 Word8 + +deriveJSON defaultOptions ''PaletteColor diff --git a/src/Data/Preload/Render.hs b/src/Data/Preload/Render.hs index 1cfa16312..73217aa4e 100644 --- a/src/Data/Preload/Render.hs +++ b/src/Data/Preload/Render.hs @@ -11,7 +11,8 @@ import Graphics.GL.Core45 import Shader.Data data RenderData = RenderData - { _lightingWallShadShader :: Shader + { _computeShadowShader :: GLuint + , _lightingWallShadShader :: Shader , _lightingLineShadowShader :: Shader , _lightingCapShader :: Shader , _lightingTextureShader :: Shader diff --git a/src/Dodge/Data/Config.hs b/src/Dodge/Data/Config.hs index e86d1e339..d0737b64b 100644 --- a/src/Dodge/Data/Config.hs +++ b/src/Dodge/Data/Config.hs @@ -100,6 +100,7 @@ data ShadowRendering | NoObjShads | NoShadows | NoLighting + | ComputeShader deriving (Show, Eq, Ord, Enum, Bounded) data RoomClipping = NoRoomClipBoundaries | AllRoomClipBoundaries | IntersectingRoomClipBoundaries diff --git a/src/Dodge/Floor.hs b/src/Dodge/Floor.hs index 31b8eaabe..5ea877534 100644 --- a/src/Dodge/Floor.hs +++ b/src/Dodge/Floor.hs @@ -15,6 +15,12 @@ import Dodge.Tree import LensHelp import RandomHelp +startWorldTreeTest :: Annotation +startWorldTreeTest = + OnwardList $ + [ IntAnno $ AnTree . startRoom + ] + initialAnoTree :: Annotation initialAnoTree = OnwardList $ @@ -103,4 +109,5 @@ initialAnoTree = -- | A test level tree. initialRoomTree :: State (StdGen, Int) (MetaTree Room String) -initialRoomTree = annoToRoomTree initialAnoTree +--initialRoomTree = annoToRoomTree initialAnoTree +initialRoomTree = annoToRoomTree startWorldTreeTest diff --git a/src/Dodge/Placement/Instance/Wall.hs b/src/Dodge/Placement/Instance/Wall.hs index 2c48a6660..f370eaf1d 100644 --- a/src/Dodge/Placement/Instance/Wall.hs +++ b/src/Dodge/Placement/Instance/Wall.hs @@ -91,7 +91,7 @@ baseBlockPane = --, _wlColor = greyN 0.5 , _wlColor = dark $ dark orange --, _wlOpacity = Opaque 10 - , _wlOpacity = Opaque 14 + , _wlOpacity = Opaque 17 , _wlUnshadowed = True , _wlFireThrough = True , _wlPenetrable = True diff --git a/src/Dodge/Render.hs b/src/Dodge/Render.hs index af7f8881b..c00303755 100644 --- a/src/Dodge/Render.hs +++ b/src/Dodge/Render.hs @@ -209,6 +209,9 @@ doDrawing' win pdata u = do pdata glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE --apply lightmap to base buffer + glDisable GL_CULL_FACE + glDepthFunc GL_ALWAYS + glDepthMask GL_FALSE glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboBase . _1 . unFBO) glBindTextureUnit 0 (pdata ^. fboLighting . _2 . unTO) glEnable GL_BLEND @@ -244,100 +247,100 @@ doDrawing' win pdata u = do replicateM_ 2 $ pingPongBetween (_fboHalf1 pdata) (_fboHalf2 pdata) (_bloomBlurShader pdata) glEnable GL_BLEND setViewport _graphics_world_resolution cfig - --draw clouds onto cloud buffer - glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboCloud pdata))) - glDepthFunc GL_LEQUAL - glDepthMask GL_FALSE - --blendFunc $= (SrcAlphaSaturate,One) - --blendColor $= Color4 0.5 0.5 0.5 0.5 - --blendFuncSeparate $= ((SrcAlphaSaturate,One) , (One,OneMinusSrcAlpha)) - --blendFuncSeparate $= ((SrcAlpha, OneMinusSrcAlpha), (One, OneMinusSrcAlpha)) - --glBlendFuncSeparate GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA GL_ONE GL_ONE_MINUS_SRC_ALPHA - glBlendFuncSeparate GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA GL_ONE_MINUS_DST_ALPHA GL_ONE - --glBlendFuncSeparate GL_SRC_ALPHA_SATURATE GL_ONE_MINUS_SRC_ALPHA GL_ONE GL_ONE_MINUS_SRC_ALPHA - --glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - withArray [GL_COLOR_ATTACHMENT0, GL_NONE] $ \ptr -> glDrawBuffers 2 ptr - withArray [0.5, 0.5, 0.5, 0] $ \ptr -> - glClearNamedFramebufferfv - (pdata ^. fboCloud . _1 . unFBO) - GL_COLOR - 0 - ptr - -- renderLayer MidLayer shadV layerCounts - glUseProgram (pdata ^. cloudShader . shaderUINT) - glBindVertexArray $ pdata ^. cloudShader . shaderVAO . vaoName - glDrawElements - (pdata ^. cloudShader . shaderPrimitive . unPrimitiveMode) - (fromIntegral nCloudIs) - GL_UNSIGNED_SHORT - nullPtr - drawShader (_windowShader pdata) nWins - when (_graphics_cloud_shadows cfig) $ do - ----render transparency depths - glDepthMask GL_TRUE - glDepthFunc GL_ALWAYS - glDisable GL_BLEND - withArray [GL_NONE, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2] $ \ptr -> glDrawBuffers 3 ptr - withArray [0, 0, 0, 0] $ \ptr -> - glClearNamedFramebufferfv - (pdata ^. fboCloud . _1 . unFBO) - GL_COLOR - 1 - ptr - withArray [0, 0, 0, 0] $ \ptr -> - glClearNamedFramebufferfv - (pdata ^. fboCloud . _1 . unFBO) - GL_COLOR - 2 - ptr - glEnable GL_BLEND - -- we sum the positions weighted by alpha, and sum the alpha - glBlendFuncSeparatei 1 GL_SRC_ALPHA GL_ONE GL_ONE GL_ONE - -- and sum the normals weighted by alpha - glBlendFunci 2 GL_SRC_ALPHA GL_ONE - glUseProgram (pdata ^. cloudShader . shaderUINT) - glBindVertexArray $ pdata ^. cloudShader . shaderVAO . vaoName - glDepthMask GL_TRUE - glDrawElements - (pdata ^. cloudShader . shaderPrimitive . unPrimitiveMode) - (fromIntegral nCloudIs) - GL_UNSIGNED_SHORT - nullPtr - drawShader (_windowShader pdata) nWins - glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboPos . _1 . unFBO) - withArray [0, 0, 0, 0] $ \ptr -> - glClearNamedFramebufferfv - (pdata ^. fboPos . _1 . unFBO) - GL_COLOR - 0 - ptr - glBindTextureUnit 0 (pdata ^. fboCloud . _2 . _2 . unTO) - glDepthMask GL_FALSE - drawShader (pdata ^. alphaDivideShader) 4 - ----draw lightmap for cloud buffer - glDepthFunc GL_LESS - glEnable GL_BLEND - glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata))) - createLightMap - cfig - (fromIntegral trueNWalls) - nSilIndices - nIndices - (pdata ^. fboPos . _2) - (pdata ^. fboCloud . _2 . _3) - lightPoints - pdata - glInvalidateBufferData (pdata ^. vboShapes . vboName) - --apply lightmap to cloud buffer - glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboCloud pdata))) - glDepthMask GL_FALSE - withArray [GL_COLOR_ATTACHMENT0, GL_NONE] $ \ptr -> glDrawBuffers 2 ptr - glDepthFunc GL_ALWAYS - glBindTextureUnit 0 (_unTO . snd $ _fboLighting pdata) - glEnable GL_BLEND - glBlendFuncSeparate GL_ZERO GL_ONE_MINUS_SRC_COLOR GL_ZERO GL_ONE - drawShader (_fullscreenShader pdata) 4 - glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA +-- --draw clouds onto cloud buffer +-- glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboCloud pdata))) +-- glDepthFunc GL_LEQUAL +-- glDepthMask GL_FALSE +-- --blendFunc $= (SrcAlphaSaturate,One) +-- --blendColor $= Color4 0.5 0.5 0.5 0.5 +-- --blendFuncSeparate $= ((SrcAlphaSaturate,One) , (One,OneMinusSrcAlpha)) +-- --blendFuncSeparate $= ((SrcAlpha, OneMinusSrcAlpha), (One, OneMinusSrcAlpha)) +-- --glBlendFuncSeparate GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA GL_ONE GL_ONE_MINUS_SRC_ALPHA +-- glBlendFuncSeparate GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA GL_ONE_MINUS_DST_ALPHA GL_ONE +-- --glBlendFuncSeparate GL_SRC_ALPHA_SATURATE GL_ONE_MINUS_SRC_ALPHA GL_ONE GL_ONE_MINUS_SRC_ALPHA +-- --glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA +-- withArray [GL_COLOR_ATTACHMENT0, GL_NONE] $ \ptr -> glDrawBuffers 2 ptr +-- withArray [0.5, 0.5, 0.5, 0] $ \ptr -> +-- glClearNamedFramebufferfv +-- (pdata ^. fboCloud . _1 . unFBO) +-- GL_COLOR +-- 0 +-- ptr +-- -- renderLayer MidLayer shadV layerCounts +-- glUseProgram (pdata ^. cloudShader . shaderUINT) +-- glBindVertexArray $ pdata ^. cloudShader . shaderVAO . vaoName +-- glDrawElements +-- (pdata ^. cloudShader . shaderPrimitive . unPrimitiveMode) +-- (fromIntegral nCloudIs) +-- GL_UNSIGNED_SHORT +-- nullPtr +-- drawShader (_windowShader pdata) nWins +-- when (_graphics_cloud_shadows cfig) $ do +-- ----render transparency depths +-- glDepthMask GL_TRUE +-- glDepthFunc GL_ALWAYS +-- glDisable GL_BLEND +-- withArray [GL_NONE, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2] $ \ptr -> glDrawBuffers 3 ptr +-- withArray [0, 0, 0, 0] $ \ptr -> +-- glClearNamedFramebufferfv +-- (pdata ^. fboCloud . _1 . unFBO) +-- GL_COLOR +-- 1 +-- ptr +-- withArray [0, 0, 0, 0] $ \ptr -> +-- glClearNamedFramebufferfv +-- (pdata ^. fboCloud . _1 . unFBO) +-- GL_COLOR +-- 2 +-- ptr +-- glEnable GL_BLEND +-- -- we sum the positions weighted by alpha, and sum the alpha +-- glBlendFuncSeparatei 1 GL_SRC_ALPHA GL_ONE GL_ONE GL_ONE +-- -- and sum the normals weighted by alpha +-- glBlendFunci 2 GL_SRC_ALPHA GL_ONE +-- glUseProgram (pdata ^. cloudShader . shaderUINT) +-- glBindVertexArray $ pdata ^. cloudShader . shaderVAO . vaoName +-- glDepthMask GL_TRUE +-- glDrawElements +-- (pdata ^. cloudShader . shaderPrimitive . unPrimitiveMode) +-- (fromIntegral nCloudIs) +-- GL_UNSIGNED_SHORT +-- nullPtr +-- drawShader (_windowShader pdata) nWins +-- glBindFramebuffer GL_FRAMEBUFFER (pdata ^. fboPos . _1 . unFBO) +-- withArray [0, 0, 0, 0] $ \ptr -> +-- glClearNamedFramebufferfv +-- (pdata ^. fboPos . _1 . unFBO) +-- GL_COLOR +-- 0 +-- ptr +-- glBindTextureUnit 0 (pdata ^. fboCloud . _2 . _2 . unTO) +-- glDepthMask GL_FALSE +-- drawShader (pdata ^. alphaDivideShader) 4 +-- ----draw lightmap for cloud buffer +-- glDepthFunc GL_LESS +-- glEnable GL_BLEND +-- glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata))) +-- createLightMap +-- cfig +-- (fromIntegral trueNWalls) +-- nSilIndices +-- nIndices +-- (pdata ^. fboPos . _2) +-- (pdata ^. fboCloud . _2 . _3) +-- lightPoints +-- pdata +-- glInvalidateBufferData (pdata ^. vboShapes . vboName) +-- --apply lightmap to cloud buffer +-- glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboCloud pdata))) +-- glDepthMask GL_FALSE +-- withArray [GL_COLOR_ATTACHMENT0, GL_NONE] $ \ptr -> glDrawBuffers 2 ptr +-- glDepthFunc GL_ALWAYS +-- glBindTextureUnit 0 (_unTO . snd $ _fboLighting pdata) +-- glEnable GL_BLEND +-- glBlendFuncSeparate GL_ZERO GL_ONE_MINUS_SRC_COLOR GL_ZERO GL_ONE +-- drawShader (_fullscreenShader pdata) 4 +-- glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA -- bind base buffer for drawing bloom then clouds glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboBase pdata))) --Draw blurred bloom onto base buffer @@ -346,9 +349,9 @@ doDrawing' win pdata u = do glBindTextureUnit 0 (_unTO . snd $ _fboHalf1 pdata) drawShader (_fullscreenShader pdata) 4 glBlendFunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA - --draw shadowed clouds onto base buffer - glBindTextureUnit 0 (pdata ^. fboCloud . _2 . _1 . unTO) - drawShader (_fullscreenShader pdata) 4 +-- --draw shadowed clouds onto base buffer +-- glBindTextureUnit 0 (pdata ^. fboCloud . _2 . _1 . unTO) +-- drawShader (_fullscreenShader pdata) 4 --set viewport for radial distortion --setViewportSize (round winx) (round winy) setViewport (const FullRes) cfig diff --git a/src/Dodge/TestString.hs b/src/Dodge/TestString.hs index 6d06118a4..feaeded2e 100644 --- a/src/Dodge/TestString.hs +++ b/src/Dodge/TestString.hs @@ -19,6 +19,7 @@ import Dodge.Data.Universe testStringInit :: Universe -> [String] testStringInit u = [show $ u ^. uvWorld . input . smoothScrollAmount , show $ getSmoothScrollValue (u ^. uvWorld . input) + , show (u ^. uvConfig . windowX) ++ " " ++ show (u ^. uvConfig . windowY) ] -- [show $ length $ lightsToRender (u ^. uvConfig) (u ^. uvWorld . wCam) -- (u ^. uvWorld . cWorld . lWorld) diff --git a/src/Picture/Base.hs b/src/Picture/Base.hs index f49537430..44a6234a8 100644 --- a/src/Picture/Base.hs +++ b/src/Picture/Base.hs @@ -201,7 +201,8 @@ stackText = mconcat . zipWith (\y s -> translate 0 y $ centerText s) [0, 100 ..] text :: String -> Picture {-# INLINE text #-} -text = translate (-50) (-100) . drawText (10) +--text = translate (-50) (-100) . drawText (10) +text = translate (-50) (-100) . drawText (-10) drawText :: Float -> String -> [Verx] drawText gap = map f . stringToList gap diff --git a/src/Preload/Render.hs b/src/Preload/Render.hs index 9868a4df5..c3e456c7e 100644 --- a/src/Preload/Render.hs +++ b/src/Preload/Render.hs @@ -6,20 +6,20 @@ module Preload.Render ( ) where import Control.Concurrent -import Shader.AuxAddition -import Shape.Data -import GLHelp import Control.Lens import Control.Monad import Data.Preload.Render import qualified Data.Vector.Mutable as MV import Foreign import Framebuffer.Setup +import GLHelp +import Graphics.GL.Core45 import Shader +import Shader.AuxAddition import Shader.Compile import Shader.Data import Shader.Parameters -import Graphics.GL.Core45 +import Shape.Data {- BINDING LIST: 0 base @@ -30,24 +30,46 @@ import Graphics.GL.Core45 preloadRender :: IO RenderData preloadRender = do + putStrLn "Number cores available:" + getNumCapabilities >>= print + + forM_ [0, 1, 2] $ \i -> do + putStrLn $ "GL_MAX_COMPUTE_WORK_GROUP_COUNT " ++ show i + alloca $ \ptr -> do + glGetIntegeri_v GL_MAX_COMPUTE_WORK_GROUP_COUNT i ptr + x <- peek ptr + putStrLn $ show x + + forM_ [0, 1, 2] $ \i -> do + putStrLn $ "GL_MAX_COMPUTE_WORK_GROUP_SIZE " ++ show i + alloca $ \ptr -> do + glGetIntegeri_v GL_MAX_COMPUTE_WORK_GROUP_SIZE i ptr + x <- peek ptr + putStrLn $ show x + putStrLn $ "GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS" + alloca $ \ptr -> do + glGetIntegerv GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS ptr + x <- peek ptr + putStrLn $ show x + -- set up uniform buffer object + putStrLn "Setup UBO" theUBO <- mglCreate glCreateBuffers glNamedBufferData theUBO 64 nullPtr GL_STREAM_DRAW glBindBufferBase GL_UNIFORM_BUFFER 0 theUBO - getNumCapabilities >>= print - --- orthonormalUBO <- mglCreate glCreateBuffers --- withArray idMat $ \ptr -> --- glNamedBufferStorage orthonormalUBO 64 ptr 0 + -- orthonormalUBO <- mglCreate glCreateBuffers + -- withArray idMat $ \ptr -> + -- glNamedBufferStorage orthonormalUBO 64 ptr 0 lightsubo <- mglCreate glCreateBuffers glNamedBufferData lightsubo 640 nullPtr GL_STREAM_DRAW glBindBufferBase GL_UNIFORM_BUFFER 1 lightsubo -- setup shape geometry/cap VBO and two VAOs + putStrLn "Setup shape VBO, VAO, EBO" shVBO <- setupVBO nShapeVerxComp - shPosVAO <- setupVAOUsingVBO [4] shVBO + shPosVAO <- setupVAOUsingVBO [4] shVBO shEBO <- setupEBO shPosVAO -- note the shape shader vao is distinct from the position vao, but they -- share an EBO @@ -55,41 +77,52 @@ preloadRender = do glVertexArrayElementBuffer (shapeshader ^. shaderVAO . vaoName) (shEBO ^. eboName) --setup silhouette edge VAO - shedgevao <- setupVAOUsingVBO [4] shVBO + putStrLn "Setup silhouette VAO, EBO" + shedgevao <- setupVAOUsingVBO [4] shVBO shedgeebo <- setupEBO shedgevao + putStrLn "Setup wall/windows VBO, VAO, EBO, shader" let wallverxstrd = 8 wallvbo <- setupVBO wallverxstrd + winvbo <- setupVBO 8 + windowshader <- makeShaderUsingVBO "wall/blank" [vert, geom, frag] [4, 4] pmPoints winvbo + wallshader <- makeShaderUsingVBO "wall/basic" [vert, geom, frag] [4, 4] pmPoints wallvbo + putStrLn "Setup lighting shaders" lightingWallShadShad <- makeShaderUsingVBO "lighting/wallShadow" [vert, geom] [4] pmPoints wallvbo lightingCapShad <- makeShaderUsingVAO "lighting/cap" [vert, geom] pmTriangles shPosVAO lightingLineShadowShad <- - makeShaderUsingVAO "lighting/lineShadow" [vert, geom] pmLinesAdjacency shedgevao + makeShaderUsingVAO "lighting/lineShadow" [vert, geom] pmLinesAdjacency shedgevao shadowedgeshader <- makeShaderUsingVAO "shadow/edge" [vert, geom] pmLinesAdjacency shedgevao shadowcapshader <- makeShaderUsingVAO "shadow/cap" [vert, geom] pmTriangles shPosVAO shadowwallshader <- makeShaderUsingVBO "shadow/wallShadow" [vert, geom] [4] pmPoints wallvbo - shadowlightshader <- makeShaderSized "shadow/light" [vert, geom, frag] - [1] 1 - pmPoints - shadowcombineshader <- makeShaderSized "shadow/combine" [vert,geom,frag] [1] 1 pmPoints + shadowlightshader <- + makeShaderSized + "shadow/light" + [vert, geom, frag] + [1] + 1 + pmPoints + shadowcombineshader <- makeShaderSized "shadow/combine" [vert, geom, frag] [1] 1 pmPoints poke (shadVBOptr shadowlightshader) 1 - -- 2D draw shaders + putStrLn "Setup 2D shaders" bslist <- makeShaderVBO "dualTwoD/basic" [vert, frag] [3, 4] pmTriangles aslist <- makeShaderVBO "dualTwoD/arc" [vert, frag] [3, 4, 3] pmTriangles eslist <- makeShaderVBO "dualTwoD/ellipse" [vert, geom, frag] [3, 4] pmTriangles cslist <- makeShaderVBO "picture/charArray" [vert, frag] [3, 4, 4] pmTriangles --- initTexture2DArray 50 "data/texture/charMapVertBig.png" 2 32 64 95 GL_NEAREST_MIPMAP_LINEAR GL_LINEAR --- initTexture2DArray 50 "data/texture/charMapVert16Block.png" 2 16 32 95 GL_NEAREST GL_NEAREST - initTexture2DArray 50 "data/texture/charMapVert8Block.png" 2 8 16 95 GL_NEAREST GL_NEAREST + -- initTexture2DArray 50 "data/texture/charMapVertBig.png" 2 32 64 95 GL_NEAREST_MIPMAP_LINEAR GL_LINEAR + initTexture2DArray 50 "data/texture/charMapVert16Block.png" 2 16 32 95 GL_NEAREST GL_NEAREST + --initTexture2DArray 50 "data/texture/charMapVert8Block.png" 2 8 16 95 GL_NEAREST GL_NEAREST --initTexture2DArray 50 "data/texture/charMapVertBig.png" 2 32 64 95 GL_LINEAR_MIPMAP_LINEAR GL_LINEAR --initTexture2DArray 50 "data/texture/charMapVertBig.png" 2 32 64 95 GL_LINEAR_MIPMAP_NEAREST GL_LINEAR + putStrLn "Setup full screen shaders" screentexturevbo <- mglCreate glCreateBuffers withArray (concat cornerList) $ \ptr -> glNamedBufferStorage @@ -97,8 +130,8 @@ preloadRender = do (fromIntegral $ floatSize * length (concat cornerList)) ptr 0 - screentexturevao <- setupVAOvbo' [2,2] 4 screentexturevbo - alphadivideshader <- makeShaderUsingVAO "texture2D/alphaDivide" [vert,frag] pmTriangleStrip screentexturevao + screentexturevao <- setupVAOvbo' [2, 2] 4 screentexturevbo + alphadivideshader <- makeShaderUsingVAO "texture2D/alphaDivide" [vert, frag] pmTriangleStrip screentexturevao fsShad <- makeShaderUsingVAO "texture/simple" [vert, frag] pmTriangleStrip screentexturevao bloomBlurShad <- makeShaderUsingVAO "texture/bloomBlur" [vert, frag] pmTriangleStrip screentexturevao colorBlurShad <- makeShaderUsingVAO "texture/colorBlur" [vert, frag] pmTriangleStrip screentexturevao @@ -107,24 +140,24 @@ preloadRender = do makeShaderUsingVAO "lighting/texture" [vert, frag] pmTriangleStrip screentexturevao barrelShad <- makeShaderVBO "texture/barrel" [vert, geom, frag] [2, 2, 2, 1] pmPoints -- blank wallShader - winvbo <- setupVBO 8 - windowshader <- makeShaderUsingVBO "wall/blank" [vert, geom, frag] [4,4] pmPoints winvbo - wallshader <- makeShaderUsingVBO "wall/basic" [vert,geom,frag] [4,4] pmPoints wallvbo + putStrLn "Setup floor VBO, shader" let floorverxstrd = 8 floorvbo <- setupVBOStatic floorverxstrd - floorshader <- makeShaderUsingVBO "floor/arrayPos" [vert, frag] [4,4] pmTriangles floorvbo + floorshader <- makeShaderUsingVBO "floor/arrayPos" [vert, frag] [4, 4] pmTriangles floorvbo initTexture2DArraySquare 40 3 GL_LINEAR_MIPMAP_LINEAR GL_LINEAR "data/normalMaps/diffuseArray.png" initTexture2DArraySquare 41 3 GL_LINEAR_MIPMAP_LINEAR GL_LINEAR "data/normalMaps/normalArray.png" - let cloudverxsizes = [4,4,4,4] + putStrLn "Setup cloud VBO, shader" + let cloudverxsizes = [4, 4, 4, 4] cloudvbo <- setupVBO (sum cloudverxsizes) - (cloudshader, cloudebo) - <- makeShaderEBO "cloud/basic" [vert, frag] cloudverxsizes pmTriangles cloudvbo + (cloudshader, cloudebo) <- + makeShaderEBO "cloud/basic" [vert, frag] cloudverxsizes pmTriangles cloudvbo framebuf2 <- newTextureFramebuffer framebuf3 <- newTextureFramebuffer + putStrLn "Setup framebuffers" rboBaseBloomName <- mglCreate glCreateRenderbuffers - glNamedRenderbufferStorage + glNamedRenderbufferStorage rboBaseBloomName GL_DEPTH24_STENCIL8 800 @@ -156,10 +189,16 @@ preloadRender = do , aslist , eslist ] + + -- setup compute shader + computeshadowshader <- makeSourcedShader "compute/shadow" [GL_COMPUTE_SHADER] + initializeGLState + putStrLn "Return preload" return $ RenderData - { _pictureShaders = shadV + { _computeShadowShader = computeshadowshader + , _pictureShaders = shadV , _shapeShader = shapeshader -- & shaderVAO' .~ shPosColVAO , _shapeEBO = shEBO , _silhouetteEBO = shedgeebo @@ -193,8 +232,8 @@ preloadRender = do , _fboOverlay = fbooverlay , _rboBaseBloom = rboBaseBloomName , _matUBO = theUBO --- , _orthonormalMatUBO = orthonormalUBO - , _lightsUBO = lightsubo + , -- , _orthonormalMatUBO = orthonormalUBO + _lightsUBO = lightsubo , _vboWindows = winvbo , _vboShapes = shVBO , _floorVBO = floorvbo @@ -215,6 +254,7 @@ cornerList = , [1, 1, 1, 1] , [1, -1, 1, 0] ] + --cornerListForTriangles :: [[Float]] --cornerListForTriangles = -- [ [-1, 1, 0, 1] @@ -229,11 +269,11 @@ initializeGLState :: IO () initializeGLState = do glEnable GL_DEPTH_TEST - cleanUpRenderPreload :: RenderData -> IO () cleanUpRenderPreload _ = return () + --cleanUpRenderPreload pd = do - -- TODO fix this - --mapM_ freeShaderPointers $ _pictureShaders pd - --freeShaderPointers' $ _lightingWallShadShader pd - --freeShaderPointers' $ _fullscreenShader pd +-- TODO fix this +--mapM_ freeShaderPointers $ _pictureShaders pd +--freeShaderPointers' $ _lightingWallShadShader pd +--freeShaderPointers' $ _fullscreenShader pd diff --git a/src/Render.hs b/src/Render.hs index ce3a089ff..1b0cf99ae 100644 --- a/src/Render.hs +++ b/src/Render.hs @@ -44,6 +44,7 @@ createLightMap cfig = case shadrendertype of InstancingShads -> instanceLightMap cfig NoShadows -> const . const . const renderLightingNoShadows NoLighting -> const . const . const . const . const . const renderFlatLighting + ComputeShader -> renderComputeShadows _ -> renderShadows shadrendertype where shadrendertype = cfig ^. graphics_shadow_rendering @@ -103,6 +104,28 @@ renderLightingNoShadows positiontexture normaltexture lightPoints pdata = do glDisable GL_CULL_FACE glDisable GL_STENCIL_TEST +renderComputeShadows :: + GLsizei -> + Int -> + Int -> + TO -> + TO -> + [(Point3, Float, Point3)] -> + RenderData -> + IO () +renderComputeShadows _ _ _ toPos tanormals lightPoints rd = do + withArray (lightsToArray lightPoints) $ \ptr -> + glNamedBufferSubData (rd ^. lightsUBO) 0 620 ptr + glBindTextureUnit 0 (toPos ^. unTO) + glBindTextureUnit 1 (tanormals ^. unTO) + glBindImageTexture 5 (rd ^. fboLighting . _2 . unTO) 0 GL_FALSE 0 GL_WRITE_ONLY GL_RGBA8 + glUseProgram (rd ^. computeShadowShader) + glDispatchCompute 800 835 1 + -- the following should be later, just before the texture is accessed + --glMemoryBarrier GL_SHADER_IMAGE_ACCESS_BARRIER_BIT + glMemoryBarrier GL_TEXTURE_FETCH_BARRIER_BIT + return () + renderFlatLighting :: RenderData -> IO () renderFlatLighting pdata = do glBindFramebuffer GL_FRAMEBUFFER (_unFBO (fst (_fboLighting pdata))) @@ -145,12 +168,14 @@ renderShadows shadrendertype nWalls nSils nCaps positiontexture normaltexture li ptr -- for each of the lights: -- 1. stencil out the shadows from this light's point of view - -- 2. calculate lighting based on each fragment's position - -- to consider: adding normals/a "material" for each fragment + -- 2. calculate lighting based on each fragment's position and normal glBlendFunc GL_ZERO GL_ONE_MINUS_SRC_COLOR glEnable GL_STENCIL_TEST glStencilOpSeparate GL_FRONT GL_KEEP GL_KEEP GL_INCR_WRAP glStencilOpSeparate GL_BACK GL_KEEP GL_KEEP GL_DECR_WRAP + -- bind world position texture-- these will be used by the lighting shader + glBindTextureUnit 0 (positiontexture ^. unTO) + glBindTextureUnit 1 (normaltexture ^. unTO) flip VFSM.mapM_ (VFSM.fromList lightPoints) $ \(V3 x y z, rad, V3 r g b) -> do glDepthFunc GL_LESS -- setup stencil @@ -200,10 +225,7 @@ renderShadows shadrendertype nWalls nSils nCaps positiontexture normaltexture li _ -> return () --draw lightmap itself glDepthFunc GL_ALWAYS - -- bind world position texture glDisable GL_CULL_FACE - glBindTextureUnit 0 (positiontexture ^. unTO) - glBindTextureUnit 1 (normaltexture ^. unTO) glColorMask GL_TRUE GL_TRUE GL_TRUE GL_TRUE glStencilFunc GL_EQUAL 0 255 glUseProgram (ltextShad ^. shaderUINT) --Just (_shadProg ltextShad) diff --git a/src/Shader/Compile.hs b/src/Shader/Compile.hs index 6f0f4dd4e..b7eb55d60 100644 --- a/src/Shader/Compile.hs +++ b/src/Shader/Compile.hs @@ -12,6 +12,7 @@ module Shader.Compile ( setupVAOvbo', setupEBO, setupVertexAttribPointer, + makeSourcedShader, ) where import Control.Lens @@ -66,7 +67,8 @@ makeShaderEBO s shaderlist sizes pm vbo = do shad <- makeShaderUsingVBO s shaderlist sizes pm vbo ebo <- setupEBO (shad ^. shaderVAO) glVertexArrayElementBuffer (shad ^. shaderVAO . vaoName) (ebo ^. eboName) - return ( shad + return + ( shad , ebo ) @@ -81,7 +83,7 @@ makeShaderUsingVBO :: VBO -> IO Shader makeShaderUsingVBO s shaderlist sizes pm vbo = do - vao <- setupVAOUsingVBO sizes vbo + vao <- setupVAOUsingVBO sizes vbo makeShaderUsingVAO s shaderlist pm vao setupVBO :: Int -> IO VBO @@ -183,6 +185,7 @@ shaderTypeExt :: GLenum -> String shaderTypeExt GL_VERTEX_SHADER = ".vert" shaderTypeExt GL_GEOMETRY_SHADER = ".geom" shaderTypeExt GL_FRAGMENT_SHADER = ".frag" +shaderTypeExt GL_COMPUTE_SHADER = ".comp" shaderTypeExt _ = undefined -- I think that this requires that the correct shader program is bound? @@ -207,7 +210,7 @@ setupVAOUsingVBO sizes vbo = do vaoname <- mglCreate glCreateVertexArrays glBindVertexArray vaoname setupVertexAttribs vbo vaoname sizes strd - return VAO { _vaoName = vaoname } + return VAO{_vaoName = vaoname} setupEBO :: VAO -> IO EBO setupEBO vao = do diff --git a/src/Shader/Poke.hs b/src/Shader/Poke.hs index eff910f66..c5995921a 100644 --- a/src/Shader/Poke.hs +++ b/src/Shader/Poke.hs @@ -3,22 +3,23 @@ module Shader.Poke ( pokeLayVerxs, pokeArrayOff, pokeShape, + pokeShape', pokeWallsWindows, memoTopPrismEdgeIndices, - pokeFloors + pokeFloors, ) where -import Geometry.Vector -import Dodge.Data.Wall -import Geometry.Triangulate import Control.Monad.Primitive import qualified Data.Vector as V import qualified Data.Vector.Fusion.Stream.Monadic as VFSM import qualified Data.Vector.Mutable as MV import qualified Data.Vector.Unboxed as UV import qualified Data.Vector.Unboxed.Mutable as UMV +import Dodge.Data.Wall import Foreign import Geometry.Data +import Geometry.Triangulate +import Geometry.Vector import Graphics.GL.Core45 import Linear.V3 (cross) import Picture.Data @@ -34,6 +35,7 @@ pokeVerxs :: pokeVerxs vbos count = VFSM.mapM_ (pokeVerx vbos count) . VFSM.fromList pokeVerx :: MV.MVector (PrimState IO) (Shader, VBO) -> UMV.MVector (PrimState IO) Int -> Verx -> IO () +{-# INLINE pokeVerx #-} pokeVerx vbos offsets Verx{_vxPos = thePos, _vxCol = theCol, _vxExt = ext, _vxShadNum = shadnum} = do typeOff <- UMV.unsafeRead offsets sn basePtr <- _vboPtr . snd <$> MV.unsafeRead vbos sn @@ -53,9 +55,10 @@ pokeWallsWindows :: pokeWallsWindows wiptr truewlptr wis truewls = do wlcounts2 <- VFSM.foldlM' (pokeW wiptr) 0 (VFSM.fromList wis) wlcounts3 <- VFSM.foldlM' (pokeWall truewlptr) 0 (VFSM.fromList truewls) - return ( wlcounts2, wlcounts3) + return (wlcounts2, wlcounts3) -pokeFloors :: Ptr Float -> +pokeFloors :: + Ptr Float -> [(Point3, Point3)] -> IO Int pokeFloors flptr fls = VFSM.foldlM' (pokeF flptr) 0 (VFSM.fromList fls) @@ -72,8 +75,9 @@ pokeF ptr i' (V3 a b c, V3 d e f) = do return $ i' + 1 pokeWall :: Ptr Float -> Int -> Wall -> IO Int +{-# INLINE pokeWall #-} pokeWall ptr nw wl = do - UV.imapM_ f $ UV.fromList [x,y,x1,y1,t,a,1,1] + UV.imapM_ f $ UV.fromList [x, y, x1, y1, t, a, 1, 1] return $ nw + 1 where f i = pokeElemOff ptr (nw * 8 + i) @@ -94,6 +98,15 @@ pokeW ptr i' ((V2 a b, V2 c d), V4 e f g h) = do pokeElemOff ptr (i + 7) h return $ i' + 1 +pokeShape' :: + Ptr Float -> + Ptr GLushort -> + Ptr GLushort -> + (Int, Int, Int) -> + [Surface] -> + IO (Int, Int, Int) +pokeShape' = pokeShape $ const False + pokeShape :: (Surface -> Bool) -> Ptr Float -> @@ -102,8 +115,9 @@ pokeShape :: (Int, Int, Int) -> [Surface] -> IO (Int, Int, Int) -pokeShape shadowtest ptr iptr ieptr is = VFSM.foldlM' (pokeShapeObj shadowtest ptr iptr ieptr) is - . VFSM.fromList +pokeShape shadowtest ptr iptr ieptr is = + VFSM.foldlM' (pokeShapeObj shadowtest ptr iptr ieptr) is + . VFSM.fromList pokeShapeObj :: (Surface -> Bool) -> @@ -139,12 +153,17 @@ pokeRoundedFaces sfid col size ptr iptr ieptr (nv, nsi, nei) (tc : bc : svs) = d (pokeIndex nv iptr) nsi (memoTopPrismIndices V.! (size - 3)) - nei' <- if sfid then return nei - else UV.foldM' (pokeIndex nv ieptr) nei $ - memoTopPrismEdgeIndices V.! (size - 3) + nei' <- + if sfid + then return nei + else + UV.foldM' (pokeIndex nv ieptr) nei $ + memoTopPrismEdgeIndices V.! (size - 3) return (nv', nsi', nei') where - xdata | sfid = 0 + xdata + | sfid = 0 -- this records whether the shadow should be shown or not + -- honestly, I think things where faster without this | otherwise = 1 pokeRoundedFaces _ _ _ _ _ _ _ _ = undefined @@ -166,13 +185,16 @@ pokeCylinder sfid col size ptr iptr ieptr (nv, nsi, nei) (tc : bc : svs) = do (pokeIndex nv iptr) nsi (memoCylinderIndices V.! (size - 3)) - nei' <- if sfid - then return nei - else UV.foldM' (pokeIndex nv ieptr) nei $ - memoTopPrismEdgeIndices V.! (size - 3) + nei' <- + if sfid + then return nei + else + UV.foldM' (pokeIndex nv ieptr) nei $ + memoTopPrismEdgeIndices V.! (size - 3) return (nv', nsi', nei') where - xdata | sfid = 0 + xdata + | sfid = 0 | otherwise = 1 pokeCylinder _ _ _ _ _ _ _ _ = undefined @@ -180,11 +202,12 @@ pokeRoundedCurve :: Float -> Point4 -> Ptr Float -> Point3 -> Point3 -> [Point3] {-# INLINE pokeRoundedCurve #-} pokeRoundedCurve xdata col ptr tc bc = go True where - go True (x : xs) n = pokeJustV xdata tc col ptr n x >>= go False xs - go False (x : xs) n = pokeJustV xdata bc col ptr n x >>= go True xs + go True (x : xs) n = pokeJustV xdata tc col ptr n x >>= go False xs + go False (x : xs) n = pokeJustV xdata bc col ptr n x >>= go True xs go _ [] n = return n pokeCylinderCaps :: Float -> Point4 -> Ptr Float -> Point3 -> Point3 -> [Point3] -> Int -> IO Int +{-# INLINE pokeCylinderCaps #-} pokeCylinderCaps xdata col ptr tc bc = go True where go True (x : xs) n = pokeJustVInvNormal xdata tc col ptr n x >>= go False xs @@ -209,17 +232,22 @@ pokeBox sfid col size ptr iptr ieptr (nv, nsi, nei) svs = do (pokeIndex nv iptr) nsi (memoFlatIndices V.! (size -3)) - nei' <- if sfid then return nei - else UV.foldM' (pokeIndex nv ieptr) nei $ - memoBoxEdgeIndices V.! (size - 3) + nei' <- + if sfid + then return nei + else + UV.foldM' (pokeIndex nv ieptr) nei $ + memoBoxEdgeIndices V.! (size - 3) return (nv', nsi', nei') where svsv = UV.fromList svs - xdata | sfid = 0 + xdata + | sfid = 0 | otherwise = 1 -- should probably use a vector of Point3 pokeBoxSurface :: Float -> Point4 -> Ptr Float -> UV.Vector Point3 -> Int -> [Int] -> IO Int +{-# INLINE pokeBoxSurface #-} pokeBoxSurface xdata col ptr vs n is = UV.foldM' (pokeFlatV xdata norm col ptr) @@ -241,11 +269,11 @@ boxSurfaces size = where f x = map (`mod` (size * 2)) [x, x + 1, x + 3, x + 2] -boxSurfaces' :: Int -> [[Int]] -boxSurfaces' n = +boxSurfacesIndices :: Int -> [[Int]] +boxSurfacesIndices n = [0 .. n -1] : reverse [n .. n * 2 -1] : - [ map ((2 * n) +) [4 * i, 4 * i + 1, 4 * i + 2, 4 * i + 3] | i <- [0 .. n -1]] + [map ((2 * n) +) [4 * i, 4 * i + 1, 4 * i + 2, 4 * i + 3] | i <- [0 .. n -1]] pokeIndex :: -- | base index @@ -261,11 +289,11 @@ pokeIndex nv eiptr ni ioff = do pokeElemOff eiptr ni (fromIntegral $ nv + ioff) return $ ni + 1 - memoFlatIndices :: V.Vector (UV.Vector Int) +{-# INLINE memoFlatIndices #-} memoFlatIndices = V.generate 10 $ - UV.fromList . concatMap polyToTris . boxSurfaces' . (+ 3) + UV.fromList . concatMap polyToTris . boxSurfacesIndices . (+ 3) memoTopPrismIndices :: V.Vector (UV.Vector Int) {-# INLINE memoTopPrismIndices #-} @@ -289,10 +317,21 @@ topPrismEdgeIndices :: [Int] topPrismEdgeIndices n = concatMap f [0 .. n -1] where - f i = map g - [ 0 , 2 , 1 , 4 - , 0 , 1 , -2 , 3 - , 1 , 3 , -1 , 2 + f i = + map + g + [ 0 + , 2 + , 1 + , 4 + , 0 + , 1 + , -2 + , 3 + , 1 + , 3 + , -1 + , 2 ] where g j = (2 * i + j) `mod` (2 * n) @@ -308,10 +347,20 @@ boxEdgeIndices :: [Int] boxEdgeIndices n = concatMap f [0 .. n -1] where - f i = [ g 0 , g 1 ,n + g 0 , g 2 - , g 0 , n + g 0 , n + g (-1) , g 1 - , n + g 0 , n + g 1 , n + g (-1) , g 1 - ] + f i = + [ g 0 + , g 1 + , n + g 0 + , g 2 + , g 0 + , n + g 0 + , n + g (-1) + , g 1 + , n + g 0 + , n + g 1 + , n + g (-1) + , g 1 + ] where g j = (i + j) `mod` n @@ -323,14 +372,22 @@ cylinderIndices n = cylinderRoundIndices :: Int -> [Int] cylinderRoundIndices n = - [ 2 * n -2 , 2 * n -1 , 1 - , 2 * n -2 , 1 , 0 -- last side triangle (applies mod 2n) + [ 2 * n -2 + , 2 * n -1 + , 1 + , 2 * n -2 + , 1 + , 0 -- last side triangle (applies mod 2n) ] ++ concatMap g [0 .. n -2] -- other triangles on sides where g x = - [ 2 * x , 2 * x + 1 , 2 * x + 3 - , 2 * x , 2 * x + 3 , 2 * x + 2 + [ 2 * x + , 2 * x + 1 + , 2 * x + 3 + , 2 * x + , 2 * x + 3 + , 2 * x + 2 ] topPrismIndices :: Int -> [Int] @@ -338,21 +395,27 @@ topPrismIndices n = concatMap f [1 .. n -2] -- triangles on top face ++ concatMap f' [1 .. n -2] -- triangles on bottom face -- these should be checked - ++ [ 2 * n -2 , 2 * n -1 , 1 - , 2 * n -2 , 1 , 0 -- last side triangle (applies mod 2n) + ++ [ 2 * n -2 + , 2 * n -1 + , 1 + , 2 * n -2 + , 1 + , 0 -- last side triangle (applies mod 2n) ] ++ concatMap g [0 .. n -2] -- other triangles on sides where f x = [0, 2 * x, 2 * x + 2] f' x = [1, 2 * x + 3, 2 * x + 1] g x = - [ 2 * x , 2 * x + 1 , 2 * x + 3 - , 2 * x , 2 * x + 3 , 2 * x + 2 + [ 2 * x + , 2 * x + 1 + , 2 * x + 3 + , 2 * x + , 2 * x + 3 + , 2 * x + 2 ] -- consider changing the position to a vec4 --- and just doing two pokes rather than seven --- (especially if adding normal data) pokeJustV :: Float -> Point3 -> diff --git a/src/Shader/Poke/Cloud.hs b/src/Shader/Poke/Cloud.hs index 9c20c065d..0dd4a428f 100644 --- a/src/Shader/Poke/Cloud.hs +++ b/src/Shader/Poke/Cloud.hs @@ -15,6 +15,7 @@ pokeCloud vptr iptr (nv,ni) cl = do return (nv + 4, ni + 6) pokeCloudVerx :: Ptr Float -> Cloud -> Int -> Int -> (Float, Float) -> IO () +{-# INLINE pokeCloudVerx #-} pokeCloudVerx ptr cl nv i (dx, dy) = UV.imapM_ (pokeCloudFloat ptr (nv + i)) $ UV.fromList [x, y, cz, 1, r, g, b, a, cx, cy, cz, rad, dx, dy, 0, 0] @@ -26,7 +27,9 @@ pokeCloudVerx ptr cl nv i (dx, dy) = a = a' * min 1 (fromIntegral (_clTimer cl) / fadet) pokeCloudFloat :: Ptr Float -> Int -> Int -> Float -> IO () +{-# INLINE pokeCloudFloat #-} pokeCloudFloat ptr nv i = pokeElemOff ptr (nv * 16 + i) pokeCloudIndex :: Ptr GLushort -> Int -> Int -> Int -> Int -> IO () +{-# INLINE pokeCloudIndex #-} pokeCloudIndex ptr nv ni ioff voff = pokeElemOff ptr (ni + ioff) (fromIntegral $ nv + voff)