Water.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. WaterClass Water;
  6. WaterMtrl *WaterMtrlLast;
  7. WaterMtrlPtr WaterMtrlNull;
  8. DEFINE_CACHE(WaterMtrl, WaterMtrls, WaterMtrlPtr, "Water Material");
  9. /******************************************************************************/
  10. // WATER PARAMETERS
  11. /******************************************************************************/
  12. WaterMtrl::WaterMtrl()
  13. {
  14. density =0.3f;
  15. density_add =0.45f;
  16. density_underwater =0.02f;
  17. density_underwater_add=0.6f;
  18. scale_color =200;
  19. scale_normal =10;
  20. scale_bump =100;
  21. rough =1;
  22. reflect_tex =0.1f;
  23. reflect_world =0.18f;
  24. refract =0.10f;
  25. refract_reflection =0.06f;
  26. refract_underwater =0.01f;
  27. specular =1.5f;
  28. wave_scale =0.25f;
  29. fresnel_pow =5.5f;
  30. fresnel_rough =4;
  31. fresnel_color .set(0.10f, 0.10f, 0.10f);
  32. color .set(0.42f, 0.50f, 0.58f);
  33. color_underwater0.set(0.26f, 0.35f, 0.42f);
  34. color_underwater1.set(0.10f, 0.20f, 0.30f);
  35. }
  36. WaterMtrl& WaterMtrl:: normalMap(C ImagePtr &image) {T. _normal_map=image; return T;}
  37. WaterMtrl& WaterMtrl::reflectionMap(C ImagePtr &image) {T._reflection_map=image; return T;}
  38. WaterMtrl& WaterMtrl:: colorMap(C ImagePtr &image)
  39. {
  40. T._color_map=image;
  41. _bump=null;
  42. if(image && image->is())
  43. {
  44. #if DX9
  45. if(D.validUsage(D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, image->hwType())) // if can use existing format
  46. {
  47. #endif
  48. _bump=image;
  49. #if DX9
  50. }else
  51. if(this==&Water) // check if can convert to supported format (this can be donly only for 'Water')
  52. {
  53. IMAGE_TYPE type=IMAGE_NONE;
  54. if(D.validUsage(D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, IMAGE_L8 ))type=IMAGE_L8 ;else
  55. if(D.validUsage(D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, IMAGE_A8 ))type=IMAGE_A8 ;else
  56. if(D.validUsage(D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, IMAGE_F32))type=IMAGE_F32;
  57. if(type)
  58. {
  59. Image temp, *src=image(); if(src->compressed())if(src->copyTry(temp, -1, -1, -1, IMAGE_A8, IMAGE_SOFT, 1))src=&temp;
  60. if(!src->compressed() && Water._bump_temp.createTry(src->w(), src->h(), 1, type, IMAGE_2D, 1, false))
  61. if( src->lock(LOCK_READ))
  62. {
  63. if(Water._bump_temp.lock(LOCK_WRITE))
  64. {
  65. if(Water._bump_temp.hwType()==IMAGE_L8 || Water._bump_temp.hwType()==IMAGE_A8)
  66. {
  67. REPD(y, Water._bump_temp.h())
  68. REPD(x, Water._bump_temp.w())Water._bump_temp.pixB(x, y)=src->color(x, y).a;
  69. }else
  70. if(Water._bump_temp.hwType()==IMAGE_F32)
  71. {
  72. REPD(y, Water._bump_temp.h())
  73. REPD(x, Water._bump_temp.w())Water._bump_temp.pixF(x, y)=src->colorF(x, y).w;
  74. }
  75. _bump=&Water._bump_temp.unlock().updateMipMaps(FILTER_BEST, false);
  76. }
  77. src->unlock();
  78. }
  79. }
  80. }
  81. #endif
  82. }
  83. if(!_bump || _bump==image)Water._bump_temp.del();
  84. return T;
  85. }
  86. WaterMtrl& WaterMtrl::reset()
  87. {
  88. T=WaterMtrl();
  89. return validate();
  90. }
  91. WaterMtrl& WaterMtrl::validate()
  92. {
  93. if(WaterMtrlLast==this)WaterMtrlLast=null;
  94. return T;
  95. }
  96. void WaterMtrl::set()
  97. {
  98. // Col[1], Col[2], Det[0] reserved for 'setImages'
  99. Sh.h_ImageCol[0]->set( _color_map());
  100. Sh.h_ImageNrm[0]->set( _normal_map());
  101. #if DX9
  102. Sh.h_ImageNrm[1]->set( _bump ());
  103. #endif
  104. Sh.h_ImageRfl[0]->set(_reflection_map());
  105. if(WaterMtrlLast!=this)
  106. {
  107. WaterMtrlLast=this;
  108. #if DX9
  109. if(_bump)SPSet("WaterBumpDot", (_bump->hwType()==IMAGE_L8 || _bump->hwType()==IMAGE_F32) ? Vec4(1, 0, 0, 0) : Vec4(0, 0, 0, 1));
  110. #endif
  111. // TODO: optimize (struct Water)
  112. SPSet("WaterScaleDif" , scale_color );
  113. SPSet("WaterScaleNrm" , scale_normal );
  114. SPSet("WaterScaleBump" , scale_bump );
  115. SPSet("WaterRfr" , refract );
  116. SPSet("WaterRgh_2" , rough*0.5f );
  117. SPSet("WaterRflFake" , reflect_tex );
  118. SPSet("WaterSpc" , specular );
  119. SPSet("WaterWave" , wave_scale );
  120. SPSet("WaterFresnelPow" , fresnel_pow );
  121. SPSet("WaterFresnelRough", fresnel_rough);
  122. SPSet("WaterFresnelColor", fresnel_color);
  123. SPSet("WaterCol" , color );
  124. SPSet("WaterDns" , Vec2(Mid(density, 0.0f, 1-EPS_GPU), density_add)); // avoid 1 in case "Pow(1-density, ..)" in shader would cause NaN or slow-downs
  125. if(Renderer._mirror_rt)
  126. {
  127. SPSet("WaterRfl" , reflect_world );
  128. SPSet("WaterRfrRfl", refract_reflection);
  129. }else
  130. {
  131. SPSet("WaterRfl" , 0);
  132. SPSet("WaterRfrRfl", 0);
  133. }
  134. }
  135. MaterialClear();
  136. }
  137. /******************************************************************************/
  138. Bool WaterMtrl::save(File &f, CChar *path)C
  139. {
  140. f.cmpUIntV(0); // version
  141. f<<density<<density_add<<density_underwater<<density_underwater_add<<scale_color<<scale_normal<<scale_bump<<rough<<reflect_tex<<reflect_world<<refract<<refract_reflection<<refract_underwater<<specular<<wave_scale<<fresnel_pow<<fresnel_rough;
  142. f<<fresnel_color<<color<<color_underwater0<<color_underwater1;
  143. f._putStr( _color_map.name(path));
  144. f._putStr( _normal_map.name(path));
  145. f._putStr(_reflection_map.name(path));
  146. return f.ok();
  147. }
  148. Bool WaterMtrl::load(File &f, CChar *path)
  149. {
  150. switch(f.decUIntV()) // version
  151. {
  152. case 0:
  153. {
  154. f>>density>>density_add>>density_underwater>>density_underwater_add>>scale_color>>scale_normal>>scale_bump>>rough>>reflect_tex>>reflect_world>>refract>>refract_reflection>>refract_underwater>>specular>>wave_scale>>fresnel_pow>>fresnel_rough;
  155. f>>fresnel_color>>color>>color_underwater0>>color_underwater1;
  156. colorMap(ImagePtr().require(f._getStr(), path));
  157. normalMap(ImagePtr().require(f._getStr(), path));
  158. reflectionMap(ImagePtr().require(f._getStr(), path));
  159. if(f.ok())return true;
  160. }break;
  161. }
  162. reset(); return false;
  163. }
  164. Bool WaterMtrl::save(C Str &name)C
  165. {
  166. File f; if(f.writeTry(name)){if(save(f, _GetPath(name)) && f.flush())return true; f.del(); FDelFile(name);}
  167. return false;
  168. }
  169. Bool WaterMtrl::load(C Str &name)
  170. {
  171. File f; if(f.readTry(name))return load(f, _GetPath(name));
  172. reset(); return false;
  173. }
  174. /******************************************************************************/
  175. // WATER PLANE
  176. /******************************************************************************/
  177. WaterClass::WaterClass()
  178. {
  179. draw =false;
  180. reflection_allow =!MOBILE;
  181. reflection_shadows =false;
  182. reflection_resolution=2;
  183. plane.normal.y =1;
  184. _max_1_light =true;
  185. _draw_plane_surface =false;
  186. _use_secondary_rt =false;
  187. _began =false;
  188. _swapped_ds =false;
  189. _reflect_renderer =RT_SIMPLE;
  190. }
  191. void WaterClass::del()
  192. {
  193. _mshr .del();
  194. _bump_temp.del();
  195. }
  196. void WaterClass::create()
  197. {
  198. del();
  199. // create mesh
  200. MeshBase mshb; mshb.createPlane(80, 130).scaleMove(Vec(1, -1, 1), Vec(0, 1, 0));
  201. REPA(mshb.vtx)
  202. {
  203. Vec &pos=mshb.vtx.pos(i);
  204. if( pos.x<=EPS || pos.x>=1-EPS
  205. || pos.y<=EPS || pos.y>=1-EPS)pos.xy=(pos.xy-0.5f)*6+0.5f;
  206. }
  207. _mshr.create(mshb);
  208. }
  209. /******************************************************************************/
  210. WaterClass& WaterClass::reflectionRenderer(RENDER_TYPE type)
  211. {
  212. Clamp(type, RENDER_TYPE(0), RENDER_TYPE(RT_NUM-1));
  213. if(type==RT_DEFERRED && D.deferredUnavailable())return T;
  214. if(type!=_reflect_renderer)
  215. {
  216. _reflect_renderer=type;
  217. if(type==RT_DEFERRED && D.deferredMSUnavailable())D.samples(1); // disable multi-sampling if we can't support it
  218. D.setShader(); // needed because shaders are set only for current renderer type
  219. }
  220. return T;
  221. }
  222. WaterClass& WaterClass::max1Light(Bool on) {/*if(_max_1_light!=on)*/_max_1_light=on; return T;}
  223. /******************************************************************************/
  224. void WaterClass::prepare() // this is called at the start
  225. {
  226. WaterMtrlLast=null;
  227. _under_mtrl =null;
  228. _draw_plane_surface=false;
  229. // check visibility for water plane
  230. if(draw)
  231. {
  232. Matrix3 matrix; matrix.setUp(plane.normal);
  233. Flt size=D.viewRange();
  234. VecD p =PointOnPlane(CamMatrix.pos, plane.pos, plane.normal);
  235. under(plane, T);
  236. if(Frustum(Box(size*2, wave_scale, size*2), MatrixM(matrix, p)))
  237. {
  238. _draw_plane_surface=true;
  239. _quad.set(p+size*(matrix.z-matrix.x), p+size*(matrix.x+matrix.z), p+size*(matrix.x-matrix.z), p+size*(-matrix.x-matrix.z));
  240. }
  241. }
  242. // !! it is important to call this as the first thing during rendering, because 'Game.WorldManager.draw' assumes so, if this needs to be changed then rework 'Game.WorldManager.draw' !!
  243. // test for under-water on all other water elements
  244. {
  245. _mode=MODE_UNDERWATER; Renderer.mode(RM_WATER); Renderer._render();
  246. _mode=MODE_DRAW ;
  247. }
  248. // set draw plane surface
  249. if(_draw_plane_surface)
  250. {
  251. if(_under_mtrl && _under_step>=1) // totally under water
  252. {
  253. _draw_plane_surface=false;
  254. }else
  255. {
  256. VecD left =FullScreenToPos(Vec2(D.viewRect().min.x, 0), D.viewRange()),
  257. right=FullScreenToPos(Vec2(D.viewRect().max.x, 0), D.viewRange());
  258. left =PointOnPlaneRay(left , plane.pos, plane.normal, CamMatrix.y);
  259. right=PointOnPlaneRay(right, plane.pos, plane.normal, CamMatrix.y);
  260. Vec2 l2=PosToFullScreen(left ),
  261. r2=PosToFullScreen(right);
  262. Rect rect=D.viewRect();
  263. Flt dot =Dot(CamMatrix.y, plane.normal);
  264. if(dot>EPS)
  265. {
  266. rect.max.y=Max(l2.y, r2.y);
  267. if(rect.max.y<rect.min.y)_draw_plane_surface=false;else MIN(rect.max.y, D.viewRect().max.y);
  268. }else
  269. if(dot<-EPS)
  270. {
  271. rect.min.y=Min(l2.y, r2.y);
  272. if(rect.min.y>rect.max.y)_draw_plane_surface=false;else MAX(rect.min.y, D.viewRect().min.y);
  273. }
  274. /*l2.draw(RED);
  275. r2.draw(RED);
  276. rect.draw(0x30FFFFFF);*/
  277. if(_draw_plane_surface)
  278. {
  279. // full range is D.viewRect().min.y .. D.viewRect().max.y
  280. // drawing range is rect .min.y .. rect .max.y
  281. Flt y_min_frac=LerpR(D.viewRect().min.y, D.viewRect().max.y, rect.min.y),
  282. y_max_frac=LerpR(D.viewRect().min.y, D.viewRect().max.y, rect.max.y);
  283. #if 1
  284. _y_mul_add.x=y_max_frac-y_min_frac;
  285. _y_mul_add.y=1-y_max_frac;
  286. #else
  287. _y_mul_add.x=1;
  288. _y_mul_add.y=0;
  289. #endif
  290. if(reflection_allow && reflect_world>EPS_COL)Renderer.requestMirror(plane, 1, reflection_shadows, reflection_resolution);
  291. WS.load();
  292. }
  293. }
  294. }
  295. // test for lake reflections
  296. if(reflection_allow && reflect_world>EPS_COL && !Renderer._mirror_want)
  297. if(!(_under_mtrl && _under_step>=1))
  298. {
  299. _mode=MODE_REFLECTION; Renderer.mode(RM_WATER); Renderer._render();
  300. _mode=MODE_DRAW ;
  301. }
  302. }
  303. /******************************************************************************/
  304. void WaterClass::setEyeViewport()
  305. {
  306. Renderer.setEyeViewport();
  307. if(Renderer._mirror_rt)
  308. {
  309. Vec2 scale=1,
  310. offs =0;
  311. if(Renderer._stereo)
  312. {
  313. scale.x=2;
  314. if(Renderer._eye)offs.x-=1;
  315. offs.x-=ProjMatrixEyeOffset[Renderer._eye]*0.5f;
  316. }
  317. SPSet("WaterRflMulAdd", Vec4(scale, offs));
  318. }else
  319. {
  320. SPSet("WaterRflMulAdd", Vec4(1, 1, 0, 0));
  321. }
  322. }
  323. /******************************************************************************/
  324. void WaterClass::begin()
  325. {
  326. if(!_began)
  327. {
  328. _began=true;
  329. WS.load();
  330. Renderer._has_glow=true;
  331. D.alpha(ALPHA_NONE);
  332. if(_use_secondary_rt)
  333. {
  334. _swapped_ds=false;
  335. Renderer._water_col.get (ImageRTDesc(Renderer._col->w(), Renderer._col->h(), IMAGERT_RGBA)); // here Alpha is used for Glow
  336. Renderer._water_nrm.get (ImageRTDesc(Renderer._col->w(), Renderer._col->h(), D.signedNrmRT() ? IMAGERT_RGBA_S : IMAGERT_RGBA)); // here Alpha is used for Specular
  337. Renderer._water_ds .getDS( Renderer._col->w(), Renderer._col->h(), 1, false);
  338. if(Renderer.stage)switch(Renderer.stage)
  339. {
  340. case RS_WATER_COLOR : Renderer._water_col->clearFull(); break;
  341. case RS_WATER_NORMAL: Renderer._water_nrm->clearFull(); break;
  342. }
  343. // set RT's and depth buffer
  344. if(Shader *shader=Sh.h_SetDepth) // if we can copy depth buffer from existing solid's, then do it, to prevent drawing water pixels if they're occluded
  345. {
  346. #if DX9
  347. Renderer.set(Renderer._water_col(), Renderer._water_nrm(), null, null, Renderer._water_ds(), true); // DX9 always requires a RT set
  348. D.colWrite(0, 0);
  349. D.colWrite(0, 1);
  350. #else
  351. Renderer.set(null, Renderer._water_ds(), true);
  352. #endif
  353. D.depthLock (true); D.depthFunc(FUNC_ALWAYS); D.stencil(STENCIL_ALWAYS_SET, 0); shader->draw(Renderer._ds_1s);
  354. D.depthUnlock( ); D.depthFunc(FUNC_LESS ); D.stencil(STENCIL_NONE );
  355. #if DX9
  356. D.colWrite(COL_WRITE_RGBA, 0);
  357. D.colWrite(COL_WRITE_RGBA, 1);
  358. #else
  359. //Renderer.set(Renderer._water_col(), Renderer._water_nrm(), null, null, Renderer._water_ds(), true); don't set, instead swap first and set later
  360. #endif
  361. _swapped_ds=Renderer.swapDS1S(Renderer._water_ds); // try to swap DS to put existing stencil values into '_water_ds' because we will write water depths onto '_water_ds' and we want to use it later instead of '_ds_1s' so we want all stencil values to be kept
  362. Renderer.set(Renderer._water_col(), Renderer._water_nrm(), null, null, Renderer._water_ds(), true);
  363. }else // if we can't copy then just clear it
  364. {
  365. Renderer.set(Renderer._water_col(), Renderer._water_nrm(), null, null, Renderer._water_ds(), true);
  366. D.clearDS();
  367. }
  368. }else
  369. {
  370. if(Lights.elms() && Lights[0].type==LIGHT_DIR)Lights[0].dir.set();else LightDir(Vec(0,-1,0), VecZero, 0).set();
  371. // we're going to draw water on top of existing RT, including refraction, so we need to have a color copy of what's underwater (solid) for the refraction, also we want to do softing so we need to backup depth because we can't read and write to depth in the same time
  372. Renderer._water_col.get(ImageRTDesc(Renderer._col->w(), Renderer._col->h(), GetImageRTType(Renderer._col->type()))); // create RT for the copy
  373. Renderer._col->copyHw(*Renderer._water_col, false, D.viewRect()); // copy
  374. if(_shader_soft)
  375. {
  376. Renderer._water_ds.get(ImageRTDesc(Renderer._col->w(), Renderer._col->h(), IMAGERT_F32));
  377. Renderer._ds_1s->copyHw(*Renderer._water_ds, false, D.viewRect());
  378. }
  379. setImages(Renderer._water_col(), Renderer._water_ds());
  380. Renderer.set(Renderer._col(), Renderer._ds(), true);
  381. }
  382. SetOneMatrix();
  383. D.wire (Renderer.wire);
  384. D.depth (true);
  385. D.cull (true);
  386. D.sampler3D ( );
  387. D.stencil (STENCIL_WATER_SET, STENCIL_REF_WATER);
  388. SPSet("WaterFlow", Time.time()*3);
  389. SPSet("WaterOfs" , _offset );
  390. Rect uv=D.screenToUV(D.viewRect()); // UV
  391. if(Renderer._mirror_rt)
  392. {
  393. uv=Round(uv*Renderer._mirror_rt->size()); // convert to RectI of RT size
  394. uv.extend(-0.5f)/=Renderer._mirror_rt->size(); // decrease half pixel to avoid tex filtering issues and convert back to UV
  395. SPSet("WaterPlnPos", Renderer._mirror_plane.pos *CamMatrixInv );
  396. SPSet("WaterPlnNrm", Renderer._mirror_plane.normal*CamMatrixInv.orn());
  397. }
  398. SPSet("WaterClamp", uv);
  399. setEyeViewport();
  400. }
  401. }
  402. void WaterClass::end()
  403. {
  404. if(_began)
  405. {
  406. _began=false;
  407. D.wire (false);
  408. D.sampler2D();
  409. D.stencil (STENCIL_NONE);
  410. if(!_use_secondary_rt)
  411. {
  412. endImages();
  413. Renderer._water_col.clear();
  414. Renderer._water_ds .clear();
  415. if(Renderer._ds!=Renderer._ds_1s && Renderer._ds_1s) // if we've drawn to MSAA ds, then we need to setup 1S DS
  416. {
  417. Renderer.set(null, Renderer._ds_1s(), true);
  418. D.alpha(ALPHA_NONE);
  419. D.depthLock (true); Sh.h_ResolveDepth->draw(Renderer._ds); // here we can keep FUNC_LESS because 1S DS was already set before and we just need to apply water on top
  420. D.depthUnlock( );
  421. }
  422. }
  423. }
  424. }
  425. /******************************************************************************/
  426. void WaterClass::under(C PlaneM &plane, WaterMtrl &mtrl)
  427. {
  428. Flt step=(Dist(CamMatrix.pos, plane)-D.viewFromActual())/-WATER_SMOOTH+1;
  429. if( step>EPS_COL)
  430. {
  431. if(!_under_mtrl || step>_under_step){_under_mtrl=&mtrl; _under_step=step; _under_plane=plane; _under_plane.pos+=_under_plane.normal*(D.viewFromActual()+WATER_SMOOTH);}
  432. }
  433. }
  434. /******************************************************************************/
  435. void WaterClass::setImages(Image *src, Image *depth)
  436. {
  437. Sh.h_ImageCol[1]->set(Renderer._mirror_rt()); Sh.h_ImageCol[1]->_sampler=&SamplerLinearClamp; // reflection
  438. Sh.h_ImageCol[2]->set( src ); Sh.h_ImageCol[2]->_sampler=&SamplerLinearClamp; // solid underwater
  439. Sh.h_ImageDet[0]->set( depth ); // solid depth
  440. }
  441. void WaterClass::endImages()
  442. {
  443. Sh.h_ImageCol[1]->_sampler=null;
  444. Sh.h_ImageCol[2]->_sampler=null;
  445. MaterialClear();
  446. }
  447. /******************************************************************************/
  448. Bool WaterClass::ocean()
  449. {
  450. #define EPS_WAVE_SCALE 0.001f // 1 mm
  451. return _bump && wave_scale>EPS_WAVE_SCALE;
  452. }
  453. Shader* WaterClass::shader()
  454. {
  455. Bool fake_reflect=(_reflection_map!=null);
  456. return _use_secondary_rt ? (ocean() ? WS.h_Ocean : WS.h_Lake )[fake_reflect]
  457. : (ocean() ? WS.h_OceanL : WS.h_LakeL)[fake_reflect][_shader_shadow][_shader_soft];
  458. }
  459. /******************************************************************************/
  460. void WaterClass::drawSurfaces()
  461. {
  462. // these are used only when '_use_secondary_rt' is disabled
  463. _shader_shadow=((Lights.elms() && Lights[0].type==LIGHT_DIR && Lights[0].shadow) ? D.shadowMapNumActual() : 0);
  464. _shader_soft =Renderer.canReadDepth();
  465. REPS(Renderer._eye, Renderer._eye_num)
  466. {
  467. setEyeViewport();
  468. if(_draw_plane_surface)
  469. if(Shader *shader=T.shader())
  470. {
  471. begin();
  472. set ();
  473. if(ocean())
  474. {
  475. SPSet("WaterPlnPos" , plane.pos *CamMatrixInv );
  476. SPSet("WaterPlnNrm" , plane.normal*CamMatrixInv.orn());
  477. SPSet("WaterYMulAdd", _y_mul_add );
  478. shader->begin(); _mshr.set().drawFull();
  479. ShaderEnd();
  480. }else
  481. {
  482. VI.shader(shader);
  483. VI.cull (true );
  484. VI.quad (_quad );
  485. VI.end ( );
  486. }
  487. }
  488. if(!(_under_mtrl && _under_step>=1)) // don't draw any surfaces when totally under water
  489. {
  490. Renderer.mode(RM_WATER); Renderer._render();
  491. }
  492. }
  493. end();
  494. }
  495. /******************************************************************************/
  496. WaterClass& WaterClass::update(C Vec2 &vel)
  497. {
  498. _offset+=vel*Time.d();
  499. return T;
  500. }
  501. /******************************************************************************/
  502. // WATER MESH
  503. /******************************************************************************/
  504. void WaterMesh::zero()
  505. {
  506. depth=0;
  507. _lake =false;
  508. _box.zero();
  509. }
  510. WaterMesh::WaterMesh() {zero();}
  511. void WaterMesh::del()
  512. {
  513. _mshb.del();
  514. _mshr.del();
  515. _material.clear();
  516. zero();
  517. }
  518. void WaterMesh::create(C MeshBase &src, Bool lake, Flt depth, C WaterMtrlPtr &material)
  519. {
  520. T._lake =lake;
  521. T. depth =depth;
  522. T._material=material;
  523. _mshb.create(src, VTX_POS|VTX_TEX0|TRI_IND|QUAD_IND).getBox(_box);
  524. _mshr.create(_mshb); // 'mshb' is kept for testing 'under'
  525. WS.load();
  526. }
  527. /******************************************************************************/
  528. Bool WaterMesh::under(C Vec &pos, Flt *depth)C
  529. {
  530. if(pos.x>=_box.min.x && pos.x<=_box.max.x
  531. && pos.z>=_box.min.z && pos.z<=_box.max.z
  532. && pos.y<=_box.max.y && pos.y>=_box.min.y-T.depth)
  533. {
  534. Bool flat=(_box.h()<=0.01f);
  535. // per face precision
  536. Vec2 pos2=pos.xz();
  537. C Vec *p =_mshb.vtx.pos();
  538. REPA(_mshb.tri)
  539. {
  540. C VecI &ind=_mshb.tri.ind(i);
  541. Tri2 tri(p[ind.x].xz(), p[ind.y].xz(), p[ind.z].xz());
  542. if(Cuts(pos2, tri))
  543. {
  544. if(flat)
  545. {
  546. if(depth)*depth=_box.max.y-pos.y;
  547. return true;
  548. }else
  549. {
  550. Vec blend=TriBlend(pos2, tri);
  551. Flt water=p[ind.x].y*blend.x + p[ind.y].y*blend.y + p[ind.z].y*blend.z,
  552. d =water-pos.y;
  553. if( d>=0 && d<T.depth)
  554. {
  555. if(depth)*depth=d;
  556. return true;
  557. }
  558. return false;
  559. }
  560. }
  561. }
  562. REPA(_mshb.quad)
  563. {
  564. C VecI4 &ind=_mshb.quad.ind(i);
  565. Quad2 quad(p[ind.x].xz(), p[ind.y].xz(), p[ind.z].xz(), p[ind.w].xz());
  566. if(Cuts(pos2, quad))
  567. {
  568. if(flat)
  569. {
  570. if(depth)*depth=_box.max.y-pos.y;
  571. return true;
  572. }else
  573. {
  574. Vec blend=TriBlend(pos2, quad.tri013());
  575. Flt water=p[ind.x].y*blend.x + p[ind.y].y*blend.y + p[ind.w].y*blend.z,
  576. d =water-pos.y;
  577. if( d>=0 && d<T.depth)
  578. {
  579. if(depth)*depth=d;
  580. return true;
  581. }
  582. return false;
  583. }
  584. }
  585. }
  586. }
  587. return false;
  588. }
  589. /******************************************************************************/
  590. Shader* WaterMesh::shader()C
  591. {
  592. if(WaterMtrl *mtrl=getMaterial())
  593. {
  594. Bool fake_reflect=(mtrl->_reflection_map!=null);
  595. return Water._use_secondary_rt ? (_lake ? WS.h_Lake : WS.h_River )[fake_reflect]
  596. : (_lake ? WS.h_LakeL : WS.h_RiverL)[fake_reflect][Water._shader_shadow][Water._shader_soft];
  597. }
  598. return null;
  599. }
  600. /******************************************************************************/
  601. void WaterMesh::draw()C
  602. {
  603. if(WaterMtrl *mtrl=getMaterial())switch(Water._mode)
  604. {
  605. case WaterClass::MODE_DRAW:
  606. {
  607. if(Frustum(_box) && _mshr.is())
  608. if(Shader *shader=T.shader())
  609. {
  610. Water .begin();
  611. mtrl ->set ();
  612. shader->begin(); _mshr.set().drawFull();
  613. ShaderEnd();
  614. }
  615. }break;
  616. case WaterClass::MODE_REFLECTION:
  617. {
  618. if(_box.h()<=0.01f /*&& mtrl->reflect>EPS_COL*/) // for reflections accept only flat waters, 'reflect' is taken globally
  619. if(CamMatrix.pos.y>=_box.min.y) // if camera is above surface
  620. if(Frustum(_box) && _mshr.is())
  621. Renderer.requestMirror(PlaneM(VecD(0, _box.max.y, 0), Vec(0, 1, 0)), 0, Water.reflection_shadows, Water.reflection_resolution);
  622. }break;
  623. case WaterClass::MODE_UNDERWATER:
  624. {
  625. if(_mshb.vtxs())
  626. {
  627. Flt depth, eps=D.viewFromActual()+WATER_SMOOTH;
  628. VecD test=CamMatrix.pos; test.y-=eps;
  629. if(under(test, &depth))
  630. {
  631. test.y+=depth;
  632. Water.under(PlaneM(test, Vec(0, 1, 0)), *mtrl);
  633. }
  634. }
  635. }break;
  636. }
  637. }
  638. /******************************************************************************/
  639. Bool WaterMesh::save(File &f, CChar *path)C
  640. {
  641. f.cmpUIntV(0); // version
  642. f<<_lake<<depth<<_box;
  643. if(_mshb.save(f))
  644. if(_mshr.save(f))
  645. {
  646. f._putStr(_material.name(path));
  647. return f.ok();
  648. }
  649. return false;
  650. }
  651. Bool WaterMesh::load(File &f, CChar *path)
  652. {
  653. switch(f.decUIntV()) // version
  654. {
  655. case 0:
  656. {
  657. f>>_lake>>depth>>_box;
  658. if(_mshb.load(f))
  659. if(_mshr.load(f))
  660. {
  661. _material.require(f._getStr(), path);
  662. if(f.ok())
  663. {
  664. WS.load();
  665. return true;
  666. }
  667. }
  668. }break;
  669. }
  670. del(); return false;
  671. }
  672. /******************************************************************************/
  673. // WATER DROPS
  674. /******************************************************************************
  675. struct WaterDrops
  676. {
  677. Int num ; // number of water drops
  678. Vec *pos , // position
  679. *nrm , // normal (1st random direction)
  680. *tan ; // tangent (2nd random direction)
  681. Flt *time , // time offset
  682. *blend ; // bone blend value
  683. VecB4 *matrix; // bone matrix index
  684. Image *image ; // drop texture
  685. // manage
  686. WaterDrops& del ( ); // delete
  687. WaterDrops& create(Image &image,Int num ); // create with 'num' drops
  688. WaterDrops& create(Image &image,Int num,Shape *shape,Int shapes); // create from shapes
  689. WaterDrops& create(Image &image,Int num,Ragdoll &ragdoll ); // create from ragdoll
  690. // operations
  691. void setSkin(Skeleton &skeleton); // recalculate bone skinning values according to 'skeleton'
  692. // draw
  693. void draw( ); // render with active matrix
  694. void draw(Matrix &matrix ); // render with 'matrix' matrix
  695. void draw(AnimatedSkeleton &anim_skel); // render with 'anim_skel' matrixes
  696. ~WaterDrops() {del ( );}
  697. WaterDrops() {Zero(T);}
  698. NO_COPY_CONSTRUCTOR(WaterDrops);
  699. };
  700. /******************************************************************************
  701. WaterDrops& WaterDrops::del()
  702. {
  703. Free(pos);
  704. Free(nrm);
  705. Free(tan);
  706. Free(time);
  707. Free(blend);
  708. Free(matrix);
  709. Zero(T); return T;
  710. }
  711. WaterDrops& WaterDrops::create(Image &image,Int num)
  712. {
  713. del();
  714. T.image=&image;
  715. T.num = num ;
  716. Alloc(pos ,num);
  717. Alloc(nrm ,num);
  718. Alloc(tan ,num);
  719. Alloc(time,num);
  720. return T;
  721. }
  722. WaterDrops& WaterDrops::create(Image &image,Int num,Shape *shape,Int shapes)
  723. {
  724. create(image,num);
  725. Box box;
  726. Bool box_set=false;
  727. REP(shapes)
  728. {
  729. Box b;
  730. Shape &s=shape[i];
  731. if(s.type==SHAPE_BALL)
  732. {
  733. Ball &ball=s.ball;
  734. b.set(ball.pos-ball.r,ball.pos+ball.r);
  735. }else
  736. if(s.type==SHAPE_CAPSULE)
  737. {
  738. Capsule &capsule=s.capsule;
  739. Vec up =capsule.up*(capsule.h*0.5f-capsule.r);
  740. b.from(capsule.pos-up,capsule.pos+up).extend(capsule.r);
  741. }else continue;
  742. if(!box_set){box_set=true; box=b;}else box|=b;
  743. }
  744. REP(num)
  745. {
  746. pos [i].zero();
  747. nrm [i]=Random (Ball(1),false)*Random.f(1/1.2f,1.2f)*0.008f;
  748. tan [i]=Random (Ball(1),false)*Random.f(1/1.2f,1.2f)*0.008f;
  749. time[i]=Random.f(10);
  750. Vec &p=pos[i];
  751. REPD(a,256)
  752. {
  753. p=Random(box);
  754. Bool cut=false;
  755. REP(shapes)
  756. {
  757. Shape &s=shape[i];
  758. if(s.type==SHAPE_BALL && Cuts(p,s.ball )){cut=true; break;}else
  759. if(s.type==SHAPE_CAPSULE && Cuts(p,s.capsule)){cut=true; break;}
  760. }
  761. if(cut)break;
  762. }
  763. }
  764. return T;
  765. }
  766. WaterDrops& WaterDrops::create(Image &image,Int num,Ragdoll &ragdoll)
  767. {
  768. return create(image,num,ragdoll.shape,ragdoll.bones);
  769. }
  770. /******************************************************************************
  771. void WaterDrops::setSkin(Skeleton &skeleton)
  772. {
  773. if(!blend )Alloc(blend ,num);
  774. if(!matrix)Alloc(matrix,num);
  775. REP(num)skeleton.getSkin(pos[i],blend[i],matrix[i]);
  776. }
  777. /******************************************************************************
  778. void WaterDrops::draw()
  779. {
  780. VI.image (image);
  781. VI.technique(blend ? Sh.h_RndrWaterdS : Sh.h_RndrWaterd);
  782. REP(num)
  783. {
  784. Flt t1=Sin(Time.time()*1.5f+time[i]),
  785. t2=Sin(Time.time()*1.7f+time[i]);
  786. Vec p=pos[i]+t1*nrm[i]+t2*tan[i];
  787. if(blend)VI.image(WHITE,0.020f,p,blend[i],matrix[i]);
  788. else VI.image(WHITE,0.020f,p);
  789. }
  790. VI.end();
  791. }
  792. void WaterDrops::draw(Matrix &matrix)
  793. {
  794. SetOneMatrix(matrix);
  795. draw();
  796. }
  797. void WaterDrops::draw(AnimatedSkeleton &anim_skel)
  798. {
  799. anim_skel.setMatrix();
  800. draw();
  801. }
  802. /******************************************************************************/
  803. }
  804. /******************************************************************************/