Display Draw.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. #if 0
  5. #define TEX_ZERO HalfZero
  6. #define TEX_ONE HalfOne
  7. #define SET_TEX(t, x, y) t.set(x, y)
  8. #else
  9. #define TEX_ZERO 0
  10. #define TEX_ONE 255
  11. #define SET_TEX(t, x, y) t.set(x, y, 0, 0)
  12. #endif
  13. /******************************************************************************/
  14. DisplayDraw::DisplayDraw()
  15. {
  16. _text_depth=false;
  17. }
  18. /******************************************************************************
  19. static Vec2 posToScreen(Vec2 &pos ); // convert from world position to screen position, according to 'scale offset'
  20. static Vec2 screenToPos(Vec2 &screen); // convert from screen position to world position, according to 'scale offset'
  21. Vec2 DisplayDraw::posToScreen(Vec2 &pos ){return D._scale * (pos+D._offset);}
  22. Vec2 DisplayDraw::screenToPos(Vec2 &screen){return screen/D._scale-D._offset ;}
  23. /******************************************************************************/
  24. void DisplayDraw::lineX(C Color &color, Flt y, Flt x0, Flt x1)
  25. {
  26. VI.color (color);
  27. VI.setType(VI_2D_FLAT, VI_LINE);
  28. if(Vtx2DFlat *v=(Vtx2DFlat*)VI.addVtx(2))
  29. {
  30. v[0].pos.set(x0, y);
  31. v[1].pos.set(x1, y);
  32. }
  33. VI.end();
  34. }
  35. void DisplayDraw::lineY(C Color &color, Flt x, Flt y0, Flt y1)
  36. {
  37. VI.color (color);
  38. VI.setType(VI_2D_FLAT, VI_LINE);
  39. if(Vtx2DFlat *v=(Vtx2DFlat*)VI.addVtx(2))
  40. {
  41. v[0].pos.set(x, y0);
  42. v[1].pos.set(x, y1);
  43. }
  44. VI.end();
  45. }
  46. void DisplayDraw::lines(C Color &color, C Vec2 *point, Int points)
  47. {
  48. if(point && points>1)
  49. {
  50. VI.color(color);
  51. if(points*SIZE(*point)>VI._mem_max)
  52. {
  53. VI.setType(VI_2D_FLAT, VI_LINE);
  54. Int lines=points-1;
  55. FREP(lines)if(Vtx2DFlat *v=(Vtx2DFlat*)VI.addVtx(2))
  56. {
  57. v[0].pos=point[i ];
  58. v[1].pos=point[i+1];
  59. }
  60. }else
  61. {
  62. VI.setType(VI_2D_FLAT, VI_LINE|VI_STRIP);
  63. if(Vtx2DFlat *v=(Vtx2DFlat*)VI.addVtx(points))CopyFast(v, point, points*SIZE(*v));
  64. }
  65. VI.end();
  66. }
  67. }
  68. /******************************************************************************/
  69. void DisplayDraw::drawShadowBorders(Byte alpha, C Rect &rect, Flt shadow_radius)
  70. {
  71. if(Gui.image_shadow)Gui.image_shadow->draw3x3Borders(Color(0, 0, 0, alpha), TRANSPARENT, Rect(rect.min.x-shadow_radius, rect.min.y-shadow_radius, rect.max.x+shadow_radius, rect.max.y+shadow_radius), shadow_radius, 0.33f);
  72. }
  73. void DisplayDraw::drawShadow(Byte alpha, C Rect &rect, Flt shadow_radius)
  74. {
  75. if(Gui.image_shadow)Gui.image_shadow->draw3x3(Color(0, 0, 0, alpha), TRANSPARENT, Rect(rect.min.x-shadow_radius, rect.min.y-shadow_radius, rect.max.x+shadow_radius, rect.max.y+shadow_radius), shadow_radius, 0.33f);
  76. }
  77. /******************************************************************************/
  78. void Image::draw(C Rect &rect)C
  79. {
  80. VI.image (this);
  81. VI.setType(VI_2D_TEX, VI_STRIP);
  82. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  83. {
  84. v[0].pos.set(rect.min.x, rect.max.y);
  85. v[1].pos.set(rect.max.x, rect.max.y);
  86. v[2].pos.set(rect.min.x, rect.min.y);
  87. v[3].pos.set(rect.max.x, rect.min.y);
  88. v[0].tex.set( 0, 0);
  89. v[1].tex.set(_part.x, 0);
  90. v[2].tex.set( 0, _part.y);
  91. v[3].tex.set(_part.x, _part.y);
  92. }
  93. VI.end(); // always call 'VI.end' in case 'VI.shader' was overriden before calling current method
  94. }
  95. void Image::draw(C Color &color, C Color &color_add, C Rect &rect)C
  96. {
  97. VI.color (color );
  98. VI.color2 (color_add);
  99. VI.image (this);
  100. VI.setType(VI_2D_TEX, VI_STRIP|VI_SP_COL);
  101. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  102. {
  103. v[0].pos.set(rect.min.x, rect.max.y);
  104. v[1].pos.set(rect.max.x, rect.max.y);
  105. v[2].pos.set(rect.min.x, rect.min.y);
  106. v[3].pos.set(rect.max.x, rect.min.y);
  107. v[0].tex.set( 0, 0);
  108. v[1].tex.set(_part.x, 0);
  109. v[2].tex.set( 0, _part.y);
  110. v[3].tex.set(_part.x, _part.y);
  111. }
  112. VI.end(); // always call 'VI.end' in case 'VI.shader' was overriden before calling current method
  113. }
  114. void Image::drawVertical(C Rect &rect)C
  115. {
  116. VI.image (this);
  117. VI.setType(VI_2D_TEX, VI_STRIP);
  118. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  119. {
  120. v[0].pos.set(rect.min.x, rect.max.y);
  121. v[1].pos.set(rect.max.x, rect.max.y);
  122. v[2].pos.set(rect.min.x, rect.min.y);
  123. v[3].pos.set(rect.max.x, rect.min.y);
  124. v[0].tex.set(_part.y, 0);
  125. v[1].tex.set(_part.y, _part.x);
  126. v[2].tex.set( 0, 0);
  127. v[3].tex.set( 0, _part.x);
  128. }
  129. VI.end(); // always call 'VI.end' in case 'VI.shader' was overriden before calling current method
  130. }
  131. void Image::drawVertical(C Color &color, C Color &color_add, C Rect &rect)C
  132. {
  133. VI.color (color );
  134. VI.color2 (color_add);
  135. VI.image (this);
  136. VI.setType(VI_2D_TEX, VI_STRIP|VI_SP_COL);
  137. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  138. {
  139. v[0].pos.set(rect.min.x, rect.max.y);
  140. v[1].pos.set(rect.max.x, rect.max.y);
  141. v[2].pos.set(rect.min.x, rect.min.y);
  142. v[3].pos.set(rect.max.x, rect.min.y);
  143. v[0].tex.set(_part.y, 0);
  144. v[1].tex.set(_part.y, _part.x);
  145. v[2].tex.set( 0, 0);
  146. v[3].tex.set( 0, _part.x);
  147. }
  148. VI.end(); // always call 'VI.end' in case 'VI.shader' was overriden before calling current method
  149. }
  150. void Image::drawFilter(C Rect &rect, FILTER_TYPE filter)C
  151. {
  152. VecI2 pixel=Round(Renderer.screenToPixelSize(rect.size())).abs(); // get target pixel size
  153. if(pixel.x>w() || pixel.y>h())switch(filter) // if that size is bigger than the image resolution
  154. {
  155. //case FILTER_LINEAR: VI.shader(null); break;
  156. case FILTER_NONE:
  157. #if DX9
  158. Sh.h_ImageCol[0]->_sampler=&SamplerPoint;
  159. #elif DX11
  160. VI.shader(Sh.h_DrawTexPoint);
  161. //SamplerPoint.setPS(SSI_DEFAULT);
  162. #elif GL // in GL 'ShaderImage.Sampler' does not affect filtering, so modify it manually
  163. D.texBind(GL_TEXTURE_2D, _txtr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  164. #endif
  165. break;
  166. case FILTER_CUBIC_FAST :
  167. case FILTER_CUBIC_FAST_SMOOTH:
  168. case FILTER_CUBIC_FAST_SHARP : VI.shader(Sh.h_DrawTexCubicFast); break;
  169. case FILTER_BEST :
  170. case FILTER_CUBIC :
  171. case FILTER_CUBIC_SHARP: Sh.loadCubicShaders(); VI.shader(Sh.h_DrawTexCubic); break;
  172. }
  173. VI.image (this);
  174. VI.setType(VI_2D_TEX, VI_STRIP);
  175. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  176. {
  177. v[0].pos.set(rect.min.x, rect.max.y);
  178. v[1].pos.set(rect.max.x, rect.max.y);
  179. v[2].pos.set(rect.min.x, rect.min.y);
  180. v[3].pos.set(rect.max.x, rect.min.y);
  181. v[0].tex.set( 0, 0);
  182. v[1].tex.set(_part.x, 0);
  183. v[2].tex.set( 0, _part.y);
  184. v[3].tex.set(_part.x, _part.y);
  185. Sh.h_ColSize->set(Vec4(1.0f/hwSize(), hwSize()));
  186. }
  187. VI.end();
  188. if(filter==FILTER_NONE)
  189. {
  190. #if DX9
  191. Sh.h_ImageCol[0]->_sampler=null;
  192. #elif DX11
  193. //SamplerLinearClamp.setPS(SSI_DEFAULT);
  194. #elif GL
  195. if(!GL_ES || ImageTI[hwType()].precision<IMAGE_PRECISION_32) // GLES2/3 don't support filtering F32 textures, without this check reading from F32 textures will fail - https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml
  196. {D.texBind(GL_TEXTURE_2D, _txtr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);}
  197. #endif
  198. }
  199. }
  200. void Image::drawFilter(C Color &color, C Color &color_add, C Rect &rect, FILTER_TYPE filter)C
  201. {
  202. VecI2 pixel=Round(Renderer.screenToPixelSize(rect.size())).abs(); // get target pixel size
  203. if(pixel.x>w() || pixel.y>h())switch(filter) // if that size is bigger than the image resolution
  204. {
  205. //case FILTER_LINEAR: VI.shader(null); break;
  206. case FILTER_NONE:
  207. #if DX9
  208. Sh.h_ImageCol[0]->_sampler=&SamplerPoint;
  209. #elif DX11
  210. VI.shader(Sh.h_DrawTexPointC);
  211. //SamplerPoint.setPS(SSI_DEFAULT);
  212. #elif GL // in GL 'ShaderImage.Sampler' does not affect filtering, so modify it manually
  213. D.texBind(GL_TEXTURE_2D, _txtr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  214. #endif
  215. break;
  216. case FILTER_CUBIC_FAST :
  217. case FILTER_CUBIC_FAST_SMOOTH:
  218. case FILTER_CUBIC_FAST_SHARP : VI.shader(Sh.h_DrawTexCubicFastC); break;
  219. case FILTER_BEST :
  220. case FILTER_CUBIC :
  221. case FILTER_CUBIC_SHARP: Sh.loadCubicShaders(); VI.shader(Sh.h_DrawTexCubicC); break;
  222. }
  223. VI.color (color );
  224. VI.color2 (color_add);
  225. VI.image (this );
  226. VI.setType(VI_2D_TEX, VI_STRIP|VI_SP_COL);
  227. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  228. {
  229. v[0].pos.set(rect.min.x, rect.max.y);
  230. v[1].pos.set(rect.max.x, rect.max.y);
  231. v[2].pos.set(rect.min.x, rect.min.y);
  232. v[3].pos.set(rect.max.x, rect.min.y);
  233. v[0].tex.set( 0, 0);
  234. v[1].tex.set(_part.x, 0);
  235. v[2].tex.set( 0, _part.y);
  236. v[3].tex.set(_part.x, _part.y);
  237. Sh.h_ColSize->set(Vec4(1.0f/hwSize(), hwSize()));
  238. }
  239. VI.end();
  240. if(filter==FILTER_NONE)
  241. {
  242. #if DX9
  243. Sh.h_ImageCol[0]->_sampler=null;
  244. #elif DX11
  245. //SamplerLinearClamp.setPS(SSI_DEFAULT);
  246. #elif GL
  247. if(!GL_ES || ImageTI[hwType()].precision<IMAGE_PRECISION_32) // GLES2/3 don't support filtering F32 textures, without this check reading from F32 textures will fail - https://www.khronos.org/registry/OpenGL-Refpages/es3.0/html/glTexImage2D.xhtml
  248. {D.texBind(GL_TEXTURE_2D, _txtr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);}
  249. #endif
  250. }
  251. }
  252. /******************************************************************************
  253. void Image::drawOutline(C Color &color, C Rect &rect, Flt tex_range)
  254. {
  255. if(color.a)
  256. {
  257. VI.shader (Sh.h_OutlineI);
  258. VI.color (color );
  259. VI.image (this );
  260. VI.setType(VI_2D_TEX, VI_STRIP|VI_SP_COL);
  261. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  262. {
  263. Vec2 tr=tex_range;
  264. v[0].pos.set(rect.min.x, rect.max.y);
  265. v[1].pos.set(rect.max.x, rect.max.y);
  266. v[2].pos.set(rect.min.x, rect.min.y);
  267. v[3].pos.set(rect.max.x, rect.min.y);
  268. v[0].tex.set( 0, 0);
  269. v[1].tex.set(_part.x, 0);
  270. v[2].tex.set( 0, _part.y);
  271. v[3].tex.set(_part.x, _part.y);
  272. Sh.h_ImgSize->set();
  273. }
  274. VI.end();
  275. }
  276. }
  277. /******************************************************************************/
  278. #define DEFAULT_FILTER (MOBILE ? FILTER_LINEAR : DX9 ? FILTER_CUBIC_FAST : FILTER_CUBIC)
  279. void Image::drawFs( FIT_MODE fit, Int filter)C {drawFilter( T.fit(D.rect(), fit), (filter>=0) ? FILTER_TYPE(filter) : DEFAULT_FILTER);}
  280. void Image::drawFs(C Color &color, C Color &color_add, FIT_MODE fit, Int filter)C {drawFilter(color, color_add, T.fit(D.rect(), fit), (filter>=0) ? FILTER_TYPE(filter) : DEFAULT_FILTER);}
  281. /******************************************************************************/
  282. void Image::drawPart(C Rect &screen_rect, C Rect &tex_rect)C
  283. {
  284. VI.image (this);
  285. VI.setType(VI_2D_TEX, VI_STRIP);
  286. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  287. {
  288. v[0].pos.set(screen_rect.min.x, screen_rect.max.y);
  289. v[1].pos.set(screen_rect.max.x, screen_rect.max.y);
  290. v[2].pos.set(screen_rect.min.x, screen_rect.min.y);
  291. v[3].pos.set(screen_rect.max.x, screen_rect.min.y);
  292. if(partial())
  293. {
  294. v[0].tex.x=v[2].tex.x=tex_rect.min.x*_part.x;
  295. v[1].tex.x=v[3].tex.x=tex_rect.max.x*_part.x;
  296. v[0].tex.y=v[1].tex.y=tex_rect.min.y*_part.y;
  297. v[2].tex.y=v[3].tex.y=tex_rect.max.y*_part.y;
  298. }else
  299. {
  300. v[0].tex.set(tex_rect.min.x, tex_rect.min.y);
  301. v[1].tex.set(tex_rect.max.x, tex_rect.min.y);
  302. v[2].tex.set(tex_rect.min.x, tex_rect.max.y);
  303. v[3].tex.set(tex_rect.max.x, tex_rect.max.y);
  304. }
  305. }
  306. VI.end(); // always call 'VI.end' in case 'VI.shader' was overriden before calling current method
  307. }
  308. void Image::drawPart(C Color &color, C Color &color_add, C Rect &screen_rect, C Rect &tex_rect)C
  309. {
  310. VI.color (color );
  311. VI.color2 (color_add);
  312. VI.image (this );
  313. VI.setType(VI_2D_TEX, VI_STRIP|VI_SP_COL);
  314. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  315. {
  316. v[0].pos.set(screen_rect.min.x, screen_rect.max.y);
  317. v[1].pos.set(screen_rect.max.x, screen_rect.max.y);
  318. v[2].pos.set(screen_rect.min.x, screen_rect.min.y);
  319. v[3].pos.set(screen_rect.max.x, screen_rect.min.y);
  320. if(partial())
  321. {
  322. v[0].tex.x=v[2].tex.x=tex_rect.min.x*_part.x;
  323. v[1].tex.x=v[3].tex.x=tex_rect.max.x*_part.x;
  324. v[0].tex.y=v[1].tex.y=tex_rect.min.y*_part.y;
  325. v[2].tex.y=v[3].tex.y=tex_rect.max.y*_part.y;
  326. }else
  327. {
  328. v[0].tex.set(tex_rect.min.x, tex_rect.min.y);
  329. v[1].tex.set(tex_rect.max.x, tex_rect.min.y);
  330. v[2].tex.set(tex_rect.min.x, tex_rect.max.y);
  331. v[3].tex.set(tex_rect.max.x, tex_rect.max.y);
  332. }
  333. }
  334. VI.end(); // always call 'VI.end' in case 'VI.shader' was overriden before calling current method
  335. }
  336. void Image::drawPartVertical(C Rect &screen_rect, C Rect &tex_rect)C
  337. {
  338. VI.image (this);
  339. VI.setType(VI_2D_TEX, VI_STRIP);
  340. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  341. {
  342. v[0].pos.set(screen_rect.min.x, screen_rect.min.y);
  343. v[1].pos.set(screen_rect.min.x, screen_rect.max.y);
  344. v[2].pos.set(screen_rect.max.x, screen_rect.min.y);
  345. v[3].pos.set(screen_rect.max.x, screen_rect.max.y);
  346. if(partial())
  347. {
  348. v[0].tex.x=v[2].tex.x=tex_rect.min.x*_part.x;
  349. v[1].tex.x=v[3].tex.x=tex_rect.max.x*_part.x;
  350. v[0].tex.y=v[1].tex.y=tex_rect.min.y*_part.y;
  351. v[2].tex.y=v[3].tex.y=tex_rect.max.y*_part.y;
  352. }else
  353. {
  354. v[0].tex.set(tex_rect.min.x, tex_rect.min.y);
  355. v[1].tex.set(tex_rect.max.x, tex_rect.min.y);
  356. v[2].tex.set(tex_rect.min.x, tex_rect.max.y);
  357. v[3].tex.set(tex_rect.max.x, tex_rect.max.y);
  358. }
  359. }
  360. VI.end(); // always call 'VI.end' in case 'VI.shader' was overriden before calling current method
  361. }
  362. void Image::drawPartVertical(C Color &color, C Color &color_add, C Rect &screen_rect, C Rect &tex_rect)C
  363. {
  364. VI.color (color );
  365. VI.color2 (color_add);
  366. VI.image (this );
  367. VI.setType(VI_2D_TEX, VI_STRIP|VI_SP_COL);
  368. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  369. {
  370. v[0].pos.set(screen_rect.min.x, screen_rect.min.y);
  371. v[1].pos.set(screen_rect.min.x, screen_rect.max.y);
  372. v[2].pos.set(screen_rect.max.x, screen_rect.min.y);
  373. v[3].pos.set(screen_rect.max.x, screen_rect.max.y);
  374. if(partial())
  375. {
  376. v[0].tex.x=v[2].tex.x=tex_rect.min.x*_part.x;
  377. v[1].tex.x=v[3].tex.x=tex_rect.max.x*_part.x;
  378. v[0].tex.y=v[1].tex.y=tex_rect.min.y*_part.y;
  379. v[2].tex.y=v[3].tex.y=tex_rect.max.y*_part.y;
  380. }else
  381. {
  382. v[0].tex.set(tex_rect.min.x, tex_rect.min.y);
  383. v[1].tex.set(tex_rect.max.x, tex_rect.min.y);
  384. v[2].tex.set(tex_rect.min.x, tex_rect.max.y);
  385. v[3].tex.set(tex_rect.max.x, tex_rect.max.y);
  386. }
  387. }
  388. VI.end(); // always call 'VI.end' in case 'VI.shader' was overriden before calling current method
  389. }
  390. /******************************************************************************/
  391. void Image::drawRotate(C Vec2 &center, C Vec2 &size, Flt angle, C Vec2 *rotation_center)C
  392. {
  393. VI.image (this);
  394. VI.setType(VI_2D_TEX, VI_STRIP);
  395. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  396. {
  397. Vec2 c=(rotation_center ? *rotation_center : 0.5f);
  398. c.x*= size.x;
  399. c.y*=-size.y;
  400. Matrix m; m.orn().setRotateZ(angle); m.pos.set(center.x, center.y, 0).xy-=c*m.orn();
  401. v[0].pos.set( 0, 0)*=m;
  402. v[1].pos.set(size.x, 0)*=m;
  403. v[2].pos.set( 0, -size.y)*=m;
  404. v[3].pos.set(size.x, -size.y)*=m;
  405. v[0].tex.set( 0, 0);
  406. v[1].tex.set(_part.x, 0);
  407. v[2].tex.set( 0, _part.y);
  408. v[3].tex.set(_part.x, _part.y);
  409. }
  410. VI.end();
  411. }
  412. void Image::drawRotate(C Color &color, C Color &color_add, C Vec2 &center, C Vec2 &size, Flt angle, C Vec2 *rotation_center)C
  413. {
  414. VI.color (color );
  415. VI.color2 (color_add);
  416. VI.image (this );
  417. VI.setType(VI_2D_TEX, VI_STRIP|VI_SP_COL);
  418. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  419. {
  420. Vec2 c=(rotation_center ? *rotation_center : 0.5f);
  421. c.x*= size.x;
  422. c.y*=-size.y;
  423. Matrix m; m.orn().setRotateZ(angle); m.pos.set(center.x, center.y, 0).xy-=c*m.orn();
  424. v[0].pos.set( 0, 0)*=m;
  425. v[1].pos.set(size.x, 0)*=m;
  426. v[2].pos.set( 0, -size.y)*=m;
  427. v[3].pos.set(size.x, -size.y)*=m;
  428. v[0].tex.set( 0, 0);
  429. v[1].tex.set(_part.x, 0);
  430. v[2].tex.set( 0, _part.y);
  431. v[3].tex.set(_part.x, _part.y);
  432. }
  433. VI.end();
  434. }
  435. /******************************************************************************/
  436. void Image::drawMask(C Color &color, C Color &color_add, C Rect &rect, C Image &mask, C Rect &mask_rect)C
  437. {
  438. Rect r=rect&mask_rect;
  439. if( r.valid())
  440. {
  441. VI.color (color );
  442. VI.color2(color_add);
  443. VI.image (this );
  444. Sh.h_ImageCol[1]->set(mask); MaterialClear();
  445. VI.setType(VI_2D_TEX2, VI_STRIP);
  446. if(Vtx2DTex2 *v=(Vtx2DTex2*)VI.addVtx(4))
  447. {
  448. v[0].pos.set(r.min.x, r.max.y);
  449. v[1].pos.set(r.max.x, r.max.y);
  450. v[2].pos.set(r.min.x, r.min.y);
  451. v[3].pos.set(r.max.x, r.min.y);
  452. v[0].tex[0].x=v[2].tex[0].x=LerpR(rect.min.x, rect.max.x, r.min.x); // min x
  453. v[1].tex[0].x=v[3].tex[0].x=LerpR(rect.min.x, rect.max.x, r.max.x); // max x
  454. v[0].tex[0].y=v[1].tex[0].y=LerpR(rect.max.y, rect.min.y, r.max.y); // min y
  455. v[2].tex[0].y=v[3].tex[0].y=LerpR(rect.max.y, rect.min.y, r.min.y); // max y
  456. v[0].tex[1].x=v[2].tex[1].x=LerpR(mask_rect.min.x, mask_rect.max.x, r.min.x); // min x
  457. v[1].tex[1].x=v[3].tex[1].x=LerpR(mask_rect.min.x, mask_rect.max.x, r.max.x); // max x
  458. v[0].tex[1].y=v[1].tex[1].y=LerpR(mask_rect.max.y, mask_rect.min.y, r.max.y); // min y
  459. v[2].tex[1].y=v[3].tex[1].y=LerpR(mask_rect.max.y, mask_rect.min.y, r.min.y); // max y
  460. if(partial())
  461. {
  462. v[0].tex[0]*=_part.xy;
  463. v[1].tex[0]*=_part.xy;
  464. v[2].tex[0]*=_part.xy;
  465. v[3].tex[0]*=_part.xy;
  466. }
  467. if(mask.partial())
  468. {
  469. v[0].tex[1]*=mask._part.xy;
  470. v[1].tex[1]*=mask._part.xy;
  471. v[2].tex[1]*=mask._part.xy;
  472. v[3].tex[1]*=mask._part.xy;
  473. }
  474. }
  475. VI.end();
  476. }
  477. }
  478. /******************************************************************************/
  479. void Image::drawTile(C Rect &rect, Flt tex_scale)C
  480. {
  481. VI.image (this);
  482. VI.wrap ( );
  483. VI.setType(VI_2D_TEX, VI_STRIP);
  484. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  485. {
  486. v[0].pos.set(rect.min.x, rect.max.y);
  487. v[1].pos.set(rect.max.x, rect.max.y);
  488. v[2].pos.set(rect.min.x, rect.min.y);
  489. v[3].pos.set(rect.max.x, rect.min.y);
  490. Flt w=rect.w()*tex_scale,
  491. h=rect.h()*tex_scale*aspect();
  492. v[0].tex.set(0, 0);
  493. v[1].tex.set(w, 0);
  494. v[2].tex.set(0, h);
  495. v[3].tex.set(w, h);
  496. }
  497. VI.end();
  498. }
  499. void Image::drawTile(C Color &color, C Color &color_add, C Rect &rect, Flt tex_scale)C
  500. {
  501. VI.color (color );
  502. VI.color2 (color_add);
  503. VI.image (this );
  504. VI.wrap ( );
  505. VI.setType(VI_2D_TEX, VI_STRIP|VI_SP_COL);
  506. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(4))
  507. {
  508. v[0].pos.set(rect.min.x, rect.max.y);
  509. v[1].pos.set(rect.max.x, rect.max.y);
  510. v[2].pos.set(rect.min.x, rect.min.y);
  511. v[3].pos.set(rect.max.x, rect.min.y);
  512. Flt w=rect.w()*tex_scale,
  513. h=rect.h()*tex_scale*aspect();
  514. v[0].tex.set(0, 0);
  515. v[1].tex.set(w, 0);
  516. v[2].tex.set(0, h);
  517. v[3].tex.set(w, h);
  518. }
  519. VI.end();
  520. }
  521. /******************************************************************************/
  522. void Image::drawBorder(C Rect &rect, Flt b, Flt tex_scale, Flt tex_offset, Bool wrap_mode)C
  523. {
  524. VI.image (this);
  525. VI.wrapX ( );
  526. VI.setType(VI_2D_TEX, wrap_mode ? VI_STRIP : 0);
  527. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(10))
  528. {
  529. Flt x0=rect.min.x, x1=rect.min.x+b, x2=rect.max.x-b, x3=rect.max.x,
  530. y0=rect.max.y, y1=rect.max.y-b, y2=rect.min.y+b, y3=rect.min.y;
  531. Flt scale=b*aspect(),
  532. w =rect.w()/scale,
  533. h =rect.h()/scale;
  534. b /= scale;
  535. if(wrap_mode)
  536. {
  537. v[0].pos.set(x0, y0);
  538. v[1].pos.set(x1, y1);
  539. v[2].pos.set(x3, y0);
  540. v[3].pos.set(x2, y1);
  541. v[4].pos.set(x3, y3);
  542. v[5].pos.set(x2, y2);
  543. v[6].pos.set(x0, y3);
  544. v[7].pos.set(x1, y2);
  545. v[8].pos.set(x0, y0);
  546. v[9].pos.set(x1, y1);
  547. v[0].tex.set( 0, 0);
  548. v[1].tex.set( 0, _part.y);
  549. v[2].tex.set(w , 0);
  550. v[3].tex.set(w , _part.y);
  551. v[4].tex.set(w+h , 0);
  552. v[5].tex.set(w+h , _part.y);
  553. v[6].tex.set(w+h+w , 0);
  554. v[7].tex.set(w+h+w , _part.y);
  555. v[8].tex.set(w+h+w+h, 0);
  556. v[9].tex.set(w+h+w+h, _part.y);
  557. }else
  558. {
  559. v[0].pos.set(x0, y0);
  560. v[1].pos.set(x3, y0);
  561. v[2].pos.set(x3, y3);
  562. v[3].pos.set(x0, y3);
  563. v[4].pos.set(x1, y1);
  564. v[5].pos.set(x2, y1);
  565. v[6].pos.set(x2, y2);
  566. v[7].pos.set(x1, y2);
  567. v[8].pos.set(x3, y3);
  568. v[9].pos.set(x2, y2);
  569. v[0].tex.set( 0, 0);
  570. v[1].tex.set(w , 0);
  571. v[2].tex.set(w-h , 0);
  572. v[3].tex.set( h , 0);
  573. v[4].tex.set( b, _part.y);
  574. v[5].tex.set(w -b, _part.y);
  575. v[6].tex.set(w-h+b, _part.y);
  576. v[7].tex.set( h-b, _part.y);
  577. v[8].tex.set(h-w , 0);
  578. v[9].tex.set(h-w+b, _part.y);
  579. }
  580. if(tex_scale!=1 || tex_offset!=0)REP(10)v[i].tex.x=v[i].tex.x*tex_scale+tex_offset;
  581. if(wrap_mode)VI.end();else VI.flushIndexed(IndBufBorder, 4*2*3);
  582. }
  583. VI.clear();
  584. }
  585. void Image::drawBorder(C Color &color, C Color &color_add, C Rect &rect, Flt b, Flt tex_scale, Flt tex_offset, Bool wrap_mode)C
  586. {
  587. VI.color (color );
  588. VI.color2 (color_add);
  589. VI.image (this );
  590. VI.wrapX ( );
  591. VI.setType(VI_2D_TEX, (wrap_mode ? VI_STRIP : 0)|VI_SP_COL);
  592. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(10))
  593. {
  594. Flt x0=rect.min.x, x1=rect.min.x+b, x2=rect.max.x-b, x3=rect.max.x,
  595. y0=rect.max.y, y1=rect.max.y-b, y2=rect.min.y+b, y3=rect.min.y;
  596. Flt scale=b*aspect(),
  597. w =rect.w()/scale,
  598. h =rect.h()/scale;
  599. b /= scale;
  600. if(wrap_mode)
  601. {
  602. v[0].pos.set(x0, y0);
  603. v[1].pos.set(x1, y1);
  604. v[2].pos.set(x3, y0);
  605. v[3].pos.set(x2, y1);
  606. v[4].pos.set(x3, y3);
  607. v[5].pos.set(x2, y2);
  608. v[6].pos.set(x0, y3);
  609. v[7].pos.set(x1, y2);
  610. v[8].pos.set(x0, y0);
  611. v[9].pos.set(x1, y1);
  612. v[0].tex.set( 0, 0);
  613. v[1].tex.set( 0, _part.y);
  614. v[2].tex.set(w , 0);
  615. v[3].tex.set(w , _part.y);
  616. v[4].tex.set(w+h , 0);
  617. v[5].tex.set(w+h , _part.y);
  618. v[6].tex.set(w+h+w , 0);
  619. v[7].tex.set(w+h+w , _part.y);
  620. v[8].tex.set(w+h+w+h, 0);
  621. v[9].tex.set(w+h+w+h, _part.y);
  622. }else
  623. {
  624. v[0].pos.set(x0, y0);
  625. v[1].pos.set(x3, y0);
  626. v[2].pos.set(x3, y3);
  627. v[3].pos.set(x0, y3);
  628. v[4].pos.set(x1, y1);
  629. v[5].pos.set(x2, y1);
  630. v[6].pos.set(x2, y2);
  631. v[7].pos.set(x1, y2);
  632. v[8].pos.set(x3, y3);
  633. v[9].pos.set(x2, y2);
  634. v[0].tex.set( 0, 0);
  635. v[1].tex.set(w , 0);
  636. v[2].tex.set(w-h , 0);
  637. v[3].tex.set( h , 0);
  638. v[4].tex.set( b, _part.y);
  639. v[5].tex.set(w -b, _part.y);
  640. v[6].tex.set(w-h+b, _part.y);
  641. v[7].tex.set( h-b, _part.y);
  642. v[8].tex.set(h-w , 0);
  643. v[9].tex.set(h-w+b, _part.y);
  644. }
  645. if(tex_scale!=1 || tex_offset!=0)REP(10)v[i].tex.x=v[i].tex.x*tex_scale+tex_offset;
  646. if(wrap_mode)VI.end();else VI.flushIndexed(IndBufBorder, 4*2*3);
  647. }
  648. VI.clear();
  649. }
  650. /******************************************************************************/
  651. void Image::draw3x3Borders(C Color &color, C Color &color_add, C Rect &rect, Flt border_size, Flt tex_frac)C
  652. {
  653. VI.color (color );
  654. VI.color2 (color_add);
  655. VI.image (this );
  656. VI.setType(VI_2D_TEX, VI_SP_COL);
  657. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(16))
  658. {
  659. Flt w=rect.w(), W=((w>=0) ? Min(w/2, border_size) : Max(w/2, -border_size)),
  660. h=rect.h(), H=((h>=0) ? Min(h/2, border_size) : Max(h/2, -border_size)),
  661. x0=rect.min.x, x3=rect.max.x, x1=x0+W, x2=x3-W,
  662. y0=rect.max.y, y3=rect.min.y, y1=y0-H, y2=y3+H,
  663. tex_frac1=1-tex_frac;
  664. v[ 0].pos.set(x0, y0);
  665. v[ 1].pos.set(x1, y0);
  666. v[ 2].pos.set(x2, y0);
  667. v[ 3].pos.set(x3, y0);
  668. v[ 4].pos.set(x0, y1);
  669. v[ 5].pos.set(x1, y1);
  670. v[ 6].pos.set(x2, y1);
  671. v[ 7].pos.set(x3, y1);
  672. v[ 8].pos.set(x0, y2);
  673. v[ 9].pos.set(x1, y2);
  674. v[10].pos.set(x2, y2);
  675. v[11].pos.set(x3, y2);
  676. v[12].pos.set(x0, y3);
  677. v[13].pos.set(x1, y3);
  678. v[14].pos.set(x2, y3);
  679. v[15].pos.set(x3, y3);
  680. v[ 0].tex.set( 0, 0);
  681. v[ 1].tex.set(tex_frac , 0);
  682. v[ 2].tex.set(tex_frac1, 0);
  683. v[ 3].tex.set( 1, 0);
  684. v[ 4].tex.set( 0, tex_frac );
  685. v[ 5].tex.set(tex_frac , tex_frac );
  686. v[ 6].tex.set(tex_frac1, tex_frac );
  687. v[ 7].tex.set( 1, tex_frac );
  688. v[ 8].tex.set( 0, tex_frac1);
  689. v[ 9].tex.set(tex_frac , tex_frac1);
  690. v[10].tex.set(tex_frac1, tex_frac1);
  691. v[11].tex.set( 1, tex_frac1);
  692. v[12].tex.set( 0, 1);
  693. v[13].tex.set(tex_frac , 1);
  694. v[14].tex.set(tex_frac1, 1);
  695. v[15].tex.set( 1, 1);
  696. if(partial())REP(16)v[i].tex*=_part.xy;
  697. VI.flushIndexed(IndBufPanel, (3*3-1)*2*3);
  698. }
  699. VI.clear();
  700. }
  701. void Image::draw3x3(C Color &color, C Color &color_add, C Rect &rect, Flt border_size, Flt tex_frac)C
  702. {
  703. VI.color (color );
  704. VI.color2 (color_add);
  705. VI.image (this );
  706. VI.setType(VI_2D_TEX, VI_SP_COL);
  707. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(16))
  708. {
  709. Flt w=rect.w(), W=((w>=0) ? Min(w/2, border_size) : Max(w/2, -border_size)),
  710. h=rect.h(), H=((h>=0) ? Min(h/2, border_size) : Max(h/2, -border_size)),
  711. x0=rect.min.x, x3=rect.max.x, x1=x0+W, x2=x3-W,
  712. y0=rect.max.y, y3=rect.min.y, y1=y0-H, y2=y3+H,
  713. tex_frac1=1-tex_frac;
  714. v[ 0].pos.set(x0, y0);
  715. v[ 1].pos.set(x1, y0);
  716. v[ 2].pos.set(x2, y0);
  717. v[ 3].pos.set(x3, y0);
  718. v[ 4].pos.set(x0, y1);
  719. v[ 5].pos.set(x1, y1);
  720. v[ 6].pos.set(x2, y1);
  721. v[ 7].pos.set(x3, y1);
  722. v[ 8].pos.set(x0, y2);
  723. v[ 9].pos.set(x1, y2);
  724. v[10].pos.set(x2, y2);
  725. v[11].pos.set(x3, y2);
  726. v[12].pos.set(x0, y3);
  727. v[13].pos.set(x1, y3);
  728. v[14].pos.set(x2, y3);
  729. v[15].pos.set(x3, y3);
  730. v[ 0].tex.set( 0, 0);
  731. v[ 1].tex.set(tex_frac , 0);
  732. v[ 2].tex.set(tex_frac1, 0);
  733. v[ 3].tex.set( 1, 0);
  734. v[ 4].tex.set( 0, tex_frac );
  735. v[ 5].tex.set(tex_frac , tex_frac );
  736. v[ 6].tex.set(tex_frac1, tex_frac );
  737. v[ 7].tex.set( 1, tex_frac );
  738. v[ 8].tex.set( 0, tex_frac1);
  739. v[ 9].tex.set(tex_frac , tex_frac1);
  740. v[10].tex.set(tex_frac1, tex_frac1);
  741. v[11].tex.set( 1, tex_frac1);
  742. v[12].tex.set( 0, 1);
  743. v[13].tex.set(tex_frac , 1);
  744. v[14].tex.set(tex_frac1, 1);
  745. v[15].tex.set( 1, 1);
  746. if(partial())REP(16)v[i].tex*=_part.xy;
  747. VI.flushIndexed(IndBufPanel, 3*3*2*3);
  748. }
  749. VI.clear();
  750. }
  751. void Image::draw3x3Vertical(C Color &color, C Color &color_add, C Rect &rect, Flt border_size, Flt tex_frac)C
  752. {
  753. VI.color (color );
  754. VI.color2 (color_add);
  755. VI.image (this );
  756. VI.setType(VI_2D_TEX, VI_SP_COL);
  757. if(Vtx2DTex *v=(Vtx2DTex*)VI.addVtx(16))
  758. {
  759. Flt w=rect.w(), W=((w>=0) ? Min(w/2, border_size) : Max(w/2, -border_size)),
  760. h=rect.h(), H=((h>=0) ? Min(h/2, border_size) : Max(h/2, -border_size)),
  761. x0=rect.min.x, x3=rect.max.x, x1=x0+W, x2=x3-W,
  762. y0=rect.max.y, y3=rect.min.y, y1=y0-H, y2=y3+H,
  763. tex_frac1=1-tex_frac;
  764. v[ 0].pos.set(x0, y0);
  765. v[ 1].pos.set(x1, y0);
  766. v[ 2].pos.set(x2, y0);
  767. v[ 3].pos.set(x3, y0);
  768. v[ 4].pos.set(x0, y1);
  769. v[ 5].pos.set(x1, y1);
  770. v[ 6].pos.set(x2, y1);
  771. v[ 7].pos.set(x3, y1);
  772. v[ 8].pos.set(x0, y2);
  773. v[ 9].pos.set(x1, y2);
  774. v[10].pos.set(x2, y2);
  775. v[11].pos.set(x3, y2);
  776. v[12].pos.set(x0, y3);
  777. v[13].pos.set(x1, y3);
  778. v[14].pos.set(x2, y3);
  779. v[15].pos.set(x3, y3);
  780. v[ 0].tex.set( 1, 0);
  781. v[ 1].tex.set( 1, tex_frac );
  782. v[ 2].tex.set( 1, tex_frac1);
  783. v[ 3].tex.set( 1, 1);
  784. v[ 4].tex.set(tex_frac1, 0);
  785. v[ 5].tex.set(tex_frac1, tex_frac );
  786. v[ 6].tex.set(tex_frac1, tex_frac1);
  787. v[ 7].tex.set(tex_frac1, 1);
  788. v[ 8].tex.set(tex_frac , 0);
  789. v[ 9].tex.set(tex_frac , tex_frac );
  790. v[10].tex.set(tex_frac , tex_frac1);
  791. v[11].tex.set(tex_frac , 1);
  792. v[12].tex.set( 0, 0);
  793. v[13].tex.set( 0, tex_frac );
  794. v[14].tex.set( 0, tex_frac1);
  795. v[15].tex.set( 0, 1);
  796. if(partial())REP(16)v[i].tex*=_part.xy;
  797. VI.flushIndexed(IndBufPanel, 3*3*2*3);
  798. }
  799. VI.clear();
  800. }
  801. /******************************************************************************/
  802. void Image::drawCubeFace(C Color &color, C Color &color_add, C Rect &rect, DIR_ENUM face)C
  803. {
  804. if(InRange(face, 6))
  805. {
  806. if(!Sh.h_DrawCubeFace)Sh.h_DrawCubeFace=Sh.get("DrawCubeFace");
  807. VI.shader (Sh.h_DrawCubeFace);
  808. VI.color (color );
  809. VI.color2 (color_add);
  810. VI.setType(VI_2D_FONT, VI_STRIP);
  811. Sh.h_ImageRfl[0]->set(this);
  812. if(Vtx2DFont *v=(Vtx2DFont*)VI.addVtx(4))
  813. {
  814. v[0].pos.set(rect.min.x, rect.max.y);
  815. v[1].pos.set(rect.max.x, rect.max.y);
  816. v[2].pos.set(rect.min.x, rect.min.y);
  817. v[3].pos.set(rect.max.x, rect.min.y);
  818. switch(face)
  819. { // here 'shade' is used as the 3rd tex Z coordinate
  820. case DIR_RIGHT : v[0].tex.set( 1, 1); v[0].shade= 1;
  821. v[1].tex.set( 1, 1); v[1].shade=-1;
  822. v[2].tex.set( 1, -1); v[2].shade= 1;
  823. v[3].tex.set( 1, -1); v[3].shade=-1; break;
  824. case DIR_LEFT : v[0].tex.set(-1, 1); v[0].shade=-1;
  825. v[1].tex.set(-1, 1); v[1].shade= 1;
  826. v[2].tex.set(-1, -1); v[2].shade=-1;
  827. v[3].tex.set(-1, -1); v[3].shade= 1; break;
  828. case DIR_UP : v[0].tex.set(-1, 1); v[0].shade=-1;
  829. v[1].tex.set( 1, 1); v[1].shade=-1;
  830. v[2].tex.set(-1, 1); v[2].shade= 1;
  831. v[3].tex.set( 1, 1); v[3].shade= 1; break;
  832. case DIR_DOWN : v[0].tex.set(-1, -1); v[0].shade= 1;
  833. v[1].tex.set( 1, -1); v[1].shade= 1;
  834. v[2].tex.set(-1, -1); v[2].shade=-1;
  835. v[3].tex.set( 1, -1); v[3].shade=-1; break;
  836. case DIR_FORWARD: v[0].tex.set(-1, 1); v[0].shade= 1;
  837. v[1].tex.set( 1, 1); v[1].shade= 1;
  838. v[2].tex.set(-1, -1); v[2].shade= 1;
  839. v[3].tex.set( 1, -1); v[3].shade= 1; break;
  840. case DIR_BACK : v[0].tex.set( 1, 1); v[0].shade=-1;
  841. v[1].tex.set(-1, 1); v[1].shade=-1;
  842. v[2].tex.set( 1, -1); v[2].shade=-1;
  843. v[3].tex.set(-1, -1); v[3].shade=-1; break;
  844. }
  845. }
  846. VI.end();
  847. }
  848. }
  849. /******************************************************************************/
  850. void Image::draw3D(C Color &color, Flt size, Flt angle, C Vec &pos, ALPHA_MODE alpha)C
  851. {
  852. #if DX9 || GL // DX10+ should support all sizes
  853. Sh.h_ColSize->set(_part.xy);
  854. #endif
  855. D .alpha (alpha);
  856. VI.image (this );
  857. VI.setType(VI_3D_BILB, VI_STRIP);
  858. if(Vtx3DBilb *v=(Vtx3DBilb*)VI.addVtx(4))
  859. {
  860. v[0].pos =v[1].pos =v[2].pos =v[3].pos =pos;
  861. #if GPU_HALF_SUPPORTED
  862. v[0].vel_angle=v[1].vel_angle=v[2].vel_angle=v[3].vel_angle.set(HalfZero, HalfZero, HalfZero, angle);
  863. #else
  864. v[0].vel_angle=v[1].vel_angle=v[2].vel_angle=v[3].vel_angle.set( 0, 0, 0, angle);
  865. #endif
  866. v[0].color =v[1].color =v[2].color =v[3].color =color;
  867. v[0].size =v[1].size =v[2].size =v[3].size =size;
  868. SET_TEX(v[0].tex, TEX_ZERO, TEX_ZERO);
  869. SET_TEX(v[1].tex, TEX_ONE , TEX_ZERO);
  870. SET_TEX(v[2].tex, TEX_ZERO, TEX_ONE );
  871. SET_TEX(v[3].tex, TEX_ONE , TEX_ONE );
  872. }
  873. VI.end();
  874. }
  875. /******************************************************************************/
  876. #pragma pack(push, 4)
  877. struct GpuVolume
  878. {
  879. Flt min_steps,
  880. max_steps,
  881. density_factor,
  882. precision ;
  883. Vec size ,
  884. pixels,
  885. inside;
  886. };
  887. #pragma pack(pop)
  888. void Image::drawVolume(C Color &color, C Color &color_add, C OBox &obox, Flt voxel_density_factor, Flt precision, Int min_steps, Int max_steps)C
  889. {
  890. if(Frustum(obox) && Renderer.canReadDepth())
  891. {
  892. if(!Sh.h_Volume)
  893. {
  894. Sh.h_Volume=GetShaderParam("Volume");
  895. Sh.h_Volume0[0]=Sh.get("Volume0"); Sh.h_Volume0[1]=Sh.get("Volume0LA");
  896. Sh.h_Volume1[0]=Sh.get("Volume1"); Sh.h_Volume1[1]=Sh.get("Volume1LA");
  897. Sh.h_Volume2[0]=Sh.get("Volume2"); Sh.h_Volume2[1]=Sh.get("Volume2LA");
  898. }
  899. GpuVolume v;
  900. Bool LA=(type()==IMAGE_R8G8); // check 'type' instead of 'hwType' because volumetric clouds may want to be set as RG, but got RGBA, however only RG was set
  901. v.min_steps =Mid(Flt(min_steps), 2.0f, 1024.0f);
  902. v.max_steps =Mid(Flt(max_steps), v.min_steps, 1024.0f);
  903. v.density_factor=Mid(voxel_density_factor, EPS_GPU, 1-EPS_GPU);
  904. v.precision =precision;
  905. v.size =obox.box.size()*0.5f;
  906. v.pixels =size3();
  907. Matrix temp;
  908. temp.pos=obox.center();
  909. temp.x =obox.matrix.x*v.size.x;
  910. temp.y =obox.matrix.y*v.size.y;
  911. temp.z =obox.matrix.z*v.size.z;
  912. SetOneMatrix(temp);
  913. Vec delta=CamMatrix.pos-temp.pos;
  914. v.inside.x=Dot(delta, obox.matrix.x);
  915. v.inside.y=Dot(delta, obox.matrix.y);
  916. v.inside.z=Dot(delta, obox.matrix.z);
  917. D .alphaFactor(TRANSPARENT);
  918. Sh.h_ImageVol[0]->set(T ); Sh.h_ImageVol[0]->_sampler=&SamplerLinearClamp;
  919. Sh.h_Color [0]->set(color );
  920. Sh.h_Color [1]->set(color_add);
  921. Sh.h_Volume ->set(v);
  922. D.cull (true);
  923. D.alpha(ALPHA_BLEND_DEC);
  924. Renderer.needDepthRead();
  925. Flt e=Frustum.view_quad_max_dist;
  926. if(v.inside.x>=-v.size.x-e && v.inside.x<=v.size.x+e
  927. && v.inside.y>=-v.size.y-e && v.inside.y<=v.size.y+e
  928. && v.inside.z>=-v.size.z-e && v.inside.z<=v.size.z+e)
  929. {
  930. D.depth(false);
  931. if(v.inside.x>=-v.size.x+e && v.inside.x<=v.size.x-e
  932. && v.inside.y>=-v.size.y+e && v.inside.y<=v.size.y-e
  933. && v.inside.z>=-v.size.z+e && v.inside.z<=v.size.z-e)Sh.h_Volume2[LA]->begin();
  934. else Sh.h_Volume1[LA]->begin();
  935. MshrBoxR.set().drawFull();
  936. ShaderEnd();
  937. }else
  938. {
  939. D .depth (true );
  940. D .depthWrite(false);
  941. Sh.h_Volume0[LA]->begin(); MshrBox.set().drawFull();
  942. ShaderEnd();
  943. }
  944. Sh.h_ImageVol[0]->_sampler=null;
  945. MaterialClear(); // because D.alphaFactor and ImageCol
  946. }
  947. }
  948. /******************************************************************************/
  949. }
  950. /******************************************************************************/