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.

413 lines
12 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( VertexLitGeneric, VertexLitGeneric_DX7 )
  12. DEFINE_FALLBACK_SHADER( Skin_DX9, VertexLitGeneric_DX7 )
  13. BEGIN_SHADER( VertexLitGeneric_DX7,
  14. "Help for VertexLitGeneric_DX7" )
  15. BEGIN_SHADER_PARAMS
  16. SHADER_PARAM( DETAIL, SHADER_PARAM_TYPE_TEXTURE, "shadertest/detail", "detail texture" )
  17. SHADER_PARAM( DETAILSCALE, SHADER_PARAM_TYPE_FLOAT, "4", "scale of the detail texture" )
  18. SHADER_PARAM( SELFILLUMTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "Self-illumination tint" )
  19. SHADER_PARAM( ENVMAP, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_env", "envmap" )
  20. SHADER_PARAM( ENVMAPFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" )
  21. SHADER_PARAM( ENVMAPMASK, SHADER_PARAM_TYPE_TEXTURE, "shadertest/shadertest_envmask", "envmap mask" )
  22. SHADER_PARAM( ENVMAPMASKFRAME, SHADER_PARAM_TYPE_INTEGER, "0", "" )
  23. SHADER_PARAM( ENVMAPMASKSCALE, SHADER_PARAM_TYPE_FLOAT, "1", "envmap mask scale" )
  24. SHADER_PARAM( ENVMAPTINT, SHADER_PARAM_TYPE_COLOR, "[1 1 1]", "envmap tint" )
  25. END_SHADER_PARAMS
  26. SHADER_INIT_PARAMS()
  27. {
  28. // FLASHLIGHTFIXME
  29. params[FLASHLIGHTTEXTURE]->SetStringValue( "effects/flashlight001" );
  30. SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_HW_SKINNING );
  31. if( !params[ENVMAPMASKSCALE]->IsDefined() )
  32. params[ENVMAPMASKSCALE]->SetFloatValue( 1.0f );
  33. if( !params[ENVMAPTINT]->IsDefined() )
  34. params[ENVMAPTINT]->SetVecValue( 1.0f, 1.0f, 1.0f );
  35. if( !params[SELFILLUMTINT]->IsDefined() )
  36. params[SELFILLUMTINT]->SetVecValue( 1.0f, 1.0f, 1.0f );
  37. if( !params[DETAILSCALE]->IsDefined() )
  38. params[DETAILSCALE]->SetFloatValue( 4.0f );
  39. // No texture means no self-illum or env mask in base alpha
  40. if ( !params[BASETEXTURE]->IsDefined() )
  41. {
  42. CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
  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. SET_FLAGS2( MATERIAL_VAR2_LIGHTING_VERTEX_LIT );
  51. SET_FLAGS2( MATERIAL_VAR2_NEEDS_BAKED_LIGHTING_SNAPSHOTS );
  52. // If mat_specular 0, then get rid of envmap
  53. if( !g_pConfig->UseSpecular() && params[ENVMAP]->IsDefined() && params[BASETEXTURE]->IsDefined() )
  54. {
  55. params[ENVMAP]->SetUndefined();
  56. }
  57. }
  58. SHADER_FALLBACK
  59. {
  60. if (g_pHardwareConfig->GetDXSupportLevel() < 70)
  61. return "VertexLitGeneric_DX6";
  62. return 0;
  63. }
  64. SHADER_INIT
  65. {
  66. LoadTexture( FLASHLIGHTTEXTURE );
  67. if (params[BASETEXTURE]->IsDefined())
  68. {
  69. LoadTexture( BASETEXTURE );
  70. if (!params[BASETEXTURE]->GetTextureValue()->IsTranslucent())
  71. {
  72. CLEAR_FLAGS( MATERIAL_VAR_SELFILLUM );
  73. CLEAR_FLAGS( MATERIAL_VAR_BASEALPHAENVMAPMASK );
  74. }
  75. }
  76. if (params[DETAIL]->IsDefined())
  77. {
  78. LoadTexture( DETAIL );
  79. }
  80. // Don't alpha test if the alpha channel is used for other purposes
  81. if (IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) || IS_FLAG_SET(MATERIAL_VAR_BASEALPHAENVMAPMASK) )
  82. CLEAR_FLAGS( MATERIAL_VAR_ALPHATEST );
  83. if (params[ENVMAP]->IsDefined())
  84. {
  85. if( !IS_FLAG_SET(MATERIAL_VAR_ENVMAPSPHERE) )
  86. LoadCubeMap( ENVMAP );
  87. else
  88. LoadTexture( ENVMAP );
  89. if( !g_pHardwareConfig->SupportsCubeMaps() )
  90. {
  91. SET_FLAGS( MATERIAL_VAR_ENVMAPSPHERE );
  92. }
  93. if (params[ENVMAPMASK]->IsDefined())
  94. LoadTexture( ENVMAPMASK );
  95. }
  96. }
  97. void DrawBaseTimesVertexColor( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow )
  98. {
  99. SHADOW_STATE
  100. {
  101. // alpha test
  102. pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) );
  103. pShaderShadow->EnableCustomPixelPipe( true );
  104. pShaderShadow->CustomTextureStages( 1 );
  105. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  106. SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X,
  107. SHADER_TEXARG_TEXTURE, SHADER_TEXARG_VERTEXCOLOR );
  108. // Get alpha from the texture so that alpha blend and alpha test work properly.
  109. bool bTextureIsTranslucent = TextureIsTranslucent( BASETEXTURE, true );
  110. if ( bTextureIsTranslucent )
  111. {
  112. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  113. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  114. SHADER_TEXARG_TEXTURE, SHADER_TEXARG_NONE );
  115. }
  116. else
  117. {
  118. if ( IsAlphaModulating() )
  119. {
  120. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  121. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  122. SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE );
  123. }
  124. else
  125. {
  126. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  127. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  128. SHADER_TEXARG_ONE, SHADER_TEXARG_NONE );
  129. }
  130. }
  131. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  132. int flags = SHADER_DRAW_POSITION | SHADER_DRAW_NORMAL | SHADER_DRAW_TEXCOORD0;
  133. pShaderShadow->DrawFlags( flags );
  134. DefaultFog();
  135. if ( IsAlphaModulating() || IsColorModulating() )
  136. {
  137. pShaderShadow->CustomTextureStages( 2 );
  138. if ( IsColorModulating() )
  139. {
  140. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1,
  141. SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE,
  142. SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR );
  143. }
  144. else
  145. {
  146. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1,
  147. SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1,
  148. SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE );
  149. }
  150. // Get alpha from the texture so that alpha blend and alpha test work properly.
  151. if ( IsAlphaModulating() && bTextureIsTranslucent )
  152. {
  153. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1,
  154. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE,
  155. SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR );
  156. }
  157. else
  158. {
  159. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1,
  160. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  161. SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE );
  162. }
  163. }
  164. SetDefaultBlendingShadowState( BASETEXTURE, true );
  165. }
  166. DYNAMIC_STATE
  167. {
  168. SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, BASETEXTURETRANSFORM );
  169. BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
  170. SetModulationDynamicState();
  171. }
  172. Draw();
  173. }
  174. void DrawVertexColorNoBase( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow )
  175. {
  176. SHADOW_STATE
  177. {
  178. pShaderShadow->EnableCustomPixelPipe( true );
  179. pShaderShadow->CustomTextureStages( 1 );
  180. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  181. SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE2X,
  182. SHADER_TEXARG_ONE, SHADER_TEXARG_VERTEXCOLOR );
  183. int flags = SHADER_DRAW_POSITION;
  184. pShaderShadow->DrawFlags( flags );
  185. DefaultFog();
  186. }
  187. DYNAMIC_STATE
  188. {
  189. // SetModulationDynamicState();
  190. }
  191. Draw();
  192. }
  193. void DrawBaseTimesBakedVertexLighting( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow )
  194. {
  195. SHADOW_STATE
  196. {
  197. // alpha test
  198. pShaderShadow->EnableAlphaTest( IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) );
  199. // base
  200. pShaderShadow->EnableTexture( SHADER_SAMPLER0, true );
  201. int flags = SHADER_DRAW_POSITION;
  202. if (params[BASETEXTURE]->IsTexture())
  203. {
  204. flags |= SHADER_DRAW_TEXCOORD1;
  205. }
  206. pShaderShadow->DrawFlags( flags );
  207. DefaultFog();
  208. pShaderShadow->EnableCustomPixelPipe( true );
  209. pShaderShadow->CustomTextureStages( 1 );
  210. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  211. SHADER_TEXCHANNEL_COLOR,
  212. SHADER_TEXOP_MODULATE2X,
  213. SHADER_TEXARG_SPECULARCOLOR, SHADER_TEXARG_TEXTURE );
  214. // Get alpha from the texture so that alpha blend and alpha test work properly.
  215. bool bTextureIsTranslucent = TextureIsTranslucent( BASETEXTURE, true );
  216. if ( bTextureIsTranslucent )
  217. {
  218. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  219. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  220. SHADER_TEXARG_TEXTURE, SHADER_TEXARG_NONE );
  221. }
  222. else
  223. {
  224. if ( IsAlphaModulating() )
  225. {
  226. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  227. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  228. SHADER_TEXARG_CONSTANTCOLOR, SHADER_TEXARG_NONE );
  229. }
  230. else
  231. {
  232. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  233. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  234. SHADER_TEXARG_ONE, SHADER_TEXARG_NONE );
  235. }
  236. }
  237. if ( IsAlphaModulating() || IsColorModulating() )
  238. {
  239. pShaderShadow->CustomTextureStages( 2 );
  240. if ( IsColorModulating())
  241. {
  242. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1,
  243. SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_MODULATE,
  244. SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR );
  245. }
  246. else
  247. {
  248. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1,
  249. SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1,
  250. SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE );
  251. }
  252. // Get alpha from the texture so that alpha blend and alpha test work properly.
  253. if ( IsAlphaModulating() && bTextureIsTranslucent )
  254. {
  255. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1,
  256. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE,
  257. SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_CONSTANTCOLOR );
  258. }
  259. else
  260. {
  261. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1,
  262. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  263. SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE );
  264. }
  265. }
  266. SetDefaultBlendingShadowState( BASETEXTURE, true );
  267. }
  268. DYNAMIC_STATE
  269. {
  270. SetFixedFunctionTextureTransform( MATERIAL_TEXTURE1, BASETEXTURETRANSFORM );
  271. BindTexture( SHADER_SAMPLER0, BASETEXTURE, FRAME );
  272. SetModulationDynamicState();
  273. }
  274. Draw();
  275. }
  276. void DrawBakedVertexLightingNoBase( IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow )
  277. {
  278. SHADOW_STATE
  279. {
  280. int flags = SHADER_DRAW_POSITION;
  281. pShaderShadow->DrawFlags( flags );
  282. DefaultFog();
  283. pShaderShadow->EnableCustomPixelPipe( true );
  284. pShaderShadow->CustomTextureStages( 1 );
  285. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  286. SHADER_TEXCHANNEL_COLOR,
  287. SHADER_TEXOP_MODULATE2X,
  288. SHADER_TEXARG_SPECULARCOLOR, SHADER_TEXARG_NONE );
  289. // Alpha isn't used, it doesn't matter what we set it to.
  290. pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0,
  291. SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1,
  292. SHADER_TEXARG_NONE, SHADER_TEXARG_NONE );
  293. }
  294. DYNAMIC_STATE
  295. {
  296. }
  297. Draw();
  298. }
  299. SHADER_DRAW
  300. {
  301. bool bBakedLighting = IS_FLAG2_SET( MATERIAL_VAR2_USE_FIXED_FUNCTION_BAKED_LIGHTING );
  302. bool hasFlashlight = UsingFlashlight( params );
  303. if( hasFlashlight )
  304. {
  305. DrawFlashlight_dx70( params, pShaderAPI, pShaderShadow, FLASHLIGHTTEXTURE, FLASHLIGHTTEXTUREFRAME );
  306. return;
  307. }
  308. // Pass 1 : Base * lightmap or just lightmap
  309. if ( params[BASETEXTURE]->IsTexture() )
  310. {
  311. // Draw base times lighting.
  312. // Lighting is either sent down per vertex from the app, or it's in the second
  313. // stream as color values.
  314. if( bBakedLighting )
  315. {
  316. DrawBaseTimesBakedVertexLighting( params, pShaderAPI, pShaderShadow );
  317. }
  318. else
  319. {
  320. DrawBaseTimesVertexColor( params, pShaderAPI, pShaderShadow );
  321. }
  322. // Detail map
  323. FixedFunctionMultiplyByDetailPass(
  324. BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE );
  325. // Draw the selfillum pass
  326. if ( IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) )
  327. {
  328. FixedFunctionSelfIlluminationPass(
  329. SHADER_SAMPLER0, BASETEXTURE, FRAME, BASETEXTURETRANSFORM, SELFILLUMTINT );
  330. }
  331. }
  332. else
  333. {
  334. if( bBakedLighting )
  335. {
  336. DrawBakedVertexLightingNoBase( params, pShaderAPI, pShaderShadow );
  337. }
  338. else
  339. {
  340. DrawVertexColorNoBase( params, pShaderAPI, pShaderShadow );
  341. }
  342. FixedFunctionMultiplyByDetailPass(
  343. BASETEXTURE, FRAME, BASETEXTURETRANSFORM, DETAIL, DETAILSCALE );
  344. }
  345. // Pass 2 : Masked environment map
  346. if ( params[ENVMAP]->IsTexture() && (IS_FLAG_SET(MATERIAL_VAR_MULTIPASS)) )
  347. {
  348. FixedFunctionAdditiveMaskedEnvmapPass(
  349. ENVMAP, ENVMAPMASK, BASETEXTURE,
  350. ENVMAPFRAME, ENVMAPMASKFRAME, FRAME,
  351. BASETEXTURETRANSFORM, ENVMAPMASKSCALE, ENVMAPTINT );
  352. }
  353. }
  354. END_SHADER