Team Fortress 2 Source Code as on 22/4/2020
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.

231 lines
6.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=====================================================================================//
  6. #include "BaseVSShader.h"
  7. #include "unlitgeneric_vs11.inc"
  8. #include "cloak_blended_pass_helper.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. DEFINE_FALLBACK_SHADER( Modulate, Modulate_DX8 )
  12. BEGIN_VS_SHADER( Modulate_DX8,
  13. "Help for Modulate" )
  14. BEGIN_SHADER_PARAMS
  15. SHADER_PARAM( WRITEZ, SHADER_PARAM_TYPE_BOOL, "0", "Forces z to be written if set" )
  16. SHADER_PARAM( MOD2X, SHADER_PARAM_TYPE_BOOL, "0", "forces a 2x modulate so that you can brighten and darken things" )
  17. // Cloak Pass
  18. SHADER_PARAM( CLOAKPASSENABLED, SHADER_PARAM_TYPE_BOOL, "0", "Enables cloak render in a second pass" )
  19. SHADER_PARAM( CLOAKFACTOR, SHADER_PARAM_TYPE_FLOAT, "0.0", "" )
  20. SHADER_PARAM( CLOAKCOLORTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Cloak color tint" )
  21. SHADER_PARAM( REFRACTAMOUNT, SHADER_PARAM_TYPE_FLOAT, "2", "" )
  22. END_SHADER_PARAMS
  23. SHADER_FALLBACK
  24. {
  25. if ( IsPC() && !g_pHardwareConfig->SupportsVertexAndPixelShaders() )
  26. return "Modulate_DX6";
  27. return 0;
  28. }
  29. // Cloak Pass
  30. void SetupVarsCloakBlendedPass( CloakBlendedPassVars_t &info )
  31. {
  32. info.m_nCloakFactor = CLOAKFACTOR;
  33. info.m_nCloakColorTint = CLOAKCOLORTINT;
  34. info.m_nRefractAmount = REFRACTAMOUNT;
  35. }
  36. bool NeedsPowerOfTwoFrameBufferTexture( IMaterialVar **params, bool bCheckSpecificToThisFrame ) const
  37. {
  38. if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking
  39. {
  40. if ( bCheckSpecificToThisFrame == false ) // For setting model flag at load time
  41. return true;
  42. else if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check
  43. return true;
  44. // else, not cloaking this frame, so check flag2 in case the base material still needs it
  45. }
  46. // Check flag2 if not drawing cloak pass
  47. return IS_FLAG2_SET( MATERIAL_VAR2_NEEDS_POWER_OF_TWO_FRAME_BUFFER_TEXTURE );
  48. }
  49. bool IsTranslucent( IMaterialVar **params ) const
  50. {
  51. if ( params[CLOAKPASSENABLED]->GetIntValue() ) // If material supports cloaking
  52. {
  53. if ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) // Per-frame check
  54. return true;
  55. // else, not cloaking this frame, so check flag in case the base material still needs it
  56. }
  57. // Check flag if not drawing cloak pass
  58. return IS_FLAG_SET( MATERIAL_VAR_TRANSLUCENT );
  59. }
  60. SHADER_INIT_PARAMS()
  61. {
  62. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  63. // Cloak Pass
  64. if ( !params[CLOAKPASSENABLED]->IsDefined() )
  65. {
  66. params[CLOAKPASSENABLED]->SetIntValue( 0 );
  67. }
  68. else if ( params[CLOAKPASSENABLED]->GetIntValue() )
  69. {
  70. CloakBlendedPassVars_t info;
  71. SetupVarsCloakBlendedPass( info );
  72. InitParamsCloakBlendedPass( this, params, pMaterialName, info );
  73. }
  74. }
  75. SHADER_INIT
  76. {
  77. if (params[BASETEXTURE]->IsDefined())
  78. LoadTexture( BASETEXTURE );
  79. // Cloak Pass
  80. if ( params[CLOAKPASSENABLED]->GetIntValue() )
  81. {
  82. CloakBlendedPassVars_t info;
  83. SetupVarsCloakBlendedPass( info );
  84. InitCloakBlendedPass( this, params, info );
  85. }
  86. }
  87. SHADER_DRAW
  88. {
  89. // Skip the standard rendering if cloak pass is fully opaque
  90. bool bDrawStandardPass = true;
  91. if ( params[CLOAKPASSENABLED]->GetIntValue() && ( pShaderShadow == NULL ) ) // && not snapshotting
  92. {
  93. CloakBlendedPassVars_t info;
  94. SetupVarsCloakBlendedPass( info );
  95. if ( CloakBlendedPassIsFullyOpaque( params, info ) )
  96. {
  97. // There is some strangeness in DX8 when trying to skip the main pass, so leave this alone for now
  98. //bDrawStandardPass = false;
  99. }
  100. }
  101. // Standard rendering pass
  102. if ( bDrawStandardPass )
  103. {
  104. bool bMod2X = params[MOD2X]->IsDefined() && params[MOD2X]->GetIntValue();
  105. bool bVertexColorOrAlpha = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) || IS_FLAG_SET( MATERIAL_VAR_VERTEXALPHA );
  106. SHADOW_STATE
  107. {
  108. if( bMod2X )
  109. {
  110. EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR );
  111. }
  112. else
  113. {
  114. EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_ZERO );
  115. }
  116. if (params[WRITEZ]->GetIntValue() != 0)
  117. {
  118. // This overrides the disabling of depth writes performed in
  119. // EnableAlphaBlending
  120. pShaderShadow->EnableDepthWrites( true );
  121. }
  122. unsigned int flags = VERTEX_POSITION;
  123. int numTexCoords = 1;
  124. if( params[BASETEXTURE]->IsTexture() )
  125. {
  126. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  127. }
  128. if( bVertexColorOrAlpha )
  129. {
  130. flags |= VERTEX_COLOR;
  131. }
  132. pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, NULL, 0 );
  133. unlitgeneric_vs11_Static_Index vshIndex;
  134. vshIndex.SetDETAIL( false );
  135. vshIndex.SetENVMAP( false );
  136. vshIndex.SetENVMAPCAMERASPACE( false );
  137. vshIndex.SetENVMAPSPHERE( false );
  138. vshIndex.SetSEPARATEDETAILUVS( false );
  139. vshIndex.SetVERTEXCOLOR( bVertexColorOrAlpha );
  140. pShaderShadow->SetVertexShader( "unlitgeneric_vs11", vshIndex.GetIndex() );
  141. pShaderShadow->SetPixelShader( "Modulate_ps11" );
  142. // We need to fog to *white* regardless of overbrighting...
  143. if( bMod2X )
  144. {
  145. FogToGrey();
  146. }
  147. else
  148. {
  149. FogToOOOverbright();
  150. }
  151. }
  152. DYNAMIC_STATE
  153. {
  154. if( params[BASETEXTURE]->IsTexture() )
  155. {
  156. BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
  157. SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, BASETEXTURETRANSFORM );
  158. }
  159. // set constant color for modulation
  160. SetModulationVertexShaderDynamicState();
  161. // We need to fog to *white* regardless of overbrighting...
  162. if( bMod2X )
  163. {
  164. float grey[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
  165. pShaderAPI->SetPixelShaderConstant( 0, grey );
  166. }
  167. else
  168. {
  169. float white[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
  170. pShaderAPI->SetPixelShaderConstant( 0, white );
  171. }
  172. unlitgeneric_vs11_Dynamic_Index vshIndex;
  173. vshIndex.SetDOWATERFOG( pShaderAPI->GetSceneFogMode() == MATERIAL_FOG_LINEAR_BELOW_FOG_Z );
  174. vshIndex.SetSKINNING( pShaderAPI->GetCurrentNumBones() > 0 );
  175. pShaderAPI->SetVertexShaderIndex( vshIndex.GetIndex() );
  176. }
  177. Draw( );
  178. }
  179. else
  180. {
  181. // Skip this pass!
  182. Draw( false );
  183. }
  184. // Cloak Pass
  185. if ( params[CLOAKPASSENABLED]->GetIntValue() )
  186. {
  187. // If ( snapshotting ) or ( we need to draw this frame )
  188. if ( ( pShaderShadow != NULL ) || ( ( params[CLOAKFACTOR]->GetFloatValue() > 0.0f ) && ( params[CLOAKFACTOR]->GetFloatValue() < 1.0f ) ) )
  189. {
  190. CloakBlendedPassVars_t info;
  191. SetupVarsCloakBlendedPass( info );
  192. DrawCloakBlendedPass( this, params, pShaderAPI, pShaderShadow, info, vertexCompression );
  193. }
  194. else // We're not snapshotting and we don't need to draw this frame
  195. {
  196. // Skip this pass!
  197. Draw( false );
  198. }
  199. }
  200. }
  201. END_SHADER