Display State.cpp 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. #include "../Shaders/!Header CPU.h"
  4. namespace EE{
  5. /******************************************************************************
  6. TODO: on DX11 states are activated ('set') for each single state change, while they should be activated only after all single changes
  7. /******************************************************************************/
  8. #define DEPTH_VALUE(x) (REVERSE_DEPTH ? -(x) : (x))
  9. #if DX9 || GL
  10. #define DEPTH_BIAS_SHADOW DEPTH_VALUE( 0.0f )
  11. #define DEPTH_BIAS_OVERLAY DEPTH_VALUE(-1.0f/(1ull<<24)) // 24-bit depth buffer
  12. #elif DX11
  13. #define DEPTH_BIAS_SHADOW DEPTH_VALUE( 0)
  14. #define DEPTH_BIAS_OVERLAY DEPTH_VALUE(-1)
  15. #endif
  16. #define SLOPE_SCALED_DEPTH_BIAS_SHADOW DEPTH_VALUE(SQRT2)
  17. #define SLOPE_SCALED_DEPTH_BIAS_OVERLAY DEPTH_VALUE(-1.0f)
  18. /******************************************************************************/
  19. #if DX9
  20. static Bool AllowLineSmooth;
  21. #elif DX11
  22. struct BlendState
  23. {
  24. ID3D11BlendState *state;
  25. void del()
  26. {
  27. if(state)
  28. {
  29. //SyncLocker locker(D._lock); if(state) lock not needed for DX11 'Release'
  30. {if(D.created())state->Release(); state=null;}
  31. }
  32. }
  33. void create(D3D11_BLEND_DESC &desc)
  34. {
  35. //SyncLocker locker(D._lock); lock not needed for DX11 'D3D'
  36. del();
  37. if(D3D)D3D->CreateBlendState(&desc, &state);
  38. }
  39. void set()
  40. {
  41. D3DC->OMSetBlendState(state, D._alpha_factor_v4.c, D._sample_mask);
  42. }
  43. BlendState() {state=null;}
  44. ~BlendState() {del();}
  45. };
  46. /******************************************************************************/
  47. struct DepthState
  48. {
  49. ID3D11DepthStencilState *state;
  50. void del()
  51. {
  52. if(state)
  53. {
  54. //SyncLocker locker(D._lock); if(state) lock not needed for DX11 'Release'
  55. {if(D.created())state->Release(); state=null;}
  56. }
  57. }
  58. void create(D3D11_DEPTH_STENCIL_DESC &desc)
  59. {
  60. //SyncLocker locker(D._lock); lock not needed for DX11 'D3D'
  61. del();
  62. if(D3D)D3D->CreateDepthStencilState(&desc, &state);
  63. }
  64. void set()
  65. {
  66. D3DC->OMSetDepthStencilState(state, D._stencil_ref);
  67. }
  68. DepthState() {state=null;}
  69. ~DepthState() {del();}
  70. };
  71. /******************************************************************************/
  72. struct RasterizerState
  73. {
  74. ID3D11RasterizerState *state;
  75. void del()
  76. {
  77. if(state)
  78. {
  79. //SyncLocker locker(D._lock); if(state) lock not needed for DX11 'Release'
  80. {if(D.created())state->Release(); state=null;}
  81. }
  82. }
  83. void create(D3D11_RASTERIZER_DESC &desc)
  84. {
  85. //SyncLocker locker(D._lock); lock not needed for DX11 'D3D'
  86. del();
  87. if(D3D)D3D->CreateRasterizerState(&desc, &state);
  88. }
  89. void set()
  90. {
  91. D3DC->RSSetState(state);
  92. }
  93. RasterizerState() {state=null;}
  94. ~RasterizerState() {del();}
  95. };
  96. /******************************************************************************/
  97. // set order that first array sizes are those not pow2, and followed by pow2 (faster accessing)
  98. static BlendState BS [ ALPHA_NUM] ; // [AlphaMode]
  99. static DepthState DS [STENCIL_NUM][2][2][8]; // [StencilMode][DepthUse][DepthWrite][DepthFunc]
  100. static RasterizerState RS[3][ BIAS_NUM][2][2][2]; // [Cull][Bias][LineSmooth][Wire][Clip]
  101. #elif GL
  102. static Bool DepthAllow=true, DepthReal;
  103. static Byte Col0WriteAllow=COL_WRITE_RGBA, Col0WriteReal=COL_WRITE_RGBA;
  104. static UInt StencilFunc=GL_ALWAYS, StencilMask=~0;
  105. #endif
  106. #if !DX11
  107. static STENCIL_MODE LastStencilMode;
  108. #endif
  109. /******************************************************************************/
  110. // DEPTH / STENCIL
  111. /******************************************************************************/
  112. DisplayState::DisplayState()
  113. {
  114. _cull =false;
  115. _line_smooth =false;
  116. _wire =false;
  117. _clip =false;
  118. _clip_allow =true;
  119. _clip_real =false;
  120. _clip_rect .zero();
  121. _clip_recti .zero();
  122. _clip_plane_allow=false;
  123. _clip_plane .zero();
  124. _sampler2D =true;
  125. _depth_lock =false;
  126. _depth =false;
  127. _depth_write =true;
  128. _depth_func =FUNC_LESS;
  129. _alpha =ALPHA_BLEND;
  130. _stencil =STENCIL_NONE;
  131. _stencil_ref =0;
  132. _bias =BIAS_ZERO;
  133. _col_write[0] =COL_WRITE_RGBA;
  134. _col_write[1] =COL_WRITE_RGBA;
  135. _col_write[2] =COL_WRITE_RGBA;
  136. _col_write[3] =COL_WRITE_RGBA;
  137. _sample_mask =~0;
  138. _viewport .zero();
  139. _alpha_factor .zero();
  140. _alpha_factor_v4 .zero();
  141. _vf =null;
  142. }
  143. void DisplayState::depthUnlock( ) { D._depth_lock=false;}
  144. void DisplayState::depthLock (Bool on) {depth(on); D._depth_lock=true ;}
  145. /******************************************************************************/
  146. #if DX9
  147. void DisplayState::depth (Bool on ) { if(D._depth !=on && !D._depth_lock)D3D->SetRenderState(D3DRS_ZENABLE , D._depth =on );}
  148. Bool DisplayState::depthWrite(Bool on ) {Bool last=D._depth_write; if(D._depth_write!=on )D3D->SetRenderState(D3DRS_ZWRITEENABLE, D._depth_write=on ); return last;}
  149. void DisplayState::depthFunc (UInt func) { if(D._depth_func !=func )D3D->SetRenderState(D3DRS_ZFUNC , D._depth_func =func);}
  150. void DisplayState::stencilRef(Byte ref ) { if(D._stencil_ref!=ref )D3D->SetRenderState(D3DRS_STENCILREF , D._stencil_ref=ref );}
  151. void DisplayState::stencil (STENCIL_MODE mode, Byte ref) {stencil(mode); stencilRef(ref);}
  152. #elif DX11
  153. #define D3D11_COMPARISON_FIRST D3D11_COMPARISON_NEVER
  154. static void SetDS() {DS[D._stencil][D._depth][D._depth_write][D._depth_func-D3D11_COMPARISON_FIRST].set();}
  155. void DisplayState::depth (Bool on ) { if(D._depth !=on && !D._depth_lock ){D._depth =on ; SetDS();}}
  156. Bool DisplayState::depthWrite(Bool on ) {Bool last=D._depth_write; if(D._depth_write!=on ){D._depth_write=on ; SetDS();} return last;}
  157. void DisplayState::depthFunc (UInt func) { if(D._depth_func !=func ){D._depth_func =func; SetDS();}}
  158. void DisplayState::stencilRef(Byte ref ) { if(D._stencil_ref!=ref ){D._stencil_ref=ref ; SetDS();}}
  159. void DisplayState::stencil (STENCIL_MODE mode, Byte ref) { if(D._stencil_ref!=ref || D._stencil!=mode){D._stencil_ref=ref ; D._stencil=mode; SetDS();}}
  160. #elif GL
  161. Bool DisplayState::depthWrite(Bool on ) {Bool last=D._depth_write; if(D._depth_write!=on )glDepthMask ( D._depth_write=on ); return last;}
  162. void DisplayState::depthFunc (UInt func) { if(D._depth_func !=func)glDepthFunc ( D._depth_func =func );}
  163. void DisplayState::stencilRef(Byte ref ) { if(D._stencil_ref!=ref )glStencilFunc(StencilFunc, D._stencil_ref=ref, StencilMask);}
  164. void DisplayState::stencil (STENCIL_MODE mode, Byte ref)
  165. {
  166. #if 1
  167. STENCIL_MODE old_mode=LastStencilMode; // remember old values
  168. Byte old_ref =D._stencil_ref; D._stencil_ref=ref; // already change 'D._stencil_ref' because calling 'stencil' might use it
  169. stencil(mode);
  170. if(old_mode==LastStencilMode && old_ref!=ref)glStencilFunc(StencilFunc, ref, StencilMask); // if 'stencil' didn't change 'LastStencilMode' and we wanted to change 'D._stencil_ref' then manually change the 'ref'
  171. #else
  172. stencil(mode); stencilRef(ref);
  173. #endif
  174. }
  175. void DisplayState::depth(Bool on)
  176. {
  177. if(D._depth!=on && !D._depth_lock)
  178. {
  179. D._depth=on;
  180. #if !IOS // on desktop OpenGL and OpenGL ES (except iOS) '_main' is always linked with '_main_ds', when setting "_main null" RT DS, '_main_ds' is set either way but with depth disabled
  181. on&=DepthAllow; if(on==DepthReal)return; DepthReal=on;
  182. #endif
  183. if(on)glEnable(GL_DEPTH_TEST);else glDisable(GL_DEPTH_TEST);
  184. }
  185. }
  186. void DisplayState::depthAllow(Bool on)
  187. {
  188. if(DepthAllow!=on)
  189. {
  190. DepthAllow=on;
  191. on&=D._depth;
  192. if(DepthReal!=on)if(DepthReal=on)glEnable(GL_DEPTH_TEST);else glDisable(GL_DEPTH_TEST);
  193. }
  194. }
  195. #endif
  196. /******************************************************************************/
  197. void DisplayState::depth2DOn(Bool background)
  198. {
  199. UInt func=(background ? FUNC_LESS_EQUAL : FUNC_GREATER);
  200. #if DX11
  201. if(D._depth!=true || D._depth_write!=false || D._depth_func!=func)
  202. {
  203. D._depth =true ;
  204. D._depth_write=false;
  205. D._depth_func =func ;
  206. SetDS();
  207. }
  208. D._depth_lock=true;
  209. #else
  210. depthLock (true );
  211. depthWrite(false);
  212. depthFunc (func );
  213. #endif
  214. }
  215. void DisplayState::depth2DOff()
  216. {
  217. UInt func=FUNC_LESS_EQUAL;
  218. #if DX11
  219. if(D._depth_write!=true || D._depth_func!=func)
  220. {
  221. D._depth_write=true;
  222. D._depth_func =func;
  223. SetDS();
  224. }
  225. D._depth_lock=false;
  226. #else
  227. depthWrite (true);
  228. depthUnlock( );
  229. depthFunc (func);
  230. #endif
  231. }
  232. /******************************************************************************/
  233. void DisplayState::stencil(STENCIL_MODE stencil)
  234. {
  235. #if DX9
  236. if(D._stencil!=stencil)
  237. {
  238. D._stencil=stencil;
  239. if(!stencil)
  240. {
  241. D3D->SetRenderState(D3DRS_STENCILENABLE, false);
  242. }else
  243. {
  244. D3D->SetRenderState(D3DRS_STENCILENABLE, true);
  245. if(LastStencilMode!=stencil)switch(LastStencilMode=stencil)
  246. {
  247. case STENCIL_ALWAYS_SET:
  248. D3D->SetRenderState(D3DRS_STENCILMASK , ~0 );
  249. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, ~0 );
  250. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_ALWAYS );
  251. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_ALWAYS );
  252. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP );
  253. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP );
  254. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_REPLACE);
  255. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_REPLACE);
  256. break;
  257. case STENCIL_TERRAIN_TEST:
  258. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_TERRAIN);
  259. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, 0 );
  260. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_EQUAL );
  261. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_EQUAL );
  262. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP );
  263. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP );
  264. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_KEEP );
  265. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_KEEP );
  266. break;
  267. case STENCIL_MSAA_SET:
  268. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_MSAA );
  269. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, STENCIL_REF_MSAA );
  270. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_ALWAYS );
  271. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_ALWAYS );
  272. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP );
  273. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP );
  274. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_REPLACE);
  275. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_REPLACE);
  276. break;
  277. case STENCIL_MSAA_TEST:
  278. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_MSAA );
  279. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, 0 );
  280. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_EQUAL );
  281. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_EQUAL );
  282. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP);
  283. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP);
  284. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_KEEP);
  285. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_KEEP);
  286. break;
  287. case STENCIL_EDGE_SOFT_SET:
  288. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_EDGE_SOFT);
  289. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, STENCIL_REF_EDGE_SOFT);
  290. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_ALWAYS );
  291. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_ALWAYS );
  292. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP );
  293. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP );
  294. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_REPLACE );
  295. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_REPLACE );
  296. break;
  297. case STENCIL_EDGE_SOFT_TEST:
  298. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_EDGE_SOFT);
  299. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, 0 );
  300. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_EQUAL );
  301. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_EQUAL );
  302. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP );
  303. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP );
  304. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_KEEP );
  305. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_KEEP );
  306. break;
  307. case STENCIL_WATER_SET:
  308. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_WATER );
  309. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, STENCIL_REF_WATER );
  310. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_ALWAYS );
  311. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_ALWAYS );
  312. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP );
  313. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP );
  314. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_REPLACE);
  315. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_REPLACE);
  316. break;
  317. case STENCIL_WATER_TEST:
  318. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_WATER);
  319. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, 0 );
  320. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_EQUAL );
  321. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_EQUAL );
  322. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP);
  323. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP);
  324. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_KEEP);
  325. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_KEEP);
  326. break;
  327. case STENCIL_OUTLINE_SET:
  328. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_OUTLINE );
  329. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, STENCIL_REF_OUTLINE );
  330. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_ALWAYS );
  331. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_ALWAYS );
  332. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP );
  333. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP );
  334. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_REPLACE);
  335. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_REPLACE);
  336. break;
  337. case STENCIL_OUTLINE_TEST:
  338. D3D->SetRenderState(D3DRS_STENCILMASK , STENCIL_REF_OUTLINE);
  339. D3D->SetRenderState(D3DRS_STENCILWRITEMASK, 0 );
  340. D3D->SetRenderState(D3DRS_STENCILFUNC , D3DCMP_EQUAL );
  341. D3D->SetRenderState(D3DRS_CCW_STENCILFUNC , D3DCMP_EQUAL );
  342. D3D->SetRenderState(D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP );
  343. D3D->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP );
  344. D3D->SetRenderState(D3DRS_STENCILPASS , D3DSTENCILOP_KEEP );
  345. D3D->SetRenderState(D3DRS_CCW_STENCILPASS , D3DSTENCILOP_KEEP );
  346. break;
  347. }
  348. }
  349. }
  350. #elif DX11
  351. if(D._stencil!=stencil){D._stencil=stencil; SetDS();}
  352. #elif GL
  353. if(D._stencil!=stencil)
  354. {
  355. D._stencil=stencil;
  356. if(!stencil)
  357. {
  358. glDisable(GL_STENCIL_TEST);
  359. }else
  360. {
  361. glEnable(GL_STENCIL_TEST);
  362. if(LastStencilMode!=stencil)switch(LastStencilMode=stencil)
  363. {
  364. case STENCIL_ALWAYS_SET:
  365. glStencilFunc(StencilFunc=GL_ALWAYS, D._stencil_ref, StencilMask=~0); // set full mask
  366. glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
  367. break;
  368. case STENCIL_TERRAIN_TEST:
  369. glStencilFunc(StencilFunc=GL_EQUAL, D._stencil_ref, StencilMask=STENCIL_REF_TERRAIN);
  370. glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
  371. break;
  372. case STENCIL_MSAA_SET:
  373. glStencilFunc(StencilFunc=GL_ALWAYS, D._stencil_ref, StencilMask=STENCIL_REF_MSAA);
  374. glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
  375. break;
  376. case STENCIL_MSAA_TEST:
  377. glStencilFunc(StencilFunc=GL_EQUAL, D._stencil_ref, StencilMask=STENCIL_REF_MSAA);
  378. glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
  379. break;
  380. case STENCIL_EDGE_SOFT_SET:
  381. glStencilFunc(StencilFunc=GL_ALWAYS, D._stencil_ref, StencilMask=STENCIL_REF_EDGE_SOFT);
  382. glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
  383. break;
  384. case STENCIL_EDGE_SOFT_TEST:
  385. glStencilFunc(StencilFunc=GL_EQUAL, D._stencil_ref, StencilMask=STENCIL_REF_EDGE_SOFT);
  386. glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
  387. break;
  388. case STENCIL_WATER_SET:
  389. glStencilFunc(StencilFunc=GL_ALWAYS, D._stencil_ref, StencilMask=STENCIL_REF_WATER);
  390. glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
  391. break;
  392. case STENCIL_WATER_TEST:
  393. glStencilFunc(StencilFunc=GL_EQUAL, D._stencil_ref, StencilMask=STENCIL_REF_WATER);
  394. glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
  395. break;
  396. case STENCIL_OUTLINE_SET:
  397. glStencilFunc(StencilFunc=GL_ALWAYS, D._stencil_ref, StencilMask=STENCIL_REF_OUTLINE);
  398. glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
  399. break;
  400. case STENCIL_OUTLINE_TEST:
  401. glStencilFunc(StencilFunc=GL_EQUAL, D._stencil_ref, StencilMask=STENCIL_REF_OUTLINE);
  402. glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
  403. break;
  404. }
  405. }
  406. }
  407. #endif
  408. }
  409. /******************************************************************************/
  410. // RASTERIZER
  411. /******************************************************************************/
  412. #if DX9
  413. Bool DisplayState::lineSmooth(Bool on ) {Bool old=D._line_smooth; if(D._line_smooth!=on){D._line_smooth=on; if(D3D && AllowLineSmooth)D3D->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, on);} return old;}
  414. void DisplayState::wire (Bool on ) {if(D._wire!=on)D3D->SetRenderState(D3DRS_FILLMODE, (D._wire=on) ? D3DFILL_WIREFRAME : D3DFILL_SOLID);}
  415. void DisplayState::cull (Bool on ) {if(D._cull!=on)D3D->SetRenderState(D3DRS_CULLMODE, Renderer._cull_mode[D._cull=on]);}
  416. void DisplayState::bias (BIAS_MODE bias)
  417. {
  418. if(D._bias!=bias)switch(D._bias=bias)
  419. {
  420. case BIAS_ZERO:
  421. {
  422. D3D->SetRenderState(D3DRS_DEPTHBIAS , 0);
  423. D3D->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
  424. }break;
  425. case BIAS_SHADOW:
  426. {
  427. Flt f;
  428. f= DEPTH_BIAS_SHADOW; D3D->SetRenderState(D3DRS_DEPTHBIAS , (UInt&)f);
  429. f=SLOPE_SCALED_DEPTH_BIAS_SHADOW; D3D->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, (UInt&)f);
  430. }break;
  431. case BIAS_OVERLAY:
  432. {
  433. Flt f;
  434. f= DEPTH_BIAS_OVERLAY; D3D->SetRenderState(D3DRS_DEPTHBIAS , (UInt&)f);
  435. f=SLOPE_SCALED_DEPTH_BIAS_OVERLAY; D3D->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, (UInt&)f);
  436. }break;
  437. }
  438. }
  439. #elif DX11
  440. static void SetRS() {RS[Renderer._cull_mode[D._cull]][D._bias][D._line_smooth][D._wire][D._clip_real].set();}
  441. Bool DisplayState::lineSmooth(Bool on ) {Bool old=D._line_smooth; if(D._line_smooth!=on){D._line_smooth=on; if(D3DC)SetRS();} return old;}
  442. void DisplayState::wire (Bool on ) {if(D._wire!=on ){D._wire=on ; SetRS();}}
  443. void DisplayState::cull (Bool on ) {if(D._cull!=on ){D._cull=on ; SetRS();}}
  444. void DisplayState::bias (BIAS_MODE bias) {if(D._bias!=bias){D._bias=bias; SetRS();}}
  445. #elif GL
  446. Bool DisplayState::lineSmooth(Bool on)
  447. {
  448. Bool old=D._line_smooth;
  449. if(D._line_smooth!=on)
  450. {
  451. D._line_smooth=on;
  452. #ifdef GL_LINE_SMOOTH
  453. if(on)glEnable(GL_LINE_SMOOTH);else glDisable(GL_LINE_SMOOTH);
  454. #endif
  455. }
  456. return old;
  457. }
  458. void DisplayState::wire(Bool on)
  459. {
  460. #if !GL_ES
  461. if(D._wire!=on)glPolygonMode(GL_FRONT_AND_BACK, (D._wire=on) ? GL_LINE : GL_FILL);
  462. #endif
  463. }
  464. void DisplayState::cull (Bool on) {if(D._cull!=on)if(D._cull=on)glEnable(GL_CULL_FACE);else glDisable(GL_CULL_FACE);}
  465. void DisplayState::cullGL( )
  466. {
  467. Bool front=(Renderer()==RM_SHADOW || !Renderer.mirror());
  468. if(!D.mainFBO())front^=1;
  469. glFrontFace(front ? GL_CW : GL_CCW);
  470. }
  471. void DisplayState::bias(BIAS_MODE bias)
  472. {
  473. if(D._bias!=bias)switch(D._bias=bias)
  474. {
  475. case BIAS_ZERO:
  476. {
  477. glDisable (GL_POLYGON_OFFSET_FILL);
  478. glPolygonOffset(0, 0);
  479. }break;
  480. case BIAS_SHADOW:
  481. {
  482. glEnable (GL_POLYGON_OFFSET_FILL);
  483. glPolygonOffset(SLOPE_SCALED_DEPTH_BIAS_SHADOW, DEPTH_BIAS_SHADOW);
  484. }break;
  485. case BIAS_OVERLAY:
  486. {
  487. glEnable (GL_POLYGON_OFFSET_FILL);
  488. glPolygonOffset(SLOPE_SCALED_DEPTH_BIAS_OVERLAY, DEPTH_BIAS_OVERLAY);
  489. }break;
  490. }
  491. }
  492. #endif
  493. /******************************************************************************/
  494. static void SetClip()
  495. {
  496. if(D._clip_real!=(D._clip && D._clip_allow))
  497. {
  498. D._clip_real^=1;
  499. #if DX9
  500. D3D->SetRenderState(D3DRS_SCISSORTESTENABLE, D._clip_real);
  501. #elif DX11
  502. SetRS();
  503. #elif GL
  504. if(D._clip_real)glEnable(GL_SCISSOR_TEST);else glDisable(GL_SCISSOR_TEST);
  505. #endif
  506. }
  507. }
  508. static void SetClipRect(C RectI &rect)
  509. {
  510. #if GL
  511. RectI r(rect.min.x, D.mainFBO() ? Renderer.resH()-rect.max.y : rect.min.y, rect.w(), rect.h()); // RectI(pos, size)
  512. #define rect r
  513. #endif
  514. if(D._clip_recti!=rect)
  515. {
  516. D._clip_recti=rect; // !! Warning: for GL this is actually RectI(pos, size)
  517. #if DX9
  518. RECT rectangle; rectangle.left=rect.min.x; rectangle.right=rect.max.x; rectangle.top=rect.min.y; rectangle.bottom=rect.max.y;
  519. D3D->SetScissorRect(&rectangle);
  520. #elif DX11
  521. D3D11_RECT rectangle; rectangle.left=rect.min.x; rectangle.right=rect.max.x; rectangle.top=rect.min.y; rectangle.bottom=rect.max.y;
  522. D3DC->RSSetScissorRects(1, &rectangle);
  523. #elif GL
  524. glScissor(r.min.x, r.min.y, r.max.x, r.max.y); // glScissor(pos, size)
  525. #undef rect
  526. #endif
  527. }
  528. }
  529. static void SetClipRect()
  530. {
  531. RectI recti=Renderer.screenToPixelI(D._clip_rect);
  532. if(recti.max.x<=recti.min.x || recti.max.y<=recti.min.y)recti.zero(); // if the rectangle is invalid then zero it, to prevent negative sizes in case drivers can't handle them properly
  533. SetClipRect(recti);
  534. }
  535. void DisplayState::clipForce(C RectI &rect) {D._clip_recti=rect;} // called only for DX9
  536. void DisplayState::clip (C Rect *rect)
  537. {
  538. if(rect)
  539. {
  540. if(!D._clip || D._clip_rect!=*rect)
  541. {
  542. D._clip = true;
  543. D._clip_rect=*rect;
  544. SetClip ();
  545. SetClipRect();
  546. }
  547. }else
  548. if(D._clip)
  549. {
  550. D._clip=false; SetClip();
  551. }
  552. }
  553. void DisplayState::clipAllow(C RectI &rect) // this gets called during shadow rendering
  554. {
  555. SetClipRect(rect);
  556. D._clip_rect=Renderer.pixelToScreen(rect); // needed in case we call 'clip' later which checks if '_clip_rect' changes
  557. D._clip=D._clip_allow=true; SetClip(); // call after setting '_clip' and '_clip_allow'
  558. }
  559. void DisplayState::clipAllow(Bool on) // this gets called when a render target has changed
  560. {
  561. //if(D._clip_allow!=on) we must always do below, because: we may have a different sized RT now, and need to recalculate clip rect. DX9 could have reset clip rect when changing RT's, for GL we may have changed between D.mainFBO for which we need different orientation of the clip rect
  562. {
  563. D._clip_allow=on; SetClip();
  564. if(D._clip_real)SetClipRect(); // call after 'SetClip' because we need '_clip_real'
  565. }
  566. }
  567. /******************************************************************************/
  568. void DisplayState::clipPlane(Bool on)
  569. {
  570. #if DX9
  571. D3D->SetRenderState(D3DRS_CLIPPLANEENABLE, on);
  572. #elif DX11
  573. D._clip_plane_allow=on;
  574. Sh.h_ClipPlane->set(on ? D._clip_plane : Vec4(0, 0, 0, 1));
  575. #elif GL && defined GL_CLIP_DISTANCE0
  576. if(on)glEnable(GL_CLIP_DISTANCE0);else glDisable(GL_CLIP_DISTANCE0);
  577. #endif
  578. }
  579. void DisplayState::clipPlane(C PlaneM &plane)
  580. {
  581. VecD pos=plane.pos *CamMatrixInv;
  582. Vec nrm=plane.normal*CamMatrixInv.orn();
  583. #if DX9
  584. Vec4 clip_plane(nrm, -Dot(pos, nrm));
  585. Matrix4 m=ProjMatrix; m.inverse().transpose(); clip_plane*=m;
  586. D3D->SetClipPlane(0, clip_plane.c);
  587. #elif DX11
  588. D._clip_plane.set(nrm, -Dot(pos, nrm));
  589. clipPlane(D._clip_plane_allow);
  590. #elif GL
  591. Vec4 clip_plane(nrm, -Dot(pos, nrm));
  592. Sh.h_ClipPlane->set(clip_plane);
  593. #endif
  594. }
  595. /******************************************************************************/
  596. // OUTPUT MERGER
  597. /******************************************************************************/
  598. ALPHA_MODE DisplayState::alpha(ALPHA_MODE alpha)
  599. {
  600. ALPHA_MODE prev=D.alpha();
  601. #if DX9
  602. if(D._alpha!=alpha)switch(D._alpha=alpha)
  603. {
  604. case ALPHA_NONE:
  605. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , false);
  606. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, false);
  607. break;
  608. case ALPHA_BLEND:
  609. // final_alpha = 1-(1-src_alpha)*(1-dest_alpha)
  610. // final_alpha = 1 - (1 - src_alpha - dest_alpha + src_alpha*dest_alpha)
  611. // final_alpha = 1 - 1 + src_alpha + dest_alpha - src_alpha*dest_alpha
  612. // final_alpha = src_alpha + dest_alpha - src_alpha*dest_alpha
  613. // final_alpha = src_alpha*(1-dest_alpha) + dest_alpha
  614. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  615. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  616. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  617. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
  618. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  619. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD );
  620. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_INVDESTALPHA);
  621. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE );
  622. break;
  623. case ALPHA_BLEND_DEC:
  624. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  625. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  626. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  627. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
  628. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  629. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD );
  630. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_ZERO );
  631. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
  632. break;
  633. case ALPHA_ADD:
  634. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true );
  635. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, false);
  636. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD);
  637. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_ONE );
  638. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  639. break;
  640. case ALPHA_MUL:
  641. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true );
  642. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, false);
  643. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  644. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_DESTCOLOR);
  645. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO );
  646. break;
  647. case ALPHA_MERGE:
  648. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  649. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  650. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD);
  651. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_ONE );
  652. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  653. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD );
  654. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_INVDESTALPHA);
  655. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE );
  656. break;
  657. case ALPHA_ADDBLEND_KEEP:
  658. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  659. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  660. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  661. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_SRCALPHA);
  662. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  663. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD);
  664. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_ZERO );
  665. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE );
  666. break;
  667. case ALPHA_ADD_KEEP:
  668. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  669. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  670. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD);
  671. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_ONE );
  672. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  673. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD);
  674. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_ZERO );
  675. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE );
  676. break;
  677. case ALPHA_BLEND_FACTOR:
  678. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  679. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  680. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  681. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
  682. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  683. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD );
  684. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_BLENDFACTOR);
  685. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
  686. break;
  687. case ALPHA_ADD_FACTOR:
  688. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  689. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  690. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD);
  691. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_ONE );
  692. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  693. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD );
  694. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_BLENDFACTOR);
  695. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE );
  696. break;
  697. case ALPHA_SETBLEND_SET:
  698. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  699. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  700. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  701. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_SRCALPHA);
  702. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO );
  703. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD);
  704. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_ONE );
  705. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO );
  706. break;
  707. case ALPHA_FACTOR:
  708. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true );
  709. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, false);
  710. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  711. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_BLENDFACTOR );
  712. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVBLENDFACTOR);
  713. break;
  714. case ALPHA_INVERT:
  715. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true );
  716. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, false);
  717. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  718. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_INVDESTCOLOR);
  719. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO );
  720. break;
  721. case ALPHA_FONT:
  722. // final = font_color.rgb * alpha.rgb + (1-alpha.rgb)*dest
  723. // src_color (PS output) = alpha.rgb
  724. // blend_factor = font_color.rgb
  725. // src_blend = blend_factor
  726. // dest_blend = inv_src_color
  727. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true );
  728. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, false);
  729. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  730. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_BLENDFACTOR);
  731. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
  732. break;
  733. case ALPHA_FONT_DEC:
  734. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  735. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  736. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD );
  737. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_BLENDFACTOR);
  738. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
  739. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD );
  740. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_ZERO );
  741. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
  742. break;
  743. case ALPHA_NONE_ADD:
  744. D3D->SetRenderState(D3DRS_ALPHABLENDENABLE , true);
  745. D3D->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true);
  746. D3D->SetRenderState(D3DRS_BLENDOP , D3DBLENDOP_ADD);
  747. D3D->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_ONE );
  748. D3D->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO );
  749. D3D->SetRenderState(D3DRS_BLENDOPALPHA , D3DBLENDOP_ADD);
  750. D3D->SetRenderState(D3DRS_SRCBLENDALPHA , D3DBLEND_ONE );
  751. D3D->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ONE );
  752. break;
  753. }
  754. #elif DX11
  755. if(D._alpha!=alpha)BS[D._alpha=alpha].set();
  756. #elif GL
  757. if(D._alpha!=alpha)switch(D._alpha=alpha)
  758. {
  759. case ALPHA_NONE:
  760. glDisable(GL_BLEND);
  761. break;
  762. case ALPHA_BLEND:
  763. glEnable (GL_BLEND);
  764. glBlendEquation (GL_FUNC_ADD);
  765. glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
  766. break;
  767. case ALPHA_BLEND_DEC:
  768. glEnable (GL_BLEND);
  769. glBlendEquation (GL_FUNC_ADD);
  770. glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
  771. break;
  772. case ALPHA_ADD:
  773. glEnable (GL_BLEND);
  774. glBlendEquation(GL_FUNC_ADD);
  775. glBlendFunc (GL_ONE, GL_ONE);
  776. break;
  777. case ALPHA_MUL:
  778. glEnable (GL_BLEND);
  779. glBlendEquation(GL_FUNC_ADD);
  780. glBlendFunc (GL_DST_COLOR, GL_ZERO);
  781. break;
  782. case ALPHA_MERGE:
  783. glEnable (GL_BLEND);
  784. glBlendEquation (GL_FUNC_ADD);
  785. glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
  786. break;
  787. case ALPHA_ADDBLEND_KEEP:
  788. glEnable (GL_BLEND);
  789. glBlendEquation (GL_FUNC_ADD);
  790. glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
  791. break;
  792. case ALPHA_ADD_KEEP:
  793. glEnable (GL_BLEND);
  794. glBlendEquation (GL_FUNC_ADD);
  795. glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ZERO, GL_ONE);
  796. break;
  797. case ALPHA_BLEND_FACTOR:
  798. glEnable (GL_BLEND);
  799. glBlendEquation (GL_FUNC_ADD);
  800. glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  801. break;
  802. case ALPHA_ADD_FACTOR:
  803. glEnable (GL_BLEND);
  804. glBlendEquation (GL_FUNC_ADD);
  805. glBlendFuncSeparate(GL_ONE, GL_ONE, GL_CONSTANT_ALPHA, GL_ONE);
  806. break;
  807. case ALPHA_SETBLEND_SET:
  808. glEnable (GL_BLEND);
  809. glBlendEquation (GL_FUNC_ADD);
  810. glBlendFuncSeparate(GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ZERO);
  811. break;
  812. case ALPHA_FACTOR:
  813. glEnable (GL_BLEND);
  814. glBlendEquation(GL_FUNC_ADD);
  815. glBlendFunc (GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR);
  816. break;
  817. case ALPHA_INVERT:
  818. glEnable (GL_BLEND);
  819. glBlendEquation(GL_FUNC_ADD);
  820. glBlendFunc (GL_ONE_MINUS_DST_COLOR, GL_ZERO);
  821. break;
  822. case ALPHA_FONT:
  823. glEnable (GL_BLEND);
  824. glBlendEquation(GL_FUNC_ADD);
  825. glBlendFunc (GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
  826. break;
  827. case ALPHA_FONT_DEC:
  828. glEnable (GL_BLEND);
  829. glBlendEquation (GL_FUNC_ADD);
  830. glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
  831. break;
  832. case ALPHA_NONE_ADD:
  833. glEnable (GL_BLEND);
  834. glBlendEquation (GL_FUNC_ADD);
  835. glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE);
  836. break;
  837. }
  838. #endif
  839. return prev;
  840. }
  841. void DisplayState::alphaFactor(C Color &factor)
  842. {
  843. if(D._alpha_factor!=factor)
  844. {
  845. D._alpha_factor=factor;
  846. #if DX9
  847. D3D->SetRenderState(D3DRS_BLENDFACTOR, VecB4(factor.b, factor.g, factor.r, factor.a).u);
  848. #elif DX11
  849. D._alpha_factor_v4=factor.asVec4();
  850. BS[D._alpha].set();
  851. #elif GL
  852. glBlendColor(factor.r/255.0f, factor.g/255.0f, factor.b/255.0f, factor.a/255.0f);
  853. #endif
  854. }
  855. }
  856. /******************************************************************************/
  857. void DisplayState::colWrite(Byte color_mask, Byte index)
  858. {
  859. RANGE_ASSERT(index, D._col_write);
  860. #if DX9
  861. if(D._col_write[index]!=color_mask)
  862. {
  863. D3DRENDERSTATETYPE out;
  864. switch(index)
  865. {
  866. case 0: out=D3DRS_COLORWRITEENABLE ; break;
  867. case 1: out=D3DRS_COLORWRITEENABLE1; break;
  868. case 2: out=D3DRS_COLORWRITEENABLE2; break;
  869. case 3: out=D3DRS_COLORWRITEENABLE3; break;
  870. default: return;
  871. }
  872. D3D->SetRenderState(out, D._col_write[index]=color_mask);
  873. }
  874. #elif DX11
  875. // color writes are not supported on DX10+ implementation
  876. #elif GL
  877. if(D._col_write[index]!=color_mask)
  878. {
  879. D._col_write[index]=color_mask;
  880. #if !IOS // on desktop OpenGL and OpenGL ES (except iOS) '_main' is always linked with '_main_ds', when setting "null _main_ds" RT DS, '_main' is set either way but with color writes disabled
  881. if(!index){color_mask&=Col0WriteAllow; if(color_mask==Col0WriteReal)return; Col0WriteReal=color_mask;}
  882. #endif
  883. #if GL_ES
  884. if(!index)glColorMask(FlagTest(color_mask, COL_WRITE_R), FlagTest(color_mask, COL_WRITE_G), FlagTest(color_mask, COL_WRITE_B), FlagTest(color_mask, COL_WRITE_A)); // TODO: 'glColorMaski' requires GLES 3.2 - https://www.khronos.org/registry/OpenGL-Refpages/es3/html/glColorMask.xhtml
  885. #else
  886. glColorMaski(index, FlagTest(color_mask, COL_WRITE_R), FlagTest(color_mask, COL_WRITE_G), FlagTest(color_mask, COL_WRITE_B), FlagTest(color_mask, COL_WRITE_A));
  887. #endif
  888. }
  889. #endif
  890. }
  891. #if GL
  892. void DisplayState::colWriteAllow(Byte color_mask) // this operates only on "index==0"
  893. {
  894. if(Col0WriteAllow!=color_mask)
  895. {
  896. Col0WriteAllow=color_mask;
  897. color_mask&=D._col_write[0];
  898. if(Col0WriteReal!=color_mask)
  899. {
  900. Col0WriteReal=color_mask;
  901. glColorMask(FlagTest(color_mask, COL_WRITE_R), FlagTest(color_mask, COL_WRITE_G), FlagTest(color_mask, COL_WRITE_B), FlagTest(color_mask, COL_WRITE_A));
  902. }
  903. }
  904. }
  905. #endif
  906. /******************************************************************************/
  907. #if DX11
  908. void DisplayState::sampleMask(UInt mask)
  909. {
  910. if(mask!=D._sample_mask){D._sample_mask=mask; BS[D._alpha].set();}
  911. }
  912. #endif
  913. /******************************************************************************/
  914. void DisplayState::viewportForce(C RectI &rect) // this is only for DX9
  915. {
  916. if(D._viewport!=rect)
  917. {
  918. D._viewport=rect;
  919. #if DX9
  920. if(Sh.h_PixelOffset)
  921. {
  922. Sh.h_PixelOffset->set(PixelOffset.set(-1.0f/rect.w(), 1.0f/rect.h()));
  923. SetProjMatrix(); // because 'ProjMatrix' in the shader is based on 'PixelOffset' in DX9, after changing it we need to update the 'ProjMatrix' shader value
  924. }
  925. #endif
  926. }
  927. }
  928. void DisplayState::viewport(C RectI &rect, Bool allow_proj_matrix_update)
  929. {
  930. if(D._viewport!=rect)
  931. {
  932. D._viewport=rect;
  933. #if DX9
  934. D3DVIEWPORT9 vp;
  935. vp.X=D._viewport.min.x; vp.Width =D._viewport.w(); vp.MinZ=0;
  936. vp.Y=D._viewport.min.y; vp.Height=D._viewport.h(); vp.MaxZ=1;
  937. D3D->SetViewport(&vp);
  938. if(Sh.h_PixelOffset)
  939. {
  940. Sh.h_PixelOffset->set(PixelOffset.set(-1.0f/vp.Width, 1.0f/vp.Height));
  941. if(allow_proj_matrix_update)SetProjMatrix(); // because 'ProjMatrix' in the shader is based on 'PixelOffset' in DX9, after changing it we need to update the 'ProjMatrix' shader value, however set this only if we allow to do so, for example we can disallow this if we're going to update it manually after changing some other settings first
  942. }
  943. #elif DX11
  944. D3D11_VIEWPORT vp;
  945. vp.TopLeftX=D._viewport.min.x; vp.Width =D._viewport.w(); vp.MinDepth=0;
  946. vp.TopLeftY=D._viewport.min.y; vp.Height=D._viewport.h(); vp.MaxDepth=1;
  947. D3DC->RSSetViewports(1, &vp);
  948. #elif GL
  949. glViewport(D._viewport.min.x, D._viewport.min.y, D._viewport.w(), D._viewport.h());
  950. #endif
  951. }
  952. }
  953. /******************************************************************************/
  954. void DisplayState::vf(GPU_API(IDirect3DVertexDeclaration9, ID3D11InputLayout, VtxFormatGL) *vf)
  955. {
  956. #if DX9
  957. if(D._vf!=vf)D3D->SetVertexDeclaration(D._vf=vf);
  958. #elif DX11
  959. if(D._vf!=vf)D3DC->IASetInputLayout(D._vf=vf);
  960. #elif GL
  961. // !! when using VAO's, this can be called only after setting the default 'VAO', because we use 'disable' expecting previous 'vf' to be in the same VAO !!
  962. //if(D._vf!=vf) OpenGL requires resetting this for each new VBO (for example Layered Clouds didn't work after displaying Sky, even though they have the same VF but different VBO)
  963. {
  964. if(D._vf )D._vf->disable ();
  965. if(D._vf=vf)D._vf-> enableSet();
  966. }
  967. #endif
  968. }
  969. /******************************************************************************/
  970. void DisplayState::sampler2D()
  971. {
  972. D._sampler2D=true;
  973. #if DX9
  974. D._sampler_filter[0]=D3DTEXF_LINEAR;
  975. D._sampler_filter[1]=D3DTEXF_LINEAR;
  976. D._sampler_filter[2]=D3DTEXF_LINEAR;
  977. D._sampler_address =D3DTADDRESS_CLAMP;
  978. REP(16)
  979. {
  980. D3D->SetSamplerState(i, D3DSAMP_MINFILTER, D._sampler_filter[0]);
  981. D3D->SetSamplerState(i, D3DSAMP_MAGFILTER, D._sampler_filter[1]);
  982. D3D->SetSamplerState(i, D3DSAMP_MIPFILTER, D._sampler_filter[2]);
  983. D3D->SetSamplerState(i, D3DSAMP_ADDRESSU , D._sampler_address );
  984. D3D->SetSamplerState(i, D3DSAMP_ADDRESSV , D._sampler_address );
  985. D3D->SetSamplerState(i, D3DSAMP_ADDRESSW , D._sampler_address );
  986. }
  987. #elif DX11
  988. SamplerLinearClamp.setPS(SSI_DEFAULT);
  989. #elif GL
  990. //D._sampler_filter[0]=GL_LINEAR; unused
  991. //D._sampler_filter[1]=GL_LINEAR; unused
  992. //D._sampler_filter[2]=GL_LINEAR; unused
  993. D._sampler_address =GL_CLAMP_TO_EDGE;
  994. #endif
  995. }
  996. void DisplayState::sampler3D()
  997. {
  998. D._sampler2D=false;
  999. #if DX9
  1000. switch(D.texFilter())
  1001. {
  1002. case 0: D._sampler_filter[0]=D3DTEXF_LINEAR ; break;
  1003. case 1: D._sampler_filter[0]=D3DTEXF_LINEAR ; break;
  1004. default: D._sampler_filter[0]=D3DTEXF_ANISOTROPIC; break;
  1005. }
  1006. switch(D.texFilter())
  1007. {
  1008. case 0: D._sampler_filter[1]=D3DTEXF_POINT ; break;
  1009. default: D._sampler_filter[1]=D3DTEXF_LINEAR; break;
  1010. }
  1011. UInt aniso=Max(D.texFilter(), 1);
  1012. D._sampler_filter[2]=(D.texMipFilter() ? D3DTEXF_LINEAR : D3DTEXF_POINT);
  1013. D._sampler_address =D3DTADDRESS_WRAP;
  1014. REP(16)
  1015. {
  1016. D3D->SetSamplerState(i, D3DSAMP_MINFILTER , D._sampler_filter[0]);
  1017. D3D->SetSamplerState(i, D3DSAMP_MAGFILTER , D._sampler_filter[1]);
  1018. D3D->SetSamplerState(i, D3DSAMP_MIPFILTER , D._sampler_filter[2]);
  1019. D3D->SetSamplerState(i, D3DSAMP_MAXANISOTROPY, aniso);
  1020. D3D->SetSamplerState(i, D3DSAMP_ADDRESSU , D._sampler_address);
  1021. D3D->SetSamplerState(i, D3DSAMP_ADDRESSV , D._sampler_address);
  1022. D3D->SetSamplerState(i, D3DSAMP_ADDRESSW , D._sampler_address);
  1023. }
  1024. #elif DX11
  1025. SamplerAnisotropic.setPS(SSI_DEFAULT);
  1026. #elif GL
  1027. /*switch(D.texFilter()) unused
  1028. {
  1029. case 0: D._sampler_filter[0]=GL_LINEAR; break; // or GL_LINEAR_MIPMAP_LINEAR
  1030. case 1: D._sampler_filter[0]=GL_LINEAR; break; // or GL_LINEAR_MIPMAP_LINEAR
  1031. default: D._sampler_filter[0]=GL_LINEAR; break; // or GL_LINEAR_MIPMAP_LINEAR
  1032. }
  1033. switch(D.texFilter())
  1034. {
  1035. case 0: D._sampler_filter[1]=GL_NEAREST; break;
  1036. default: D._sampler_filter[1]=GL_LINEAR ; break; // or GL_LINEAR_MIPMAP_LINEAR
  1037. }
  1038. D._sampler_filter[2]=(D.texMipFilter() ? GL_LINEAR : GL_NEAREST);*/
  1039. D._sampler_address=GL_REPEAT;
  1040. #endif
  1041. }
  1042. void DisplayState::samplerShadow()
  1043. {
  1044. sampler3D(); // we could potentially use a different sampler here with smaller anisotropic value, however quality does suffer (especially with filter=1, so don't go below 2), however performance difference is minimal, so for simplicity just use the default 3D sampler
  1045. }
  1046. void DisplayState::set2D() { D.clipPlane(false); D.wire(false ); D.sampler2D();}
  1047. void DisplayState::set3D() {if(Renderer.mirror())D.clipPlane(true ); D.wire(Renderer.wire); D.sampler3D();}
  1048. /******************************************************************************/
  1049. #if GL
  1050. void DisplayState::fbo(UInt fbo)
  1051. {
  1052. if(D._fbo!=fbo)glBindFramebuffer(GL_FRAMEBUFFER, D._fbo=fbo);
  1053. }
  1054. #endif
  1055. #if IOS
  1056. Bool DisplayState::mainFBO()C
  1057. {
  1058. return Renderer._cur[0]==&Renderer._main || Renderer._cur_ds==&Renderer._main_ds; // check both, because only one of them can be attached
  1059. }
  1060. #endif
  1061. /******************************************************************************/
  1062. void DisplayState::setDeviceSettings()
  1063. {
  1064. sampler2D();
  1065. DisplayState old=T;
  1066. #if DX9
  1067. D3D->SetRenderState(D3DRS_DITHERENABLE , true);
  1068. D3D->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, true);
  1069. D3D->SetRenderState(D3DRS_STENCILFAIL , D3DSTENCILOP_KEEP);
  1070. D3D->SetRenderState(D3DRS_CCW_STENCILFAIL , D3DSTENCILOP_KEEP);
  1071. REP(4)
  1072. {
  1073. D3D->SetSamplerState(D3DVERTEXTEXTURESAMPLER0+i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
  1074. D3D->SetSamplerState(D3DVERTEXTEXTURESAMPLER0+i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
  1075. D3D->SetSamplerState(D3DVERTEXTEXTURESAMPLER0+i, D3DSAMP_ADDRESSU , D3DTADDRESS_WRAP);
  1076. D3D->SetSamplerState(D3DVERTEXTEXTURESAMPLER0+i, D3DSAMP_ADDRESSV , D3DTADDRESS_WRAP);
  1077. D3D->SetSamplerState(D3DVERTEXTEXTURESAMPLER0+i, D3DSAMP_ADDRESSW , D3DTADDRESS_WRAP);
  1078. }
  1079. #elif DX11
  1080. SamplerLinearWrap .set(SSI_DEFAULT); SamplerLinearClamp.setPS(SSI_DEFAULT); // use linear wrap everywhere (needed for example in Vertex Shaders for Water), but use linear clamp for PS as it's the default 2D sampler used everywhere except 3D
  1081. SamplerPoint .set(SSI_POINT);
  1082. SamplerLinearWrap .set(SSI_LINEAR_WRAP);
  1083. SamplerLinearClamp.set(SSI_LINEAR_CLAMP);
  1084. SamplerLinearCWW .set(SSI_LINEAR_CWW);
  1085. SamplerShadowMap .set(SSI_SHADOW);
  1086. SamplerFont .set(SSI_FONT);
  1087. //SPSet("AllowAlphaToCoverage", D.multiSample() || D.densityByte()==255);
  1088. #elif GL
  1089. glEnable (GL_DITHER);
  1090. #if GL_ES
  1091. glClearDepthf(REVERSE_DEPTH ? 0.0f : 1.0f);
  1092. #else
  1093. glClearDepth (REVERSE_DEPTH ? 0.0 : 1.0);
  1094. //glAlphaFunc (GL_GREATER, 0);
  1095. glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
  1096. #endif
  1097. #if !IOS
  1098. if(DepthReal)glEnable (GL_DEPTH_TEST);else glDisable(GL_DEPTH_TEST);
  1099. glColorMask(FlagTest(Col0WriteReal, COL_WRITE_R), FlagTest(Col0WriteReal, COL_WRITE_G), FlagTest(Col0WriteReal, COL_WRITE_B), FlagTest(Col0WriteReal, COL_WRITE_A));
  1100. #endif
  1101. #endif
  1102. _vf=null;
  1103. _depth ^=1; depth (old._depth );
  1104. _depth_write^=1; depthWrite(old._depth_write);
  1105. _depth_func ^=1; depthFunc (old._depth_func );
  1106. _line_smooth^=1; lineSmooth(!_line_smooth);
  1107. _wire ^=1; wire (!_wire );
  1108. _cull ^=1; cull (!_cull );
  1109. _bias ^= 1 ; bias ((BIAS_MODE)old._bias );
  1110. _alpha =ALPHA_MODE(_alpha^1); alpha ( old._alpha );
  1111. _alpha_factor.r^= 1 ; alphaFactor( old._alpha_factor);
  1112. _clip_recti.set(0, -1);
  1113. _clip ^=1; clip (old._clip ? &old._clip_rect : null);
  1114. _clip_allow^=1; clipAllow(old._clip_allow);
  1115. _col_write[0]^=1; colWrite(old._col_write[0], 0);
  1116. _col_write[1]^=1; colWrite(old._col_write[1], 1);
  1117. _col_write[2]^=1; colWrite(old._col_write[2], 2);
  1118. _col_write[3]^=1; colWrite(old._col_write[3], 3);
  1119. _viewport.set(0, -1); viewport(old._viewport);
  1120. stencil ( STENCIL_ALWAYS_SET ); // required for DX9 and GL because of 'LastStencilMode'
  1121. stencil ( STENCIL_TERRAIN_TEST );
  1122. stencil ((STENCIL_MODE)old._stencil );
  1123. _stencil_ref^=1; stencilRef( old._stencil_ref);
  1124. clearShader();
  1125. }
  1126. /******************************************************************************/
  1127. void DisplayState::del()
  1128. {
  1129. #if DX11
  1130. REPAO(BS).del();
  1131. REPAD(i, DS)REPAD(j, DS[i])REPAD(k, DS[i][j])REPAOD(l, DS[i][j][k]).del();
  1132. REPAD(i, RS)REPAD(j, RS[i])REPAD(k, RS[i][j])REPAD (l, RS[i][j][k])REPAOD(m, RS[i][j][k][l]).del();
  1133. #endif
  1134. }
  1135. void DisplayState::create()
  1136. {
  1137. if(LogInit)LogN("DisplayState.create");
  1138. clearShader();
  1139. #if DX9
  1140. AllowLineSmooth=!Contains(D.deviceName(), "Intel", false, true); // Intel produces "fat" lines on DX9
  1141. #elif DX11
  1142. {
  1143. D3D11_BLEND_DESC desc; Zero(desc);
  1144. desc.AlphaToCoverageEnable =false;
  1145. desc.IndependentBlendEnable=false;
  1146. desc.RenderTarget[0].BlendEnable=false;
  1147. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1148. BS[ALPHA_NONE].create(desc);
  1149. }
  1150. {
  1151. D3D11_BLEND_DESC desc; Zero(desc);
  1152. desc.AlphaToCoverageEnable =false;
  1153. desc.IndependentBlendEnable=false;
  1154. desc.RenderTarget[0].BlendEnable =true;
  1155. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1156. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_SRC_ALPHA;
  1157. desc.RenderTarget[0].DestBlend =D3D11_BLEND_INV_SRC_ALPHA;
  1158. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_INV_DEST_ALPHA;
  1159. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ONE;
  1160. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1161. BS[ALPHA_BLEND].create(desc);
  1162. }
  1163. {
  1164. D3D11_BLEND_DESC desc; Zero(desc);
  1165. desc.AlphaToCoverageEnable =false;
  1166. desc.IndependentBlendEnable=false;
  1167. desc.RenderTarget[0].BlendEnable =true;
  1168. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1169. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_SRC_ALPHA;
  1170. desc.RenderTarget[0].DestBlend =D3D11_BLEND_INV_SRC_ALPHA;
  1171. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ZERO;
  1172. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_INV_SRC_ALPHA;
  1173. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1174. BS[ALPHA_BLEND_DEC].create(desc);
  1175. }
  1176. {
  1177. D3D11_BLEND_DESC desc; Zero(desc);
  1178. desc.AlphaToCoverageEnable =false;
  1179. desc.IndependentBlendEnable=false;
  1180. desc.RenderTarget[0].BlendEnable=true;
  1181. desc.RenderTarget[0]. BlendOp=desc.RenderTarget[0]. BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1182. desc.RenderTarget[0]. SrcBlend=desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ONE;
  1183. desc.RenderTarget[0].DestBlend=desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ONE;
  1184. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1185. BS[ALPHA_ADD].create(desc);
  1186. }
  1187. {
  1188. D3D11_BLEND_DESC desc; Zero(desc);
  1189. desc.AlphaToCoverageEnable =false;
  1190. desc.IndependentBlendEnable=false;
  1191. desc.RenderTarget[0].BlendEnable=true;
  1192. desc.RenderTarget[0]. BlendOp=desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1193. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_DEST_COLOR;
  1194. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_DEST_ALPHA;
  1195. desc.RenderTarget[0].DestBlend =desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ZERO;
  1196. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1197. BS[ALPHA_MUL].create(desc);
  1198. }
  1199. {
  1200. D3D11_BLEND_DESC desc; Zero(desc);
  1201. desc.AlphaToCoverageEnable =false;
  1202. desc.IndependentBlendEnable=false;
  1203. desc.RenderTarget[0].BlendEnable =true;
  1204. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1205. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_ONE;
  1206. desc.RenderTarget[0].DestBlend =D3D11_BLEND_INV_SRC_ALPHA;
  1207. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_INV_DEST_ALPHA;
  1208. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ONE;
  1209. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1210. BS[ALPHA_MERGE].create(desc);
  1211. }
  1212. {
  1213. D3D11_BLEND_DESC desc; Zero(desc);
  1214. desc.AlphaToCoverageEnable =false;
  1215. desc.IndependentBlendEnable=false;
  1216. desc.RenderTarget[0].BlendEnable=true;
  1217. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1218. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_SRC_ALPHA;
  1219. desc.RenderTarget[0].DestBlend =D3D11_BLEND_ONE ;
  1220. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ZERO;
  1221. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ONE ;
  1222. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1223. BS[ALPHA_ADDBLEND_KEEP].create(desc);
  1224. }
  1225. {
  1226. D3D11_BLEND_DESC desc; Zero(desc);
  1227. desc.AlphaToCoverageEnable =false;
  1228. desc.IndependentBlendEnable=false;
  1229. desc.RenderTarget[0].BlendEnable=true;
  1230. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1231. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_ONE ;
  1232. desc.RenderTarget[0].DestBlend =D3D11_BLEND_ONE ;
  1233. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ZERO;
  1234. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ONE ;
  1235. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1236. BS[ALPHA_ADD_KEEP].create(desc);
  1237. }
  1238. {
  1239. D3D11_BLEND_DESC desc; Zero(desc);
  1240. desc.AlphaToCoverageEnable =false;
  1241. desc.IndependentBlendEnable=false;
  1242. desc.RenderTarget[0].BlendEnable=true;
  1243. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1244. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_SRC_ALPHA ;
  1245. desc.RenderTarget[0].DestBlend =D3D11_BLEND_INV_SRC_ALPHA;
  1246. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_BLEND_FACTOR ;
  1247. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_INV_SRC_ALPHA;
  1248. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1249. BS[ALPHA_BLEND_FACTOR].create(desc);
  1250. }
  1251. {
  1252. D3D11_BLEND_DESC desc; Zero(desc);
  1253. desc.AlphaToCoverageEnable =false;
  1254. desc.IndependentBlendEnable=false;
  1255. desc.RenderTarget[0].BlendEnable=true;
  1256. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1257. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_ONE;
  1258. desc.RenderTarget[0].DestBlend =D3D11_BLEND_ONE;
  1259. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_BLEND_FACTOR;
  1260. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ONE;
  1261. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1262. BS[ALPHA_ADD_FACTOR].create(desc);
  1263. }
  1264. {
  1265. D3D11_BLEND_DESC desc; Zero(desc);
  1266. desc.AlphaToCoverageEnable =false;
  1267. desc.IndependentBlendEnable=false;
  1268. desc.RenderTarget[0].BlendEnable=true;
  1269. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1270. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_SRC_ALPHA;
  1271. desc.RenderTarget[0].DestBlend =D3D11_BLEND_ZERO;
  1272. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ONE;
  1273. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ZERO;
  1274. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1275. BS[ALPHA_SETBLEND_SET].create(desc);
  1276. }
  1277. {
  1278. D3D11_BLEND_DESC desc; Zero(desc);
  1279. desc.AlphaToCoverageEnable =false;
  1280. desc.IndependentBlendEnable=false;
  1281. desc.RenderTarget[0].BlendEnable=true;
  1282. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1283. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_BLEND_FACTOR;
  1284. desc.RenderTarget[0].DestBlend =D3D11_BLEND_INV_BLEND_FACTOR;
  1285. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_BLEND_FACTOR;
  1286. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_INV_BLEND_FACTOR;
  1287. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1288. BS[ALPHA_FACTOR].create(desc);
  1289. }
  1290. {
  1291. D3D11_BLEND_DESC desc; Zero(desc);
  1292. desc.AlphaToCoverageEnable =false;
  1293. desc.IndependentBlendEnable=false;
  1294. desc.RenderTarget[0].BlendEnable=true;
  1295. desc.RenderTarget[0]. BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1296. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_INV_DEST_COLOR;
  1297. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_INV_DEST_ALPHA;
  1298. desc.RenderTarget[0].DestBlend =desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ZERO;
  1299. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1300. BS[ALPHA_INVERT].create(desc);
  1301. }
  1302. {
  1303. D3D11_BLEND_DESC desc; Zero(desc);
  1304. desc.AlphaToCoverageEnable =false;
  1305. desc.IndependentBlendEnable=false;
  1306. desc.RenderTarget[0].BlendEnable=true;
  1307. desc.RenderTarget[0]. BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1308. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_BLEND_FACTOR;
  1309. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_BLEND_FACTOR;
  1310. desc.RenderTarget[0].DestBlend =D3D11_BLEND_INV_SRC_COLOR;
  1311. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_INV_SRC_ALPHA;
  1312. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1313. BS[ALPHA_FONT].create(desc);
  1314. }
  1315. {
  1316. D3D11_BLEND_DESC desc; Zero(desc);
  1317. desc.AlphaToCoverageEnable =false;
  1318. desc.IndependentBlendEnable=false;
  1319. desc.RenderTarget[0].BlendEnable=true;
  1320. desc.RenderTarget[0]. BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1321. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_BLEND_FACTOR;
  1322. desc.RenderTarget[0].DestBlend =D3D11_BLEND_INV_SRC_COLOR;
  1323. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ZERO;
  1324. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_INV_SRC_ALPHA;
  1325. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1326. BS[ALPHA_FONT_DEC].create(desc);
  1327. }
  1328. /*{
  1329. D3D11_BLEND_DESC desc; Zero(desc);
  1330. desc.AlphaToCoverageEnable =false;
  1331. desc.IndependentBlendEnable=false;
  1332. desc.RenderTarget[0].BlendEnable=false;
  1333. desc.RenderTarget[0].RenderTargetWriteMask=0;
  1334. BS[ALPHA_NULL].create(desc);
  1335. }*/
  1336. /*{
  1337. D3D11_BLEND_DESC desc; Zero(desc);
  1338. desc.AlphaToCoverageEnable =false;
  1339. desc.IndependentBlendEnable=false;
  1340. desc.RenderTarget[0].BlendEnable=false;
  1341. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALPHA;
  1342. BS[ALPHA_NONE_WRITE_A].create(desc);
  1343. }*/
  1344. /*{
  1345. D3D11_BLEND_DESC desc; Zero(desc);
  1346. desc.AlphaToCoverageEnable =false;
  1347. desc.IndependentBlendEnable=false;
  1348. desc.RenderTarget[0].BlendEnable=false;
  1349. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_RED|D3D11_COLOR_WRITE_ENABLE_GREEN|D3D11_COLOR_WRITE_ENABLE_BLUE;
  1350. BS[ALPHA_NONE_WRITE_RGB].create(desc);
  1351. }*/
  1352. /*{
  1353. D3D11_BLEND_DESC desc; Zero(desc);
  1354. desc.AlphaToCoverageEnable =true;
  1355. desc.IndependentBlendEnable=true;
  1356. REPAO(desc.RenderTarget ).BlendEnable=false;
  1357. REPAO(desc.RenderTarget ).RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1358. desc.RenderTarget[0].BlendEnable=true;
  1359. desc.RenderTarget[0].BlendOp=desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1360. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_ONE ;
  1361. desc.RenderTarget[0].DestBlend =D3D11_BLEND_ZERO;
  1362. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ZERO;
  1363. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ZERO;
  1364. BS[ALPHA_NONE_COVERAGE].create(desc);
  1365. }*/
  1366. /*{
  1367. D3D11_BLEND_DESC desc; Zero(desc);
  1368. desc.AlphaToCoverageEnable =true;
  1369. desc.IndependentBlendEnable=true;
  1370. REPAO(desc.RenderTarget ).BlendEnable=false;
  1371. REPAO(desc.RenderTarget ).RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1372. desc.RenderTarget[0].BlendEnable=true;
  1373. desc.RenderTarget[0].BlendOp=desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1374. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_ONE ;
  1375. desc.RenderTarget[0].DestBlend =D3D11_BLEND_ONE ;
  1376. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ZERO;
  1377. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ONE ;
  1378. BS[ALPHA_ADD_COVERAGE].create(desc);
  1379. }*/
  1380. {
  1381. D3D11_BLEND_DESC desc; Zero(desc);
  1382. desc.AlphaToCoverageEnable =false;
  1383. desc.IndependentBlendEnable=false;
  1384. desc.RenderTarget[0].BlendEnable=true;
  1385. desc.RenderTarget[0].BlendOp =desc.RenderTarget[0].BlendOpAlpha=D3D11_BLEND_OP_ADD;
  1386. desc.RenderTarget[0]. SrcBlend =D3D11_BLEND_ONE ;
  1387. desc.RenderTarget[0].DestBlend =D3D11_BLEND_ZERO;
  1388. desc.RenderTarget[0]. SrcBlendAlpha=D3D11_BLEND_ONE ;
  1389. desc.RenderTarget[0].DestBlendAlpha=D3D11_BLEND_ONE ;
  1390. desc.RenderTarget[0].RenderTargetWriteMask=D3D11_COLOR_WRITE_ENABLE_ALL;
  1391. BS[ALPHA_NONE_ADD].create(desc);
  1392. }
  1393. // depth stencil state
  1394. REPD(stencil , STENCIL_NUM)
  1395. REPD(depth_use , 2)
  1396. REPD(depth_write, 2)
  1397. REPD(depth_func , 8)
  1398. {
  1399. D3D11_DEPTH_STENCIL_DESC desc; Zero(desc);
  1400. desc.DepthEnable =depth_use;
  1401. desc.DepthWriteMask =(depth_write ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO);
  1402. desc.DepthFunc =D3D11_COMPARISON_FUNC(D3D11_COMPARISON_FIRST+depth_func);
  1403. desc.StencilEnable =(stencil!=STENCIL_NONE);
  1404. desc.StencilReadMask =D3D11_DEFAULT_STENCIL_READ_MASK;
  1405. desc.StencilWriteMask=D3D11_DEFAULT_STENCIL_WRITE_MASK;
  1406. desc.FrontFace.StencilFailOp=desc.BackFace.StencilFailOp=D3D11_STENCIL_OP_KEEP;
  1407. switch(stencil)
  1408. {
  1409. case STENCIL_ALWAYS_SET:
  1410. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_ALWAYS;
  1411. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1412. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1413. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1414. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1415. break;
  1416. case STENCIL_TERRAIN_TEST:
  1417. desc.StencilReadMask =STENCIL_REF_TERRAIN;
  1418. desc.StencilWriteMask =0;
  1419. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_EQUAL;
  1420. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1421. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1422. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1423. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1424. break;
  1425. case STENCIL_MSAA_SET:
  1426. desc.StencilReadMask =STENCIL_REF_MSAA;
  1427. desc.StencilWriteMask=STENCIL_REF_MSAA;
  1428. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_ALWAYS;
  1429. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1430. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1431. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1432. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1433. break;
  1434. case STENCIL_MSAA_TEST:
  1435. desc.StencilReadMask =STENCIL_REF_MSAA;
  1436. desc.StencilWriteMask=0;
  1437. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_EQUAL;
  1438. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1439. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1440. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1441. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1442. break;
  1443. case STENCIL_EDGE_SOFT_SET:
  1444. desc.StencilReadMask =STENCIL_REF_EDGE_SOFT;
  1445. desc.StencilWriteMask=STENCIL_REF_EDGE_SOFT;
  1446. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_ALWAYS;
  1447. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1448. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1449. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1450. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1451. break;
  1452. case STENCIL_EDGE_SOFT_TEST:
  1453. desc.StencilReadMask =STENCIL_REF_EDGE_SOFT;
  1454. desc.StencilWriteMask=0;
  1455. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_EQUAL;
  1456. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1457. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1458. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1459. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1460. break;
  1461. case STENCIL_WATER_SET:
  1462. desc.StencilReadMask =STENCIL_REF_WATER;
  1463. desc.StencilWriteMask=STENCIL_REF_WATER;
  1464. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_ALWAYS;
  1465. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1466. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1467. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1468. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1469. break;
  1470. case STENCIL_WATER_TEST:
  1471. desc.StencilReadMask =STENCIL_REF_WATER;
  1472. desc.StencilWriteMask=0;
  1473. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_EQUAL;
  1474. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1475. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1476. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1477. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1478. break;
  1479. case STENCIL_OUTLINE_SET:
  1480. desc.StencilReadMask =STENCIL_REF_OUTLINE;
  1481. desc.StencilWriteMask=STENCIL_REF_OUTLINE;
  1482. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_ALWAYS;
  1483. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1484. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_REPLACE;
  1485. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1486. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1487. break;
  1488. case STENCIL_OUTLINE_TEST:
  1489. desc.StencilReadMask =STENCIL_REF_OUTLINE;
  1490. desc.StencilWriteMask=0;
  1491. desc.FrontFace.StencilFunc=desc.BackFace.StencilFunc=D3D11_COMPARISON_EQUAL;
  1492. desc.FrontFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1493. desc. BackFace.StencilPassOp =D3D11_STENCIL_OP_KEEP;
  1494. desc.FrontFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1495. desc. BackFace.StencilDepthFailOp=D3D11_STENCIL_OP_KEEP;
  1496. break;
  1497. }
  1498. DS[stencil][depth_use][depth_write][depth_func].create(desc);
  1499. }
  1500. REPD(cull, 3)
  1501. REPD(bias, BIAS_NUM)
  1502. REPD(line, 2)
  1503. REPD(wire, 2)
  1504. REPD(clip, 2)
  1505. {
  1506. D3D11_RASTERIZER_DESC desc; Zero(desc);
  1507. desc.FillMode =(wire ? D3D11_FILL_WIREFRAME : D3D11_FILL_SOLID);
  1508. desc.CullMode =((cull==0) ? D3D11_CULL_NONE : (cull==1) ? D3D11_CULL_BACK : D3D11_CULL_FRONT);
  1509. desc.ScissorEnable =clip;
  1510. desc.DepthClipEnable=true;
  1511. if(D.shaderModel()>=SM_4_1) // in 4.1 following members affect only lines
  1512. {
  1513. desc.MultisampleEnable =false;
  1514. desc.AntialiasedLineEnable=line ;
  1515. }else // let on 4.0 smooth lines be always disabled
  1516. {
  1517. desc.MultisampleEnable =true ; // for smooth lines this should be false (but let's not bother with additional state combination only for smooth lines on 4.0)
  1518. desc.AntialiasedLineEnable=false;
  1519. }
  1520. switch(bias)
  1521. {
  1522. case BIAS_ZERO : desc.DepthBias= 0; desc.SlopeScaledDepthBias= 0; break;
  1523. case BIAS_SHADOW : desc.DepthBias=DEPTH_BIAS_SHADOW ; desc.SlopeScaledDepthBias=SLOPE_SCALED_DEPTH_BIAS_SHADOW ; break;
  1524. case BIAS_OVERLAY: desc.DepthBias=DEPTH_BIAS_OVERLAY; desc.SlopeScaledDepthBias=SLOPE_SCALED_DEPTH_BIAS_OVERLAY; break;
  1525. }
  1526. RS[cull][bias][line][wire][clip].create(desc);
  1527. }
  1528. #endif
  1529. }
  1530. /******************************************************************************/
  1531. }
  1532. /******************************************************************************/