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.

310 lines
9.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Header: $
  6. // $NoKeywords: $
  7. //=============================================================================//
  8. #include "shaderlib/cshader.h"
  9. // memdbgon must be the last include file in a .cpp file!!!
  10. #include "tier0/memdbgon.h"
  11. DEFINE_FALLBACK_SHADER( UnlitGeneric, UnlitGeneric_DX6 )
  12. DEFINE_FALLBACK_SHADER( MonitorScreen, UnlitGeneric_DX6 )
  13. DEFINE_FALLBACK_SHADER( ParticleSphere, UnlitGeneric_DX6 )
  14. DEFINE_FALLBACK_SHADER( Predator, Predator_DX60 )
  15. DEFINE_FALLBACK_SHADER( Predator_DX60, UnlitGeneric_DX6 )
  16. DEFINE_FALLBACK_SHADER( WindowImposter, WindowImposter_DX60 )
  17. DEFINE_FALLBACK_SHADER( WindowImposter_DX60, UnlitGeneric_DX6 )
  18. BEGIN_SHADER( UnlitGeneric_DX6,
  19. "Help for UnlitGeneric_DX6" )
  20. BEGIN_SHADER_PARAMS
  21. SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" )
  22. SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" )
  23. SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" )
  24. SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" )
  25. SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" )
  26. SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" )
  27. SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" )
  28. SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" )
  29. SHADER_PARAM( ENVMAPOPTIONAL, SHADER_PARAM_TYPE_BOOL, "0", "Make the envmap only apply to dx9 and higher hardware" )
  30. SHADER_PARAM( ALPHATESTREFERENCE, SHADER_PARAM_TYPE_FLOAT, "0.7", "" )
  31. END_SHADER_PARAMS
  32. SHADER_INIT_PARAMS()
  33. {
  34. if( !params[ENVMAPTINT]->IsDefined() )
  35. params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f );
  36. if( !params[ENVMAPMASKSCALE]->IsDefined() )
  37. params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f );
  38. if( !params[DETAILSCALE]->IsDefined() )
  39. params[DETAILSCALE]->SetFloatValue( 4.0f );
  40. // No texture means no env mask in base alpha
  41. if ( !params[BASETEXTURE]->IsDefined() )
  42. {
  43. CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  44. }
  45. // If in decal mode, no debug override...
  46. if (IS_FLAG_SET(MATERIAL_VAR_DECAL))
  47. {
  48. SET_FLAGS( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
  49. }
  50. // Get rid of the envmap if it's optional for this dx level.
  51. if( params[ENVMAPOPTIONAL]->IsDefined() && params[ENVMAPOPTIONAL]->GetIntValue() )
  52. {
  53. params[ENVMAP]->SetUndefined();
  54. }
  55. // If mat_specular 0, then get rid of envmap
  56. if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() )
  57. {
  58. params[ENVMAP]->SetUndefined();
  59. }
  60. }
  61. SHADER_INIT
  62. {
  63. if (params[BASETEXTURE]->IsDefined())
  64. {
  65. LoadTexture( BASETEXTURE );
  66. if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent())
  67. {
  68. if (IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK))
  69. CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  70. }
  71. }
  72. // the second texture (if there is one)
  73. if (params[DETAIL]->IsDefined())
  74. {
  75. LoadTexture( DETAIL );
  76. }
  77. // Don't alpha test if the alpha channel is used for other purposes
  78. if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) )
  79. CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST );
  80. if (params[ENVMAP]->IsDefined())
  81. {
  82. if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) )
  83. LoadCubeMap( ENVMAP );
  84. else
  85. LoadTexture( ENVMAP );
  86. if( !g_pHardwareConfig->SupportsCubeMaps() )
  87. SET_FLAGS(MATERIAL_VAR_ENVMAPSPHERE);
  88. if (params[ENVMAPMASK]->IsDefined())
  89. {
  90. LoadTexture( ENVMAPMASK );
  91. }
  92. }
  93. }
  94. int GetDrawFlagsPass1(IMaterialVar** params, bool doDetail)
  95. {
  96. int flags = SHADER_DRAW_POSITION;
  97. if (IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR))
  98. flags |= SHADER_DRAW_COLOR;
  99. if (params[BASETEXTURE]->IsTexture())
  100. flags |= SHADER_DRAW_TEXCOORD0;
  101. if (doDetail)
  102. flags |= SHADER_DRAW_TEXCOORD1;
  103. return flags;
  104. }
  105. void SetDetailShadowState(IShaderShadow* pShaderShadow)
  106. {
  107. // Specifically choose overbright2, will cause mod2x here
  108. pShaderShadow->EnableTexture( SHADER_SAMPLER1, true );
  109. pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 2.0f );
  110. }
  111. void SetDetailDymamicState(IShaderShadow* pShaderShadow)
  112. {
  113. BindTexture( SHADER_SAMPLER1, DETAIL, FRAME );
  114. SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, BASETEXTURETRANSFORM, DETAILSCALE );
  115. }
  116. void DrawAdditiveNonTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail )
  117. {
  118. SHADOW_STATE
  119. {
  120. SetModulationShadowState();
  121. SetAdditiveBlendingShadowState( );
  122. if (doDetail)
  123. SetDetailShadowState(pShaderShadow);
  124. pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) );
  125. FogToBlack();
  126. }
  127. DYNAMIC_STATE
  128. {
  129. SetModulationDynamicState();
  130. if (doDetail)
  131. SetDetailDymamicState(pShaderShadow);
  132. }
  133. Draw( );
  134. }
  135. void DrawAdditiveTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail )
  136. {
  137. SHADOW_STATE
  138. {
  139. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  140. SetModulationShadowState();
  141. SetAdditiveBlendingShadowState( BASETEXTURE, true );
  142. if (doDetail)
  143. SetDetailShadowState(pShaderShadow);
  144. pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) );
  145. FogToBlack();
  146. }
  147. DYNAMIC_STATE
  148. {
  149. BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
  150. SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM );
  151. if (doDetail)
  152. SetDetailDymamicState(pShaderShadow);
  153. SetModulationDynamicState();
  154. }
  155. Draw( );
  156. }
  157. void DrawNonTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail )
  158. {
  159. SHADOW_STATE
  160. {
  161. SetModulationShadowState();
  162. SetNormalBlendingShadowState( );
  163. if (doDetail)
  164. SetDetailShadowState(pShaderShadow);
  165. pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) );
  166. FogToFogColor();
  167. }
  168. DYNAMIC_STATE
  169. {
  170. SetModulationDynamicState();
  171. if (doDetail)
  172. SetDetailDymamicState(pShaderShadow);
  173. }
  174. Draw( );
  175. }
  176. void DrawTextured( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow, bool doDetail )
  177. {
  178. SHADOW_STATE
  179. {
  180. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  181. SetModulationShadowState();
  182. SetNormalBlendingShadowState( BASETEXTURE, true );
  183. if (doDetail)
  184. SetDetailShadowState(pShaderShadow);
  185. pShaderShadow->DrawFlags( GetDrawFlagsPass1(params, doDetail) );
  186. FogToFogColor();
  187. }
  188. DYNAMIC_STATE
  189. {
  190. BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
  191. SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM );
  192. if (doDetail)
  193. SetDetailDymamicState(pShaderShadow);
  194. SetModulationDynamicState();
  195. }
  196. Draw( );
  197. }
  198. SHADER_DRAW
  199. {
  200. bool isTextureDefined = params[BASETEXTURE]->IsTexture();
  201. bool hasVertexColor = IS_FLAG_SET(MATERIAL_VAR_VERTEXCOLOR);
  202. bool doFirstPass = isTextureDefined || hasVertexColor || (!params[ENVMAP]->IsTexture());
  203. if (doFirstPass)
  204. {
  205. SHADOW_STATE
  206. {
  207. pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) );
  208. if( params[ALPHATESTREFERENCE]->IsDefined() && params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f )
  209. {
  210. pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() );
  211. }
  212. }
  213. if (IS_FLAG_SET(MATERIAL_VAR_ADDITIVE))
  214. {
  215. if (!isTextureDefined)
  216. {
  217. bool hasDetailTexture = params[DETAIL]->IsTexture();
  218. DrawAdditiveNonTextured( params, pShaderAPI, pShaderShadow, hasDetailTexture );
  219. }
  220. else
  221. {
  222. // We can't do detail in a single pass if we're also
  223. // colormodulating and have vertex color
  224. bool hasDetailTexture = params[DETAIL]->IsTexture();
  225. bool isModulating = IsColorModulating() || IsAlphaModulating();
  226. bool onePassDetail = hasDetailTexture && (!hasVertexColor || !isModulating);
  227. DrawAdditiveTextured( params, pShaderAPI, pShaderShadow, onePassDetail );
  228. if (hasDetailTexture && !onePassDetail)
  229. {
  230. FixedFunctionMultiplyByDetailPass(
  231. BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE );
  232. }
  233. }
  234. }
  235. else
  236. {
  237. if (!isTextureDefined)
  238. {
  239. bool hasDetailTexture = params[DETAIL]->IsTexture();
  240. DrawNonTextured( params, pShaderAPI, pShaderShadow, hasDetailTexture );
  241. }
  242. else
  243. {
  244. // We can't do detail in a single pass if we're also
  245. // colormodulating and have vertex color
  246. bool hasDetailTexture = params[DETAIL]->IsTexture();
  247. bool isModulating = IsColorModulating() || IsAlphaModulating();
  248. bool onePassDetail = hasDetailTexture && (!hasVertexColor || !isModulating);
  249. DrawTextured( params, pShaderAPI, pShaderShadow, onePassDetail );
  250. if (hasDetailTexture && !onePassDetail)
  251. {
  252. FixedFunctionMultiplyByDetailPass(
  253. BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE );
  254. }
  255. }
  256. }
  257. }
  258. SHADOW_STATE
  259. {
  260. // Disable mod2x used by detail
  261. pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f );
  262. }
  263. // Second pass...
  264. if (params[ENVMAP]->IsTexture() &&
  265. (!doFirstPass || IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) )
  266. {
  267. if (doFirstPass || IS_FLAG_SET(MATERIAL_VAR_ADDITIVE))
  268. {
  269. FixedFunctionAdditiveMaskedEnvmapPass( ENVMAP, ENVMAPMASK, BASETEXTURE,
  270. ENVMAPFRAME, ENVMAPMASKFRAME, FRAME,
  271. BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT );
  272. }
  273. else
  274. {
  275. FixedFunctionMaskedEnvmapPass( ENVMAP, ENVMAPMASK, BASETEXTURE,
  276. ENVMAPFRAME, ENVMAPMASKFRAME, FRAME,
  277. BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT );
  278. }
  279. }
  280. }
  281. END_SHADER