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.

501 lines
20 KiB

  1. //========= Copyright (c) 1996-2007, Valve LLC, All rights reserved. ============
  2. //
  3. // Purpose: Lightmapped paint shader
  4. //
  5. // $Header: $
  6. // $NoKeywords: $
  7. //=============================================================================
  8. #include "lightmappedpaint_dx9_helper.h"
  9. #include "BaseVSShader.h"
  10. #include "shaderlib/commandbuilder.h"
  11. #include "convar.h"
  12. #include "lightmappedgeneric_vs20.inc"
  13. #include "lightmappedpaint_ps20.inc"
  14. #include "lightmappedpaint_ps20b.inc"
  15. #include "tier0/vprof.h"
  16. #include "shaderapifast.h"
  17. #include "tier0/memdbgon.h"
  18. extern ConVar mat_ambient_light_r;
  19. extern ConVar mat_ambient_light_g;
  20. extern ConVar mat_ambient_light_b;
  21. void DrawLightmappedPaint_DX9( CBaseVSShader *pShader, IMaterialVar** params, IShaderDynamicAPI *pShaderAPI, IShaderShadow* pShaderShadow,
  22. LightmappedGeneric_DX9_Vars_t &info, CBasePerMaterialContextData **pContextDataPtr )
  23. {
  24. SHADOW_STATE
  25. {
  26. pShader->SetInitialShadowState();
  27. }
  28. CLightmappedGeneric_DX9_Context *pContextData = reinterpret_cast< CLightmappedGeneric_DX9_Context *>( *pContextDataPtr );
  29. bool bHDR = g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE;
  30. if ( pShaderShadow || ( ! pContextData ) || pContextData->m_bMaterialVarsChanged )
  31. {
  32. static ConVarRef gpu_level( "gpu_level" );
  33. int nGPULevel = gpu_level.GetInt();
  34. bool bFullyOpaqueWithoutAlphaTest = false;
  35. bool bFullyOpaque = false;
  36. bool bNeedRegenStaticCmds = (! pContextData ) || pShaderShadow;
  37. bool bThickPaint = ( nGPULevel > 1 );
  38. #ifdef _GAMECONSOLE
  39. bThickPaint = TRUE;
  40. #endif
  41. if ( ! pContextData ) // make sure allocated
  42. {
  43. pContextData = new CLightmappedGeneric_DX9_Context;
  44. *pContextDataPtr = pContextData;
  45. }
  46. bool hasBump = true; //g_pConfig->UseBumpmapping();
  47. bool hasSSBump = hasBump && (info.m_nSelfShadowedBumpFlag != -1) && ( params[info.m_nSelfShadowedBumpFlag]->GetIntValue() );
  48. bool hasSelfIllum = IS_FLAG_SET( MATERIAL_VAR_SELFILLUM );
  49. bool bHasBlendModulateTexture =
  50. (info.m_nBlendModulateTexture != -1) &&
  51. (params[info.m_nBlendModulateTexture]->IsTexture() );
  52. pContextData->m_bFullyOpaque = bFullyOpaque;
  53. pContextData->m_bFullyOpaqueWithoutAlphaTest = bFullyOpaqueWithoutAlphaTest;
  54. bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture();
  55. if ( pShaderShadow || bNeedRegenStaticCmds )
  56. {
  57. bool hasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR );
  58. bool hasEnvmap = params[info.m_nPaintEnvmap]->IsTexture();
  59. int envmap_variant; //0 = no envmap, 1 = regular, 2 = darken in shadow mode
  60. if( hasEnvmap )
  61. {
  62. //only enabled darkened cubemap mode when the scale calls for it. And not supported in ps20 when also using a 2nd bumpmap
  63. envmap_variant = ((GetFloatParam( info.m_nEnvMapLightScale, params ) > 0.0f) && g_pHardwareConfig->SupportsPixelShaders_2_b()) ? 2 : 1;
  64. }
  65. else
  66. {
  67. envmap_variant = 1;
  68. }
  69. bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) &&
  70. ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) );
  71. if ( bNeedRegenStaticCmds )
  72. {
  73. pContextData->ResetStaticCmds();
  74. CCommandBufferBuilder< CFixedCommandStorageBuffer< 5000 > > staticCmdsBuf;
  75. #if 0
  76. int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
  77. if ( ( nLightingPreviewMode == ENABLE_FIXED_LIGHTING_OUTPUTNORMAL_AND_DEPTH ) && IsPC() )
  78. {
  79. staticCmdsBuf.SetVertexShaderNearAndFarZ( VERTEX_SHADER_SHADER_SPECIFIC_CONST_6 ); // Needed for SSAO
  80. }
  81. #endif
  82. staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER1, bHDR ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, TEXTURE_LIGHTMAP );
  83. //noise
  84. staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER6, TEXTURE_BINDFLAGS_NONE, TEXTURE_SHADOW_NOISE_2D );
  85. //paint map
  86. staticCmdsBuf.BindStandardTexture( SHADER_SAMPLER9, TEXTURE_BINDFLAGS_NONE, TEXTURE_PAINT );
  87. if ( bSeamlessMapping )
  88. {
  89. staticCmdsBuf.SetVertexShaderConstant4(
  90. VERTEX_SHADER_SHADER_SPECIFIC_CONST_0,
  91. params[info.m_nSeamlessMappingScale]->GetFloatValue(),0,0,0 );
  92. }
  93. staticCmdsBuf.StoreEyePosInPixelShaderConstant( 10 );
  94. #ifndef _PS3
  95. staticCmdsBuf.SetPixelShaderFogParams( 11 );
  96. #endif
  97. staticCmdsBuf.End();
  98. // now, copy buf
  99. pContextData->m_pStaticCmds = new uint8[staticCmdsBuf.Size()];
  100. memcpy( pContextData->m_pStaticCmds, staticCmdsBuf.Base(), staticCmdsBuf.Size() );
  101. }
  102. if ( pShaderShadow )
  103. {
  104. pShader->EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA );
  105. // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState
  106. //pShaderShadow->EnableAlphaTest( true );
  107. //pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f );
  108. unsigned int flags = VERTEX_POSITION;
  109. flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T | VERTEX_NORMAL;
  110. if( hasEnvmapMask )
  111. {
  112. pShaderShadow->EnableTexture( SHADER_SAMPLER5, true );
  113. }
  114. if( hasVertexColor )
  115. {
  116. flags |= VERTEX_COLOR;
  117. }
  118. // texcoord0 : base texcoord
  119. // texcoord1 : lightmap texcoord
  120. // texcoord2 : lightmap texcoord offset
  121. int numTexCoords;
  122. // if ( ShaderApiFast( pShaderAPI )->InEditorMode() )
  123. // if ( pShader->CanUseEditorMaterials() )
  124. // {
  125. // numTexCoords = 1;
  126. // }
  127. // else
  128. {
  129. numTexCoords = 2;
  130. if( hasBump )
  131. {
  132. numTexCoords = 3;
  133. }
  134. }
  135. int nLightingPreviewMode = 0;
  136. #if 0
  137. int nLightingPreviewMode = IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER0 ) + 2 * IS_FLAG2_SET( MATERIAL_VAR2_USE_GBUFFER1 );
  138. #endif
  139. pShaderShadow->VertexShaderVertexFormat( flags, numTexCoords, 0, 0 );
  140. // Pre-cache pixel shaders
  141. int bumpmap_variant=(hasSSBump) ? 2 : hasBump;
  142. DECLARE_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 );
  143. SET_STATIC_VERTEX_SHADER_COMBO( ENVMAP_MASK, hasEnvmapMask );
  144. SET_STATIC_VERTEX_SHADER_COMBO( TANGENTSPACE, 1 ); //need tangent transpose matrix for lighting
  145. SET_STATIC_VERTEX_SHADER_COMBO( BUMPMAP, hasBump );
  146. SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ) );
  147. SET_STATIC_VERTEX_SHADER_COMBO( VERTEXALPHATEXBLENDFACTOR, 0 );
  148. SET_STATIC_VERTEX_SHADER_COMBO( BUMPMASK, 0 );
  149. SET_STATIC_VERTEX_SHADER_COMBO( LIGHTING_PREVIEW, nLightingPreviewMode );
  150. SET_STATIC_VERTEX_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
  151. SET_STATIC_VERTEX_SHADER_COMBO( DETAILTEXTURE, 0 );
  152. SET_STATIC_VERTEX_SHADER_COMBO( FANCY_BLENDING, bHasBlendModulateTexture );
  153. SET_STATIC_VERTEX_SHADER_COMBO( SELFILLUM, hasSelfIllum );
  154. SET_STATIC_VERTEX_SHADER_COMBO( PAINT, 1 );
  155. SET_STATIC_VERTEX_SHADER_COMBO( ADDBUMPMAPS, 0 );
  156. #if defined( _X360 ) || defined( _PS3 )
  157. SET_STATIC_VERTEX_SHADER_COMBO( FLASHLIGHT, 0);
  158. #endif
  159. SET_STATIC_VERTEX_SHADER( lightmappedgeneric_vs20 );
  160. #define TCOMBINE_NONE 12 // there is no detail texture
  161. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  162. {
  163. DECLARE_STATIC_PIXEL_SHADER( lightmappedpaint_ps20b );
  164. SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant );
  165. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, envmap_variant );
  166. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
  167. SET_STATIC_PIXEL_SHADER_COMBO( THICKPAINT, bThickPaint );
  168. SET_STATIC_PIXEL_SHADER( lightmappedpaint_ps20b );
  169. }
  170. else
  171. {
  172. DECLARE_STATIC_PIXEL_SHADER( lightmappedpaint_ps20 );
  173. SET_STATIC_PIXEL_SHADER_COMBO( BUMPMAP, bumpmap_variant );
  174. SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, envmap_variant );
  175. SET_STATIC_PIXEL_SHADER_COMBO( SEAMLESS, bSeamlessMapping );
  176. SET_STATIC_PIXEL_SHADER_COMBO( THICKPAINT, bThickPaint );
  177. SET_STATIC_PIXEL_SHADER( lightmappedpaint_ps20 );
  178. }
  179. // HACK HACK HACK - enable alpha writes all the time so that we have them for
  180. // underwater stuff and writing depth to dest alpha
  181. // But only do it if we're not using the alpha already for translucency
  182. pShaderShadow->EnableAlphaWrites( bFullyOpaque );
  183. pShaderShadow->EnableSRGBWrite( true );
  184. pShader->DefaultFog();
  185. float flLScale = pShaderShadow->GetLightMapScaleFactor();
  186. pShader->PI_BeginCommandBuffer();
  187. pShader->PI_SetModulationPixelShaderDynamicState( 21 );
  188. pShader->PI_SetModulationPixelShaderDynamicState_LinearScale_ScaleInW( 12, flLScale );
  189. pShader->PI_SetModulationVertexShaderDynamicState_LinearScale( flLScale );
  190. pShader->PI_EndCommandBuffer();
  191. } // end shadow state
  192. } // end shadow || regen display list
  193. if ( pShaderAPI && ( pContextData->m_bMaterialVarsChanged ) )
  194. {
  195. // need to regenerate the semistatic cmds
  196. pContextData->m_SemiStaticCmdsOut.Reset();
  197. pContextData->m_bMaterialVarsChanged = false;
  198. // If we don't have a texture transform, we don't have
  199. // to set vertex shader constants or run vertex shader instructions
  200. // for the texture transform.
  201. bool bHasTextureTransform =
  202. !( params[info.m_nBaseTextureTransform]->MatrixIsIdentity() &&
  203. params[info.m_nBumpTransform]->MatrixIsIdentity() &&
  204. params[info.m_nBumpTransform2]->MatrixIsIdentity() &&
  205. params[info.m_nEnvmapMaskTransform]->MatrixIsIdentity() );
  206. pContextData->m_bVertexShaderFastPath = !bHasTextureTransform;
  207. if( params[info.m_nDetail]->IsTexture() )
  208. {
  209. pContextData->m_bVertexShaderFastPath = false;
  210. }
  211. int nTransformToLoad = -1;
  212. if ( ( hasBump || hasSSBump ) && !hasSelfIllum && !bHasBlendModulateTexture )
  213. {
  214. nTransformToLoad = info.m_nBumpTransform;
  215. }
  216. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform(
  217. VERTEX_SHADER_SHADER_SPECIFIC_CONST_10, nTransformToLoad );
  218. if ( ! pContextData->m_bVertexShaderFastPath )
  219. {
  220. bool bSeamlessMapping = ( ( info.m_nSeamlessMappingScale != -1 ) &&
  221. ( params[info.m_nSeamlessMappingScale]->GetFloatValue() != 0.0 ) );
  222. bool hasEnvmapMask = params[info.m_nEnvmapMask]->IsTexture();
  223. if (!bSeamlessMapping )
  224. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_0, info.m_nBaseTextureTransform );
  225. // If we have a detail texture, then the bump texcoords are the same as the base texcoords.
  226. if( hasBump )
  227. {
  228. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_2, info.m_nBumpTransform );
  229. }
  230. if( hasEnvmapMask )
  231. {
  232. pContextData->m_SemiStaticCmdsOut.SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_4, info.m_nEnvmapMaskTransform );
  233. }
  234. }
  235. pContextData->m_SemiStaticCmdsOut.SetEnvMapTintPixelShaderDynamicState( 0, info.m_nEnvmapTint );
  236. float envmapTintVal[4];
  237. float selfIllumTintVal[4];
  238. params[info.m_nEnvmapTint]->GetVecValue( envmapTintVal, 3 );
  239. params[info.m_nSelfIllumTint]->GetVecValue( selfIllumTintVal, 3 );
  240. float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue();
  241. float envmapSaturation = params[info.m_nEnvmapSaturation]->GetFloatValue();
  242. float fresnelReflection = params[info.m_nFresnelReflection]->GetFloatValue();
  243. bool hasEnvmap = params[info.m_nPaintEnvmap]->IsTexture();
  244. int envmap_variant; //0 = no envmap, 1 = regular, 2 = darken in shadow mode
  245. if( hasEnvmap )
  246. {
  247. //only enabled darkened cubemap mode when the scale calls for it. And not supported in ps20 when also using a 2nd bumpmap
  248. envmap_variant = ((GetFloatParam( info.m_nEnvMapLightScale, params ) > 0.0f) && g_pHardwareConfig->SupportsPixelShaders_2_b()) ? 2 : 1;
  249. }
  250. else
  251. {
  252. envmap_variant = 0;
  253. }
  254. pContextData->m_bPixelShaderFastPath = true;
  255. bool bUsingContrastOrSaturation = hasEnvmap && ( ( (envmapContrast != 0.0f) && (envmapContrast != 1.0f) ) || (envmapSaturation != 1.0f) );
  256. bool bUsingFresnel = hasEnvmap && (fresnelReflection != 1.0f);
  257. bool bUsingSelfIllumTint = IS_FLAG_SET(MATERIAL_VAR_SELFILLUM) && (selfIllumTintVal[0] != 1.0f || selfIllumTintVal[1] != 1.0f || selfIllumTintVal[2] != 1.0f);
  258. if ( bUsingContrastOrSaturation || bUsingFresnel || bUsingSelfIllumTint || !g_pConfig->bShowSpecular )
  259. {
  260. pContextData->m_bPixelShaderFastPath = false;
  261. }
  262. if( !pContextData->m_bPixelShaderFastPath )
  263. {
  264. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstants( 2, 3 );
  265. pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapContrast]->GetVecValue() );
  266. pContextData->m_SemiStaticCmdsOut.OutputConstantData( params[info.m_nEnvmapSaturation]->GetVecValue() );
  267. float flFresnel = params[info.m_nFresnelReflection]->GetFloatValue();
  268. // [ 0, 0, 1-R(0), R(0) ]
  269. pContextData->m_SemiStaticCmdsOut.OutputConstantData4( 0., 0., 1.0 - flFresnel, flFresnel );
  270. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant( 7, params[info.m_nSelfIllumTint]->GetVecValue() );
  271. }
  272. // parallax and cubemap light scale mapping parms (c20)
  273. if ( envmap_variant == 2 )
  274. {
  275. pContextData->m_SemiStaticCmdsOut.SetPixelShaderConstant4( 20, 0, GetFloatParam( info.m_nEnvMapLightScale, params), 0, 0 );
  276. }
  277. // texture binds
  278. // handle mat_fullbright 2
  279. bool bLightingOnly = g_pConfig->nFullbright == 2 && !IS_FLAG_SET( MATERIAL_VAR_NO_DEBUG_OVERRIDE );
  280. if( bLightingOnly )
  281. {
  282. // disable color modulation
  283. float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  284. pContextData->m_SemiStaticCmdsOut.SetVertexShaderConstant( VERTEX_SHADER_MODULATION_COLOR, color );
  285. // turn off environment mapping
  286. envmapTintVal[0] = 0.0f;
  287. envmapTintVal[1] = 0.0f;
  288. envmapTintVal[2] = 0.0f;
  289. }
  290. if( params[info.m_nPaintSplatNormal]->IsTexture() )
  291. {
  292. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER7, TEXTURE_BINDFLAGS_NONE, info.m_nPaintSplatNormal );
  293. }
  294. else
  295. {
  296. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER7, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALMAP_FLAT );
  297. }
  298. if( params[info.m_nPaintSplatBubbleLayout]->IsTexture() )
  299. {
  300. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, info.m_nPaintSplatBubbleLayout );
  301. }
  302. else
  303. {
  304. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER4, TEXTURE_BINDFLAGS_NONE, TEXTURE_BLACK );
  305. }
  306. if( params[info.m_nPaintSplatBubble]->IsTexture() )
  307. {
  308. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, info.m_nPaintSplatBubble );
  309. }
  310. else
  311. {
  312. pContextData->m_SemiStaticCmdsOut.BindStandardTexture( SHADER_SAMPLER5, TEXTURE_BINDFLAGS_NONE, TEXTURE_NORMALMAP_FLAT );
  313. }
  314. if ( bHasBlendModulateTexture )
  315. {
  316. pContextData->m_SemiStaticCmdsOut.BindTexture( pShader, SHADER_SAMPLER3, TEXTURE_BINDFLAGS_NONE, info.m_nBlendModulateTexture, -1 );
  317. }
  318. pContextData->m_SemiStaticCmdsOut.End();
  319. }
  320. }
  321. DYNAMIC_STATE
  322. {
  323. ShaderApiFast( pShaderAPI )->SetDefaultState();
  324. #ifdef _PS3
  325. CCommandBufferBuilder< CDynamicCommandStorageBuffer > DynamicCmdsOut;
  326. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( pContextData->m_pStaticCmds );
  327. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( pContextData->m_SemiStaticCmdsOut.Base() );
  328. #else
  329. CCommandBufferBuilder< CFixedCommandStorageBuffer< 1000 > > DynamicCmdsOut;
  330. DynamicCmdsOut.Call( pContextData->m_pStaticCmds );
  331. DynamicCmdsOut.Call( pContextData->m_SemiStaticCmdsOut.Base() );
  332. #endif
  333. bool hasEnvmap = params[info.m_nPaintEnvmap]->IsTexture();
  334. if ( hasEnvmap )
  335. {
  336. DynamicCmdsOut.BindEnvCubemapTexture( pShader, SHADER_SAMPLER2, bHDR ? TEXTURE_BINDFLAGS_NONE : TEXTURE_BINDFLAGS_SRGBREAD, info.m_nPaintEnvmap, info.m_nEnvmapFrame );
  337. }
  338. bool bVertexShaderFastPath = pContextData->m_bVertexShaderFastPath;
  339. int nFixedLightingMode = ShaderApiFast( pShaderAPI )->GetIntRenderingParameter( INT_RENDERPARM_ENABLE_FIXED_LIGHTING );
  340. if( nFixedLightingMode != ENABLE_FIXED_LIGHTING_NONE )
  341. {
  342. bVertexShaderFastPath = false;
  343. }
  344. float vEyePos[4];
  345. ShaderApiFast( pShaderAPI )->GetWorldSpaceCameraPosition( vEyePos );
  346. DynamicCmdsOut.SetVertexShaderConstant4( 12, vEyePos[0], vEyePos[1], vEyePos[2], 0.0f );
  347. // These constants are used to rotate the world space water normals around the up axis to align the
  348. // normal with the camera and then give us a 2D offset vector to use for reflection and refraction uv's
  349. VMatrix mView;
  350. ShaderApiFast( pShaderAPI )->GetMatrix( MATERIAL_VIEW, mView.m[0] );
  351. mView = mView.Transpose3x3();
  352. Vector4D vCameraRight( mView.m[0][0], mView.m[0][1], mView.m[0][2], 0.0f );
  353. vCameraRight.z = 0.0f; // Project onto the plane of water
  354. vCameraRight.AsVector3D().NormalizeInPlace();
  355. Vector4D vCameraForward;
  356. CrossProduct( Vector( 0.0f, 0.0f, 1.0f ), vCameraRight.AsVector3D(), vCameraForward.AsVector3D() ); // I assume the water surface normal is pointing along z!
  357. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( 22, vCameraRight.Base() );
  358. ShaderApiFast( pShaderAPI )->SetPixelShaderConstant( 23, vCameraForward.Base() );
  359. MaterialFogMode_t fogType = ShaderApiFast( pShaderAPI )->GetSceneFogMode();
  360. DECLARE_DYNAMIC_VERTEX_SHADER( lightmappedgeneric_vs20 );
  361. SET_DYNAMIC_VERTEX_SHADER_COMBO( FASTPATH, bVertexShaderFastPath );
  362. SET_DYNAMIC_VERTEX_SHADER_CMD( DynamicCmdsOut, lightmappedgeneric_vs20 );
  363. // This block of logic is up here and is so verbose because the compiler on the Mac was previously
  364. // optimizing much of this away and allowing out of range values into the logic which ultimately
  365. // computes the dynamic index. Please leave this here and don't try to weave it into the dynamic
  366. // combo setting macros below.
  367. bool bPixelShaderFastPath = false;
  368. if ( pContextData->m_bPixelShaderFastPath )
  369. bPixelShaderFastPath = true;
  370. bool bFastPath = false;
  371. if ( bPixelShaderFastPath )
  372. bFastPath = true;
  373. if ( nFixedLightingMode != ENABLE_FIXED_LIGHTING_NONE )
  374. {
  375. bPixelShaderFastPath = false;
  376. }
  377. bool bWriteDepthToAlpha;
  378. bool bWriteWaterFogToAlpha;
  379. if( pContextData->m_bFullyOpaque )
  380. {
  381. bWriteDepthToAlpha = ShaderApiFast( pShaderAPI )->ShouldWriteDepthToDestAlpha();
  382. bWriteWaterFogToAlpha = (fogType == MATERIAL_FOG_LINEAR_BELOW_FOG_Z);
  383. AssertMsg( !(bWriteDepthToAlpha && bWriteWaterFogToAlpha), "Can't write two values to alpha at the same time." );
  384. }
  385. else
  386. {
  387. //can't write a special value to dest alpha if we're actually using as-intended alpha
  388. bWriteDepthToAlpha = false;
  389. bWriteWaterFogToAlpha = false;
  390. }
  391. // only do ambient light when not using flashlight
  392. float vAmbientColor[4] = { mat_ambient_light_r.GetFloat(), mat_ambient_light_g.GetFloat(), mat_ambient_light_b.GetFloat(), 0.0f };
  393. if ( g_pConfig->nFullbright == 1 )
  394. {
  395. vAmbientColor[0] = vAmbientColor[1] = vAmbientColor[2] = 0.0f;
  396. }
  397. DynamicCmdsOut.SetPixelShaderConstant( 31, vAmbientColor, 1 );
  398. float envmapContrast = params[info.m_nEnvmapContrast]->GetFloatValue();
  399. if ( g_pHardwareConfig->SupportsPixelShaders_2_b() )
  400. {
  401. DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedpaint_ps20b );
  402. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bFastPath );
  403. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f );
  404. // Don't write fog to alpha if we're using translucency
  405. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedpaint_ps20b );
  406. }
  407. else
  408. {
  409. DECLARE_DYNAMIC_PIXEL_SHADER( lightmappedpaint_ps20 );
  410. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATH, bPixelShaderFastPath );
  411. SET_DYNAMIC_PIXEL_SHADER_COMBO( FASTPATHENVMAPCONTRAST, bPixelShaderFastPath && envmapContrast == 1.0f );
  412. // Don't write fog to alpha if we're using translucency
  413. SET_DYNAMIC_PIXEL_SHADER_CMD( DynamicCmdsOut, lightmappedpaint_ps20 );
  414. }
  415. DynamicCmdsOut.End();
  416. #ifdef _PS3
  417. ShaderApiFast( pShaderAPI )->SetPixelShaderFogParams( 11 );
  418. #endif
  419. ShaderApiFast( pShaderAPI )->ExecuteCommandBuffer( DynamicCmdsOut.Base() );
  420. }
  421. pShader->Draw();
  422. }