Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

807 lines
24 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #define DISABLE_PROTECTED_THINGS
  9. #include "togl/rendermechanism.h"
  10. #include "shadershadowdx8.h"
  11. #include "locald3dtypes.h"
  12. #include "utlvector.h"
  13. #include "shaderapi/ishaderutil.h"
  14. #include "shaderapidx8_global.h"
  15. #include "shaderapidx8.h"
  16. #include "materialsystem/imaterialsystemhardwareconfig.h"
  17. #include "materialsystem/imaterialsystem.h"
  18. #include "imeshdx8.h"
  19. #include "materialsystem/materialsystem_config.h"
  20. #include "vertexshaderdx8.h"
  21. // NOTE: This must be the last file included!
  22. #include "tier0/memdbgon.h"
  23. //-----------------------------------------------------------------------------
  24. // The DX8 implementation of the shader setup interface
  25. //-----------------------------------------------------------------------------
  26. class CShaderShadowDX8 : public IShaderShadowDX8
  27. {
  28. public:
  29. // constructor, destructor
  30. CShaderShadowDX8( );
  31. virtual ~CShaderShadowDX8();
  32. // Initialize render state
  33. void Init( );
  34. // Sets the default state
  35. void SetDefaultState();
  36. // Methods related to depth buffering
  37. void DepthFunc( ShaderDepthFunc_t depthFunc );
  38. void EnableDepthWrites( bool bEnable );
  39. void EnableDepthTest( bool bEnable );
  40. void EnablePolyOffset( PolygonOffsetMode_t nOffsetMode );
  41. // Suppresses/activates color writing
  42. void EnableColorWrites( bool bEnable );
  43. void EnableAlphaWrites( bool bEnable );
  44. // Methods related to alpha blending
  45. void EnableBlending( bool bEnable );
  46. void EnableBlendingForceOpaque( bool bEnable );
  47. void BlendFunc( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor );
  48. void BlendOp( ShaderBlendOp_t blendOp );
  49. void EnableBlendingSeparateAlpha( bool bEnable );
  50. void BlendFuncSeparateAlpha( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor );
  51. void BlendOpSeparateAlpha( ShaderBlendOp_t blendOp );
  52. // Alpha testing
  53. void EnableAlphaTest( bool bEnable );
  54. void AlphaFunc( ShaderAlphaFunc_t alphaFunc, float alphaRef /* [0-1] */ );
  55. // Wireframe/filled polygons
  56. void PolyMode( ShaderPolyModeFace_t face, ShaderPolyMode_t polyMode );
  57. // Back face culling
  58. void EnableCulling( bool bEnable );
  59. // Convert from linear to gamma color space on writes to frame buffer.
  60. void EnableSRGBWrite( bool bEnable );
  61. // Convert from gamma to linear on texture fetch.
  62. void EnableSRGBRead( Sampler_t stage, bool bEnable );
  63. // Set up appropriate shadow filtering state (such as Fetch4 on ATI)
  64. //void SetShadowDepthFiltering( Sampler_t stage );
  65. // Computes the vertex format
  66. virtual void VertexShaderVertexFormat( unsigned int nFlags,
  67. int nTexCoordCount, int* pTexCoordDimensions, int nUserDataSize );
  68. // Pixel and vertex shader methods
  69. virtual void SetVertexShader( const char* pFileName, int nStaticVshIndex );
  70. virtual void SetPixelShader( const char* pFileName, int nStaticPshIndex );
  71. // Per texture unit stuff
  72. void EnableTexture( Sampler_t stage, bool bEnable );
  73. void EnableVertexTexture( VertexTextureSampler_t sampler, bool bEnable );
  74. // Last call to be make before snapshotting
  75. void ComputeAggregateShadowState( );
  76. // Gets at the shadow state
  77. const ShadowState_t & GetShadowState();
  78. const ShadowShaderState_t & GetShadowShaderState();
  79. void FogMode( ShaderFogMode_t fogMode, bool bVertexFog );
  80. void DisableFogGammaCorrection( bool bDisable );
  81. // Alpha to coverage
  82. void EnableAlphaToCoverage( bool bEnable );
  83. virtual float GetLightMapScaleFactor( void ) const;
  84. private:
  85. struct SamplerState_t
  86. {
  87. bool m_TextureEnable : 1;
  88. };
  89. // Computes the blend factor
  90. D3DBLEND BlendFuncValue( ShaderBlendFactor_t factor ) const;
  91. // Computes the blend op
  92. D3DBLENDOP BlendOpValue( ShaderBlendOp_t blendOp ) const;
  93. // Configures our texture indices
  94. void ConfigureTextureCoordinates( unsigned int flags );
  95. // returns true if we're using texture coordinates at a given stage
  96. bool IsUsingTextureCoordinates( Sampler_t stage ) const;
  97. // State needed to create the snapshots
  98. IMaterialSystemHardwareConfig* m_pHardwareConfig;
  99. // Alpha blending...
  100. D3DBLEND m_SrcBlend;
  101. D3DBLEND m_DestBlend;
  102. D3DBLENDOP m_BlendOp;
  103. // Separate alpha blending...
  104. D3DBLEND m_SrcBlendAlpha;
  105. D3DBLEND m_DestBlendAlpha;
  106. D3DBLENDOP m_BlendOpAlpha;
  107. // Alpha testing
  108. D3DCMPFUNC m_AlphaFunc;
  109. int m_AlphaRef;
  110. // The current shadow state
  111. ShadowState_t m_ShadowState;
  112. ShadowShaderState_t m_ShadowShaderState;
  113. // State info stores with each sampler stage
  114. SamplerState_t m_SamplerState[MAX_SAMPLERS];
  115. SamplerState_t m_VertexSamplerState[MAX_VERTEX_SAMPLERS];
  116. };
  117. //-----------------------------------------------------------------------------
  118. // Class factory
  119. //-----------------------------------------------------------------------------
  120. static CShaderShadowDX8 g_ShaderShadow;
  121. IShaderShadowDX8 *g_pShaderShadowDx8 = &g_ShaderShadow;
  122. EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CShaderShadowDX8, IShaderShadow,
  123. SHADERSHADOW_INTERFACE_VERSION, g_ShaderShadow )
  124. //-----------------------------------------------------------------------------
  125. // Global instance
  126. //-----------------------------------------------------------------------------
  127. IShaderShadowDX8* ShaderShadow()
  128. {
  129. return &g_ShaderShadow;
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Constructor, destructor
  133. //-----------------------------------------------------------------------------
  134. CShaderShadowDX8::CShaderShadowDX8( ) : m_pHardwareConfig(0)
  135. {
  136. memset( &m_ShadowState, 0, sizeof(m_ShadowState) );
  137. }
  138. CShaderShadowDX8::~CShaderShadowDX8()
  139. {
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Initialize render state
  143. //-----------------------------------------------------------------------------
  144. void CShaderShadowDX8::Init( )
  145. {
  146. m_pHardwareConfig = g_pHardwareConfig;
  147. // Clear out the shadow state
  148. memset( &m_ShadowState, 0, sizeof(m_ShadowState) );
  149. m_ShadowState.m_FogAndMiscState.m_bDisableFogGammaCorrection = false;
  150. // Pixel + vertex shaders
  151. m_ShadowShaderState.m_VertexShader = INVALID_SHADER;
  152. m_ShadowShaderState.m_PixelShader = INVALID_SHADER;
  153. m_ShadowShaderState.m_nStaticPshIndex = 0;
  154. m_ShadowShaderState.m_nStaticVshIndex = 0;
  155. m_ShadowShaderState.m_VertexUsage = 0;
  156. m_ShadowState.m_nFetch4Enable = 0;
  157. #if ( defined ( DX_TO_GL_ABSTRACTION ) )
  158. m_ShadowState.m_nShadowFilterEnable = 0;
  159. #endif
  160. for (int i = 0; i < MAX_SAMPLERS; ++i)
  161. {
  162. // A *real* measure if the texture stage is being used.
  163. // we sometimes have to set the shadow state to not mirror this.
  164. m_SamplerState[i].m_TextureEnable = false;
  165. }
  166. }
  167. //-----------------------------------------------------------------------------
  168. // Sets the default state
  169. //-----------------------------------------------------------------------------
  170. void CShaderShadowDX8::SetDefaultState()
  171. {
  172. DepthFunc( SHADER_DEPTHFUNC_NEAREROREQUAL );
  173. EnableDepthWrites( true );
  174. EnableDepthTest( true );
  175. EnableColorWrites( true );
  176. EnableAlphaWrites( false );
  177. EnableAlphaTest( false );
  178. EnableBlending( false );
  179. BlendFunc( SHADER_BLEND_ZERO, SHADER_BLEND_ZERO );
  180. BlendOp( SHADER_BLEND_OP_ADD );
  181. EnableBlendingSeparateAlpha( false );
  182. BlendFuncSeparateAlpha( SHADER_BLEND_ZERO, SHADER_BLEND_ZERO );
  183. BlendOpSeparateAlpha( SHADER_BLEND_OP_ADD );
  184. AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, 0.7f );
  185. PolyMode( SHADER_POLYMODEFACE_FRONT_AND_BACK, SHADER_POLYMODE_FILL );
  186. EnableCulling( true );
  187. EnableAlphaToCoverage( false );
  188. EnablePolyOffset( SHADER_POLYOFFSET_DISABLE );
  189. EnableSRGBWrite( false );
  190. SetVertexShader( NULL, 0 );
  191. SetPixelShader( NULL, 0 );
  192. FogMode( SHADER_FOGMODE_DISABLED, false );
  193. DisableFogGammaCorrection( false );
  194. m_ShadowShaderState.m_VertexUsage = 0;
  195. int i;
  196. int nSamplerCount = HardwareConfig()->GetSamplerCount();
  197. for( i = 0; i < nSamplerCount; i++ )
  198. {
  199. EnableTexture( (Sampler_t)i, false );
  200. EnableSRGBRead( (Sampler_t)i, false );
  201. }
  202. }
  203. //-----------------------------------------------------------------------------
  204. // Gets at the shadow state
  205. //-----------------------------------------------------------------------------
  206. const ShadowState_t &CShaderShadowDX8::GetShadowState()
  207. {
  208. return m_ShadowState;
  209. }
  210. const ShadowShaderState_t &CShaderShadowDX8::GetShadowShaderState()
  211. {
  212. return m_ShadowShaderState;
  213. }
  214. //-----------------------------------------------------------------------------
  215. // Depth functions...
  216. //-----------------------------------------------------------------------------
  217. void CShaderShadowDX8::DepthFunc( ShaderDepthFunc_t depthFunc )
  218. {
  219. D3DCMPFUNC zFunc;
  220. switch( depthFunc )
  221. {
  222. case SHADER_DEPTHFUNC_NEVER:
  223. zFunc = D3DCMP_NEVER;
  224. break;
  225. case SHADER_DEPTHFUNC_NEARER:
  226. zFunc = (ShaderUtil()->GetConfig().bReverseDepth ^ ReverseDepthOnX360()) ? D3DCMP_GREATER : D3DCMP_LESS;
  227. break;
  228. case SHADER_DEPTHFUNC_EQUAL:
  229. zFunc = D3DCMP_EQUAL;
  230. break;
  231. case SHADER_DEPTHFUNC_NEAREROREQUAL:
  232. zFunc = (ShaderUtil()->GetConfig().bReverseDepth ^ ReverseDepthOnX360()) ? D3DCMP_GREATEREQUAL : D3DCMP_LESSEQUAL;
  233. break;
  234. case SHADER_DEPTHFUNC_FARTHER:
  235. zFunc = (ShaderUtil()->GetConfig().bReverseDepth ^ ReverseDepthOnX360()) ? D3DCMP_LESS : D3DCMP_GREATER;
  236. break;
  237. case SHADER_DEPTHFUNC_NOTEQUAL:
  238. zFunc = D3DCMP_NOTEQUAL;
  239. break;
  240. case SHADER_DEPTHFUNC_FARTHEROREQUAL:
  241. zFunc = (ShaderUtil()->GetConfig().bReverseDepth ^ ReverseDepthOnX360()) ? D3DCMP_LESSEQUAL : D3DCMP_GREATEREQUAL;
  242. break;
  243. case SHADER_DEPTHFUNC_ALWAYS:
  244. zFunc = D3DCMP_ALWAYS;
  245. break;
  246. default:
  247. zFunc = D3DCMP_ALWAYS;
  248. Warning( "DepthFunc: invalid param\n" );
  249. break;
  250. }
  251. m_ShadowState.m_DepthTestState.m_ZFunc = zFunc;
  252. }
  253. void CShaderShadowDX8::EnableDepthWrites( bool bEnable )
  254. {
  255. m_ShadowState.m_DepthTestState.m_ZWriteEnable = bEnable;
  256. }
  257. void CShaderShadowDX8::EnableDepthTest( bool bEnable )
  258. {
  259. m_ShadowState.m_DepthTestState.m_ZEnable = bEnable ? D3DZB_TRUE : D3DZB_FALSE;
  260. }
  261. void CShaderShadowDX8::EnablePolyOffset( PolygonOffsetMode_t nOffsetMode )
  262. {
  263. m_ShadowState.m_DepthTestState.m_ZBias = nOffsetMode;
  264. }
  265. //-----------------------------------------------------------------------------
  266. // Color write state
  267. //-----------------------------------------------------------------------------
  268. void CShaderShadowDX8::EnableColorWrites( bool bEnable )
  269. {
  270. if (bEnable)
  271. {
  272. m_ShadowState.m_DepthTestState.m_ColorWriteEnable |= D3DCOLORWRITEENABLE_BLUE |
  273. D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED;
  274. }
  275. else
  276. {
  277. m_ShadowState.m_DepthTestState.m_ColorWriteEnable &= ~( D3DCOLORWRITEENABLE_BLUE |
  278. D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED );
  279. }
  280. }
  281. void CShaderShadowDX8::EnableAlphaWrites( bool bEnable )
  282. {
  283. if (bEnable)
  284. {
  285. m_ShadowState.m_DepthTestState.m_ColorWriteEnable |= D3DCOLORWRITEENABLE_ALPHA;
  286. }
  287. else
  288. {
  289. m_ShadowState.m_DepthTestState.m_ColorWriteEnable &= ~D3DCOLORWRITEENABLE_ALPHA;
  290. }
  291. }
  292. //-----------------------------------------------------------------------------
  293. // Alpha blending states
  294. //-----------------------------------------------------------------------------
  295. void CShaderShadowDX8::EnableBlending( bool bEnable )
  296. {
  297. m_ShadowState.m_AlphaBlendState.m_AlphaBlendEnable = bEnable;
  298. m_ShadowState.m_AlphaBlendState.m_AlphaBlendEnabledForceOpaque = false;
  299. }
  300. void CShaderShadowDX8::EnableBlendingForceOpaque( bool bEnable )
  301. {
  302. m_ShadowState.m_AlphaBlendState.m_AlphaBlendEnable = bEnable;
  303. m_ShadowState.m_AlphaBlendState.m_AlphaBlendEnabledForceOpaque = true;
  304. }
  305. // Separate alpha blending
  306. void CShaderShadowDX8::EnableBlendingSeparateAlpha( bool bEnable )
  307. {
  308. m_ShadowState.m_AlphaBlendState.m_SeparateAlphaBlendEnable = bEnable;
  309. }
  310. void CShaderShadowDX8::EnableAlphaTest( bool bEnable )
  311. {
  312. m_ShadowState.m_AlphaTestAndMiscState.m_AlphaTestEnable = bEnable;
  313. }
  314. void CShaderShadowDX8::AlphaFunc( ShaderAlphaFunc_t alphaFunc, float alphaRef /* [0-1] */ )
  315. {
  316. D3DCMPFUNC d3dCmpFunc;
  317. switch( alphaFunc )
  318. {
  319. case SHADER_ALPHAFUNC_NEVER:
  320. d3dCmpFunc = D3DCMP_NEVER;
  321. break;
  322. case SHADER_ALPHAFUNC_LESS:
  323. d3dCmpFunc = D3DCMP_LESS;
  324. break;
  325. case SHADER_ALPHAFUNC_EQUAL:
  326. d3dCmpFunc = D3DCMP_EQUAL;
  327. break;
  328. case SHADER_ALPHAFUNC_LEQUAL:
  329. d3dCmpFunc = D3DCMP_LESSEQUAL;
  330. break;
  331. case SHADER_ALPHAFUNC_GREATER:
  332. d3dCmpFunc = D3DCMP_GREATER;
  333. break;
  334. case SHADER_ALPHAFUNC_NOTEQUAL:
  335. d3dCmpFunc = D3DCMP_NOTEQUAL;
  336. break;
  337. case SHADER_ALPHAFUNC_GEQUAL:
  338. d3dCmpFunc = D3DCMP_GREATEREQUAL;
  339. break;
  340. case SHADER_ALPHAFUNC_ALWAYS:
  341. d3dCmpFunc = D3DCMP_ALWAYS;
  342. break;
  343. default:
  344. Warning( "AlphaFunc: invalid param\n" );
  345. return;
  346. }
  347. m_AlphaFunc = d3dCmpFunc;
  348. m_AlphaRef = (int)(alphaRef * 255);
  349. }
  350. D3DBLEND CShaderShadowDX8::BlendFuncValue( ShaderBlendFactor_t factor ) const
  351. {
  352. switch( factor )
  353. {
  354. case SHADER_BLEND_ZERO:
  355. return D3DBLEND_ZERO;
  356. case SHADER_BLEND_ONE:
  357. return D3DBLEND_ONE;
  358. case SHADER_BLEND_DST_COLOR:
  359. return D3DBLEND_DESTCOLOR;
  360. case SHADER_BLEND_ONE_MINUS_DST_COLOR:
  361. return D3DBLEND_INVDESTCOLOR;
  362. case SHADER_BLEND_SRC_ALPHA:
  363. return D3DBLEND_SRCALPHA;
  364. case SHADER_BLEND_ONE_MINUS_SRC_ALPHA:
  365. return D3DBLEND_INVSRCALPHA;
  366. case SHADER_BLEND_DST_ALPHA:
  367. return D3DBLEND_DESTALPHA;
  368. case SHADER_BLEND_ONE_MINUS_DST_ALPHA:
  369. return D3DBLEND_INVDESTALPHA;
  370. case SHADER_BLEND_SRC_ALPHA_SATURATE:
  371. return D3DBLEND_SRCALPHASAT;
  372. case SHADER_BLEND_SRC_COLOR:
  373. return D3DBLEND_SRCCOLOR;
  374. case SHADER_BLEND_ONE_MINUS_SRC_COLOR:
  375. return D3DBLEND_INVSRCCOLOR;
  376. }
  377. Warning( "BlendFunc: invalid factor\n" );
  378. return D3DBLEND_ONE;
  379. }
  380. D3DBLENDOP CShaderShadowDX8::BlendOpValue( ShaderBlendOp_t blendOp ) const
  381. {
  382. switch( blendOp )
  383. {
  384. case SHADER_BLEND_OP_ADD:
  385. return D3DBLENDOP_ADD;
  386. case SHADER_BLEND_OP_SUBTRACT:
  387. return D3DBLENDOP_SUBTRACT;
  388. case SHADER_BLEND_OP_REVSUBTRACT:
  389. return D3DBLENDOP_REVSUBTRACT;
  390. case SHADER_BLEND_OP_MIN:
  391. return D3DBLENDOP_MIN;
  392. case SHADER_BLEND_OP_MAX:
  393. return D3DBLENDOP_MAX;
  394. }
  395. Warning( "BlendOp: invalid op\n" );
  396. return D3DBLENDOP_ADD;
  397. }
  398. void CShaderShadowDX8::BlendFunc( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor )
  399. {
  400. D3DBLEND d3dSrcFactor = BlendFuncValue( srcFactor );
  401. D3DBLEND d3dDstFactor = BlendFuncValue( dstFactor );
  402. m_SrcBlend = d3dSrcFactor;
  403. m_DestBlend = d3dDstFactor;
  404. }
  405. // Separate alpha blending
  406. void CShaderShadowDX8::BlendFuncSeparateAlpha( ShaderBlendFactor_t srcFactor, ShaderBlendFactor_t dstFactor )
  407. {
  408. D3DBLEND d3dSrcFactor = BlendFuncValue( srcFactor );
  409. D3DBLEND d3dDstFactor = BlendFuncValue( dstFactor );
  410. m_SrcBlendAlpha = d3dSrcFactor;
  411. m_DestBlendAlpha = d3dDstFactor;
  412. }
  413. void CShaderShadowDX8::BlendOp( ShaderBlendOp_t blendOp )
  414. {
  415. m_BlendOp = BlendOpValue( blendOp );
  416. }
  417. void CShaderShadowDX8::BlendOpSeparateAlpha( ShaderBlendOp_t blendOp )
  418. {
  419. m_BlendOpAlpha = BlendOpValue( blendOp );
  420. }
  421. //-----------------------------------------------------------------------------
  422. // Polygon fill mode states
  423. //-----------------------------------------------------------------------------
  424. void CShaderShadowDX8::PolyMode( ShaderPolyModeFace_t face, ShaderPolyMode_t polyMode )
  425. {
  426. // DX8 can't handle different modes on front and back faces
  427. // FIXME: Assert( face == SHADER_POLYMODEFACE_FRONT_AND_BACK );
  428. if (face == SHADER_POLYMODEFACE_BACK)
  429. return;
  430. D3DFILLMODE fillMode;
  431. switch( polyMode )
  432. {
  433. case SHADER_POLYMODE_POINT:
  434. fillMode = D3DFILL_POINT;
  435. break;
  436. case SHADER_POLYMODE_LINE:
  437. fillMode = D3DFILL_WIREFRAME;
  438. break;
  439. case SHADER_POLYMODE_FILL:
  440. fillMode = D3DFILL_SOLID;
  441. break;
  442. default:
  443. Warning( "PolyMode: invalid poly mode\n" );
  444. return;
  445. }
  446. m_ShadowState.m_AlphaTestAndMiscState.m_FillMode = fillMode;
  447. }
  448. //-----------------------------------------------------------------------------
  449. // Backface cull states
  450. //-----------------------------------------------------------------------------
  451. void CShaderShadowDX8::EnableCulling( bool bEnable )
  452. {
  453. m_ShadowState.m_AlphaTestAndMiscState.m_CullEnable = bEnable;
  454. }
  455. //-----------------------------------------------------------------------------
  456. // Alpha to coverage
  457. //-----------------------------------------------------------------------------
  458. void CShaderShadowDX8::EnableAlphaToCoverage( bool bEnable )
  459. {
  460. m_ShadowState.m_AlphaTestAndMiscState.m_EnableAlphaToCoverage = bEnable;
  461. }
  462. //-----------------------------------------------------------------------------
  463. // Enables auto-conversion from linear to gamma space on write to framebuffer.
  464. //-----------------------------------------------------------------------------
  465. void CShaderShadowDX8::EnableSRGBWrite( bool bEnable )
  466. {
  467. if ( m_pHardwareConfig->SupportsSRGB() )
  468. {
  469. m_ShadowState.m_FogAndMiscState.m_SRGBWriteEnable = bEnable;
  470. }
  471. else
  472. {
  473. m_ShadowState.m_FogAndMiscState.m_SRGBWriteEnable = false;
  474. }
  475. }
  476. void CShaderShadowDX8::EnableTexture( Sampler_t sampler, bool bEnable )
  477. {
  478. if ( sampler < m_pHardwareConfig->GetSamplerCount() )
  479. {
  480. m_SamplerState[sampler].m_TextureEnable = bEnable;
  481. }
  482. else
  483. {
  484. Warning( "Attempting to bind a texture to an invalid sampler (%d)!\n", sampler );
  485. }
  486. }
  487. void CShaderShadowDX8::EnableVertexTexture( VertexTextureSampler_t vtSampler, bool bEnable )
  488. {
  489. if ( vtSampler < m_pHardwareConfig->GetVertexSamplerCount() )
  490. {
  491. m_VertexSamplerState[vtSampler].m_TextureEnable = bEnable;
  492. }
  493. else
  494. {
  495. Warning( "Attempting to bind a texture to an invalid vertex sampler (%d)!\n", vtSampler );
  496. }
  497. }
  498. void CShaderShadowDX8::EnableSRGBRead( Sampler_t sampler, bool bEnable )
  499. {
  500. }
  501. #if 0
  502. void CShaderShadowDX8::SetShadowDepthFiltering( Sampler_t stage )
  503. {
  504. int nMask = ( 1 << stage );
  505. if ( stage < m_pHardwareConfig->GetSamplerCount() )
  506. {
  507. #if ( defined ( POSIX ) )
  508. // m_ShadowState.m_ShadowFilterEnable |= nMask;
  509. #else
  510. if ( !m_pHardwareConfig->SupportsFetch4() )
  511. {
  512. m_ShadowState.m_nFetch4Enable &= ~nMask;
  513. }
  514. else
  515. {
  516. m_ShadowState.m_nFetch4Enable |= nMask;
  517. }
  518. #endif
  519. }
  520. else
  521. {
  522. Warning( "Attempting set shadow filtering state on an invalid sampler (%d)!\n", stage );
  523. }
  524. }
  525. #endif
  526. //-----------------------------------------------------------------------------
  527. // Compute the vertex format from vertex descriptor flags
  528. //-----------------------------------------------------------------------------
  529. void CShaderShadowDX8::VertexShaderVertexFormat( unsigned int nFlags,
  530. int nTexCoordCount, int* pTexCoordDimensions, int nUserDataSize )
  531. {
  532. // Code that creates a Mesh should specify whether it contains bone weights+indices, *not* the shader.
  533. Assert( ( nFlags & VERTEX_BONE_INDEX ) == 0 );
  534. nFlags &= ~VERTEX_BONE_INDEX;
  535. // This indicates we're using a vertex shader
  536. m_ShadowShaderState.m_VertexUsage = MeshMgr()->ComputeVertexFormat( nFlags, nTexCoordCount,
  537. pTexCoordDimensions, 0, nUserDataSize );
  538. // Avoid an error if vertex stream 0 is too narrow
  539. if ( CVertexBufferBase::VertexFormatSize( m_ShadowShaderState.m_VertexUsage ) <= 16 )
  540. {
  541. // FIXME: this is only necessary because we
  542. // (a) put the flex normal/position stream in ALL vertex decls
  543. // (b) bind stream 0's VB to stream 2 if there is no actual flex data
  544. // ...it would be far more sensible to not add stream 2 to all vertex decls.
  545. static bool bComplained = false;
  546. if( !bComplained )
  547. {
  548. Warning( "ERROR: shader asking for a too-narrow vertex format - you will see errors if running with debug D3D DLLs!\n\tPadding the vertex format with extra texcoords\n\tWill not warn again.\n" );
  549. bComplained = true;
  550. }
  551. // All vertex formats should contain position...
  552. Assert( nFlags & VERTEX_POSITION );
  553. nFlags |= VERTEX_POSITION;
  554. // This error should occur only if we have zero texcoords, or if we have a single, 1-D texcoord
  555. Assert( ( nTexCoordCount == 0 ) ||
  556. ( ( nTexCoordCount == 1 ) && pTexCoordDimensions && ( pTexCoordDimensions[0] == 1 ) ) );
  557. nTexCoordCount = 1;
  558. m_ShadowShaderState.m_VertexUsage = MeshMgr()->ComputeVertexFormat( nFlags, nTexCoordCount, NULL, 0, nUserDataSize );
  559. }
  560. }
  561. //-----------------------------------------------------------------------------
  562. // Pixel and vertex shader methods
  563. //-----------------------------------------------------------------------------
  564. void CShaderShadowDX8::SetVertexShader( const char* pFileName, int nStaticVshIndex )
  565. {
  566. char debugLabel[500] = "";
  567. #ifdef DX_TO_GL_ABSTRACTION
  568. Q_snprintf( debugLabel, sizeof(debugLabel), "vs-file %s vs-index %d", pFileName, nStaticVshIndex );
  569. #endif
  570. m_ShadowShaderState.m_VertexShader = ShaderManager()->CreateVertexShader( pFileName, nStaticVshIndex, debugLabel );
  571. m_ShadowShaderState.m_nStaticVshIndex = nStaticVshIndex;
  572. }
  573. void CShaderShadowDX8::SetPixelShader( const char* pFileName, int nStaticPshIndex )
  574. {
  575. char debugLabel[500] = "";
  576. #ifdef DX_TO_GL_ABSTRACTION
  577. Q_snprintf( debugLabel, sizeof(debugLabel), "ps-file %s ps-index %d", pFileName, nStaticPshIndex );
  578. #endif
  579. m_ShadowShaderState.m_PixelShader = ShaderManager()->CreatePixelShader( pFileName, nStaticPshIndex, debugLabel );
  580. m_ShadowShaderState.m_nStaticPshIndex = nStaticPshIndex;
  581. }
  582. //-----------------------------------------------------------------------------
  583. // Returns the lightmap scale factor
  584. //-----------------------------------------------------------------------------
  585. float CShaderShadowDX8::GetLightMapScaleFactor( void ) const
  586. {
  587. return g_pHardwareConfig->GetLightMapScaleFactor();
  588. }
  589. //-----------------------------------------------------------------------------
  590. // Fog
  591. //-----------------------------------------------------------------------------
  592. void CShaderShadowDX8::FogMode( ShaderFogMode_t fogMode, bool bVertexFog )
  593. {
  594. Assert( fogMode >= 0 && fogMode < SHADER_FOGMODE_NUMFOGMODES );
  595. m_ShadowState.m_FogAndMiscState.m_FogMode = fogMode;
  596. m_ShadowState.m_FogAndMiscState.m_bVertexFogEnable = bVertexFog;
  597. }
  598. void CShaderShadowDX8::DisableFogGammaCorrection( bool bDisable )
  599. {
  600. m_ShadowState.m_FogAndMiscState.m_bDisableFogGammaCorrection = bDisable;
  601. }
  602. //-----------------------------------------------------------------------------
  603. // NOTE: See Version 5 of this file for NVidia 8-stage shader stuff
  604. //-----------------------------------------------------------------------------
  605. inline bool CShaderShadowDX8::IsUsingTextureCoordinates( Sampler_t sampler ) const
  606. {
  607. return m_SamplerState[sampler].m_TextureEnable;
  608. }
  609. //-----------------------------------------------------------------------------
  610. // Computes shadow state based on bunches of other parameters
  611. //-----------------------------------------------------------------------------
  612. void CShaderShadowDX8::ComputeAggregateShadowState( )
  613. {
  614. // Initialize the texture stage usage; this may get changed later
  615. int nEnableMask = 0;
  616. for (int i = 0; i < m_pHardwareConfig->GetSamplerCount(); ++i)
  617. {
  618. if ( IsUsingTextureCoordinates( (Sampler_t)i ) )
  619. {
  620. nEnableMask |= ( 1 << i );
  621. }
  622. }
  623. // Always use the same alpha src + dest if it's disabled
  624. // NOTE: This is essential for stateblocks to work
  625. if ( m_ShadowState.m_AlphaBlendState.m_AlphaBlendEnable )
  626. {
  627. m_ShadowState.m_AlphaBlendState.m_SrcBlend = m_SrcBlend;
  628. m_ShadowState.m_AlphaBlendState.m_DestBlend = m_DestBlend;
  629. m_ShadowState.m_AlphaBlendState.m_BlendOp = m_BlendOp;
  630. }
  631. else
  632. {
  633. m_ShadowState.m_AlphaBlendState.m_SrcBlend = D3DBLEND_ONE;
  634. m_ShadowState.m_AlphaBlendState.m_DestBlend = D3DBLEND_ZERO;
  635. m_ShadowState.m_AlphaBlendState.m_BlendOp = D3DBLENDOP_ADD;
  636. }
  637. // GR
  638. if (m_ShadowState.m_AlphaBlendState.m_SeparateAlphaBlendEnable)
  639. {
  640. m_ShadowState.m_AlphaBlendState.m_SrcBlendAlpha = m_SrcBlendAlpha;
  641. m_ShadowState.m_AlphaBlendState.m_DestBlendAlpha = m_DestBlendAlpha;
  642. m_ShadowState.m_AlphaBlendState.m_BlendOpAlpha = m_BlendOpAlpha;
  643. }
  644. else
  645. {
  646. m_ShadowState.m_AlphaBlendState.m_SrcBlendAlpha = D3DBLEND_ONE;
  647. m_ShadowState.m_AlphaBlendState.m_DestBlendAlpha = D3DBLEND_ZERO;
  648. m_ShadowState.m_AlphaBlendState.m_BlendOpAlpha = D3DBLENDOP_ADD;
  649. }
  650. // Use the same func if it's disabled
  651. if (m_ShadowState.m_AlphaTestAndMiscState.m_AlphaTestEnable)
  652. {
  653. // If alpha test is enabled, just use the values set
  654. m_ShadowState.m_AlphaTestAndMiscState.m_AlphaFunc = m_AlphaFunc;
  655. m_ShadowState.m_AlphaTestAndMiscState.m_AlphaRef = m_AlphaRef;
  656. }
  657. else
  658. {
  659. // A default value
  660. m_ShadowState.m_AlphaTestAndMiscState.m_AlphaFunc = D3DCMP_GREATEREQUAL;
  661. m_ShadowState.m_AlphaTestAndMiscState.m_AlphaRef = 0;
  662. // If not alpha testing and doing a standard alpha blend, force on alpha testing
  663. if ( m_ShadowState.m_AlphaBlendState.m_AlphaBlendEnable )
  664. {
  665. if ( ( m_ShadowState.m_AlphaBlendState.m_SrcBlend == D3DBLEND_SRCALPHA ) && ( m_ShadowState.m_AlphaBlendState.m_DestBlend == D3DBLEND_INVSRCALPHA ) )
  666. {
  667. m_ShadowState.m_AlphaTestAndMiscState.m_AlphaFunc = D3DCMP_GREATEREQUAL;
  668. m_ShadowState.m_AlphaTestAndMiscState.m_AlphaRef = 1;
  669. }
  670. }
  671. }
  672. // Alpha to coverage
  673. if ( m_ShadowState.m_AlphaTestAndMiscState.m_EnableAlphaToCoverage )
  674. {
  675. // Only allow this to be enabled if blending is disabled and testing is enabled
  676. if ( ( m_ShadowState.m_AlphaBlendState.m_AlphaBlendEnable == true ) || ( m_ShadowState.m_AlphaTestAndMiscState.m_AlphaTestEnable == false ) )
  677. {
  678. m_ShadowState.m_AlphaTestAndMiscState.m_EnableAlphaToCoverage = false;
  679. }
  680. }
  681. }