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.

5750 lines
193 KiB

  1. //=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
  2. //
  3. // The copyright to the contents herein is the property of Valve, L.L.C.
  4. // The contents may be used and/or copied only with the written permission of
  5. // Valve, L.L.C., or in accordance with the terms and conditions stipulated in
  6. // the agreement/contract under which the contents have been supplied.
  7. //
  8. // $Header: $
  9. // $NoKeywords: $
  10. //
  11. // Render system unit test
  12. //=============================================================================
  13. #include "rendersystemtest.h"
  14. #include "inputsystem/iinputsystem.h"
  15. #include "materialsystem2/imaterialsystem2.h"
  16. #include "worldrenderer/iworldrenderermgr.h"
  17. #include "meshsystem/imeshsystem.h"
  18. #include "filesystem.h"
  19. #include "vstdlib/jobthread.h"
  20. #include "particles/particles.h"
  21. #include "dynamicdrawhelper.h"
  22. #include "tier0/vprof.h"
  23. #include "keyvalues.h"
  24. #include "scenesystem/iscenesystem.h"
  25. #include "icommandline.h"
  26. #include "inputsystem/iinputstacksystem.h"
  27. struct usercmd_t
  28. {
  29. float m_flForwardMove;
  30. float m_flRightMove;
  31. float m_flYawMove;
  32. float m_flPitchMove;
  33. uint32 m_nKeys;
  34. };
  35. struct BoxVertex_t
  36. {
  37. Vector m_vPos;
  38. };
  39. #define FKEY_FORWARD 0x00000001
  40. #define FKEY_BACK 0x00000002
  41. #define FKEY_LEFT 0x00000004
  42. #define FKEY_RIGHT 0x00000008
  43. #define FKEY_TURNLEFT 0x00000010
  44. #define FKEY_TURNRIGHT 0x00000020
  45. #define FKEY_TURNUP 0x00000040
  46. #define FKEY_TURNDOWN 0x00000080
  47. #define FKEY_SHOOTDECAL 0x00000100
  48. #define FKEY_SHOOTPSYSTEM 0x00000200
  49. #define FKEY_SHOOTSSYSTEM 0x00000400
  50. #define FKEY_LIGHTELV 0x00000800
  51. #define FKEY_LIGHTANG_POS 0x00001000
  52. #define FKEY_LIGHTANG_NEG 0x00002000
  53. #define FKEY_FAST 0x00004000
  54. #define FKEY_ENABLE_VIS 0x00008000
  55. #define FKEY_DISABLE_VIS 0x00010000
  56. #define FKEY_DROP_FRUSTUM 0x00020000
  57. #define FKEY_TOGGLE_AERIAL 0x00040000
  58. #define FKEY_TOGGLE_BOUNCE 0x00080000
  59. #define FKEY_TOGGLE_DIRECT 0x00100000
  60. #define FKEY_TOGGLE_LIGHTING_ONLY 0x00200000
  61. #define FKEY_SSAO 0x00400000
  62. #define FKEY_BLUR_LIGHTING 0x00800000
  63. #define FKEY_BLUR_SHADOWS 0x01000000
  64. #define FKEY_FLASHLIGHT 0x02000000
  65. #define FKEY_SHOOTDECAL2 0x04000000
  66. #define FKEY_SHOOTWALLMONSTER 0x08000000
  67. #define NUM_SHADOW_SPLITS 3
  68. #define NUM_MULTI_SHADOWS 20
  69. #define NUM_HIGH_RES_SHADOWS 4
  70. #define SQRT_NUM_HIGH_RES_SHADOWS 2
  71. #define NUM_LOW_RES_SHADOWS 16
  72. #define SQRT_NUM_LOW_RES_SHADOWS 4
  73. #define MAX_LIGHT_DISTANCE 2000.0f
  74. #define MAX_MESH_SYSTEM_MODELS 5
  75. char *g_pRenderableList[ MAX_MESH_SYSTEM_MODELS ] =
  76. {
  77. "models/w_minigun_reference.dmx",
  78. "models/pm_heavy_reference.dmx",
  79. "models/w_bonesaw_reference.dmx",
  80. "models/w_guitar_reference.dmx",
  81. "models/w_harpahorn.dmx",
  82. };
  83. int g_nCurrentModel = 0;
  84. struct DecalVertex_t
  85. {
  86. Vector m_vPos;
  87. Vector m_vDecalOrigin;
  88. Vector m_vDecalRight;
  89. Vector4D m_vDecalUpAndInfluence;
  90. };
  91. struct SphereVertex_t
  92. {
  93. Vector m_vPos;
  94. };
  95. struct QuadVertex_t
  96. {
  97. Vector m_vPos;
  98. Vector m_vEyeRay;
  99. };
  100. struct ViewRelatedConstants_t
  101. {
  102. VMatrix m_mViewProjection;
  103. Vector4D m_vEyePt;
  104. Vector4D m_vEyeDir;
  105. Vector4D m_flFarPlane;
  106. };
  107. struct LightingConstants_t
  108. {
  109. Vector4D m_vLightDir;
  110. Vector4D m_vLightColor;
  111. VMatrix m_mShadowMatrices[NUM_SHADOW_SPLITS];
  112. };
  113. struct DeferredLightingConstants_t
  114. {
  115. Vector4D m_vLightDir;
  116. Vector4D m_vLightColor;
  117. Vector4D m_vInvScreenExtents;
  118. Vector4D m_vEyePt;
  119. VMatrix m_mInvViewProj;
  120. VMatrix m_mShadowMatrix[NUM_SHADOW_SPLITS];
  121. };
  122. struct AerialPerspectiveConstants_t
  123. {
  124. Vector4D m_vLightDir;
  125. Vector4D m_vLightColor;
  126. Vector4D m_vInvScreenExtents;
  127. Vector4D m_vBm;
  128. Vector4D m_flG;
  129. Vector4D m_vNearAndFar;
  130. Vector4D m_vEyePt;
  131. VMatrix m_mInvViewProj;
  132. };
  133. struct DecalScreenData_t
  134. {
  135. Vector4D m_vInvScreenExtents;
  136. VMatrix m_mInvViewProj;
  137. Vector4D m_vEyePt;
  138. Vector4D m_vEyeDir;
  139. };
  140. struct BlurParams_t
  141. {
  142. Vector4D m_flBlurFalloff;
  143. Vector4D m_flSharpness;
  144. Vector4D m_flFarPlane;
  145. };
  146. #define NUM_SSAO_SAMPLES 16
  147. struct SampleSphereData_t
  148. {
  149. VMatrix m_mViewProj;
  150. Vector4D m_vRandSampleScale;
  151. Vector4D m_vSampleRadiusNBias;
  152. Vector4D m_vSphereSamples[ NUM_SSAO_SAMPLES ];
  153. };
  154. struct LightBufferData_t
  155. {
  156. Vector4D m_vInvScreenExtents;
  157. };
  158. struct SkyVSCB_t
  159. {
  160. VMatrix m_mViewProj;
  161. Vector4D m_vSkyScale;
  162. };
  163. struct SkyPSCB_t
  164. {
  165. Vector4D m_vLightDir;
  166. Vector4D m_vEyePt;
  167. Vector4D m_vLightColor;
  168. Vector4D m_vBm;
  169. Vector4D m_flG;
  170. };
  171. struct PerParticleData_t
  172. {
  173. Vector4D m_vPosRadius;
  174. Vector4D m_vColor;
  175. };
  176. struct SimulateWorkUnitWorldRender_t
  177. {
  178. CParticleCollection *m_pParticles;
  179. int m_nNumSystems;
  180. float m_flTimeStep;
  181. };
  182. const int g_nNothingRenderedStencilRef = 0;
  183. const int g_nCanSeeSkyStencilRef = 1;
  184. const int g_nCannotSeeSkyStencilRef = 2;
  185. // Globalizing these so we can render nodes in parallel
  186. class CWorldRendererTest;
  187. CWorldRendererTest *g_pWorldRendererTest = NULL;
  188. enum RenderViewFlags_t
  189. {
  190. VIEW_PLAYER_CAMERA = 0x00000001,
  191. VIEW_LIGHT_SHADOW = 0x00000002,
  192. VIEW_REFLECTION = 0x00000004,
  193. VIEW_MONITOR = 0x00000008,
  194. VIEW_POST_PROCESS = 0x00000010,
  195. VIEW_LIGHTING = 0x00000020,
  196. VIEW_DECALS = 0x00000040
  197. };
  198. enum RenderTargetType_t
  199. {
  200. DS_SHADOW_DEPTH0 = 0x0,
  201. DS_SHADOW_DEPTH1,
  202. DS_SHADOW_DEPTH2,
  203. DS_SHADOW_DEPTH_MULTIPLE,
  204. RT_SHADOW_MULTIPLE_0,
  205. RT_SHADOW_MULTIPLE_1,
  206. RT_SHADOW_BLUR_TEMP,
  207. DS_DEPTH_HIGHRES,
  208. RT_VIEW_DEPTH_HIGHRES,
  209. RT_VIEW_NORMAL_HIGHRES,
  210. RT_VIEW_SPEC_HIGHRES,
  211. RT_LIGHTING_HIGHRES, // Alpha contains occlusion
  212. RT_SPECULAR_HIGHRES,
  213. DS_DEPTH_LOWRES,
  214. RT_VIEW_DEPTH_LOWRES,
  215. RT_VIEW_NORMAL_LOWRES,
  216. RT_LIGHTING_LOWRES,
  217. RT_LIGHTING_TEMP_LOWRES,
  218. MAX_RENDER_TARGET_TYPES
  219. };
  220. char *g_pRenderTargetName[] =
  221. {
  222. {"DS_SHADOW_DEPTH0"},
  223. {"DS_SHADOW_DEPTH1"},
  224. {"DS_SHADOW_DEPTH2"},
  225. {"DS_SHADOW_DEPTH_MULTIPLE"},
  226. {"RT_SHADOW_MULTIPLE_1"},
  227. {"RT_SHADOW_MULTIPLE_2"},
  228. {"RT_SHADOW_BLUR_TEMP"},
  229. {"DS_DEPTH_HIGHRES"},
  230. {"RT_VIEW_DEPTH_HIGHRES"},
  231. {"RT_VIEW_NORMAL_HIGHRES"},
  232. {"RT_VIEW_SPEC_HIGHRES"},
  233. {"RT_LIGHTING_HIGHRES"},
  234. {"RT_SPECULAR_HIGHRES"},
  235. {"DS_DEPTH_LOWRES"},
  236. {"RT_VIEW_DEPTH_LOWRES"},
  237. {"RT_VIEW_NORMAL_LOWRES"},
  238. {"RT_LIGHTING_LOWRES"},
  239. {"RT_LIGHTING_TEMP_LOWRES"},
  240. {"MAX_RENDER_TARGET_TYPES"}
  241. };
  242. enum ViewBindingType_t
  243. {
  244. RTB_SHADOW_DEPTH0 = 0x0,
  245. RTB_SHADOW_DEPTH1,
  246. RTB_SHADOW_DEPTH2,
  247. RTB_SHADOW_DEPTH_MULTIPLE_0,
  248. RTB_SHADOW_DEPTH_MULTIPLE_1,
  249. RTB_SHADOW_DEPTH_MULTIPLE_2,
  250. RTB_SHADOW_DEPTH_MULTIPLE_3,
  251. RTB_SHADOW_DEPTH_MULTIPLE_4,
  252. RTB_SHADOW_DEPTH_MULTIPLE_5,
  253. RTB_SHADOW_DEPTH_MULTIPLE_6,
  254. RTB_SHADOW_DEPTH_MULTIPLE_7,
  255. RTB_SHADOW_DEPTH_MULTIPLE_8,
  256. RTB_SHADOW_DEPTH_MULTIPLE_9,
  257. RTB_SHADOW_DEPTH_MULTIPLE_10,
  258. RTB_SHADOW_DEPTH_MULTIPLE_11,
  259. RTB_SHADOW_DEPTH_MULTIPLE_12,
  260. RTB_SHADOW_DEPTH_MULTIPLE_13,
  261. RTB_SHADOW_DEPTH_MULTIPLE_14,
  262. RTB_SHADOW_DEPTH_MULTIPLE_15,
  263. RTB_SHADOW_DEPTH_MULTIPLE_16,
  264. RTB_SHADOW_DEPTH_MULTIPLE_17,
  265. RTB_SHADOW_DEPTH_MULTIPLE_18,
  266. RTB_SHADOW_DEPTH_MULTIPLE_19,
  267. RTB_SHADOW_DEPTH_MULTIPLE_20,
  268. RTB_SHADOW_DEPTH_MULTIPLE_21,
  269. RTB_SHADOW_DEPTH_MULTIPLE_22,
  270. RTB_SHADOW_DEPTH_MULTIPLE_23,
  271. RTB_SHADOW_DEPTH_MULTIPLE_24,
  272. RTB_SHADOW_DEPTH_MULTIPLE_25,
  273. RTB_SHADOW_DEPTH_MULTIPLE_26,
  274. RTB_SHADOW_DEPTH_MULTIPLE_27,
  275. RTB_SHADOW_DEPTH_MULTIPLE_28,
  276. RTB_SHADOW_DEPTH_MULTIPLE_29,
  277. RTB_SHADOW_DEPTH_MULTIPLE_30,
  278. RTB_SHADOW_DEPTH_MULTIPLE_31,
  279. RTB_DEFERRED_DEPTH_NORM_SPEC,
  280. RTB_DEFERRED_SCALE_DOWN,
  281. RTB_DEFERRED_NORM_SPEC,
  282. RTB_CLEAR_SPEC_HIGHRES,
  283. RTB_LIGHTING_HIGHRES,
  284. RTB_LIGHTING_LOWRES,
  285. RTB_SSAO_LOWRES,
  286. RTB_BILAT_UPSAMPLE_0,
  287. RTB_BILAT_UPSAMPLE_1,
  288. RTB_LIGHT_BLUR_0,
  289. RTB_LIGHT_BLUR_1,
  290. RTB_SHADOW_BLUR_0,
  291. RTB_SHADOW_BLUR_1,
  292. RTB_SHADOW_BLUR_2,
  293. RTB_SAMPLE_LIGHTING,
  294. RTB_AERIAL_PERSPECTIVE,
  295. RTB_SKY,
  296. RTB_FORWARD,
  297. MAX_VIEW_BINDING_TYPES
  298. };
  299. ViewRelatedConstants_t CreateViewConstantsForFrustum( CWorldRenderFrustum* pFrustum )
  300. {
  301. const Vector vEyePt = pFrustum->GetCameraPosition();
  302. Vector vEyeDir = pFrustum->Forward();
  303. float flFarPlane = pFrustum->GetFarPlane();
  304. vEyeDir /= flFarPlane;
  305. ViewRelatedConstants_t viewConstants;
  306. viewConstants.m_mViewProjection = pFrustum->GetViewProj();
  307. viewConstants.m_vEyePt.Init( vEyePt.x, vEyePt.y, vEyePt.z, 1 );
  308. viewConstants.m_flFarPlane.Init( flFarPlane, flFarPlane, flFarPlane, 1 );
  309. viewConstants.m_vEyeDir.Init( vEyeDir.x, vEyeDir.y, vEyeDir.z, 1 );
  310. return viewConstants;
  311. }
  312. #define MAX_SIMUL_VIEWS 5
  313. class CRenderView;
  314. class CStaticMeshRenderable
  315. {
  316. public:
  317. CStaticMeshRenderable() {}
  318. ~CStaticMeshRenderable() {}
  319. inline bool operator==( const CStaticMeshRenderable& src ) const { return src.m_pDrawCall == m_pDrawCall; }
  320. IBVHNode *m_pNode;
  321. CBVHDrawCall *m_pDrawCall;
  322. };
  323. class CDynamicRenderable
  324. {
  325. public:
  326. CDynamicRenderable() {}
  327. ~CDynamicRenderable() {}
  328. inline bool operator==( const CDynamicRenderable &src ) const { return src.m_hRenderable == m_hRenderable; }
  329. HRenderableStrong m_hRenderable;
  330. VMatrix m_mWorld;
  331. Vector m_vOrigin;
  332. };
  333. class CPointLightRenderable
  334. {
  335. public:
  336. CPointLightRenderable() {}
  337. ~CPointLightRenderable() {}
  338. inline bool operator==( const CPointLightRenderable& src ) const { return src.m_pLight == m_pLight; }
  339. PointLightData_t *m_pLight;
  340. Vector m_vOrigin;
  341. };
  342. class CSpotLightRenderable
  343. {
  344. public:
  345. CSpotLightRenderable() {}
  346. ~CSpotLightRenderable() {}
  347. inline bool operator==( const CSpotLightRenderable& src ) const { return src.m_pLight == m_pLight; }
  348. SpotLightData_t *m_pLight;
  349. Vector m_vOrigin;
  350. float m_flSquaredDistToEye;
  351. bool m_bInterior;
  352. bool m_bValid;
  353. };
  354. class CHemiLightRenderable
  355. {
  356. public:
  357. CHemiLightRenderable() {}
  358. ~CHemiLightRenderable() {}
  359. inline bool operator==( const CHemiLightRenderable& src ) const { return src.m_pLight == m_pLight; }
  360. HemiLightData_t *m_pLight;
  361. Vector m_vOrigin;
  362. };
  363. struct RenderJob_t
  364. {
  365. CWorldRendererTest *m_pTestApp;
  366. CRenderView *m_pRenderView;
  367. int m_nStartStatic;
  368. int m_nCountStatic;
  369. int m_nStartDynamic;
  370. int m_nCountDynamic;
  371. int m_nIndex;
  372. };
  373. class CRenderView
  374. {
  375. public:
  376. CRenderView() {}
  377. ~CRenderView() { g_pRenderDevice->DestroyRenderTargetBinding( m_hRenderTargetBinding ); }
  378. void Init( IRenderDevice* pRenderDevice,
  379. CWorldRenderFrustum *pFrustum,
  380. RenderTargetBinding_t hRenderTargetBinding,
  381. RenderViewport_t &viewport,
  382. RenderViewFlags_t nFlags,
  383. int nPass,
  384. int nViewType )
  385. {
  386. g_pRenderDevice = pRenderDevice;
  387. m_pFrustum = pFrustum;
  388. m_hRenderTargetBinding = hRenderTargetBinding;
  389. m_viewport = viewport;
  390. m_nFlags = nFlags;
  391. m_nPass = nPass;
  392. m_nViewType = nViewType;
  393. m_bValid = true;
  394. }
  395. RenderTargetBinding_t GetRenderTargetBinding() { return m_hRenderTargetBinding; }
  396. RenderViewFlags_t GetViewFlags() { return m_nFlags; }
  397. int GetRenderPass() { return m_nPass; }
  398. int GetViewType() { return m_nViewType; }
  399. CWorldRenderFrustum *GetFrustum() { return m_pFrustum; }
  400. IRenderDevice *GetRenderDevice() { return g_pRenderDevice; }
  401. bool IsValid() { return m_bValid; }
  402. void SetValid( bool bValid ) { m_bValid = bValid; }
  403. void UpdateFrustum( CWorldRenderFrustum *pFrustum )
  404. {
  405. m_pFrustum = pFrustum;
  406. }
  407. void Clear( IRenderContext *pRenderContext, Vector4D &vClearColor, int nFlags )
  408. {
  409. Assert( pRenderContext );
  410. BeginRender( pRenderContext );
  411. pRenderContext->Clear( vClearColor, nFlags );
  412. // don't call endrender because it clears the rendercontext and the renderable list
  413. pRenderContext->Submit();
  414. }
  415. void BeginRender( IRenderContext *pRenderContext )
  416. {
  417. pRenderContext->BindRenderTargets( m_hRenderTargetBinding );
  418. pRenderContext->SetViewports( 1, &m_viewport );
  419. }
  420. void EndRender( IRenderContext *pRenderContext, bool bClearList = true )
  421. {
  422. if ( pRenderContext )
  423. {
  424. pRenderContext->Submit();
  425. }
  426. if ( bClearList )
  427. {
  428. if ( m_renderableList.Count() > 0 )
  429. {
  430. m_renderableList.SetCountNonDestructively( 0 );
  431. }
  432. if ( m_dynList.Count() > 0 )
  433. {
  434. m_dynList.SetCountNonDestructively( 0 );
  435. }
  436. }
  437. }
  438. void AddStaticMeshRenderable( CStaticMeshRenderable *pRenderable )
  439. {
  440. m_renderableList.AddToTail( pRenderable );
  441. }
  442. void AddDynamicRenderable( CDynamicRenderable *pRenderable )
  443. {
  444. m_dynList.AddToTail( pRenderable );
  445. }
  446. bool HasRenderables() { return ( ( m_renderableList.Count() != 0 ) || ( m_dynList.Count() != 0 ) ); }
  447. CUtlVector< CStaticMeshRenderable* > &GetRenderableList() { return m_renderableList; }
  448. CUtlVector< CDynamicRenderable* > &GetDynamicList() { return m_dynList; }
  449. private:
  450. RenderTargetBinding_t m_hRenderTargetBinding;
  451. RenderViewport_t m_viewport;
  452. RenderViewFlags_t m_nFlags;
  453. int m_nPass;
  454. int m_nViewType;
  455. bool m_bValid;
  456. IRenderDevice *g_pRenderDevice;
  457. CWorldRenderFrustum *m_pFrustum;
  458. CUtlVector< CStaticMeshRenderable* > m_renderableList;
  459. CUtlVector< CDynamicRenderable* > m_dynList;
  460. };
  461. float RPercent()
  462. {
  463. return float( rand() - (RAND_MAX/2) ) / (float)(RAND_MAX/2);
  464. }
  465. float RPercentABS()
  466. {
  467. return float( rand() ) / (float)(RAND_MAX);
  468. }
  469. //-----------------------------------------------------------------------------
  470. // Tests the world renderer
  471. //-----------------------------------------------------------------------------
  472. class CWorldRendererTest : public CRenderSystemBenchmarkTest
  473. {
  474. typedef CRenderSystemBenchmarkTest BaseClass;
  475. public:
  476. CWorldRendererTest( int nVariant );
  477. virtual ~CWorldRendererTest( void );
  478. virtual void RenderFrame( const RenderViewport_t &viewport, PlatWindow_t hWnd );
  479. virtual void RenderFrame_Internal( const RenderViewport_t &viewport );
  480. virtual void SimulateFrame( float flTimeStep );
  481. virtual void GetDescription( char *pNameBufferOut, size_t nBufLen );
  482. virtual bool ProcessUserInput( const InputEvent_t &ie );
  483. virtual bool CanBeRun();
  484. void RenderViewStatic( CRenderView *pRenderView, int nStart, int nCount, int nIndex );
  485. void RenderViewDynamic( CRenderView *pRenderView, int nStart, int nCount, int nIndex );
  486. void SetStateForRenderViewType( IRenderContext *pRenderContext, int nRenderView );
  487. ConstantBufferHandle_t GetViewRelated() { return m_hViewRelated; }
  488. ConstantBufferHandle_t GetLightBufferRelated() { return m_hLightBufferData; }
  489. IResourceDictionary *GetResourceDictionary() { return m_pResourceDictionary; }
  490. RsDepthStencilStateHandle_t GetSetStencilDS() { return m_hSetStencilDS; }
  491. LightBufferData_t *GetLightBufferData() { return &m_lightBufferData; }
  492. private:
  493. void SetupMultiShadowMatrices( int nViewportStart, int nSqrtNumShadows, float flBias );
  494. void SetupShadowMatrices();
  495. void CullRenderablesAgainstView( CRenderView &renderView, CUtlVector<CStaticMeshRenderable> &renderableList, CUtlVector<CDynamicRenderable> &dynList );
  496. void RenderView( CRenderView &renderView );
  497. void UpdateShadowData();
  498. void UpdateFlashlightData();
  499. void UpdateViewModelData();
  500. void UpdateDroppedRenderables( float flElapsedTime );
  501. void GenerateRenderables( Vector &vCameraPos );
  502. void GeneratePointLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye );
  503. void GenerateSpotLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye );
  504. void GenerateHemiLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye );
  505. void BilateralUpsample();
  506. void RenderSSAO();
  507. void ScaleDepthAndNormalBuffers();
  508. void RenderAerialPerspective();
  509. void RenderSky();
  510. void RenderShadowDepthBuffers( IRenderContext *pRenderContext );
  511. void RenderSunShadowFrustums( IRenderContext *pRenderContext );
  512. void RenderBouncedLight( IRenderContext *pRenderContext );
  513. void RenderDirectLight( IRenderContext *pRenderContext );
  514. void BlurLightBuffer( );
  515. void BlurShadowBuffers( );
  516. void RenderDecals( IRenderContext *pRenderContext, int nVariation );
  517. void RenderDynamic( IRenderContext *pRenderContext, CDynamicRenderable *pRenderable, int nVariation, bool bSunDepth, bool bSetStencil );
  518. void RenderParticleLights( IRenderContext *pRenderContext, CParticleCollection *pParticles, int nVariation, bool bSunDepth, bool bSetStencil );
  519. void RenderScenePointLights( IRenderContext *pRenderContext, CUtlVector<CPointLightRenderable> &lightVector, bool bInterior );
  520. void RenderSceneHemiLights( IRenderContext *pRenderContext, CUtlVector<CHemiLightRenderable> &lightVector, bool bInterior );
  521. void RenderSceneSpotLights( IRenderContext *pRenderContext, CUtlVector<CSpotLightRenderable> &lightVector, bool bInterior );
  522. void RenderShadowedSpotLights( IRenderContext *pRenderContext, CUtlVector<CSpotLightRenderable> &lightVector );
  523. void SimulateParticles( float flTimeStep );
  524. void CalculateEyeRays( float flFarPlane );
  525. void InitDeferredData( const RenderViewport_t &viewport );
  526. void InitParticleData();
  527. void InitRenderableData();
  528. void UpdateFrustum( int nWidth, int nHeight );
  529. void AddDecal( IRenderContext *pRenderContext, Vector &vHit, Vector &vDecalDir, float flDecalSizeU, float flDecalSizeV, float flDecalShift, float flDecalInfluenceLength, bool bPaint );
  530. void AddWallMonster( IRenderContext *pRenderContext, Vector &vHit, Vector &vDecalDir, float flDecalSizeU, float flDecalSizeV, float flDecalShift, float flDecalInfluenceLength );
  531. void DropRenderable();
  532. void CreateSphere( int nTessellation );
  533. void CreateHemi( int nTessellationRes );
  534. void CreateCone( int nTessellation );
  535. void RenderScreenQuad( IRenderContext *pRenderContext, Vector *pEyeRays, const char *pDebugName );
  536. RenderShaderHandle_t GetVertexShader( char *pShaderName, IRenderDevice *pDevice, const char *pShaderVersion, const char *pDefineText = NULL );
  537. RenderShaderHandle_t GetPixelShader( char *pShaderName, IRenderDevice *pDevice, const char *pShaderVersion, const char *pDefineText = NULL );
  538. HRenderTexture CreateRenderTarget( RenderTargetType_t type, const RenderViewport_t &viewport );
  539. RenderTargetBinding_t CreateRenderTargetBinding( ViewBindingType_t type, const RenderViewport_t &viewport );
  540. void InitRenderTargetsAndViews( const RenderViewport_t &viewport );
  541. CWorldRenderFrustum *m_pFrustum;
  542. CWorldRenderFrustum *m_pDropFrustum;
  543. Vector m_vCullPos;
  544. usercmd_t m_cmd;
  545. HRenderTextureStrong m_pRenderTargets[ MAX_RENDER_TARGET_TYPES ];
  546. RenderTargetBinding_t m_pViewBindings[ MAX_VIEW_BINDING_TYPES ];
  547. CRenderView m_pRenderViews[ MAX_VIEW_BINDING_TYPES ];
  548. int m_nRenderThreads;
  549. RenderJob_t *m_pRenderJobs;
  550. // Resources
  551. ConstantBufferHandle_t m_hViewRelated;
  552. ConstantBufferHandle_t m_hSingleMatrixRelated;
  553. ConstantBufferHandle_t m_hLightingRelated;
  554. ConstantBufferHandle_t m_hDeferredLightingRelated;
  555. ConstantBufferHandle_t m_hLightBufferData;
  556. ConstantBufferHandle_t m_hDecalScreenData;
  557. ConstantBufferHandle_t m_hBlurParams;
  558. ConstantBufferHandle_t m_hSphereSampleData;
  559. CWorldRenderFrustum *m_pSplitFrustums[ NUM_SHADOW_SPLITS ];
  560. VMatrix m_pShadowMatrices[ NUM_SHADOW_SPLITS ];
  561. CWorldRenderFrustum *m_pMultiShadowFrustums[ NUM_MULTI_SHADOWS ];
  562. VMatrix m_pMultiShadowMatrices[ NUM_MULTI_SHADOWS ];
  563. LightingConstants_t m_forwardLightingData;
  564. DeferredLightingConstants_t m_deferredLightingData;
  565. BlurParams_t m_blurParams;
  566. LightBufferData_t m_lightBufferData;
  567. AerialPerspectiveConstants_t m_aerialPerspectiveData;
  568. SampleSphereData_t m_sphereSampleData;
  569. float m_flSampleRadius;
  570. // Render list and renderable lists
  571. CUtlVector<IBVHNode*> m_renderList;
  572. CUtlVector<CStaticMeshRenderable> m_renderableList;
  573. CUtlVector<CDynamicRenderable> m_dynRenderableList;
  574. CUtlVector<CPointLightRenderable> m_exteriorPointLights;
  575. CUtlVector<CPointLightRenderable> m_interiorPointLights;
  576. CUtlVector<CSpotLightRenderable> m_exteriorSpotLights;
  577. CUtlVector<CSpotLightRenderable> m_interiorSpotLights;
  578. CUtlVector<CHemiLightRenderable> m_exteriorHemiLights;
  579. CUtlVector<CHemiLightRenderable> m_interiorHemiLights;
  580. CUtlVector<CSpotLightRenderable> m_shadowedSpotLights;
  581. SpotLightData_t m_flashlight;
  582. float m_flMaxLightEncompassingFarPlane;
  583. bool m_bEnableVis;
  584. bool m_bDropFrustum;
  585. bool m_bSSAO;
  586. bool m_bBlurLighting;
  587. bool m_bBlurShadows;
  588. bool m_bDrawAerialPerspective;
  589. bool m_bDrawBouncedLight;
  590. bool m_bDrawDirectLight;
  591. bool m_bLightingOnly;
  592. bool m_bFlashlight;
  593. bool m_bViewLowTexture;
  594. // Deferred resources
  595. bool m_bMultiThreaded;
  596. bool m_bDeferred;
  597. bool m_bDeferredInit;
  598. bool m_bRenderTargetsInit;
  599. RenderTargetType_t m_nViewBuffer;
  600. float m_flLowResBufferScale;
  601. RenderShaderHandle_t m_hCopyTexture[4];
  602. RenderShaderHandle_t m_hBilateralBlur[4];
  603. RenderShaderHandle_t m_hShadowBlur[4];
  604. RenderInputLayout_t m_hQuadLayout;
  605. Vector m_vEyeRays[4];
  606. Vector m_vEyeLocalRays[4];
  607. int m_nRandTextureSize;
  608. HRenderTextureStrong m_hFlashlightCookie[2];
  609. HRenderTextureStrong m_hRandomTexture;
  610. RenderShaderHandle_t m_hSSAOPS;
  611. RenderShaderHandle_t m_hAerialPerspectivePS[2];
  612. ConstantBufferHandle_t m_hAerialPerspectivePSCB;
  613. RsBlendStateHandle_t m_hExtinctionBS;
  614. RsBlendStateHandle_t m_hInscatteringBS;
  615. RsBlendStateHandle_t m_hAdditiveBS;
  616. RsBlendStateHandle_t m_hWriteAlphaBS;
  617. RsBlendStateHandle_t m_hWriteAllBS;
  618. RsDepthStencilStateHandle_t m_hSetStencilDS;
  619. RsDepthStencilStateHandle_t m_hZWriteNoTestDS;
  620. RenderShaderHandle_t m_hShadowFrustumVS[3];
  621. RenderShaderHandle_t m_hShadowFrustumPS[3];
  622. int m_nSphereIndices;
  623. int m_nHemiIndices;
  624. int m_nConeIndices;
  625. HRenderBufferStrong m_hSphereVB;
  626. HRenderBufferStrong m_hSphereIB;
  627. HRenderBufferStrong m_hHemiVB;
  628. HRenderBufferStrong m_hHemiIB;
  629. HRenderBufferStrong m_hConeVB;
  630. HRenderBufferStrong m_hConeIB;
  631. RenderShaderHandle_t m_hSceneLightVS[3];
  632. RenderShaderHandle_t m_hSceneLightPS[6];
  633. RenderInputLayout_t m_hSceneLightLayout[3];
  634. // Sky
  635. RenderInputLayout_t m_hSphereLayout;
  636. RenderShaderHandle_t m_hSkyVS;
  637. RenderShaderHandle_t m_hSkyPS;
  638. ConstantBufferHandle_t m_hSkyVSCB;
  639. ConstantBufferHandle_t m_hSkyPSCB;
  640. SkyPSCB_t m_skyData;
  641. Vector4D m_vRenderLightColor;
  642. bool m_bRenderSky;
  643. RsDepthStencilStateHandle_t m_hZTestAndStencilTestDS;
  644. RsDepthStencilStateHandle_t m_hStencilTestDS;
  645. // Decals
  646. RenderInputLayout_t m_hDecalLayout;
  647. HRenderBufferStrong m_hDecalVB;
  648. HRenderBufferStrong m_hDecalVB2;
  649. HRenderBufferStrong m_hDecalVB3;
  650. HRenderBufferStrong m_hDecalIB;
  651. RenderShaderHandle_t m_hDecalVS[2];
  652. RenderShaderHandle_t m_hDecalPS[2];
  653. HRenderTextureStrong m_hDecalAlbedo;
  654. HRenderTextureStrong m_hDecalAlbedo2;
  655. HRenderTextureStrong m_hDecalNormal;
  656. HRenderTextureStrong m_hDecalNormal2;
  657. HRenderTextureStrong m_hDecalNormal3[3];
  658. DecalScreenData_t m_decalScreenData;
  659. DecalScreenData_t m_lowResScreenData;
  660. DecalScreenData_t m_shadowScreenData;
  661. DecalVertex_t *m_pDecalBackingStore;
  662. DecalVertex_t *m_pDecalBackingStore2;
  663. int m_nMaxDecals;
  664. bool m_bFullBuffer;
  665. bool m_bFullBuffer2;
  666. int m_nGlobalDecalPos;
  667. int m_nGlobalDecalPos2;
  668. int m_nGlobalDecalPos3;
  669. Vector m_vPreviousMonsterNormal;
  670. int m_nWallMonsterTexture;
  671. float m_flWallMonsterTimer;
  672. int m_nNumTriangles;
  673. // Particles
  674. CUtlVector<CParticleCollection*> m_lightSystemList;
  675. CUtlVector<CParticleCollection*> m_sphereSystemList;
  676. CUtlVector<SimulateWorkUnitWorldRender_t> m_particleWorkUnits;
  677. RenderInputLayout_t m_hPointLightLayout;
  678. RenderShaderHandle_t m_hPointLightVS[5];
  679. RenderShaderHandle_t m_hPointLightPS[5];
  680. // Renderable test
  681. RenderShaderHandle_t m_hSimpleMeshVS[4];
  682. RenderShaderHandle_t m_hSimpleMeshPS[4];
  683. Vector m_vLightDir;
  684. Vector2D m_vLightAngleElevation;
  685. float m_flLightAngSpeed;
  686. float m_flLightElvSpeed;
  687. int m_nShadowSplits;
  688. RenderViewport_t m_shadowViewport;
  689. RenderViewport_t m_multiShadowViewport[ NUM_MULTI_SHADOWS ];
  690. VMatrix m_splitScaleBiasMatrices[ NUM_SHADOW_SPLITS ];
  691. VMatrix m_multiShadowScaleBiasMatrices[ NUM_MULTI_SHADOWS ];
  692. int m_nCurrentFrameNumber;
  693. int m_nShadowSize;
  694. int m_nLastFrustumWidth;
  695. int m_nLastFrustumHeight;
  696. int m_nWindowCenterX;
  697. int m_nWindowCenterY;
  698. int m_nCursorDeltaX;
  699. int m_nCursorDeltaY;
  700. int m_nCursorDeltaResetX;
  701. int m_nCursorDeltaResetY;
  702. int m_nReportLevel;
  703. float m_flDecalCountdown;
  704. float m_flParticleCountdown;
  705. float m_flNearPlane;
  706. float m_flFarPlane;
  707. // WorldRenderer
  708. IWorldRendererMgr *m_pWorldRendererMgr;
  709. IWorldRenderer *m_pWorldRenderer;
  710. IResourceDictionary *m_pResourceDictionary;
  711. bool m_bWorldLoaded;
  712. };
  713. DECLARE_TEST( CWorldRendererTest );
  714. static void PerformStaticMeshWorkUnit( RenderJob_t & job )
  715. {
  716. job.m_pTestApp->RenderViewStatic( job.m_pRenderView, job.m_nStartStatic, job.m_nCountStatic, job.m_nIndex );
  717. job.m_pTestApp->RenderViewDynamic( job.m_pRenderView, job.m_nStartDynamic, job.m_nCountDynamic, job.m_nIndex );
  718. }
  719. static int g_pBoxIndices[36] = { 2,1,0,3,2,0, 6,5,1,2,6,1, 7,4,5,6,7,5, 3,0,4,7,3,4, 6,2,3,7,6,3, 1,5,4,0,1,4 };
  720. //-----------------------------------------------------------------------------
  721. // Constructor, destructor
  722. //-----------------------------------------------------------------------------
  723. CWorldRendererTest::CWorldRendererTest( int nVariant ) : BaseClass( nVariant )
  724. {
  725. if ( !g_pWorldRendererMgr )
  726. return;
  727. g_pWorldRendererTest = this;
  728. // Disable HW instancing on GL for now
  729. if ( g_nPlatform == RST_PLATFORM_GL )
  730. g_pWorldRendererMgr->SetHWInstancingEnabled( false );
  731. CRenderContextPtr pRenderContext( g_pRenderDevice );
  732. m_flDecalCountdown = 0.0f;
  733. m_flParticleCountdown = 0.0f;
  734. if ( IsPlatformX360() )
  735. {
  736. m_nShadowSize = 512;
  737. }
  738. else
  739. {
  740. m_nShadowSize = 1024;
  741. }
  742. m_shadowViewport.Init( 0, 0, m_nShadowSize, m_nShadowSize, 0, 1 );
  743. SetupShadowMatrices();
  744. m_nViewBuffer = RT_LIGHTING_HIGHRES;
  745. m_nRenderThreads = g_pThreadPool->NumThreads();
  746. m_pRenderJobs = new RenderJob_t[ m_nRenderThreads ];
  747. m_nCurrentFrameNumber = 0;
  748. m_hViewRelated = g_pRenderDevice->CreateConstantBuffer( sizeof( ViewRelatedConstants_t ) );
  749. m_hSingleMatrixRelated = g_pRenderDevice->CreateConstantBuffer( sizeof( VMatrix ) );
  750. m_hLightingRelated = g_pRenderDevice->CreateConstantBuffer( sizeof( LightingConstants_t ) );
  751. m_hSkyVSCB = g_pRenderDevice->CreateConstantBuffer( sizeof( SkyVSCB_t ) );
  752. m_hSkyPSCB = g_pRenderDevice->CreateConstantBuffer( sizeof( SkyPSCB_t ) );
  753. //m_flLowResBufferScale = 0.5f;
  754. m_flLowResBufferScale = 0.5f;
  755. m_bEnableVis = true;
  756. m_bDropFrustum = false;
  757. m_bSSAO = true;
  758. m_bBlurLighting = false;
  759. m_bBlurShadows = true;
  760. m_bDrawAerialPerspective = true;
  761. m_bDrawBouncedLight = true;
  762. m_bDrawDirectLight = true;
  763. m_bLightingOnly = false;
  764. m_bFlashlight = false;
  765. m_bViewLowTexture = false;
  766. // Deferred
  767. m_bDeferred = true;
  768. m_bDeferredInit = false;
  769. m_bRenderTargetsInit = false;
  770. m_bMultiThreaded = true;
  771. // No deferred on GL yet
  772. if ( g_nPlatform == RST_PLATFORM_GL || g_nPlatform == RST_PLATFORM_X360 )
  773. m_bDeferred = false;
  774. m_bWorldLoaded = true;
  775. // Create a world renderer
  776. m_pWorldRenderer = g_pWorldRendererMgr->CreateWorldRenderer();
  777. // Load the world
  778. const char *pWorldName = CommandLine()->ParmValue( "-map", "maps/ep2_outland_10" );
  779. if ( !m_pWorldRenderer->Unserialize( pWorldName ) )
  780. {
  781. Error( "Cannot load world!\n" );
  782. m_bWorldLoaded = false;
  783. return;
  784. }
  785. m_pResourceDictionary = m_pWorldRenderer->GetResourceDictionary();
  786. // Initialization
  787. static const uint64 sMegabyte = 1024 * 1024;
  788. uint64 nMaxGPUMemory = 768 * sMegabyte;
  789. uint64 nMaxSysMemory = 512 * sMegabyte;
  790. if ( IsPlatformX360() )
  791. {
  792. // Set this low until texture eviction works on the 360
  793. nMaxGPUMemory = 256 * sMegabyte;
  794. nMaxSysMemory = 32 * sMegabyte;
  795. }
  796. m_pWorldRenderer->Initialize( g_pRenderDevice, nMaxGPUMemory, nMaxSysMemory );
  797. // Alloc split frustums
  798. for ( int s=0; s<NUM_SHADOW_SPLITS; ++s )
  799. {
  800. m_pSplitFrustums[s] = (CWorldRenderFrustum*)MemAlloc_AllocAligned( sizeof( CWorldRenderFrustum ), 16 );
  801. }
  802. // Alloc multi-shadow frustums
  803. for ( int s=0; s<NUM_MULTI_SHADOWS; ++s )
  804. {
  805. m_pMultiShadowFrustums[s] = (CWorldRenderFrustum*)MemAlloc_AllocAligned( sizeof( CWorldRenderFrustum ), 16 );
  806. }
  807. // Build up a frustum
  808. m_pFrustum = (CWorldRenderFrustum*)MemAlloc_AllocAligned( sizeof( CWorldRenderFrustum ), 16 );
  809. m_pDropFrustum = (CWorldRenderFrustum*)MemAlloc_AllocAligned( sizeof( CWorldRenderFrustum ), 16 );
  810. m_nLastFrustumWidth = 1024;
  811. m_nLastFrustumHeight = 768;
  812. float flFOVY = 90.0f;
  813. float flAspect = m_nLastFrustumWidth / (float)m_nLastFrustumHeight;
  814. // Find the player start
  815. Vector vEyePos( 0, 0, 0 );
  816. QAngle vAngles( -64, 90, 0 );
  817. CUtlVector< KeyValues* > playerstarts;
  818. m_pWorldRenderer->GetEntities( "info_player_start", playerstarts );
  819. if ( playerstarts.Count() )
  820. {
  821. const char *pEye = playerstarts[0]->GetString( "origin" );
  822. const char *pAngles = playerstarts[0]->GetString( "angles" );
  823. sscanf( pEye, "%f %f %f", &vEyePos.x, &vEyePos.y, &vEyePos.z );
  824. sscanf( pAngles, "%f %f %f", &vAngles.x, &vAngles.y, &vAngles.z );
  825. vEyePos.z += 64;
  826. }
  827. // eyepos, eyeangles, znear, zfar, fov, aspect ratio
  828. m_flNearPlane = 10.0f;
  829. m_flFarPlane = 18000.0f;
  830. m_pFrustum->InitCamera( vEyePos, vAngles, m_flNearPlane, m_flFarPlane, CalcFovX(flFOVY, flAspect), flAspect );
  831. m_pFrustum->UpdateFrustumFromCamera();
  832. // parallel spit shadow maps
  833. m_vLightAngleElevation.x = 120.0f;
  834. m_vLightAngleElevation.y = 70.0f;
  835. m_vLightDir = Vector(0,0,1);
  836. Q_memset( &m_skyData, 0, sizeof( SkyPSCB_t ) );
  837. m_vRenderLightColor = Vector4D(1,1,1,1);
  838. m_flLightAngSpeed = 20.0f;
  839. m_flLightElvSpeed = 20.0f;
  840. m_nShadowSplits = NUM_SHADOW_SPLITS;
  841. const char *pVertexShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_VERTEX_SHADER );
  842. const char *pPixelShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_PIXEL_SHADER );
  843. // sphere and cone primitives
  844. CreateSphere( 10 );
  845. CreateHemi( 10 );
  846. CreateCone( 10 );
  847. if ( m_bDeferred )
  848. {
  849. // Decals
  850. m_nMaxDecals = 2000;
  851. m_bFullBuffer = false;
  852. m_nGlobalDecalPos = 0;
  853. m_bFullBuffer2 = false;
  854. m_nGlobalDecalPos2 = 0;
  855. m_nGlobalDecalPos3 = 0;
  856. m_vPreviousMonsterNormal.Init( 0, 0, 1 );
  857. m_nWallMonsterTexture = 0;
  858. m_flWallMonsterTimer = 0.0f;
  859. static RenderInputLayoutField_t decalLayout[] =
  860. {
  861. DEFINE_PER_VERTEX_FIELD( 0, "position", 0, DecalVertex_t, m_vPos )
  862. DEFINE_PER_VERTEX_FIELD( 0, "texcoord", 0, DecalVertex_t, m_vDecalOrigin )
  863. DEFINE_PER_VERTEX_FIELD( 0, "texcoord", 1, DecalVertex_t, m_vDecalRight )
  864. DEFINE_PER_VERTEX_FIELD( 0, "texcoord", 2, DecalVertex_t, m_vDecalUpAndInfluence )
  865. };
  866. m_hDecalLayout = g_pRenderDevice->CreateInputLayout( "decallayout", ARRAYSIZE( decalLayout ), decalLayout );
  867. BufferDesc_t decalDesc;
  868. decalDesc.m_nElementCount = m_nMaxDecals * 8;
  869. decalDesc.m_nElementSizeInBytes = sizeof( DecalVertex_t );
  870. decalDesc.m_pBudgetGroupName = "decals";
  871. decalDesc.m_pDebugName = "decalVB";
  872. m_hDecalVB = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_SEMISTATIC, decalDesc );
  873. decalDesc.m_pDebugName = "decalVB2";
  874. m_hDecalVB2 = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_SEMISTATIC, decalDesc );
  875. decalDesc.m_nElementCount = 8;
  876. decalDesc.m_pDebugName = "decalVB3";
  877. m_hDecalVB3 = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_SEMISTATIC, decalDesc );
  878. decalDesc.m_nElementCount = m_nMaxDecals * 36;
  879. decalDesc.m_nElementSizeInBytes = sizeof( uint16 );
  880. decalDesc.m_pDebugName = "decalIB";
  881. m_hDecalIB = g_pRenderDevice->CreateIndexBuffer( RENDER_BUFFER_TYPE_STATIC, decalDesc );
  882. LockDesc_t lockDesc;
  883. pRenderContext->LockIndexBuffer( m_hDecalIB, m_nMaxDecals * 36 * sizeof( uint16 ), &lockDesc );
  884. uint16 *pIndices = (uint16*)lockDesc.m_pMemory;
  885. int nOffset = 0;
  886. for ( int d=0; d<m_nMaxDecals; ++d )
  887. {
  888. for ( int i=0; i<36; ++i )
  889. {
  890. pIndices[i] = g_pBoxIndices[i] + nOffset;
  891. }
  892. nOffset += 8;
  893. pIndices += 36;
  894. }
  895. pRenderContext->UnlockIndexBuffer( m_hDecalIB, m_nMaxDecals * 36 * sizeof( uint16 ), &lockDesc );
  896. m_hDecalVS[0] = GetVertexShader( "maps/decalsvs", g_pRenderDevice, pVertexShaderVersion, "#define SHADER_VARIATION 0\n" );
  897. m_hDecalPS[0] = GetPixelShader( "maps/decalsps", g_pRenderDevice, pPixelShaderVersion, "#define SHADER_VARIATION 0\n" );
  898. m_hDecalVS[1] = GetVertexShader( "maps/decalsvs", g_pRenderDevice, pVertexShaderVersion, "#define SHADER_VARIATION 1\n" );
  899. m_hDecalPS[1] = GetPixelShader( "maps/decalsps", g_pRenderDevice, pPixelShaderVersion, "#define SHADER_VARIATION 1\n" );
  900. m_hDecalScreenData = g_pRenderDevice->CreateConstantBuffer( sizeof( DecalScreenData_t ) );
  901. m_hDecalAlbedo = RENDER_TEXTURE_HANDLE_INVALID;//g_pRenderDevice->FindOrCreateFileTexture( "maps/decaltest_albedo.vtf" );
  902. //m_hDecalNormal = g_pRenderDevice->FindOrCreateFileTexture( "maps/decaltest_normal.vtf" );
  903. m_hDecalNormal = g_pRenderDevice->FindOrCreateFileTexture( "materials/plastercrack.vtf" );
  904. m_hDecalAlbedo2 = g_pRenderDevice->FindOrCreateFileTexture( "materials/paintdecal.vtf" );
  905. m_hDecalNormal2 = g_pRenderDevice->FindOrCreateFileTexture( "materials/paintdecalnorm.vtf" );
  906. m_hDecalNormal3[0] = g_pRenderDevice->FindOrCreateFileTexture( "materials/gearhead1.vtf" );
  907. m_hDecalNormal3[1] = g_pRenderDevice->FindOrCreateFileTexture( "materials/gearhead2.vtf" );
  908. m_hDecalNormal3[2] = g_pRenderDevice->FindOrCreateFileTexture( "materials/gearhead3.vtf" );
  909. m_pDecalBackingStore = new DecalVertex_t[ m_nMaxDecals * 8 ];
  910. m_pDecalBackingStore2 = new DecalVertex_t[ m_nMaxDecals * 8 ];
  911. }
  912. m_bRenderSky = true;
  913. if ( m_bRenderSky )
  914. {
  915. // Load shaders
  916. m_hSkyVS = GetVertexShader( "maps/skyvs", g_pRenderDevice, pVertexShaderVersion );
  917. m_hSkyPS = GetPixelShader( "maps/skyps", g_pRenderDevice, pPixelShaderVersion );
  918. }
  919. if ( m_bDeferred )
  920. {
  921. // particle system
  922. InitParticleData();
  923. }
  924. InitRenderableData();
  925. // Input
  926. Q_memset( &m_cmd, 0, sizeof( usercmd_t ) );
  927. m_nWindowCenterX = -1;
  928. m_nWindowCenterY = -1;
  929. m_nCursorDeltaX = 0;
  930. m_nCursorDeltaY = 0;
  931. m_nCursorDeltaResetX = 0;
  932. m_nCursorDeltaResetY = 0;
  933. m_nReportLevel = 0;
  934. g_pInputStackSystem->SetCursorVisible( GetInputContext(), false );
  935. }
  936. CWorldRendererTest::~CWorldRendererTest( void )
  937. {
  938. if ( !g_pWorldRendererMgr )
  939. return;
  940. g_pInputStackSystem->SetCursorVisible( GetInputContext(), true );
  941. g_pRenderDevice->DestroyConstantBuffer( m_hViewRelated );
  942. g_pRenderDevice->DestroyConstantBuffer( m_hLightingRelated );
  943. m_pWorldRenderer->DestroyResources( g_pRenderDevice );
  944. g_pWorldRendererMgr->DestroyWorldRenderer( m_pWorldRenderer );
  945. m_dynRenderableList.RemoveAll();
  946. for ( int s=0; s<NUM_SHADOW_SPLITS; ++s )
  947. {
  948. MemAlloc_FreeAligned( m_pSplitFrustums[s] );
  949. }
  950. for ( int s=0; s<NUM_MULTI_SHADOWS; ++s )
  951. {
  952. MemAlloc_FreeAligned( m_pMultiShadowFrustums[s] );
  953. }
  954. MemAlloc_FreeAligned( m_pFrustum );
  955. }
  956. class CUniformSampler
  957. {
  958. private:
  959. Vector* m_pvDirections;
  960. int m_NumSamples;
  961. int m_NumVariations;
  962. public:
  963. CUniformSampler() :
  964. m_pvDirections( NULL ),
  965. m_NumSamples( 0 ),
  966. m_NumVariations( 0 )
  967. {
  968. }
  969. ~CUniformSampler()
  970. {
  971. if ( m_pvDirections ) { delete []m_pvDirections; };
  972. }
  973. int GetNumVariations() { return m_NumVariations; }
  974. int GetNumSamples() { return m_NumSamples; }
  975. bool InitSamples( int SqrtNumSamples, int NumVariations );
  976. Vector GetSampleDirection( int Sample, int Variation );
  977. };
  978. bool CUniformSampler::InitSamples( int SqrtNumSamples, int NumVariations )
  979. {
  980. m_NumSamples = SqrtNumSamples * SqrtNumSamples;
  981. m_NumVariations = NumVariations;
  982. m_pvDirections = new Vector[ m_NumSamples * m_NumVariations ];
  983. if ( !m_pvDirections )
  984. return false;
  985. #if 1
  986. int i=0; // array index
  987. float oneoverN = 1.0f/(float)SqrtNumSamples;
  988. for ( int n=0; n<m_NumVariations; n++ )
  989. {
  990. // fill an N*N*2 array with uniformly distributed
  991. // samples across the sphere using jittered stratification
  992. for ( int a=0; a<SqrtNumSamples; a++ )
  993. {
  994. for ( int b=0; b<SqrtNumSamples; b++ )
  995. {
  996. // generate unbiased distribution of spherical coords
  997. float x = ( a + fabs( RPercent() ) ) * oneoverN; // do not reuse results
  998. float y = ( b + fabs( RPercent() ) ) * oneoverN; // each sample must be random
  999. float theta = 2.0f * acosf(sqrtf(1.0f - x));
  1000. float phi = 2.0f * M_PI * y;
  1001. // convert spherical coords to unit vector
  1002. Vector vec(sinf(theta)*cosf(phi), sinf(theta)*sinf(phi), cosf(theta));
  1003. m_pvDirections[i] = vec;
  1004. ++i;
  1005. }
  1006. }
  1007. }
  1008. #else
  1009. int i=0;
  1010. for ( int n=0; n<m_NumVariations; n++ )
  1011. {
  1012. // fill an N*N*2 array with uniformly distributed
  1013. // samples across the sphere using jittered stratification
  1014. for ( int a=0; a<SqrtNumSamples * SqrtNumSamples; a++ )
  1015. {
  1016. m_pvDirections[i].x = RPercent();
  1017. m_pvDirections[i].y = RPercent();
  1018. m_pvDirections[i].z = RPercent();
  1019. m_pvDirections[i].NormalizeInPlace();
  1020. i++;
  1021. }
  1022. }
  1023. #endif
  1024. return true;
  1025. }
  1026. Vector CUniformSampler::GetSampleDirection( int Sample, int Variation )
  1027. {
  1028. int Start = m_NumSamples * Variation;
  1029. return m_pvDirections[ Start + Sample ];
  1030. }
  1031. void CWorldRendererTest::InitDeferredData( const RenderViewport_t &viewport )
  1032. {
  1033. CRenderContextPtr pRenderContext( g_pRenderDevice );
  1034. static RenderInputLayoutField_t quadLayout[] =
  1035. {
  1036. DEFINE_PER_VERTEX_FIELD( 0, "position", 0, QuadVertex_t, m_vPos )
  1037. DEFINE_PER_VERTEX_FIELD( 0, "texcoord", 0, QuadVertex_t, m_vEyeRay )
  1038. };
  1039. m_hQuadLayout = g_pRenderDevice->CreateInputLayout( "quadlayout", ARRAYSIZE( quadLayout ), quadLayout );
  1040. // Constants
  1041. m_hDeferredLightingRelated = g_pRenderDevice->CreateConstantBuffer( sizeof( DeferredLightingConstants_t ) );
  1042. m_hLightBufferData = g_pRenderDevice->CreateConstantBuffer( sizeof( LightBufferData_t ) );
  1043. const char *pVertexShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_VERTEX_SHADER );
  1044. const char *pPixelShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_PIXEL_SHADER );
  1045. // Shaders for low-res buffers
  1046. //float flBlurFalloff = 0.0005f;
  1047. float flBlurFalloff = 0.005f;
  1048. float flSharpness = 1000.0f;
  1049. m_blurParams.m_flBlurFalloff.Init( flBlurFalloff, flBlurFalloff, flBlurFalloff, flBlurFalloff );
  1050. m_blurParams.m_flSharpness.Init( flSharpness, flSharpness, flSharpness, flSharpness );
  1051. m_blurParams.m_flFarPlane.Init( 1, 1, 1, 1 );
  1052. m_hBlurParams = g_pRenderDevice->CreateConstantBuffer( sizeof( BlurParams_t ) );
  1053. m_hCopyTexture[0] = GetPixelShader( "maps/copytextureps", g_pRenderDevice, pPixelShaderVersion, "#define SINGLE_TARGET 0\n#define COPY_TARGET_W 0\n#define COMBINE_LIGHTING 0\n" );
  1054. m_hCopyTexture[1] = GetPixelShader( "maps/copytextureps", g_pRenderDevice, pPixelShaderVersion, "#define SINGLE_TARGET 1\n#define COPY_TARGET_W 0\n#define COMBINE_LIGHTING 0\n" );
  1055. m_hCopyTexture[2] = GetPixelShader( "maps/copytextureps", g_pRenderDevice, pPixelShaderVersion, "#define SINGLE_TARGET 1\n#define COPY_TARGET_W 1\n#define COMBINE_LIGHTING 0\n" );
  1056. m_hCopyTexture[3] = GetPixelShader( "maps/copytextureps", g_pRenderDevice, pPixelShaderVersion, "#define SINGLE_TARGET 1\n#define COPY_TARGET_W 0\n#define COMBINE_LIGHTING 1\n" );
  1057. m_hBilateralBlur[0] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 1\n#define HORZ_BLUR 1\n#define BLUR_RADIUS 8\n" );
  1058. m_hBilateralBlur[1] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 1\n#define HORZ_BLUR 0\n#define BLUR_RADIUS 8\n" );
  1059. m_hBilateralBlur[2] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 1\n#define HORZ_BLUR_FULL 1\n#define BLUR_RADIUS 6\n" );
  1060. m_hBilateralBlur[3] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 1\n#define HORZ_BLUR 0\n#define BLUR_RADIUS 6\n" );
  1061. m_hShadowBlur[0] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 0\n#define HORZ_BLUR_FULL 1\n#define BLUR_RADIUS 3\n" );
  1062. m_hShadowBlur[1] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 0\n#define HORZ_BLUR 0\n#define BLUR_RADIUS 3\n" );
  1063. m_hShadowBlur[2] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 0\n#define HORZ_BLUR_FULL 1\n#define BLUR_RADIUS 2\n" );
  1064. m_hShadowBlur[3] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 0\n#define HORZ_BLUR 0\n#define BLUR_RADIUS 2\n" );
  1065. // Shaders for deferred ligthing
  1066. m_hShadowFrustumVS[0] = GetVertexShader( "maps/shadowfrustumvs", g_pRenderDevice, pVertexShaderVersion, "#define DISCARD_OUTSIDE 1\n#define ALL_FRUSTUMS 0\n" );
  1067. m_hShadowFrustumPS[0] = GetPixelShader( "maps/shadowfrustumps", g_pRenderDevice, pPixelShaderVersion, "#define DISCARD_OUTSIDE 1\n#define ALL_FRUSTUMS 0\n" );
  1068. m_hShadowFrustumVS[1] = GetVertexShader( "maps/shadowfrustumvs", g_pRenderDevice, pVertexShaderVersion, "#define ALL_FRUSTUMS 0\n" );
  1069. m_hShadowFrustumPS[1] = GetPixelShader( "maps/shadowfrustumps", g_pRenderDevice, pPixelShaderVersion, "#define ALL_FRUSTUMS 0\n" );
  1070. m_hShadowFrustumVS[2] = GetVertexShader( "maps/shadowfrustumvs", g_pRenderDevice, pVertexShaderVersion, "#define ALL_FRUSTUMS 1\n" );
  1071. m_hShadowFrustumPS[2] = GetPixelShader( "maps/shadowfrustumps", g_pRenderDevice, pPixelShaderVersion, "#define ALL_FRUSTUMS 1\n" );
  1072. // Scene light shaders
  1073. m_hSceneLightVS[0] = GetVertexShader( "maps/scenelightvs", g_pRenderDevice, pVertexShaderVersion, "#define LIGHT_TYPE 0\n" );
  1074. m_hSceneLightVS[1] = GetVertexShader( "maps/scenelightvs", g_pRenderDevice, pVertexShaderVersion, "#define LIGHT_TYPE 1\n" );
  1075. m_hSceneLightVS[2] = GetVertexShader( "maps/scenelightvs", g_pRenderDevice, pVertexShaderVersion, "#define LIGHT_TYPE 2\n" );
  1076. m_hSceneLightPS[0] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 0\n#define LIGHT_SHADOWED 0\n" );
  1077. m_hSceneLightPS[1] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 1\n#define LIGHT_SHADOWED 0\n" );
  1078. m_hSceneLightPS[2] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 2\n#define LIGHT_SHADOWED 0\n" );
  1079. m_hSceneLightPS[3] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 0\n#define LIGHT_SHADOWED 1\n" );
  1080. m_hSceneLightPS[4] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 1\n#define LIGHT_SHADOWED 1\n" );
  1081. m_hSceneLightPS[5] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 2\n#define LIGHT_SHADOWED 1\n" );
  1082. static RenderInputLayoutField_t pointLightLayout[] =
  1083. {
  1084. DEFINE_PER_VERTEX_FIELD( 0, "position", 0, SphereVertex_t, m_vPos )
  1085. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 0, PointLightData_t, m_vOrigin )
  1086. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 1, PointLightData_t, m_vColorNRadius )
  1087. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 2, PointLightData_t, m_vAttenuation )
  1088. };
  1089. static RenderInputLayoutField_t hemiLightLayout[] =
  1090. {
  1091. DEFINE_PER_VERTEX_FIELD( 0, "position", 0, SphereVertex_t, m_vPos )
  1092. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 0, HemiLightData_t, m_vTransform0 )
  1093. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 1, HemiLightData_t, m_vTransform1 )
  1094. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 2, HemiLightData_t, m_vTransform2 )
  1095. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 3, HemiLightData_t, m_vColorNRadius )
  1096. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 4, HemiLightData_t, m_vAttenuation )
  1097. };
  1098. static RenderInputLayoutField_t spotLightLayout[] =
  1099. {
  1100. DEFINE_PER_VERTEX_FIELD( 0, "position", 0, SphereVertex_t, m_vPos )
  1101. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 0, SpotLightData_t, m_vTransform0 )
  1102. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 1, SpotLightData_t, m_vTransform1 )
  1103. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 2, SpotLightData_t, m_vTransform2 )
  1104. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 3, SpotLightData_t, m_vColorNRadius )
  1105. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 4, SpotLightData_t, m_vAttenuationNCosSpot )
  1106. };
  1107. m_hSceneLightLayout[0] = g_pRenderDevice->CreateInputLayout( "scenelight_point", ARRAYSIZE( pointLightLayout ), pointLightLayout );
  1108. m_hSceneLightLayout[1] = g_pRenderDevice->CreateInputLayout( "scenelight_hemi", ARRAYSIZE( hemiLightLayout ), hemiLightLayout );
  1109. m_hSceneLightLayout[2] = g_pRenderDevice->CreateInputLayout( "scenelight_spot", ARRAYSIZE( spotLightLayout ), spotLightLayout );
  1110. m_hFlashlightCookie[0] = g_pRenderDevice->FindOrCreateFileTexture( "materials/flashlight4.vtf" );
  1111. m_hFlashlightCookie[1] = g_pRenderDevice->FindOrCreateFileTexture( "materials/flashlight16.vtf" );
  1112. // SSAO
  1113. m_hSSAOPS = GetPixelShader( "maps/ssao", g_pRenderDevice, pPixelShaderVersion );
  1114. CUniformSampler ssaoSampler;
  1115. ssaoSampler.InitSamples( (int)sqrtf( (float)NUM_SSAO_SAMPLES ), 1 );
  1116. m_hSphereSampleData = g_pRenderDevice->CreateConstantBuffer( sizeof( SampleSphereData_t ) );
  1117. m_flSampleRadius = 16.0f;
  1118. m_sphereSampleData.m_vRandSampleScale.Init( 1, 1, 1, 1 );
  1119. m_sphereSampleData.m_vSampleRadiusNBias.Init( m_flSampleRadius, m_flSampleRadius, m_flSampleRadius, m_flSampleRadius );
  1120. for ( int s=0; s<NUM_SSAO_SAMPLES; ++s )
  1121. {
  1122. Vector vSample = ssaoSampler.GetSampleDirection( s, 0 );
  1123. //vSample *= 0.2f + 0.8f * RPercentABS();
  1124. vSample *= RPercentABS();
  1125. m_sphereSampleData.m_vSphereSamples[s].Init( vSample.x, vSample.y, vSample.z, 1 );
  1126. }
  1127. pRenderContext->SetConstantBufferData( m_hSphereSampleData, &m_sphereSampleData, sizeof( SampleSphereData_t ) );
  1128. #if 1
  1129. // random texture
  1130. m_nRandTextureSize = 4;
  1131. CUniformSampler randTexSampler;
  1132. randTexSampler.InitSamples( m_nRandTextureSize, 1 );
  1133. TextureHeader_t randSpec;
  1134. memset( &randSpec, 0, sizeof(TextureHeader_t) );
  1135. randSpec.m_nWidth = m_nRandTextureSize;
  1136. randSpec.m_nHeight = m_nRandTextureSize;
  1137. randSpec.m_nNumMipLevels = 1;
  1138. randSpec.m_nDepth = 1;
  1139. randSpec.m_nFlags = TSPEC_UNFILTERABLE_OK;
  1140. randSpec.m_nImageFormat = IMAGE_FORMAT_BGRA8888;
  1141. if ( g_nPlatform == RST_PLATFORM_DX11 )
  1142. {
  1143. randSpec.m_nImageFormat = IMAGE_FORMAT_RGBA8888;
  1144. }
  1145. m_hRandomTexture = g_pRenderDevice->FindOrCreateTexture( "worldrenderertest", "randomtexture", &randSpec );
  1146. int nTotalRands = randSpec.m_nWidth * randSpec.m_nHeight;
  1147. uint8 *pRandBits = new uint8[ nTotalRands * 4 ];
  1148. for ( int r=0; r<nTotalRands; ++r )
  1149. {
  1150. Vector vRandVector = randTexSampler.GetSampleDirection( r, 0 );
  1151. pRandBits[ r * 4 ] = (uint8)( ( vRandVector.z * 128.0f ) + 127 );
  1152. pRandBits[ r * 4 + 1 ] = (uint8)( ( vRandVector.y * 128.0f ) + 127 );
  1153. pRandBits[ r * 4 + 2 ] = (uint8)( ( vRandVector.x * 128.0f ) + 127 );
  1154. pRandBits[ r * 4 + 3 ] = 0;
  1155. }
  1156. pRenderContext->SetTextureData( m_hRandomTexture, &randSpec, pRandBits, nTotalRands * 4, false );
  1157. delete []pRandBits;
  1158. #else
  1159. // random texture
  1160. m_nRandTextureSize = 32;
  1161. m_hRandomTexture = g_pRenderDevice->FindOrCreateFileTexture( "materials/SSAOReflectionVectors.vtf" );
  1162. #endif
  1163. // Aerial perspective
  1164. m_hAerialPerspectivePS[0] = GetPixelShader( "maps/aerialperspectiveps", g_pRenderDevice, pPixelShaderVersion, "#define SHADER_VARIATION 0\n" );
  1165. m_hAerialPerspectivePS[1] = GetPixelShader( "maps/aerialperspectiveps", g_pRenderDevice, pPixelShaderVersion, "#define SHADER_VARIATION 1\n" );
  1166. m_hAerialPerspectivePSCB = g_pRenderDevice->CreateConstantBuffer( sizeof( AerialPerspectiveConstants_t ) );
  1167. // states for aerial perspective
  1168. RsBlendStateDesc_t bd;
  1169. memset( &bd, 0, sizeof( bd ) );
  1170. bd.m_bAlphaToCoverageEnable = false;
  1171. bd.m_bIndependentBlendEnable = false;
  1172. for ( int i=0; i<4; ++i )
  1173. {
  1174. bd.m_bBlendEnable[i] = true;
  1175. bd.m_srcBlend[i] = RS_BLEND_MODE_ZERO;
  1176. bd.m_destBlend[i] = RS_BLEND_MODE_SRC_COLOR;
  1177. bd.m_blendOp[i] = RS_BLEND_OP_ADD;
  1178. bd.m_nRenderTargetWriteMask[i] = RS_COLOR_WRITE_ENABLE_R | RS_COLOR_WRITE_ENABLE_G | RS_COLOR_WRITE_ENABLE_B;
  1179. }
  1180. m_hExtinctionBS = pRenderContext->FindOrCreateBlendState( &bd );
  1181. for ( int i=0; i<4; ++i )
  1182. {
  1183. bd.m_srcBlend[i] = RS_BLEND_MODE_ONE;
  1184. bd.m_destBlend[i] = RS_BLEND_MODE_ONE;
  1185. }
  1186. m_hInscatteringBS = pRenderContext->FindOrCreateBlendState( &bd );
  1187. m_hAdditiveBS = pRenderContext->FindOrCreateBlendState( &bd );
  1188. for ( int i=0; i<4; ++i )
  1189. {
  1190. bd.m_bBlendEnable[i] = false;
  1191. bd.m_srcBlend[i] = RS_BLEND_MODE_ZERO;
  1192. bd.m_destBlend[i] = RS_BLEND_MODE_SRC_COLOR;
  1193. bd.m_blendOp[i] = RS_BLEND_OP_ADD;
  1194. bd.m_nRenderTargetWriteMask[i] = RS_COLOR_WRITE_ENABLE_A;
  1195. }
  1196. m_hWriteAlphaBS = pRenderContext->FindOrCreateBlendState( &bd );
  1197. for ( int i=0; i<4; ++i )
  1198. {
  1199. bd.m_bBlendEnable[i] = false;
  1200. bd.m_srcBlend[i] = RS_BLEND_MODE_ZERO;
  1201. bd.m_destBlend[i] = RS_BLEND_MODE_SRC_COLOR;
  1202. bd.m_blendOp[i] = RS_BLEND_OP_ADD;
  1203. bd.m_nRenderTargetWriteMask[i] = RS_COLOR_WRITE_ENABLE_ALL;
  1204. }
  1205. m_hWriteAllBS = pRenderContext->FindOrCreateBlendState( &bd );
  1206. RsDepthStencilStateDesc_t dsDesc;
  1207. dsDesc.m_bDepthTestEnable = true;
  1208. dsDesc.m_bDepthWriteEnable = false;
  1209. dsDesc.m_depthFunc = RS_CMP_LESS_EQUAL;
  1210. dsDesc.m_hiZEnable360 = RS_HI_Z_AUTOMATIC;
  1211. dsDesc.m_hiZWriteEnable360 = RS_HI_Z_AUTOMATIC;
  1212. dsDesc.m_bStencilEnable = true;
  1213. dsDesc.m_nStencilReadMask = 0xFF;
  1214. dsDesc.m_nStencilWriteMask = 0xFF;
  1215. dsDesc.m_frontStencilFailOp = RS_STENCIL_OP_KEEP;
  1216. dsDesc.m_frontStencilDepthFailOp = RS_STENCIL_OP_KEEP;
  1217. dsDesc.m_frontStencilPassOp = RS_STENCIL_OP_KEEP;
  1218. dsDesc.m_frontStencilFunc = RS_CMP_EQUAL;
  1219. dsDesc.m_backStencilFailOp = RS_STENCIL_OP_KEEP;
  1220. dsDesc.m_backStencilDepthFailOp = RS_STENCIL_OP_KEEP;
  1221. dsDesc.m_backStencilPassOp = RS_STENCIL_OP_KEEP;
  1222. dsDesc.m_backStencilFunc = RS_CMP_EQUAL;
  1223. dsDesc.m_bHiStencilEnable360 = false;
  1224. dsDesc.m_bHiStencilWriteEnable360 = false;
  1225. dsDesc.m_hiStencilFunc360 = RS_HI_STENCIL_CMP_EQUAL;
  1226. dsDesc.m_nHiStencilRef360 = 0;
  1227. m_hZTestAndStencilTestDS = pRenderContext->FindOrCreateDepthStencilState( &dsDesc );
  1228. dsDesc.m_bDepthTestEnable = false;
  1229. dsDesc.m_bDepthWriteEnable = false;
  1230. m_hStencilTestDS = pRenderContext->FindOrCreateDepthStencilState( &dsDesc );
  1231. dsDesc.m_bDepthTestEnable = true;
  1232. dsDesc.m_bDepthWriteEnable = true;
  1233. dsDesc.m_frontStencilFailOp = RS_STENCIL_OP_KEEP;
  1234. dsDesc.m_frontStencilDepthFailOp = RS_STENCIL_OP_KEEP;
  1235. dsDesc.m_frontStencilPassOp = RS_STENCIL_OP_REPLACE;
  1236. dsDesc.m_frontStencilFunc = RS_CMP_ALWAYS;
  1237. dsDesc.m_backStencilFailOp = RS_STENCIL_OP_KEEP;
  1238. dsDesc.m_backStencilDepthFailOp = RS_STENCIL_OP_KEEP;
  1239. dsDesc.m_backStencilPassOp = RS_STENCIL_OP_REPLACE;
  1240. dsDesc.m_backStencilFunc = RS_CMP_ALWAYS;
  1241. m_hSetStencilDS = pRenderContext->FindOrCreateDepthStencilState( &dsDesc );
  1242. //
  1243. dsDesc.m_bDepthTestEnable = true;
  1244. dsDesc.m_bDepthWriteEnable = true;
  1245. dsDesc.m_depthFunc = RS_CMP_ALWAYS;
  1246. dsDesc.m_hiZEnable360 = RS_HI_Z_AUTOMATIC;
  1247. dsDesc.m_hiZWriteEnable360 = RS_HI_Z_AUTOMATIC;
  1248. dsDesc.m_bStencilEnable = false;
  1249. dsDesc.m_nStencilReadMask = 0xFF;
  1250. dsDesc.m_nStencilWriteMask = 0xFF;
  1251. dsDesc.m_frontStencilFailOp = RS_STENCIL_OP_KEEP;
  1252. dsDesc.m_frontStencilDepthFailOp = RS_STENCIL_OP_KEEP;
  1253. dsDesc.m_frontStencilPassOp = RS_STENCIL_OP_KEEP;
  1254. dsDesc.m_frontStencilFunc = RS_CMP_EQUAL;
  1255. dsDesc.m_backStencilFailOp = RS_STENCIL_OP_KEEP;
  1256. dsDesc.m_backStencilDepthFailOp = RS_STENCIL_OP_KEEP;
  1257. dsDesc.m_backStencilPassOp = RS_STENCIL_OP_KEEP;
  1258. dsDesc.m_backStencilFunc = RS_CMP_EQUAL;
  1259. dsDesc.m_bHiStencilEnable360 = false;
  1260. dsDesc.m_bHiStencilWriteEnable360 = false;
  1261. m_hZWriteNoTestDS = pRenderContext->FindOrCreateDepthStencilState( &dsDesc );
  1262. m_bDeferredInit = true;
  1263. }
  1264. void CWorldRendererTest::InitParticleData()
  1265. {
  1266. CRenderContextPtr pRenderContext( g_pRenderDevice );
  1267. struct ParticleVertex_t
  1268. {
  1269. Vector m_vPos;
  1270. };
  1271. static RenderInputLayoutField_t pointLightLayout[] =
  1272. {
  1273. DEFINE_PER_VERTEX_FIELD( 0, "position", 0, ParticleVertex_t, m_vPos )
  1274. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 0, PerParticleData_t, m_vPosRadius )
  1275. DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 1, PerParticleData_t, m_vColor )
  1276. };
  1277. m_hPointLightLayout = g_pRenderDevice->CreateInputLayout( "pointlight", ARRAYSIZE( pointLightLayout ), pointLightLayout );
  1278. const char *pVertexShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_VERTEX_SHADER);
  1279. const char *pPixelShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_PIXEL_SHADER );
  1280. for ( int i=0; i<5; ++i )
  1281. {
  1282. char pBuffer[100];
  1283. Q_snprintf( pBuffer, 100, "#define SHADER_VARIATION %d\n", i );
  1284. m_hPointLightVS[i] = GetVertexShader( "maps/pointlightvs", g_pRenderDevice, pVertexShaderVersion, pBuffer );
  1285. m_hPointLightPS[i] = GetPixelShader( "maps/pointlightps", g_pRenderDevice, pPixelShaderVersion, pBuffer );
  1286. }
  1287. }
  1288. void CWorldRendererTest::InitRenderableData()
  1289. {
  1290. CRenderContextPtr pRenderContext( g_pRenderDevice );
  1291. // Load the simple shaders for dynamic renderables
  1292. const char *pVertexShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_VERTEX_SHADER);
  1293. const char *pPixelShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_PIXEL_SHADER );
  1294. for ( int i=0; i<4; ++i )
  1295. {
  1296. char pBuffer[100];
  1297. Q_snprintf( pBuffer, 100, "#define SHADER_VARIATION %d\n#define g_flPhongExp 10\n#define g_flPhongBoost 1.5\n", i );
  1298. m_hSimpleMeshVS[i] = GetVertexShader( "maps/meshsimplevs", g_pRenderDevice, pVertexShaderVersion, pBuffer );
  1299. m_hSimpleMeshPS[i] = GetPixelShader( "maps/meshsimpleps", g_pRenderDevice, pPixelShaderVersion, pBuffer );
  1300. }
  1301. // Load the minigun
  1302. HRenderable hRenderable = g_pMeshSystem->FindOrCreateFileRenderable( g_pRenderableList[ 0 ] );
  1303. int index = m_dynRenderableList.AddToTail();
  1304. m_dynRenderableList[ index ].m_hRenderable = hRenderable;
  1305. m_dynRenderableList[ index ].m_vOrigin.Init( 0, 0, 0 );
  1306. m_dynRenderableList[ index ].m_mWorld.Identity();
  1307. }
  1308. void CWorldRendererTest::UpdateFrustum( int nWidth, int nHeight )
  1309. {
  1310. // Build up a frustum
  1311. if ( nWidth == m_nLastFrustumWidth && nHeight == m_nLastFrustumHeight )
  1312. return;
  1313. m_nLastFrustumWidth = nWidth;
  1314. m_nLastFrustumHeight = nHeight;
  1315. float flAspect = nWidth / (float)nHeight;
  1316. m_pFrustum->SetAspect( flAspect );
  1317. m_pFrustum->SetFOV( CalcFovX(90.0f, flAspect) );
  1318. m_pFrustum->UpdateFrustumFromCamera();
  1319. }
  1320. void CWorldRendererTest::RenderScreenQuad( IRenderContext *pRenderContext, Vector *pEyeRays, const char *pDebugName )
  1321. {
  1322. CDynamicVertexData<QuadVertex_t> vb( pRenderContext, 4, pDebugName, "screenquad" );
  1323. vb.Lock( );
  1324. vb->m_vPos = Vector( -1, -1, 0.5f );
  1325. vb->m_vEyeRay = pEyeRays[0];
  1326. vb.AdvanceVertex();
  1327. vb->m_vPos = Vector( 1, -1, 0.5f );
  1328. vb->m_vEyeRay = pEyeRays[1];
  1329. vb.AdvanceVertex();
  1330. vb->m_vPos = Vector( -1, 1, 0.5f );
  1331. vb->m_vEyeRay = pEyeRays[2];
  1332. vb.AdvanceVertex();
  1333. vb->m_vPos = Vector( 1, 1, 0.5f );
  1334. vb->m_vEyeRay = pEyeRays[3];
  1335. vb.AdvanceVertex();
  1336. vb.Unlock();
  1337. vb.Bind( 0, 0 );
  1338. pRenderContext->Draw( RENDER_PRIM_TRIANGLE_STRIP, 0, 4 );
  1339. }
  1340. void CWorldRendererTest::RenderFrame( const RenderViewport_t &viewport, PlatWindow_t hWnd )
  1341. {
  1342. if ( !m_bRenderTargetsInit )
  1343. {
  1344. InitRenderTargetsAndViews( viewport );
  1345. }
  1346. if ( !m_bDeferredInit )
  1347. {
  1348. InitDeferredData( viewport );
  1349. }
  1350. if ( m_nReportLevel == 1 )
  1351. {
  1352. g_VProfCurrentProfile.Reset();
  1353. g_VProfCurrentProfile.ResetPeaks();
  1354. g_VProfCurrentProfile.Start();
  1355. m_nReportLevel++;
  1356. Msg("VPROF Trace Begin\n");
  1357. }
  1358. RenderFrame_Internal( viewport );
  1359. if ( m_nReportLevel == 3 )
  1360. {
  1361. g_VProfCurrentProfile.Stop();
  1362. g_VProfCurrentProfile.OutputReport( VPRT_FULL & ~VPRT_HIERARCHY, NULL );
  1363. Msg("VPROF Trace Complete\n");
  1364. m_nReportLevel = 0;
  1365. }
  1366. else if ( m_nReportLevel )
  1367. {
  1368. g_VProfCurrentProfile.MarkFrame();
  1369. }
  1370. }
  1371. void CWorldRendererTest::CullRenderablesAgainstView( CRenderView &renderView, CUtlVector<CStaticMeshRenderable> &renderableList, CUtlVector<CDynamicRenderable> &dynList )
  1372. {
  1373. if ( !renderView.IsValid() )
  1374. return;
  1375. RenderViewFlags_t nFlags = renderView.GetViewFlags();
  1376. if ( !( nFlags & ( VIEW_PLAYER_CAMERA | VIEW_LIGHT_SHADOW | VIEW_REFLECTION ) ) )
  1377. return;
  1378. if ( nFlags & ( VIEW_POST_PROCESS | VIEW_LIGHTING | VIEW_DECALS ) )
  1379. return;
  1380. CWorldRenderFrustum *pFrustum = renderView.GetFrustum();
  1381. if( !pFrustum )
  1382. return;
  1383. if ( m_bDropFrustum && pFrustum == m_pFrustum )
  1384. pFrustum = m_pDropFrustum;
  1385. // Static
  1386. int nRenderables = renderableList.Count();
  1387. for ( int r=0; r<nRenderables; ++r )
  1388. {
  1389. CStaticMeshRenderable &renderable = renderableList[ r ];
  1390. IBVHNode *pNode = renderable.m_pNode;
  1391. Vector vOriginShift = pNode->GetOrigin().m_vLocal;
  1392. CBVHDrawCall *pDraw = renderable.m_pDrawCall;
  1393. if ( pDraw->m_Flags & DRAW_CULL )
  1394. {
  1395. if ( !pFrustum->BoundingVolumeIntersectsFrustum( pDraw->m_Bounds, vOriginShift ) )
  1396. {
  1397. continue;
  1398. }
  1399. }
  1400. // Add a renderable
  1401. renderView.AddStaticMeshRenderable( &renderable );
  1402. }
  1403. // Dynamic
  1404. nRenderables = dynList.Count();
  1405. for ( int r=0; r<nRenderables; ++r )
  1406. {
  1407. CDynamicRenderable &renderable = dynList[ r ];
  1408. if ( !g_pMeshSystem->RenderableIntersectsFrustum( renderable.m_hRenderable, pFrustum, -renderable.m_vOrigin ) )
  1409. continue;
  1410. // Add a renderable
  1411. renderView.AddDynamicRenderable( &renderable );
  1412. }
  1413. }
  1414. void CWorldRendererTest::SetupMultiShadowMatrices( int nViewportStart, int nSqrtNumShadows, float flBias )
  1415. {
  1416. int nGutterSize = 4;
  1417. if ( nViewportStart > 0 )
  1418. nGutterSize = 2;
  1419. float flScale = ( 0.5f / nSqrtNumShadows ) - ( nGutterSize / (float)m_nShadowSize );
  1420. int nMultiShadowSize = m_nShadowSize / nSqrtNumShadows;
  1421. int nTop = 0;
  1422. int nViewport = nViewportStart;
  1423. float frange = 1.0f;
  1424. if ( IsPlatformX360() )
  1425. {
  1426. frange = -1.0f;
  1427. flBias = flBias * frange;
  1428. }
  1429. for ( int t=0; t<nSqrtNumShadows; ++t )
  1430. {
  1431. int nLeft = 0;
  1432. for( int s=0; s<nSqrtNumShadows; ++s )
  1433. {
  1434. int nGutteredLeft = nLeft + nGutterSize;
  1435. int nGutteredTop = nTop + nGutterSize;
  1436. int nGutteredMultiShadowedSize = nMultiShadowSize - nGutterSize * 2;
  1437. m_multiShadowViewport[ nViewport ].Init( nGutteredLeft, nGutteredTop, nGutteredMultiShadowedSize, nGutteredMultiShadowedSize, 0, 1.0f );
  1438. float fBiasVal = flBias;
  1439. if ( IsPlatformX360() )
  1440. {
  1441. fBiasVal = 1.0f - flBias;
  1442. }
  1443. float flShiftX = flScale + ( nGutteredLeft + 0.5f ) / m_nShadowSize;
  1444. float flShiftY = flScale + ( nGutteredTop + 0.5f ) / m_nShadowSize;
  1445. VMatrix texScaleBiasMat( flScale, 0.0f, 0.0f, 0.0f,
  1446. 0.0f, -flScale, 0.0f, 0.0f,
  1447. 0.0f, 0.0f, frange, 0.0f,
  1448. flShiftX, flShiftY, fBiasVal, 1.0f );
  1449. m_multiShadowScaleBiasMatrices[ nViewport ] = texScaleBiasMat;
  1450. nViewport++;
  1451. nLeft += nMultiShadowSize;
  1452. }
  1453. nTop += nMultiShadowSize;
  1454. }
  1455. }
  1456. void CWorldRendererTest::SetupShadowMatrices()
  1457. {
  1458. // Multiple shadow viewports
  1459. float fOffsetX = 0.5f + (0.5f / (float)m_nShadowSize);
  1460. float fOffsetY = 0.5f + (0.5f / (float)m_nShadowSize);
  1461. float frange = 1.0f;
  1462. float fBias = -0.001f * frange;
  1463. if ( IsPlatformX360() )
  1464. {
  1465. frange = -1.0f;
  1466. fBias = 0.005f * frange;
  1467. }
  1468. for ( int s=0; s<NUM_SHADOW_SPLITS; ++s )
  1469. {
  1470. //set special texture matrix for shadow mapping
  1471. float fBiasVal = fBias;
  1472. if ( IsPlatformX360() )
  1473. {
  1474. fBiasVal = 1.0f - fBias;
  1475. }
  1476. VMatrix texScaleBiasMat( 0.5f, 0.0f, 0.0f, 0.0f,
  1477. 0.0f, -0.5f, 0.0f, 0.0f,
  1478. 0.0f, 0.0f, frange, 0.0f,
  1479. fOffsetX, fOffsetY, fBiasVal, 1.0f );
  1480. m_splitScaleBiasMatrices[ s ] = texScaleBiasMat;
  1481. fBias *= 1.5f;
  1482. }
  1483. SetupMultiShadowMatrices( 0, SQRT_NUM_HIGH_RES_SHADOWS, -0.001f );
  1484. if ( SQRT_NUM_LOW_RES_SHADOWS )
  1485. {
  1486. SetupMultiShadowMatrices( NUM_HIGH_RES_SHADOWS, SQRT_NUM_LOW_RES_SHADOWS, -0.003f );
  1487. }
  1488. }
  1489. int SortSpotLights( const CSpotLightRenderable *pOne, const CSpotLightRenderable *pTwo )
  1490. {
  1491. if ( pOne->m_flSquaredDistToEye < pTwo->m_flSquaredDistToEye )
  1492. return -1;
  1493. else if ( pOne->m_flSquaredDistToEye > pTwo->m_flSquaredDistToEye )
  1494. return 1;
  1495. return 0;
  1496. }
  1497. void CWorldRendererTest::GenerateRenderables( Vector &vCameraPos )
  1498. {
  1499. // Figure out where we are and if we're interior or not
  1500. int nLeafNode = m_pWorldRenderer->GetLeafNodeForPoint( vCameraPos );
  1501. bool bCanSeeSky = true;
  1502. if ( nLeafNode != -1 )
  1503. {
  1504. IBVHNode *pNode = m_pWorldRenderer->GetNode( nLeafNode );
  1505. int nFlags = pNode->GetFlags();
  1506. bCanSeeSky = ( nFlags & NODE_CAN_SEE_SKY ) != 0;
  1507. }
  1508. // Clear renderables
  1509. m_renderList.SetCountNonDestructively( 0 );
  1510. m_renderableList.SetCountNonDestructively( 0 );
  1511. m_interiorPointLights.SetCountNonDestructively( 0 );
  1512. m_exteriorPointLights.SetCountNonDestructively( 0 );
  1513. m_interiorSpotLights.SetCountNonDestructively( 0 );
  1514. m_exteriorSpotLights.SetCountNonDestructively( 0 );
  1515. m_interiorHemiLights.SetCountNonDestructively( 0 );
  1516. m_exteriorHemiLights.SetCountNonDestructively( 0 );
  1517. m_shadowedSpotLights.SetCountNonDestructively( 0 );
  1518. // Clear far plane
  1519. m_flMaxLightEncompassingFarPlane = 0.0f;
  1520. // Build the render list for this view
  1521. BVHNodeFlags_t nSkipFlags = (BVHNodeFlags_t)0x0;
  1522. if ( bCanSeeSky == false )
  1523. nSkipFlags = NODE_CAN_SEE_SKY;
  1524. float flLODScale = 1.0f;
  1525. if ( IsPlatformX360() )
  1526. {
  1527. flLODScale = 0.5f;
  1528. }
  1529. float flElapsedTime = 0.0f;
  1530. m_pWorldRenderer->BuildRenderList( &m_renderList, nSkipFlags, vCameraPos, flLODScale, m_pFrustum->GetFarPlane(), flElapsedTime, m_nCurrentFrameNumber );
  1531. // Distance sort render traversals
  1532. m_pWorldRenderer->SortRenderList( &m_renderList, vCameraPos );
  1533. //Create node requests and dispatch them to the async filesystem
  1534. // This can cause eviction of resources.
  1535. m_pWorldRenderer->CreateAndDispatchLoadRequests( g_pRenderDevice, m_pFrustum->GetCameraPosition() );
  1536. // Create renderables from each draw call encountered
  1537. int nNodes = m_renderList.Count();
  1538. for ( int n=0; n<nNodes; ++n )
  1539. {
  1540. IBVHNode *pNode = m_renderList[ n ];
  1541. Vector vOriginShift = pNode->GetOrigin().m_vLocal;
  1542. // Gross cull of the bounds before turning them into renderables
  1543. AABB_t bounds = pNode->GetBounds();
  1544. if ( !m_pFrustum->BoundingVolumeIntersectsFrustum( bounds, vOriginShift ) )
  1545. continue;
  1546. // Draw calls
  1547. int nDraws = pNode->GetNumDrawCalls();
  1548. for ( int d=0; d<nDraws; ++d )
  1549. {
  1550. CBVHDrawCall &draw = pNode->GetDrawCall( d );
  1551. CStaticMeshRenderable renderable;
  1552. renderable.m_pNode = pNode;
  1553. renderable.m_pDrawCall = &draw;
  1554. m_renderableList.AddToTail( renderable );
  1555. }
  1556. // Point Lights
  1557. GeneratePointLightRenderables( pNode, vOriginShift, m_pFrustum, vCameraPos );
  1558. // Spot lights
  1559. GenerateSpotLightRenderables( pNode, vOriginShift, m_pFrustum, vCameraPos );
  1560. // Hemi lights
  1561. GenerateHemiLightRenderables( pNode, vOriginShift, m_pFrustum, vCameraPos );
  1562. }
  1563. if ( m_bFlashlight )
  1564. {
  1565. CSpotLightRenderable renderable;
  1566. renderable.m_vOrigin.Init( 0, 0, 0 );
  1567. renderable.m_pLight = &m_flashlight;
  1568. renderable.m_bValid = true;
  1569. renderable.m_flSquaredDistToEye = 0.0f;
  1570. // We're outside the light
  1571. renderable.m_bInterior = false;
  1572. m_shadowedSpotLights.AddToTail( renderable );
  1573. }
  1574. // We've been storing squared distance, but we want linear distance
  1575. m_flMaxLightEncompassingFarPlane = sqrtf( m_flMaxLightEncompassingFarPlane );
  1576. // Sort spot lights and set the NUM_MULTI_SHADOWS closest as shadow casting
  1577. m_shadowedSpotLights.Sort( SortSpotLights );
  1578. /*
  1579. // Artificially limit shadows past a certain point
  1580. int nShadows = 0;
  1581. for ( int s=0; s<m_shadowedSpotLights.Count(); ++s )
  1582. {
  1583. if ( m_shadowedSpotLights[ s ].m_flSquaredDistToEye > MAX_LIGHT_DISTANCE * MAX_LIGHT_DISTANCE )
  1584. {
  1585. break;
  1586. }
  1587. nShadows++;
  1588. }*/
  1589. int nShadows = m_shadowedSpotLights.Count();
  1590. nShadows = MIN( nShadows, NUM_MULTI_SHADOWS );
  1591. m_shadowedSpotLights.SetCountNonDestructively( nShadows );
  1592. for ( int s=0; s<nShadows; ++s )
  1593. {
  1594. int index = m_exteriorSpotLights.Find( m_shadowedSpotLights[s] );
  1595. if ( index != -1 )
  1596. {
  1597. m_exteriorSpotLights.FastRemove( index );
  1598. }
  1599. index = m_interiorSpotLights.Find( m_shadowedSpotLights[s] );
  1600. if ( index != -1 )
  1601. {
  1602. m_interiorSpotLights.FastRemove( index );
  1603. }
  1604. }
  1605. }
  1606. void CWorldRendererTest::GeneratePointLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye )
  1607. {
  1608. float flNearPlane = pFrustum->GetNearPlane();
  1609. int nLights = pNode->GetNumPointLights();
  1610. PointLightData_t *pPointLights = pNode->GetPointLights();
  1611. for ( int i=0; i<nLights; ++i )
  1612. {
  1613. float flRadius = pPointLights[i].m_vColorNRadius.w;
  1614. AABB_t bounds;
  1615. Vector vLightOrigin = pPointLights[i].m_vOrigin;
  1616. bounds.m_vMinBounds = vLightOrigin - Vector( flRadius, flRadius, flRadius );
  1617. bounds.m_vMaxBounds = vLightOrigin + Vector( flRadius, flRadius, flRadius );
  1618. if ( pFrustum->BoundingVolumeIntersectsFrustum( bounds, vOrigin ) )
  1619. {
  1620. CPointLightRenderable renderable;
  1621. renderable.m_vOrigin = vOrigin;
  1622. renderable.m_pLight = &pPointLights[i];
  1623. Vector vNewOrigin = vLightOrigin - vOrigin;
  1624. Vector vDelta = vEye - vNewOrigin;
  1625. float flSquaredDist = DotProduct( vDelta, vDelta );
  1626. float flTargetRad = flRadius * 1.2f + flNearPlane;
  1627. if ( DotProduct( vDelta, vDelta ) < flTargetRad * flTargetRad )
  1628. {
  1629. // We're inside the light
  1630. m_interiorPointLights.AddToTail( renderable );
  1631. }
  1632. else
  1633. {
  1634. // We're outside the light
  1635. m_exteriorPointLights.AddToTail( renderable );
  1636. }
  1637. m_flMaxLightEncompassingFarPlane = MAX( m_flMaxLightEncompassingFarPlane, flSquaredDist + flTargetRad * flTargetRad );
  1638. }
  1639. }
  1640. }
  1641. void CWorldRendererTest::GenerateSpotLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye )
  1642. {
  1643. float flNearPlane = pFrustum->GetNearPlane();
  1644. Vector vForward = pFrustum->Forward();
  1645. Vector vFarEye = vEye + flNearPlane * vForward * 1.2f;
  1646. int nLights = pNode->GetNumSpotLights();
  1647. SpotLightData_t *pSpotLights = pNode->GetSpotLights();
  1648. for ( int i=0; i<nLights; ++i )
  1649. {
  1650. float flRadius = pSpotLights[i].m_vColorNRadius.w;
  1651. float flTargetRad = flRadius * 1.2f + 500.0f + flNearPlane;
  1652. Vector vLightOrigin = Vector( pSpotLights[i].m_vTransform0.w, pSpotLights[i].m_vTransform1.w, pSpotLights[i].m_vTransform2.w );
  1653. AABB_t bounds;
  1654. bounds.m_vMinBounds = vLightOrigin - Vector( flTargetRad, flTargetRad, flTargetRad );
  1655. bounds.m_vMaxBounds = vLightOrigin + Vector( flTargetRad, flTargetRad, flTargetRad );
  1656. if ( pFrustum->BoundingVolumeIntersectsFrustum( bounds, vOrigin ) )
  1657. {
  1658. CSpotLightRenderable renderable;
  1659. renderable.m_vOrigin = vOrigin;
  1660. renderable.m_pLight = &pSpotLights[i];
  1661. renderable.m_bValid = true;
  1662. Vector vNewOrigin = vLightOrigin - vOrigin;
  1663. Vector vDelta = vEye - vNewOrigin;
  1664. Vector vLightDir = Vector( pSpotLights[i].m_vTransform0.z, pSpotLights[i].m_vTransform1.z, pSpotLights[i].m_vTransform2.z );
  1665. float flSquaredDist = DotProduct( vDelta, vDelta );
  1666. renderable.m_flSquaredDistToEye = flSquaredDist;
  1667. //if ( flRadius > 3000.0f )
  1668. // renderable.m_flSquaredDistToEye = FLT_MAX;
  1669. Vector vToLightFar = vFarEye - vNewOrigin;
  1670. Vector vToLightNear = vEye - vNewOrigin;
  1671. vToLightFar.NormalizeInPlace();
  1672. vToLightNear.NormalizeInPlace();
  1673. float flDotFar = DotProduct( vToLightFar, vLightDir );
  1674. float flDotNear = DotProduct( vToLightNear, vLightDir );
  1675. float flCosAngle = pSpotLights[i].m_vAttenuationNCosSpot.w * 0.85f;
  1676. bool bInCone = ( flDotFar > flCosAngle || flDotNear > flCosAngle );
  1677. if ( flSquaredDist < flTargetRad * flTargetRad && bInCone )
  1678. {
  1679. // We're inside the light
  1680. renderable.m_bInterior = true;
  1681. m_interiorSpotLights.AddToTail( renderable );
  1682. }
  1683. else
  1684. {
  1685. // We're outside the light
  1686. renderable.m_bInterior = false;
  1687. m_exteriorSpotLights.AddToTail( renderable );
  1688. }
  1689. m_shadowedSpotLights.AddToTail( renderable );
  1690. m_flMaxLightEncompassingFarPlane = MAX( m_flMaxLightEncompassingFarPlane, flSquaredDist + flTargetRad * flTargetRad + 4000 * 4000 );
  1691. }
  1692. }
  1693. }
  1694. void CWorldRendererTest::GenerateHemiLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye )
  1695. {
  1696. float flNearPlane = pFrustum->GetNearPlane();
  1697. Vector vForward = pFrustum->Forward();
  1698. Vector vFarEye = vEye + flNearPlane * vForward * 1.1f;
  1699. int nLights = pNode->GetNumHemiLights();
  1700. HemiLightData_t *pHemiLights = pNode->GetHemiLights();
  1701. for ( int i=0; i<nLights; ++i )
  1702. {
  1703. float flRadius = pHemiLights[i].m_vColorNRadius.w;
  1704. Vector vLightOrigin = Vector( pHemiLights[i].m_vTransform0.w, pHemiLights[i].m_vTransform1.w, pHemiLights[i].m_vTransform2.w );
  1705. AABB_t bounds;
  1706. bounds.m_vMinBounds = vLightOrigin - Vector( flRadius, flRadius, flRadius );
  1707. bounds.m_vMaxBounds = vLightOrigin + Vector( flRadius, flRadius, flRadius );
  1708. if ( pFrustum->BoundingVolumeIntersectsFrustum( bounds, vOrigin ) )
  1709. {
  1710. CHemiLightRenderable renderable;
  1711. renderable.m_vOrigin = vOrigin;
  1712. renderable.m_pLight = &pHemiLights[i];
  1713. Vector vNewOrigin = vLightOrigin - vOrigin;
  1714. Vector vDelta = vEye - vNewOrigin;
  1715. float flSquaredDist = DotProduct( vDelta, vDelta );
  1716. Vector vLightDir = Vector( pHemiLights[i].m_vTransform0.z, pHemiLights[i].m_vTransform1.z, pHemiLights[i].m_vTransform2.z );
  1717. float flTargetRad = flRadius * 1.2f + flNearPlane;
  1718. Vector vToLightFar = vFarEye - vNewOrigin;
  1719. Vector vToLightNear = vEye - vNewOrigin;
  1720. vToLightFar.NormalizeInPlace();
  1721. vToLightNear.NormalizeInPlace();
  1722. float flDotFar = DotProduct( vToLightFar, vLightDir );
  1723. float flDotNear = DotProduct( vToLightNear, vLightDir );
  1724. float flCosAngle = 0.0f;
  1725. bool bInHemi = ( flDotFar > flCosAngle || flDotNear > flCosAngle );
  1726. if ( DotProduct( vDelta, vDelta ) < flTargetRad * flTargetRad && bInHemi )
  1727. {
  1728. // We're inside the light
  1729. m_interiorHemiLights.AddToTail( renderable );
  1730. }
  1731. else
  1732. {
  1733. // We're outside the light
  1734. m_exteriorHemiLights.AddToTail( renderable );
  1735. }
  1736. m_flMaxLightEncompassingFarPlane = MAX( m_flMaxLightEncompassingFarPlane, flSquaredDist + flTargetRad * flTargetRad );
  1737. }
  1738. }
  1739. }
  1740. void CWorldRendererTest::RenderViewStatic( CRenderView *pRenderView, int nStart, int nCount, int nIndex )
  1741. {
  1742. CRenderContextPtr pRenderContext( g_pRenderDevice );
  1743. pRenderView->BeginRender( pRenderContext );
  1744. SetStateForRenderViewType( pRenderContext, pRenderView->GetViewType() );
  1745. int nRenderPass = pRenderView->GetRenderPass();
  1746. CWorldRenderFrustum *pFrustum = pRenderView->GetFrustum();
  1747. CUtlVector< CStaticMeshRenderable* > &renderableList = pRenderView->GetRenderableList();
  1748. // Set commonly used constants
  1749. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( pFrustum );
  1750. if ( nRenderPass == VARIATION_SAMPLE_LIGHTING )
  1751. {
  1752. pRenderContext->SetConstantBufferData( m_hLightBufferData, (void*)&m_lightBufferData, sizeof( LightBufferData_t ) );
  1753. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hLightBufferData, 0, 0 );
  1754. }
  1755. if ( m_bViewLowTexture && nRenderPass == VARIATION_SAMPLE_LIGHTING )
  1756. {
  1757. nRenderPass = VARIATION_SAMPLE_LIGHTING_LOW_TEXTURE;
  1758. }
  1759. // Render the nodes
  1760. Vector vLastOrigin = Vector(0,0,0);
  1761. bool bFirst = true;
  1762. bool bSunDepth = false;
  1763. if ( nRenderPass == VARIATION_DEPTH && pRenderView->GetViewType() < RTB_SHADOW_DEPTH_MULTIPLE_0 )
  1764. bSunDepth = true;
  1765. bool bSetStencil = false;
  1766. if ( nRenderPass == VARIATION_NORM_DEPTH_SPEC )
  1767. bSetStencil = true;
  1768. for ( int r=0; r<nCount; ++r )
  1769. {
  1770. CStaticMeshRenderable *pRenderable = renderableList[ nStart + r ];
  1771. IBVHNode *pNode = pRenderable->m_pNode;
  1772. AABB_t bounds = pNode->GetBounds();
  1773. Vector vOrigin = pNode->GetOrigin().m_vLocal;
  1774. int nFlags = pNode->GetFlags();
  1775. bool bCanSeeSky = ( nFlags & NODE_CAN_SEE_SKY ) != 0;
  1776. // Don't render depth for sun shadow maps if we can't see the sky
  1777. if ( bSunDepth && !bCanSeeSky )
  1778. continue;
  1779. if ( ( vLastOrigin != vOrigin ) || bFirst )
  1780. {
  1781. VMatrix mViewRelated = viewConstants.m_mViewProjection;
  1782. VMatrix mTrans;
  1783. mTrans.Identity();
  1784. mTrans.SetTranslation( -vOrigin );
  1785. mViewRelated = mTrans.Transpose() * mViewRelated;
  1786. ViewRelatedConstants_t newViewConstants = viewConstants;
  1787. newViewConstants.m_mViewProjection = mViewRelated;
  1788. newViewConstants.m_vEyePt.x += vOrigin.x;
  1789. newViewConstants.m_vEyePt.y += vOrigin.y;
  1790. newViewConstants.m_vEyePt.z += vOrigin.z;
  1791. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&newViewConstants, sizeof( ViewRelatedConstants_t ) );
  1792. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  1793. vLastOrigin = vOrigin;
  1794. bFirst = false;
  1795. }
  1796. if ( bSetStencil )
  1797. {
  1798. if ( bCanSeeSky )
  1799. {
  1800. pRenderContext->SetDepthStencilState( m_hSetStencilDS, g_nCanSeeSkyStencilRef );
  1801. }
  1802. else
  1803. {
  1804. pRenderContext->SetDepthStencilState( m_hSetStencilDS, g_nCannotSeeSkyStencilRef );
  1805. }
  1806. }
  1807. pNode->Draw( pRenderContext, pRenderable->m_pDrawCall, m_pResourceDictionary, (ShaderComboVariation_t)nRenderPass, m_hSingleMatrixRelated );
  1808. }
  1809. pRenderView->EndRender( pRenderContext, false );
  1810. }
  1811. void CWorldRendererTest::RenderViewDynamic( CRenderView *pRenderView, int nStart, int nCount, int nIndex )
  1812. {
  1813. CRenderContextPtr pRenderContext( g_pRenderDevice );
  1814. pRenderView->BeginRender( pRenderContext );
  1815. // Get view constants
  1816. CWorldRenderFrustum *pFrustum = pRenderView->GetFrustum();
  1817. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( pFrustum );
  1818. // Init material data
  1819. RenderMaterialData_t &materialData = pRenderContext->GetMaterialData();
  1820. materialData.Init();
  1821. materialData.flTime = Plat_FloatTime();
  1822. materialData.mVP = viewConstants.m_mViewProjection;
  1823. materialData.mWVP = viewConstants.m_mViewProjection;
  1824. materialData.vCameraPosition = viewConstants.m_vEyePt.AsVector3D();
  1825. materialData.vCameraForwardVec = viewConstants.m_vEyeDir.AsVector3D().Normalized();
  1826. materialData.flFarPlane = viewConstants.m_flFarPlane.x;
  1827. materialData.vViewportSize[0] = 1.0f / m_lightBufferData.m_vInvScreenExtents.x;
  1828. materialData.vViewportSize[1] = 1.0f / m_lightBufferData.m_vInvScreenExtents.y;
  1829. materialData.customTextures[0] = m_pRenderTargets[ RT_LIGHTING_HIGHRES ];
  1830. materialData.customTextures[1] = m_pRenderTargets[ RT_SPECULAR_HIGHRES ];
  1831. int nRenderPass = pRenderView->GetRenderPass();
  1832. if ( nRenderPass == VARIATION_DEPTH )
  1833. {
  1834. materialData.nMode = MODE_DEPTH;
  1835. }
  1836. else if ( nRenderPass == VARIATION_NORM_DEPTH_SPEC )
  1837. {
  1838. materialData.nMode = MODE_NORMAL_DEPTH_SPEC;
  1839. }
  1840. else if ( nRenderPass == VARIATION_SAMPLE_LIGHTING )
  1841. {
  1842. materialData.nMode = MODE_DEFERRED_GATHER;
  1843. }
  1844. else
  1845. {
  1846. materialData.nMode = MODE_FORWARD;
  1847. }
  1848. // Sun and stencil bools
  1849. bool bSunDepth = false;
  1850. if ( ( nRenderPass == VARIATION_DEPTH ) && ( pRenderView->GetViewType() < RTB_SHADOW_DEPTH_MULTIPLE_0 ) )
  1851. {
  1852. bSunDepth = true;
  1853. }
  1854. bool bSetStencil = false;
  1855. if ( nRenderPass == VARIATION_NORM_DEPTH_SPEC )
  1856. {
  1857. bSetStencil = true;
  1858. }
  1859. // Render the nodes
  1860. CUtlVector< CDynamicRenderable * > &renderableList = pRenderView->GetDynamicList();
  1861. for ( int r = 0; r < nCount; r++ )
  1862. {
  1863. CDynamicRenderable *pRenderable = renderableList[ nStart + r ];
  1864. // Copy world matrix into material data
  1865. memcpy( materialData.mWorldArray[0], &( pRenderable->m_mWorld.m[0] ), sizeof( pRenderable->m_mWorld ) );
  1866. RenderDynamic( pRenderContext, pRenderable, ( ShaderComboVariation_t )nRenderPass, bSunDepth, bSetStencil );
  1867. }
  1868. pRenderView->EndRender( pRenderContext, false );
  1869. }
  1870. void CWorldRendererTest::RenderView( CRenderView &renderView )
  1871. {
  1872. if ( m_bMultiThreaded )
  1873. {
  1874. CUtlVector< CStaticMeshRenderable* > &renderableList = renderView.GetRenderableList();
  1875. CUtlVector< CDynamicRenderable* > &dynList = renderView.GetDynamicList();
  1876. int nRenderablesStatic = renderableList.Count();
  1877. int nRenderablesDynamic = dynList.Count();
  1878. int nCountStatic = nRenderablesStatic / m_nRenderThreads;
  1879. int nCountDynamic = nRenderablesDynamic / m_nRenderThreads;
  1880. int nTotalRenderablesStatic = 0;
  1881. int nTotalRenderablesDynamic = 0;
  1882. for ( int t=0; t<m_nRenderThreads; ++t )
  1883. {
  1884. m_pRenderJobs[ t ].m_pRenderView = &renderView;
  1885. m_pRenderJobs[ t ].m_nStartStatic = nTotalRenderablesStatic;
  1886. m_pRenderJobs[ t ].m_nCountStatic = nCountStatic;
  1887. m_pRenderJobs[ t ].m_nStartDynamic = nTotalRenderablesDynamic;
  1888. m_pRenderJobs[ t ].m_nCountDynamic = nCountDynamic;
  1889. m_pRenderJobs[ t ].m_pTestApp = this;
  1890. m_pRenderJobs[ t ].m_nIndex = t;
  1891. nTotalRenderablesStatic += nCountStatic;
  1892. nTotalRenderablesDynamic += nCountDynamic;
  1893. }
  1894. m_pRenderJobs[ m_nRenderThreads - 1 ].m_nCountStatic = nRenderablesStatic - m_pRenderJobs[ m_nRenderThreads - 1 ].m_nStartStatic;
  1895. m_pRenderJobs[ m_nRenderThreads - 1 ].m_nCountDynamic = nRenderablesDynamic - m_pRenderJobs[ m_nRenderThreads - 1 ].m_nStartDynamic;
  1896. ParallelProcess( m_pRenderJobs, m_nRenderThreads, PerformStaticMeshWorkUnit );
  1897. }
  1898. else
  1899. {
  1900. RenderViewStatic( &renderView, 0, renderView.GetRenderableList().Count(), 0 );
  1901. RenderViewDynamic( &renderView, 0, renderView.GetDynamicList().Count(), 0 );
  1902. }
  1903. }
  1904. void CWorldRendererTest::UpdateShadowData()
  1905. {
  1906. for ( int s=0; s<m_nShadowSplits; ++s )
  1907. {
  1908. VMatrix mLightRelated;
  1909. mLightRelated = m_pSplitFrustums[s]->GetViewProj();
  1910. m_pShadowMatrices[s] = mLightRelated * m_splitScaleBiasMatrices[ s ];
  1911. m_forwardLightingData.m_mShadowMatrices[s] = m_pShadowMatrices[s];
  1912. }
  1913. for ( int s=0; s<NUM_MULTI_SHADOWS; ++s )
  1914. {
  1915. m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].SetValid( false );
  1916. }
  1917. for ( int s=0; s<m_shadowedSpotLights.Count(); ++s )
  1918. {
  1919. CSpotLightRenderable &renderable = m_shadowedSpotLights[s];
  1920. Vector vOrigin = Vector( renderable.m_pLight->m_vTransform0.w, renderable.m_pLight->m_vTransform1.w, renderable.m_pLight->m_vTransform2.w );
  1921. vOrigin -= renderable.m_vOrigin;
  1922. Vector vDirection = Vector( renderable.m_pLight->m_vTransform0.z, renderable.m_pLight->m_vTransform1.z, renderable.m_pLight->m_vTransform2.z );
  1923. Vector vUp = Vector( renderable.m_pLight->m_vTransform0.y, renderable.m_pLight->m_vTransform1.y, renderable.m_pLight->m_vTransform2.y );
  1924. vDirection.NormalizeInPlace();
  1925. vUp.NormalizeInPlace();
  1926. QAngle vAngles;
  1927. VectorAngles( vDirection, vUp, vAngles );
  1928. float flRadius = renderable.m_pLight->m_vColorNRadius.w;
  1929. float flFOV = RAD2DEG( acosf( renderable.m_pLight->m_vAttenuationNCosSpot.w ) * 2 );
  1930. m_pMultiShadowFrustums[ s ]->InitCamera( vOrigin, vAngles, 20.0f, flRadius + 500.0f, flFOV, 1.0f );
  1931. m_pMultiShadowFrustums[ s ]->UpdateFrustumFromCamera();
  1932. VMatrix mLightRelated = m_pMultiShadowFrustums[ s ]->GetViewProj();
  1933. m_pMultiShadowMatrices[ s ] = mLightRelated * m_multiShadowScaleBiasMatrices[ s ];
  1934. m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].SetValid( true );
  1935. }
  1936. }
  1937. void CWorldRendererTest::UpdateFlashlightData()
  1938. {
  1939. float flFlashlightLength = 1000.0f;
  1940. float flSpotAngle = DEG2RAD( 45.0f );
  1941. Vector vColor( 1,1,0.8f );
  1942. vColor *= 100.0f;
  1943. float flMax = 255.0f;
  1944. Vector vAttenuation;
  1945. vAttenuation.x = 0;
  1946. vAttenuation.y = flMax / flFlashlightLength;
  1947. vAttenuation.z = 0;
  1948. float flTan45 = tanf( M_PI / 4.0f );
  1949. float flScale = tanf( flSpotAngle ) / flTan45;
  1950. Vector vOrigin = m_pFrustum->GetCameraPosition();
  1951. Vector vDirection = m_pFrustum->Forward();
  1952. Vector vLeft = m_pFrustum->Left();
  1953. Vector vUp = m_pFrustum->Up();
  1954. vOrigin -= vUp * 15.0f;
  1955. vOrigin += vLeft * 25;
  1956. Vector vRight = -vLeft;
  1957. vRight *= flScale * flFlashlightLength;
  1958. vUp *= flScale * flFlashlightLength;
  1959. vDirection *= flFlashlightLength;
  1960. m_flashlight.m_vTransform0.Init( vRight.x, vUp.x, vDirection.x, vOrigin.x );
  1961. m_flashlight.m_vTransform1.Init( vRight.y, vUp.y, vDirection.y, vOrigin.y );
  1962. m_flashlight.m_vTransform2.Init( vRight.z, vUp.z, vDirection.z, vOrigin.z );
  1963. m_flashlight.m_vColorNRadius.Init( vColor.x, vColor.y, vColor.z, flFlashlightLength );
  1964. m_flashlight.m_vAttenuationNCosSpot.Init( vAttenuation.x, vAttenuation.y, vAttenuation.z, cosf( flSpotAngle ) );
  1965. }
  1966. void CWorldRendererTest::UpdateViewModelData()
  1967. {
  1968. if ( m_dynRenderableList.Count() < 1 )
  1969. return;
  1970. Vector vOrigin = m_pFrustum->GetCameraPosition();
  1971. Vector vDirection = m_pFrustum->Forward();
  1972. Vector vLeft = m_pFrustum->Left();
  1973. Vector vUp = m_pFrustum->Up();
  1974. vOrigin -= vUp * 15.0f;
  1975. vOrigin -= vLeft * 25;
  1976. vOrigin += vDirection * 30;
  1977. VMatrix mWorld;
  1978. mWorld.Identity();
  1979. mWorld.SetForward( vDirection * 0.6f );
  1980. mWorld.SetLeft( vLeft );
  1981. mWorld.SetUp( vUp );
  1982. VMatrix mRot;
  1983. Vector vAxis( 0, 0, 1 );
  1984. MatrixBuildRotationAboutAxis( mRot, vAxis, 90.0f );
  1985. vAxis.Init( 1, 0, 0 );
  1986. MatrixRotate( mRot, vAxis, 90.0f );
  1987. m_dynRenderableList[ 0 ].m_vOrigin = vOrigin;
  1988. m_dynRenderableList[ 0 ].m_mWorld = mWorld * mRot;
  1989. m_dynRenderableList[ 0 ].m_mWorld.SetTranslation( vOrigin );
  1990. }
  1991. void CWorldRendererTest::UpdateDroppedRenderables( float flElapsedTime )
  1992. {
  1993. int nRenderables = m_dynRenderableList.Count();
  1994. for ( int i=1; i<nRenderables; ++i )
  1995. {
  1996. Vector vAxis( 0, 1, 0 );
  1997. MatrixRotate( m_dynRenderableList[ i ].m_mWorld, vAxis, flElapsedTime * 60.0f );
  1998. m_dynRenderableList[ i ].m_mWorld.SetTranslation( m_dynRenderableList[ i ].m_vOrigin );
  1999. }
  2000. }
  2001. void CWorldRendererTest::RenderShadowDepthBuffers( IRenderContext *pRenderContext )
  2002. {
  2003. Vector4D vShadowClear(1,1,1,1);
  2004. VPROF_SCOPE_BEGIN("RenderSplitShadows");
  2005. for ( int s=0; s<m_nShadowSplits; ++s )
  2006. {
  2007. m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ].Clear( pRenderContext, vShadowClear, RENDER_CLEAR_FLAGS_CLEAR_DEPTH );
  2008. if ( m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ].HasRenderables() )
  2009. {
  2010. RenderView( m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ] );
  2011. // Render spheres
  2012. m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ].BeginRender( pRenderContext );
  2013. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pSplitFrustums[s] );
  2014. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2015. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2016. pRenderContext->SetBlendMode( RENDER_BLEND_NOPIXELWRITE );
  2017. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE );
  2018. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2019. int nParticleSystems = m_sphereSystemList.Count();
  2020. for ( int p=0; p<nParticleSystems; ++p )
  2021. {
  2022. RenderParticleLights( pRenderContext, m_sphereSystemList[p], VARIATION_DEPTH, true, false );
  2023. }
  2024. // Submit
  2025. m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ].EndRender( pRenderContext );
  2026. }
  2027. }
  2028. VPROF_SCOPE_END();
  2029. VPROF_SCOPE_BEGIN("RenderMultiShadows");
  2030. for ( int s=0; s<m_shadowedSpotLights.Count(); ++s )
  2031. {
  2032. if ( s == 0 )
  2033. {
  2034. m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].BeginRender( pRenderContext );
  2035. pRenderContext->SetViewports( 1, &m_shadowViewport );
  2036. pRenderContext->Clear( vShadowClear, RENDER_CLEAR_FLAGS_CLEAR_DEPTH );
  2037. m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].EndRender( pRenderContext, false );
  2038. }
  2039. if ( s == NUM_HIGH_RES_SHADOWS )
  2040. {
  2041. m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].BeginRender( pRenderContext );
  2042. pRenderContext->SetViewports( 1, &m_shadowViewport );
  2043. pRenderContext->Clear( vShadowClear, RENDER_CLEAR_FLAGS_CLEAR_DEPTH );
  2044. m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].EndRender( pRenderContext, false );
  2045. }
  2046. if ( m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].HasRenderables() )
  2047. {
  2048. RenderView( m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ] );
  2049. }
  2050. // Render spheres
  2051. m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].BeginRender( pRenderContext );
  2052. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pMultiShadowFrustums[ s ] );
  2053. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2054. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2055. int nParticleSystems = m_sphereSystemList.Count();
  2056. for ( int p=0; p<nParticleSystems; ++p )
  2057. {
  2058. RenderParticleLights( pRenderContext, m_sphereSystemList[p], VARIATION_DEPTH, false, false );
  2059. }
  2060. // Submit
  2061. m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].EndRender( pRenderContext );
  2062. }
  2063. VPROF_SCOPE_END();
  2064. }
  2065. void CWorldRendererTest::RenderSunShadowFrustums( IRenderContext *pRenderContext )
  2066. {
  2067. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2068. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2069. pRenderContext->SetBlendState( m_hAdditiveBS );
  2070. pRenderContext->SetDepthStencilState( m_hStencilTestDS, g_nCanSeeSkyStencilRef );
  2071. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_NORMAL_HIGHRES ] );
  2072. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT );
  2073. if ( IsPlatformX360() )
  2074. {
  2075. pRenderContext->BindTexture( 1, m_pRenderTargets[ DS_DEPTH_HIGHRES ] );
  2076. }
  2077. else
  2078. {
  2079. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  2080. }
  2081. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT );
  2082. pRenderContext->BindTexture( 2, m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ] );
  2083. pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2084. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2085. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2086. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2087. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowFrustumPS[2] );
  2088. for ( int s=0; s<NUM_SHADOW_SPLITS; ++s )
  2089. {
  2090. m_deferredLightingData.m_mShadowMatrix[s] = m_pShadowMatrices[s];
  2091. pRenderContext->BindTexture( 4 + s, m_pRenderTargets[ DS_SHADOW_DEPTH0 + s ] );
  2092. if ( g_nPlatform == RST_PLATFORM_DX11 )
  2093. {
  2094. pRenderContext->SetSamplerStatePS( 4 + s, RS_FILTER_MIN_MAG_MIP_POINT );
  2095. }
  2096. else
  2097. {
  2098. pRenderContext->SetSamplerStatePS( 4 + s, RS_FILTER_MIN_MAG_MIP_LINEAR );
  2099. }
  2100. }
  2101. pRenderContext->SetConstantBufferData( m_hDeferredLightingRelated, (void*)&m_deferredLightingData, sizeof( DeferredLightingConstants_t ) );
  2102. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDeferredLightingRelated, 0, 0 );
  2103. RenderScreenQuad( pRenderContext, m_vEyeRays, "sunshadows" );
  2104. }
  2105. void CWorldRendererTest::RenderBouncedLight( IRenderContext *pRenderContext )
  2106. {
  2107. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2108. pRenderContext->SetBlendState( m_hAdditiveBS );
  2109. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
  2110. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2111. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_NORMAL_LOWRES ] );
  2112. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2113. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ] );
  2114. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2115. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2116. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2117. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_lowResScreenData, sizeof( DecalScreenData_t ) );
  2118. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2119. RenderSceneHemiLights( pRenderContext, m_exteriorHemiLights, false );
  2120. RenderSceneHemiLights( pRenderContext, m_interiorHemiLights, true );
  2121. }
  2122. void CWorldRendererTest::RenderDirectLight( IRenderContext *pRenderContext )
  2123. {
  2124. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2125. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2126. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2127. if ( IsPlatformX360() )
  2128. {
  2129. pRenderContext->BindTexture( 1, m_pRenderTargets[ DS_DEPTH_HIGHRES ] );
  2130. }
  2131. else
  2132. {
  2133. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  2134. }
  2135. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT );
  2136. pRenderContext->BindTexture( 2, m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ] );
  2137. pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2138. // Additive light phase
  2139. pRenderContext->SetBlendState( m_hAdditiveBS );
  2140. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE_STENCIL_TEST_NOTEQUAL );
  2141. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2142. int nParticleSystems = m_lightSystemList.Count();
  2143. for ( int p=0; p<nParticleSystems; ++p )
  2144. {
  2145. RenderParticleLights( pRenderContext, m_lightSystemList[p], VARIATION_DEFAULT, false, false );
  2146. }
  2147. // Render scene lights
  2148. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  2149. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2150. RenderScenePointLights( pRenderContext, m_exteriorPointLights, false );
  2151. RenderScenePointLights( pRenderContext, m_interiorPointLights, true );
  2152. RenderSceneSpotLights( pRenderContext, m_exteriorSpotLights, false );
  2153. RenderSceneSpotLights( pRenderContext, m_interiorSpotLights, true );
  2154. RenderShadowedSpotLights( pRenderContext, m_shadowedSpotLights );
  2155. }
  2156. void CWorldRendererTest::BlurLightBuffer( )
  2157. {
  2158. CRenderContextPtr pRenderContext( g_pRenderDevice );
  2159. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2160. // Bilat blur ( Horizontal )
  2161. {
  2162. m_pRenderViews[ RTB_LIGHT_BLUR_0 ].BeginRender( pRenderContext );
  2163. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2164. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2165. //pRenderContext->SetBlendState( m_hWriteAllBS );
  2166. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  2167. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  2168. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2169. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_LIGHTING_HIGHRES ] );
  2170. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2171. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2172. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2173. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  2174. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2175. pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&m_blurParams, sizeof( BlurParams_t ) );
  2176. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
  2177. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2178. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hBilateralBlur[2] );
  2179. RenderScreenQuad( pRenderContext, m_vEyeRays, "bilatblurhorz" );
  2180. // Submit
  2181. m_pRenderViews[ RTB_LIGHT_BLUR_0 ].EndRender( pRenderContext );
  2182. }
  2183. // Bilat upsampling ( Vertical )
  2184. {
  2185. m_pRenderViews[ RTB_LIGHT_BLUR_1 ].BeginRender( pRenderContext );
  2186. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2187. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2188. //pRenderContext->SetBlendState( m_hWriteAllBS );
  2189. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  2190. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  2191. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2192. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ] );
  2193. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2194. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2195. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2196. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  2197. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2198. pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&m_blurParams, sizeof( BlurParams_t ) );
  2199. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
  2200. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2201. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hBilateralBlur[3] );
  2202. RenderScreenQuad( pRenderContext, m_vEyeRays, "bilatblurvert" );
  2203. // Submit
  2204. m_pRenderViews[ RTB_LIGHT_BLUR_1 ].EndRender( pRenderContext );
  2205. }
  2206. }
  2207. void CWorldRendererTest::BlurShadowBuffers( )
  2208. {
  2209. CRenderContextPtr pRenderContext( g_pRenderDevice );
  2210. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2211. BlurParams_t highResBlurParams = m_blurParams;
  2212. BlurParams_t lowResBlurParams = m_blurParams;
  2213. // High res shadow blur
  2214. {
  2215. // blur ( Horizontal )
  2216. {
  2217. m_pRenderViews[ RTB_SHADOW_BLUR_0 ].BeginRender( pRenderContext );
  2218. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2219. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2220. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  2221. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ] );
  2222. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2223. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2224. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2225. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_shadowScreenData, sizeof( DecalScreenData_t ) );
  2226. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2227. pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&highResBlurParams, sizeof( BlurParams_t ) );
  2228. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
  2229. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2230. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowBlur[0] );
  2231. RenderScreenQuad( pRenderContext, m_vEyeRays, "blurshadowshorz" );
  2232. // Submit
  2233. m_pRenderViews[ RTB_SHADOW_BLUR_0 ].EndRender( pRenderContext );
  2234. }
  2235. // blur ( Vertical )
  2236. {
  2237. m_pRenderViews[ RTB_SHADOW_BLUR_1 ].BeginRender( pRenderContext );
  2238. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2239. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2240. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  2241. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SHADOW_BLUR_TEMP ] );
  2242. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2243. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2244. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2245. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_shadowScreenData, sizeof( DecalScreenData_t ) );
  2246. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2247. pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&highResBlurParams, sizeof( BlurParams_t ) );
  2248. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
  2249. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2250. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowBlur[1] );
  2251. RenderScreenQuad( pRenderContext, m_vEyeRays, "blurshadowvert" );
  2252. // Submit
  2253. m_pRenderViews[ RTB_SHADOW_BLUR_1 ].EndRender( pRenderContext );
  2254. }
  2255. }
  2256. // Low res shadow blur
  2257. {
  2258. // blur ( Horizontal )
  2259. {
  2260. m_pRenderViews[ RTB_SHADOW_BLUR_0 ].BeginRender( pRenderContext );
  2261. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2262. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2263. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  2264. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SHADOW_MULTIPLE_1 ] );
  2265. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2266. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2267. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2268. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_shadowScreenData, sizeof( DecalScreenData_t ) );
  2269. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2270. pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&lowResBlurParams, sizeof( BlurParams_t ) );
  2271. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
  2272. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2273. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowBlur[2] );
  2274. RenderScreenQuad( pRenderContext, m_vEyeRays, "blurshadowhorz2" );
  2275. // Submit
  2276. m_pRenderViews[ RTB_SHADOW_BLUR_0 ].EndRender( pRenderContext );
  2277. }
  2278. // blur ( Vertical )
  2279. {
  2280. m_pRenderViews[ RTB_SHADOW_BLUR_2 ].BeginRender( pRenderContext );
  2281. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2282. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2283. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  2284. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SHADOW_BLUR_TEMP ] );
  2285. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2286. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2287. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2288. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_shadowScreenData, sizeof( DecalScreenData_t ) );
  2289. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2290. pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&lowResBlurParams, sizeof( BlurParams_t ) );
  2291. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
  2292. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2293. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowBlur[3] );
  2294. RenderScreenQuad( pRenderContext, m_vEyeRays, "blurshadowvert2" );
  2295. // Submit
  2296. m_pRenderViews[ RTB_SHADOW_BLUR_2 ].EndRender( pRenderContext );
  2297. }
  2298. }
  2299. }
  2300. void CWorldRendererTest::RenderDecals( IRenderContext *pRenderContext, int nVariation )
  2301. {
  2302. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2303. // Paint Decals
  2304. if ( m_bFullBuffer2 || m_nGlobalDecalPos2 )
  2305. {
  2306. pRenderContext->SetBlendMode( RENDER_BLEND_ALPHABLENDING );
  2307. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2308. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2309. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  2310. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2311. if ( nVariation == 0 )
  2312. {
  2313. pRenderContext->BindTexture( 1, m_hDecalNormal2 );
  2314. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2315. }
  2316. else
  2317. {
  2318. pRenderContext->BindTexture( 1, m_hDecalAlbedo2 );
  2319. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2320. }
  2321. pRenderContext->BindVertexBuffer( 1, 0, 0, 0 );
  2322. pRenderContext->BindVertexBuffer( 0, m_hDecalVB2, 0, sizeof( DecalVertex_t ) );
  2323. pRenderContext->BindIndexBuffer( m_hDecalIB, 0 );
  2324. pRenderContext->BindVertexShader( m_hDecalVS[ nVariation ], m_hDecalLayout );
  2325. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hDecalPS[ nVariation ] );
  2326. int nIndices = 0;
  2327. if ( m_bFullBuffer2 )
  2328. {
  2329. nIndices = m_nMaxDecals * 36;
  2330. }
  2331. else
  2332. {
  2333. nIndices = m_nGlobalDecalPos2 * 36;
  2334. }
  2335. pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, nIndices );
  2336. }
  2337. // Bullet Decals
  2338. if ( m_bFullBuffer || m_nGlobalDecalPos )
  2339. {
  2340. bool bDraw = true;
  2341. pRenderContext->SetBlendMode( RENDER_BLEND_ALPHABLENDING );
  2342. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2343. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2344. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  2345. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2346. if ( nVariation == 0 )
  2347. {
  2348. pRenderContext->BindTexture( 1, m_hDecalNormal );
  2349. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2350. }
  2351. else
  2352. {
  2353. if ( m_hDecalAlbedo == RENDER_TEXTURE_HANDLE_INVALID )
  2354. {
  2355. bDraw = false;
  2356. }
  2357. else
  2358. {
  2359. pRenderContext->BindTexture( 1, m_hDecalAlbedo );
  2360. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2361. }
  2362. }
  2363. if ( bDraw )
  2364. {
  2365. pRenderContext->BindVertexBuffer( 0, m_hDecalVB, 0, sizeof( DecalVertex_t ) );
  2366. pRenderContext->BindIndexBuffer( m_hDecalIB, 0 );
  2367. pRenderContext->BindVertexShader( m_hDecalVS[ nVariation ], m_hDecalLayout );
  2368. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hDecalPS[ nVariation ] );
  2369. int nIndices = 0;
  2370. if ( m_bFullBuffer )
  2371. {
  2372. nIndices = m_nMaxDecals * 36;
  2373. }
  2374. else
  2375. {
  2376. nIndices = m_nGlobalDecalPos * 36;
  2377. }
  2378. pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, nIndices );
  2379. }
  2380. }
  2381. // Wall monster decals
  2382. if ( m_nGlobalDecalPos3 )
  2383. {
  2384. pRenderContext->SetBlendMode( RENDER_BLEND_ALPHABLENDING );
  2385. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2386. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2387. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  2388. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2389. if ( nVariation == 0 )
  2390. {
  2391. pRenderContext->BindTexture( 1, m_hDecalNormal3[ m_nWallMonsterTexture ] );
  2392. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2393. pRenderContext->BindVertexBuffer( 0, m_hDecalVB3, 0, sizeof( DecalVertex_t ) );
  2394. pRenderContext->BindIndexBuffer( m_hDecalIB, 0 );
  2395. pRenderContext->BindVertexShader( m_hDecalVS[ nVariation ], m_hDecalLayout );
  2396. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hDecalPS[ nVariation ] );
  2397. int nIndices = 36;
  2398. pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, nIndices );
  2399. }
  2400. }
  2401. }
  2402. void CWorldRendererTest::RenderDynamic( IRenderContext *pRenderContext, CDynamicRenderable *pRenderable, int nVariation, bool bSunDepth, bool bSetStencil )
  2403. {
  2404. if ( bSunDepth )
  2405. {
  2406. bool bCanSeeSky = true;
  2407. int nLeafNode = m_pWorldRenderer->GetLeafNodeForPoint( pRenderable->m_vOrigin );
  2408. if ( nLeafNode > -1 )
  2409. {
  2410. IBVHNode *pNode = m_pWorldRenderer->GetNode( nLeafNode );
  2411. if ( pNode )
  2412. {
  2413. int nFlags = pNode->GetFlags();
  2414. bCanSeeSky = ( nFlags & NODE_CAN_SEE_SKY ) ? true : false;
  2415. }
  2416. }
  2417. if ( !bCanSeeSky )
  2418. {
  2419. return;
  2420. }
  2421. }
  2422. g_pMeshSystem->DrawRenderable( pRenderContext, pRenderable->m_hRenderable, m_hSimpleMeshVS[ nVariation ], m_hSimpleMeshPS[ nVariation ] );
  2423. }
  2424. void CWorldRendererTest::RenderParticleLights( IRenderContext *pRenderContext, CParticleCollection *pInputSystem, int nVariation, bool bSunDepth, bool bSetStencil )
  2425. {
  2426. VPROF("RenderParticleLights");
  2427. Vector vCenter = pInputSystem->GetControlPointAtCurrentTime( 0 );
  2428. int nLeafNode = m_pWorldRenderer->GetLeafNodeForPoint( vCenter );
  2429. IBVHNode *pNode = m_pWorldRenderer->GetNode( nLeafNode );
  2430. int nFlags = pNode->GetFlags();
  2431. bool bCanSeeSky = ( nFlags & NODE_CAN_SEE_SKY ) != 0;
  2432. if ( bSunDepth && !bCanSeeSky )
  2433. return;
  2434. if ( bSetStencil )
  2435. {
  2436. if ( bCanSeeSky )
  2437. {
  2438. pRenderContext->SetDepthStencilState( m_hSetStencilDS, g_nCanSeeSkyStencilRef );
  2439. }
  2440. else
  2441. {
  2442. pRenderContext->SetDepthStencilState( m_hSetStencilDS, g_nCannotSeeSkyStencilRef );
  2443. }
  2444. }
  2445. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  2446. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2447. pRenderContext->BindVertexShader( m_hPointLightVS[nVariation], m_hPointLightLayout );
  2448. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hPointLightPS[nVariation] );
  2449. pRenderContext->BindVertexBuffer( 0, m_hSphereVB, 0, sizeof( SphereVertex_t ) );
  2450. pRenderContext->BindIndexBuffer( m_hSphereIB, 0 );
  2451. CDynamicVertexData<PerParticleData_t> vb( pRenderContext, pInputSystem->m_nActiveParticles, "particles", "particles" );
  2452. vb.Lock( );
  2453. for ( int p=0; p<pInputSystem->m_nActiveParticles; ++p )
  2454. {
  2455. float const *pPos = pInputSystem->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_XYZ, p );
  2456. float const *pRadius = pInputSystem->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_RADIUS, p );
  2457. float const *pColor = pInputSystem->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_TINT_RGB, p );
  2458. switch( nVariation )
  2459. {
  2460. case VARIATION_DEFAULT:
  2461. vb->m_vPosRadius.Init( pPos[0], pPos[4], pPos[8], pRadius[0] );
  2462. break;
  2463. case 4:
  2464. vb->m_vPosRadius.Init( pPos[0], pPos[4], pPos[8], pRadius[0] * 0.05f );
  2465. break;
  2466. default:
  2467. vb->m_vPosRadius.Init( pPos[0], pPos[4], pPos[8], pRadius[0] * 0.10f );
  2468. break;
  2469. }
  2470. vb->m_vColor.Init( pColor[0], pColor[4], pColor[8], 1 );
  2471. //vb->m_vColor.Init( 0.9, 0.4, 1.0, 1 );
  2472. vb->m_vColor.AsVector3D().NormalizeInPlace();
  2473. vb.AdvanceVertex();
  2474. }
  2475. vb.Unlock( );
  2476. vb.Bind( 1, 0 );
  2477. pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nNumTriangles * 3, pInputSystem->m_nActiveParticles );
  2478. }
  2479. void CWorldRendererTest::RenderScenePointLights( IRenderContext *pRenderContext, CUtlVector<CPointLightRenderable> &lightVector, bool bInterior )
  2480. {
  2481. if ( bInterior )
  2482. {
  2483. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING );
  2484. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE );
  2485. }
  2486. else
  2487. {
  2488. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2489. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
  2490. }
  2491. const int nMaxLightsPerDraw = 512;
  2492. CDynamicVertexData<PointLightData_t> *pVB = NULL;
  2493. int nLights = lightVector.Count();
  2494. int nLightsDrawn = 0;
  2495. for ( int i=0; i<nLights; ++i )
  2496. {
  2497. if ( !pVB )
  2498. {
  2499. pVB = new CDynamicVertexData<PointLightData_t>( pRenderContext, nMaxLightsPerDraw, "scenelights_point", "scenelights_point" );
  2500. pVB->Lock();
  2501. }
  2502. Vector vLightOrigin = lightVector[i].m_pLight->m_vOrigin;
  2503. Vector vNewOrigin = vLightOrigin - lightVector[i].m_vOrigin;
  2504. (*pVB)->m_vOrigin = vNewOrigin;
  2505. (*pVB)->m_vColorNRadius = lightVector[i].m_pLight->m_vColorNRadius;
  2506. (*pVB)->m_vAttenuation = lightVector[i].m_pLight->m_vAttenuation;
  2507. pVB->AdvanceVertex();
  2508. nLightsDrawn ++;
  2509. if ( nLightsDrawn >= nMaxLightsPerDraw )
  2510. {
  2511. nLightsDrawn = 0;
  2512. pVB->Unlock();
  2513. pRenderContext->BindVertexBuffer( 0, m_hSphereVB, 0, sizeof( SphereVertex_t ) );
  2514. pRenderContext->BindIndexBuffer( m_hSphereIB, 0 );
  2515. pVB->Bind( 1, 0 );
  2516. pRenderContext->BindVertexShader( m_hSceneLightVS[0], m_hSceneLightLayout[0] );
  2517. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[0] );
  2518. pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nSphereIndices, nMaxLightsPerDraw );
  2519. delete pVB;
  2520. pVB = NULL;
  2521. }
  2522. }
  2523. if ( pVB )
  2524. {
  2525. Assert( nLightsDrawn > 0 );
  2526. pVB->Unlock();
  2527. pRenderContext->BindVertexBuffer( 0, m_hSphereVB, 0, sizeof( SphereVertex_t ) );
  2528. pRenderContext->BindIndexBuffer( m_hSphereIB, 0 );
  2529. pVB->Bind( 1, 0 );
  2530. pRenderContext->BindVertexShader( m_hSceneLightVS[0], m_hSceneLightLayout[0] );
  2531. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[0] );
  2532. pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nSphereIndices, nLightsDrawn );
  2533. delete pVB;
  2534. }
  2535. }
  2536. void CWorldRendererTest::RenderSceneHemiLights( IRenderContext *pRenderContext, CUtlVector<CHemiLightRenderable> &lightVector, bool bInterior )
  2537. {
  2538. if ( bInterior )
  2539. {
  2540. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING );
  2541. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE );
  2542. }
  2543. else
  2544. {
  2545. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2546. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
  2547. }
  2548. const int nMaxLightsPerDraw = 512;
  2549. CDynamicVertexData<HemiLightData_t> *pVB = NULL;
  2550. int nLights = lightVector.Count();
  2551. int nLightsDrawn = 0;
  2552. for ( int i=0; i<nLights; ++i )
  2553. {
  2554. if ( !pVB )
  2555. {
  2556. pVB = new CDynamicVertexData<HemiLightData_t>( pRenderContext, nMaxLightsPerDraw, "scenelights_hemi", "scenelights_hemi" );
  2557. pVB->Lock();
  2558. }
  2559. Vector vOrigin = lightVector[i].m_vOrigin;
  2560. (*pVB)->m_vTransform0 = lightVector[i].m_pLight->m_vTransform0;
  2561. (*pVB)->m_vTransform1 = lightVector[i].m_pLight->m_vTransform1;
  2562. (*pVB)->m_vTransform2 = lightVector[i].m_pLight->m_vTransform2;
  2563. (*pVB)->m_vTransform0.w -= vOrigin.x;
  2564. (*pVB)->m_vTransform1.w -= vOrigin.y;
  2565. (*pVB)->m_vTransform2.w -= vOrigin.z;
  2566. (*pVB)->m_vColorNRadius = lightVector[i].m_pLight->m_vColorNRadius;
  2567. (*pVB)->m_vAttenuation = lightVector[i].m_pLight->m_vAttenuation;
  2568. pVB->AdvanceVertex();
  2569. nLightsDrawn ++;
  2570. if ( nLightsDrawn >= nMaxLightsPerDraw )
  2571. {
  2572. nLightsDrawn = 0;
  2573. pVB->Unlock();
  2574. pRenderContext->BindVertexBuffer( 0, m_hHemiVB, 0, sizeof( SphereVertex_t ) );
  2575. pRenderContext->BindIndexBuffer( m_hHemiIB, 0 );
  2576. pVB->Bind( 1, 0 );
  2577. pRenderContext->BindVertexShader( m_hSceneLightVS[1], m_hSceneLightLayout[1] );
  2578. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[1] );
  2579. pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nHemiIndices, nMaxLightsPerDraw );
  2580. delete pVB;
  2581. pVB = NULL;
  2582. }
  2583. }
  2584. if ( pVB )
  2585. {
  2586. pVB->Unlock();
  2587. if ( nLightsDrawn > 0 )
  2588. {
  2589. pRenderContext->BindVertexBuffer( 0, m_hHemiVB, 0, sizeof( SphereVertex_t ) );
  2590. pRenderContext->BindIndexBuffer( m_hHemiIB, 0 );
  2591. pVB->Bind( 1, 0 );
  2592. pRenderContext->BindVertexShader( m_hSceneLightVS[1], m_hSceneLightLayout[1] );
  2593. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[1] );
  2594. pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nHemiIndices, nLightsDrawn );
  2595. }
  2596. delete pVB;
  2597. }
  2598. }
  2599. void CWorldRendererTest::RenderSceneSpotLights( IRenderContext *pRenderContext, CUtlVector<CSpotLightRenderable> &lightVector, bool bInterior )
  2600. {
  2601. if ( bInterior )
  2602. {
  2603. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING );
  2604. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE );
  2605. }
  2606. else
  2607. {
  2608. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2609. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
  2610. }
  2611. const int nMaxLightsPerDraw = 512;
  2612. CDynamicVertexData<SpotLightData_t> *pVB = NULL;
  2613. int nLights = lightVector.Count();
  2614. int nLightsDrawn = 0;
  2615. for ( int i=0; i<nLights; ++i )
  2616. {
  2617. if ( !lightVector[i].m_bValid )
  2618. continue;
  2619. if ( !pVB )
  2620. {
  2621. pVB = new CDynamicVertexData<SpotLightData_t>( pRenderContext, nMaxLightsPerDraw, "scenelights_spot", "scenelights_spot" );
  2622. pVB->Lock();
  2623. }
  2624. Vector vOrigin = lightVector[i].m_vOrigin;
  2625. (*pVB)->m_vTransform0 = lightVector[i].m_pLight->m_vTransform0;
  2626. (*pVB)->m_vTransform1 = lightVector[i].m_pLight->m_vTransform1;
  2627. (*pVB)->m_vTransform2 = lightVector[i].m_pLight->m_vTransform2;
  2628. (*pVB)->m_vTransform0.w -= vOrigin.x;
  2629. (*pVB)->m_vTransform1.w -= vOrigin.y;
  2630. (*pVB)->m_vTransform2.w -= vOrigin.z;
  2631. (*pVB)->m_vColorNRadius = lightVector[i].m_pLight->m_vColorNRadius;
  2632. (*pVB)->m_vAttenuationNCosSpot = lightVector[i].m_pLight->m_vAttenuationNCosSpot;
  2633. pVB->AdvanceVertex();
  2634. nLightsDrawn ++;
  2635. if ( nLightsDrawn >= nMaxLightsPerDraw )
  2636. {
  2637. nLightsDrawn = 0;
  2638. pVB->Unlock();
  2639. pRenderContext->BindVertexBuffer( 0, m_hConeVB, 0, sizeof( SphereVertex_t ) );
  2640. pRenderContext->BindIndexBuffer( m_hConeIB, 0 );
  2641. pVB->Bind( 1, 0 );
  2642. pRenderContext->BindVertexShader( m_hSceneLightVS[2], m_hSceneLightLayout[2] );
  2643. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[2] );
  2644. pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nHemiIndices, nMaxLightsPerDraw );
  2645. delete pVB;
  2646. pVB = NULL;
  2647. }
  2648. }
  2649. if ( pVB )
  2650. {
  2651. pVB->Unlock();
  2652. Assert( nLightsDrawn > 0 );
  2653. pRenderContext->BindVertexBuffer( 0, m_hConeVB, 0, sizeof( SphereVertex_t ) );
  2654. pRenderContext->BindIndexBuffer( m_hConeIB, 0 );
  2655. pVB->Bind( 1, 0 );
  2656. pRenderContext->BindVertexShader( m_hSceneLightVS[2], m_hSceneLightLayout[2] );
  2657. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[2] );
  2658. pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nConeIndices, nLightsDrawn );
  2659. delete pVB;
  2660. }
  2661. }
  2662. void CWorldRendererTest::RenderShadowedSpotLights( IRenderContext *pRenderContext, CUtlVector<CSpotLightRenderable> &lightVector )
  2663. {
  2664. int nLights = lightVector.Count();
  2665. if ( nLights == 0 )
  2666. return;
  2667. const int nMaxLightsPerDraw = NUM_MULTI_SHADOWS;
  2668. CDynamicVertexData<SpotLightData_t> *pVB = new CDynamicVertexData<SpotLightData_t>( pRenderContext, nMaxLightsPerDraw, "scenelights_shadowspot", "scenelights_shadowspot" );
  2669. pVB->Lock();
  2670. Assert( nLights <= NUM_MULTI_SHADOWS );
  2671. for ( int i=0; i<nLights; ++i )
  2672. {
  2673. Vector vOrigin = lightVector[i].m_vOrigin;
  2674. (*pVB)->m_vTransform0 = lightVector[i].m_pLight->m_vTransform0;
  2675. (*pVB)->m_vTransform1 = lightVector[i].m_pLight->m_vTransform1;
  2676. (*pVB)->m_vTransform2 = lightVector[i].m_pLight->m_vTransform2;
  2677. (*pVB)->m_vTransform0.w -= vOrigin.x;
  2678. (*pVB)->m_vTransform1.w -= vOrigin.y;
  2679. (*pVB)->m_vTransform2.w -= vOrigin.z;
  2680. (*pVB)->m_vColorNRadius = lightVector[i].m_pLight->m_vColorNRadius;
  2681. (*pVB)->m_vAttenuationNCosSpot = lightVector[i].m_pLight->m_vAttenuationNCosSpot;
  2682. pVB->AdvanceVertex();
  2683. }
  2684. pVB->Unlock();
  2685. // Bind
  2686. pRenderContext->BindVertexShader( m_hSceneLightVS[2], m_hSceneLightLayout[2] );
  2687. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[5] );
  2688. pRenderContext->BindVertexBuffer( 0, m_hConeVB, 0, sizeof( SphereVertex_t ) );
  2689. pRenderContext->BindIndexBuffer( m_hConeIB, 0 );
  2690. for ( int i=0; i<nLights; ++i )
  2691. {
  2692. if ( i < NUM_HIGH_RES_SHADOWS )
  2693. {
  2694. pRenderContext->BindTexture( 4, m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ] );
  2695. pRenderContext->SetSamplerStatePS( 4, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2696. pRenderContext->BindTexture( 3, m_hFlashlightCookie[0] );
  2697. pRenderContext->SetSamplerStatePS( 3, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2698. }
  2699. else
  2700. {
  2701. pRenderContext->BindTexture( 4, m_pRenderTargets[ RT_SHADOW_MULTIPLE_1 ] );
  2702. pRenderContext->SetSamplerStatePS( 4, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2703. pRenderContext->BindTexture( 3, m_hFlashlightCookie[1] );
  2704. pRenderContext->SetSamplerStatePS( 3, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2705. }
  2706. pRenderContext->SetConstantBufferData( m_hSingleMatrixRelated, &m_pMultiShadowMatrices[ i ], sizeof( VMatrix ) );
  2707. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hSingleMatrixRelated, 1, 7 );
  2708. if ( lightVector[i].m_bInterior )
  2709. {
  2710. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING );
  2711. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE );
  2712. }
  2713. else
  2714. {
  2715. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2716. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
  2717. }
  2718. pVB->Bind( 1, i * sizeof( SpotLightData_t ) );
  2719. pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nConeIndices, 1 );
  2720. }
  2721. delete pVB;
  2722. }
  2723. void CWorldRendererTest::CalculateEyeRays( float flFarPlane )
  2724. {
  2725. Vector vForward = m_pFrustum->Forward();
  2726. Vector vUp = m_pFrustum->Up();
  2727. Vector vLeft = m_pFrustum->Left();
  2728. float flFovX = m_pFrustum->GetFOV();
  2729. float flFovY = CalcFovY( flFovX, m_pFrustum->GetAspect() );
  2730. flFovX *= 0.5f;
  2731. flFovY *= 0.5f;
  2732. Vector vFowardShift = flFarPlane * vForward;
  2733. Vector vUpShift = flFarPlane * tanf( DEG2RAD( flFovY ) ) * vUp;
  2734. Vector vRightShift = flFarPlane * tanf( DEG2RAD( flFovX ) ) * -vLeft;
  2735. m_vEyeRays[0] = vFowardShift + -vRightShift + -vUpShift;
  2736. m_vEyeRays[1] = vFowardShift + vRightShift + -vUpShift;
  2737. m_vEyeRays[2] = vFowardShift + -vRightShift + vUpShift;
  2738. m_vEyeRays[3] = vFowardShift + vRightShift + vUpShift;
  2739. vFowardShift = flFarPlane * Vector( 0, 0, 1 );
  2740. vUpShift = flFarPlane * tanf( DEG2RAD( flFovY ) ) * Vector( 0, 1, 0 );
  2741. vRightShift = flFarPlane * tanf( DEG2RAD( flFovX ) ) * Vector( 1, 0, 0 );
  2742. m_vEyeLocalRays[0] = vFowardShift + -vRightShift + -vUpShift;
  2743. m_vEyeLocalRays[1] = vFowardShift + vRightShift + -vUpShift;
  2744. m_vEyeLocalRays[2] = vFowardShift + -vRightShift + vUpShift;
  2745. m_vEyeLocalRays[3] = vFowardShift + vRightShift + vUpShift;
  2746. }
  2747. void CWorldRendererTest::BilateralUpsample( )
  2748. {
  2749. CRenderContextPtr pRenderContext( g_pRenderDevice );
  2750. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2751. // Bilat upsampling ( Horizontal )
  2752. {
  2753. m_pRenderViews[ RTB_BILAT_UPSAMPLE_0 ].BeginRender( pRenderContext );
  2754. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2755. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2756. pRenderContext->SetBlendState( m_hWriteAllBS );
  2757. if ( IsPlatformX360() )
  2758. pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_LOWRES ] );
  2759. else
  2760. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ] );
  2761. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2762. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_LIGHTING_LOWRES ] );
  2763. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2764. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2765. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2766. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_lowResScreenData, sizeof( DecalScreenData_t ) );
  2767. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2768. pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&m_blurParams, sizeof( BlurParams_t ) );
  2769. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
  2770. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2771. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hBilateralBlur[0] );
  2772. RenderScreenQuad( pRenderContext, m_vEyeRays, "bilatupsamplehorz" );
  2773. // Submit
  2774. m_pRenderViews[ RTB_BILAT_UPSAMPLE_0 ].EndRender( pRenderContext );
  2775. }
  2776. // Bilat upsampling ( Vertical )
  2777. {
  2778. m_pRenderViews[ RTB_BILAT_UPSAMPLE_1 ].BeginRender( pRenderContext );
  2779. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2780. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2781. pRenderContext->SetBlendState( m_hWriteAllBS );
  2782. if ( IsPlatformX360() )
  2783. pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] );
  2784. else
  2785. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  2786. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2787. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_LIGHTING_TEMP_LOWRES ] );
  2788. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2789. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2790. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2791. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  2792. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2793. pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&m_blurParams, sizeof( BlurParams_t ) );
  2794. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
  2795. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2796. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hBilateralBlur[1] );
  2797. RenderScreenQuad( pRenderContext, m_vEyeRays, "bilatupsamplevert" );
  2798. // Submit
  2799. m_pRenderViews[ RTB_BILAT_UPSAMPLE_1 ].EndRender( pRenderContext );
  2800. }
  2801. }
  2802. void CWorldRendererTest::RenderSSAO()
  2803. {
  2804. CRenderContextPtr pRenderContext( g_pRenderDevice );
  2805. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2806. m_pRenderViews[ RTB_SSAO_LOWRES ].BeginRender( pRenderContext );
  2807. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  2808. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2809. pRenderContext->SetBlendState( m_hWriteAlphaBS );
  2810. #if 0
  2811. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ] );
  2812. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2813. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_NORMAL_LOWRES ] );
  2814. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2815. pRenderContext->BindTexture( 2, m_hRandomTexture );
  2816. pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_WRAP, RS_TEXTURE_ADDRESS_WRAP, RS_TEXTURE_ADDRESS_WRAP );
  2817. #else
  2818. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ] );
  2819. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2820. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_NORMAL_LOWRES ] );
  2821. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2822. pRenderContext->BindTexture( 2, m_hRandomTexture );
  2823. pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_WRAP, RS_TEXTURE_ADDRESS_WRAP, RS_TEXTURE_ADDRESS_WRAP );
  2824. #endif
  2825. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2826. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2827. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_lowResScreenData, sizeof( DecalScreenData_t ) );
  2828. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2829. pRenderContext->SetConstantBufferData( m_hSphereSampleData, &m_sphereSampleData, sizeof( SampleSphereData_t ) );
  2830. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hSphereSampleData, 1, 7 );
  2831. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2832. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSSAOPS );
  2833. RenderScreenQuad( pRenderContext, m_vEyeRays/*m_vEyeLocalRays*/, "ssao" );
  2834. // Submit
  2835. m_pRenderViews[ RTB_SSAO_LOWRES ].EndRender( pRenderContext );
  2836. }
  2837. void CWorldRendererTest::ScaleDepthAndNormalBuffers()
  2838. {
  2839. CRenderContextPtr pRenderContext( g_pRenderDevice );
  2840. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2841. m_pRenderViews[ RTB_DEFERRED_SCALE_DOWN ].BeginRender( pRenderContext );
  2842. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2843. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  2844. pRenderContext->SetDepthStencilState( m_hZWriteNoTestDS );
  2845. if ( IsPlatformX360() )
  2846. {
  2847. pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] );
  2848. }
  2849. else
  2850. {
  2851. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  2852. }
  2853. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT/*RENDER_TEXFILTERMODE_LINEAR*/, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2854. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_NORMAL_HIGHRES ] );
  2855. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT/*RENDER_TEXFILTERMODE_LINEAR*/, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  2856. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2857. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2858. DecalScreenData_t lowResCopyData = m_lowResScreenData;
  2859. lowResCopyData.m_mInvViewProj = viewConstants.m_mViewProjection;
  2860. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &lowResCopyData, sizeof( DecalScreenData_t ) );
  2861. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  2862. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2863. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hCopyTexture[0] );
  2864. RenderScreenQuad( pRenderContext, m_vEyeRays, "scaledepthnorm" );
  2865. // Submit
  2866. m_pRenderViews[ RTB_DEFERRED_SCALE_DOWN ].EndRender( pRenderContext );
  2867. }
  2868. void CWorldRendererTest::RenderAerialPerspective()
  2869. {
  2870. CRenderContextPtr pRenderContext( g_pRenderDevice );
  2871. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  2872. m_pRenderViews[ RTB_AERIAL_PERSPECTIVE ].BeginRender( pRenderContext );
  2873. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE_STENCIL_TEST_NOTEQUAL );
  2874. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  2875. if ( IsPlatformX360() )
  2876. {
  2877. pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] );
  2878. }
  2879. else
  2880. {
  2881. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  2882. }
  2883. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT );
  2884. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  2885. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  2886. pRenderContext->SetConstantBufferData( m_hAerialPerspectivePSCB, (void*)&m_aerialPerspectiveData, sizeof( AerialPerspectiveConstants_t ) );
  2887. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hAerialPerspectivePSCB, 0, 0 );
  2888. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  2889. // Extinction
  2890. pRenderContext->SetBlendState( m_hExtinctionBS );
  2891. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hAerialPerspectivePS[0] );
  2892. RenderScreenQuad( pRenderContext, m_vEyeRays, "exinction" );
  2893. // In-scattering
  2894. pRenderContext->SetDepthStencilState( m_hStencilTestDS, g_nCanSeeSkyStencilRef );
  2895. pRenderContext->SetBlendState( m_hInscatteringBS );
  2896. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hAerialPerspectivePS[1] );
  2897. RenderScreenQuad( pRenderContext, m_vEyeRays, "inscattering" );
  2898. // Submit
  2899. m_pRenderViews[ RTB_AERIAL_PERSPECTIVE ].EndRender( pRenderContext );
  2900. }
  2901. void CWorldRendererTest::RenderSky()
  2902. {
  2903. VPROF("RenderSky");
  2904. CRenderContextPtr pRenderContext( g_pRenderDevice );
  2905. // Update the camera
  2906. m_pFrustum->SetNearFarPlanes( m_flNearPlane, m_flFarPlane );
  2907. m_pFrustum->UpdateFrustumFromCamera();
  2908. if ( m_bDeferred )
  2909. {
  2910. m_pRenderViews[ RTB_SKY ].BeginRender( pRenderContext );
  2911. }
  2912. else
  2913. {
  2914. m_pRenderViews[ RTB_FORWARD ].BeginRender( pRenderContext );
  2915. }
  2916. // Sky
  2917. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  2918. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING );
  2919. if ( m_bDeferred )
  2920. {
  2921. pRenderContext->SetDepthStencilState( m_hZTestAndStencilTestDS, g_nNothingRenderedStencilRef );
  2922. }
  2923. else
  2924. {
  2925. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
  2926. }
  2927. SkyVSCB_t skyVSCB;
  2928. VMatrix mTrans;
  2929. mTrans.Identity();
  2930. mTrans.SetTranslation( m_pFrustum->GetCameraPosition() );
  2931. skyVSCB.m_mViewProj = mTrans.Transpose() * m_pFrustum->GetViewProj();
  2932. skyVSCB.m_vSkyScale = Vector4D( 17000.0f, 17000.0f, 3000.0f, 0.0f );
  2933. m_skyData.m_vEyePt = Vector4D( 0,0,0,0 );
  2934. m_skyData.m_vLightDir = Vector4D( m_vLightDir.x, m_vLightDir.y, m_vLightDir.z, 1 );
  2935. pRenderContext->SetConstantBufferData( m_hSkyVSCB, (void*)&skyVSCB, sizeof( SkyVSCB_t ) );
  2936. pRenderContext->SetConstantBufferData( m_hSkyPSCB, (void*)&m_skyData, sizeof( SkyPSCB_t ) );
  2937. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hSkyVSCB, 0, 0 );
  2938. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hSkyPSCB, 0, 0 );
  2939. pRenderContext->BindVertexShader( m_hSkyVS, m_hSphereLayout );
  2940. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSkyPS );
  2941. pRenderContext->BindVertexBuffer( 0, m_hSphereVB, 0, sizeof( SphereVertex_t ) );
  2942. pRenderContext->BindIndexBuffer( m_hSphereIB, 0 );
  2943. pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, m_nNumTriangles * 3 );
  2944. // Submit
  2945. if ( m_bDeferred )
  2946. {
  2947. m_pRenderViews[ RTB_SKY ].EndRender( pRenderContext );
  2948. }
  2949. else
  2950. {
  2951. m_pRenderViews[ RTB_FORWARD ].EndRender( pRenderContext );
  2952. }
  2953. }
  2954. void CWorldRendererTest::RenderFrame_Internal( const RenderViewport_t &viewport )
  2955. {
  2956. VPROF("RenderFrame_Internal");
  2957. if ( !m_bWorldLoaded )
  2958. return;
  2959. m_nWindowCenterX = viewport.m_nTopLeftX + (viewport.m_nWidth / 2);
  2960. m_nWindowCenterY = viewport.m_nTopLeftY + (viewport.m_nHeight / 2);
  2961. RenderViewport_t lowResViewport;
  2962. lowResViewport = viewport;
  2963. lowResViewport.m_nWidth = (int)( lowResViewport.m_nWidth * m_flLowResBufferScale );
  2964. lowResViewport.m_nHeight = (int)( lowResViewport.m_nHeight * m_flLowResBufferScale );
  2965. UpdateFrustum( viewport.m_nWidth, viewport.m_nHeight );
  2966. CRenderContextPtr pRenderContext( g_pRenderDevice );
  2967. VMatrix mWorld;
  2968. mWorld.Identity();
  2969. Vector vCameraPos = m_pFrustum->GetCameraPosition();
  2970. float flFarPlane = m_pWorldRenderer->GetMaxVisibleDistance( vCameraPos );
  2971. float flShiftedFar = m_flFarPlane;
  2972. if ( m_bEnableVis )
  2973. flShiftedFar = MIN( flFarPlane, m_flFarPlane );
  2974. CWorldRenderFrustum *pCullFrustum = m_pFrustum;
  2975. if ( m_bDropFrustum )
  2976. {
  2977. pCullFrustum = m_pDropFrustum;
  2978. vCameraPos = m_vCullPos;
  2979. flShiftedFar = m_flFarPlane;
  2980. }
  2981. // Update the camera
  2982. m_pFrustum->SetNearFarPlanes( m_flNearPlane, flShiftedFar );
  2983. m_pFrustum->UpdateFrustumFromCamera();
  2984. VMatrix mViewProj = m_pFrustum->GetViewProj();
  2985. // Shadow split frustums
  2986. float flLightDistance = 5000.0f;
  2987. float flLightFarPlane = 8000.0f;
  2988. float flMaxShadowDistance = 5000.0f;
  2989. m_pFrustum->CalculateLightFrusta( m_pSplitFrustums, m_nShadowSplits, m_vLightDir, flLightDistance, flLightFarPlane, flMaxShadowDistance );
  2990. // Pull flashlight data from the camera
  2991. UpdateFlashlightData();
  2992. // Pull viewmodel data from the camera
  2993. UpdateViewModelData();
  2994. // Build renderables list
  2995. GenerateRenderables( vCameraPos );
  2996. // Update Shadow Data (do this before culling!!!)
  2997. UpdateShadowData();
  2998. // Culling
  2999. if ( m_bDeferred )
  3000. {
  3001. for ( int v=0; v<RTB_FORWARD; ++v )
  3002. {
  3003. CullRenderablesAgainstView( m_pRenderViews[ v ], m_renderableList, m_dynRenderableList );
  3004. }
  3005. }
  3006. else
  3007. {
  3008. for ( int v=RTB_SHADOW_DEPTH0; v<RTB_SHADOW_DEPTH_MULTIPLE_0; ++v )
  3009. {
  3010. CullRenderablesAgainstView( m_pRenderViews[ v ], m_renderableList, m_dynRenderableList );
  3011. }
  3012. CullRenderablesAgainstView( m_pRenderViews[ RTB_FORWARD ], m_renderableList, m_dynRenderableList );
  3013. }
  3014. // Update the camera to make sure we shift the far plane out enough to encompass any lights
  3015. flShiftedFar = MAX( flShiftedFar, m_flMaxLightEncompassingFarPlane );
  3016. m_pFrustum->SetNearFarPlanes( m_flNearPlane, flShiftedFar );
  3017. m_pFrustum->UpdateFrustumFromCamera();
  3018. mViewProj = m_pFrustum->GetViewProj();
  3019. ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
  3020. m_forwardLightingData.m_vLightColor = m_vRenderLightColor;
  3021. m_forwardLightingData.m_vLightDir = Vector4D( m_vLightDir.x, m_vLightDir.y, m_vLightDir.z, 1 );
  3022. m_lightBufferData.m_vInvScreenExtents = Vector4D( 1.0f / viewport.m_nWidth, 1.0f / viewport.m_nHeight, 0, 0 );
  3023. // Calculate eye rays
  3024. CalculateEyeRays( flShiftedFar );
  3025. //
  3026. // Start of rendering
  3027. //
  3028. // Shadow depth buffers
  3029. RenderShadowDepthBuffers( pRenderContext );
  3030. if ( m_bDeferred )
  3031. {
  3032. m_deferredLightingData.m_vLightColor = m_vRenderLightColor;
  3033. m_deferredLightingData.m_vLightDir = Vector4D( m_vLightDir.x, m_vLightDir.y, m_vLightDir.z, 1 );
  3034. m_deferredLightingData.m_vInvScreenExtents = Vector4D( 1.0f / viewport.m_nWidth, 1.0f / viewport.m_nHeight, 0, 0 );
  3035. m_deferredLightingData.m_vEyePt = Vector4D( vCameraPos.x, vCameraPos.y, vCameraPos.z, 1 );
  3036. m_aerialPerspectiveData.m_vLightDir = m_deferredLightingData.m_vLightDir;
  3037. m_aerialPerspectiveData.m_vLightColor = m_skyData.m_vLightColor;
  3038. m_aerialPerspectiveData.m_vInvScreenExtents = m_deferredLightingData.m_vInvScreenExtents;
  3039. m_aerialPerspectiveData.m_vBm = m_skyData.m_vBm;
  3040. m_aerialPerspectiveData.m_flG = Vector4D( 0.7f, 0,0,0 );
  3041. m_aerialPerspectiveData.m_vNearAndFar = Vector4D( m_flNearPlane, flShiftedFar, 0, 0 );
  3042. m_aerialPerspectiveData.m_vEyePt = Vector4D( vCameraPos.x, vCameraPos.y, vCameraPos.z, 1 );
  3043. m_sphereSampleData.m_mViewProj = viewConstants.m_mViewProjection;
  3044. m_sphereSampleData.m_vRandSampleScale.Init( 1 / (float)m_nRandTextureSize, 1 / (float)m_nRandTextureSize,
  3045. 0.5f + ( 0.5f / lowResViewport.m_nWidth ),
  3046. 0.5f + ( 0.5f / lowResViewport.m_nHeight ) );
  3047. float flSSAOBias = 0.005f;
  3048. float flSSAOStrenth = 5.0f;
  3049. m_sphereSampleData.m_vSampleRadiusNBias.Init( m_flSampleRadius, flShiftedFar / ( m_flSampleRadius * flSSAOStrenth ), flShiftedFar, flSSAOBias * flShiftedFar );
  3050. m_blurParams.m_flFarPlane.Init( flShiftedFar, flShiftedFar, flShiftedFar, flShiftedFar );
  3051. VMatrix mPosLookupViewProj = mViewProj;
  3052. if ( IsPlatformX360() )
  3053. {
  3054. VMatrix mDepthFlip( 1.0f, 0.0f, 0.0f, 0.0f,
  3055. 0.0f, 1.0f, 0.0f, 0.0f,
  3056. 0.0f, 0.0f, -1.0f, 0.0f,
  3057. 0.0f, 0.0f, 1.0f, 1.0f );
  3058. mPosLookupViewProj = mPosLookupViewProj * mDepthFlip;
  3059. }
  3060. if ( !MatrixInverseGeneral( mPosLookupViewProj, m_deferredLightingData.m_mInvViewProj ) )
  3061. return;
  3062. m_decalScreenData.m_vInvScreenExtents = m_deferredLightingData.m_vInvScreenExtents;
  3063. m_decalScreenData.m_mInvViewProj = m_deferredLightingData.m_mInvViewProj;
  3064. m_decalScreenData.m_vEyePt = m_aerialPerspectiveData.m_vEyePt;
  3065. m_decalScreenData.m_vEyeDir = viewConstants.m_vEyeDir;
  3066. m_lowResScreenData.m_vInvScreenExtents = Vector4D( 1.0f / lowResViewport.m_nWidth, 1.0f / lowResViewport.m_nHeight, 0, 0 );
  3067. m_lowResScreenData.m_mInvViewProj = m_deferredLightingData.m_mInvViewProj;
  3068. m_lowResScreenData.m_vEyePt = m_aerialPerspectiveData.m_vEyePt;
  3069. m_lowResScreenData.m_vEyeDir = viewConstants.m_vEyeDir;
  3070. m_shadowScreenData.m_vInvScreenExtents = Vector4D( 1.0f / m_shadowViewport.m_nWidth, 1.0f / m_shadowViewport.m_nHeight, 0, 0 );
  3071. m_shadowScreenData.m_mInvViewProj = m_deferredLightingData.m_mInvViewProj;
  3072. m_shadowScreenData.m_vEyePt = m_aerialPerspectiveData.m_vEyePt;
  3073. m_shadowScreenData.m_vEyeDir = viewConstants.m_vEyeDir;
  3074. m_aerialPerspectiveData.m_mInvViewProj = m_deferredLightingData.m_mInvViewProj;;
  3075. // Blur shadow buffers
  3076. if ( m_bBlurShadows )
  3077. {
  3078. BlurShadowBuffers();
  3079. }
  3080. // Render depth and normal pass
  3081. {
  3082. // SetRenderTarget must be the first call in any command list
  3083. Vector4D vNormalClear(1,1,1,1);
  3084. m_pRenderViews[ RTB_DEFERRED_DEPTH_NORM_SPEC ].Clear( pRenderContext, vNormalClear, RENDER_CLEAR_FLAGS_CLEAR_DEPTH | RENDER_CLEAR_FLAGS_CLEAR_STENCIL );
  3085. RenderView( m_pRenderViews[ RTB_DEFERRED_DEPTH_NORM_SPEC ] );
  3086. // Render spheres
  3087. m_pRenderViews[ RTB_DEFERRED_DEPTH_NORM_SPEC ].BeginRender( pRenderContext );
  3088. VMatrix mViewRelated;
  3089. mViewRelated = m_pFrustum->GetViewProj();
  3090. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  3091. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  3092. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  3093. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE_STENCIL_SET1 );
  3094. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  3095. int nParticleSystems = m_sphereSystemList.Count();
  3096. for ( int p=0; p<nParticleSystems; ++p )
  3097. {
  3098. RenderParticleLights( pRenderContext, m_sphereSystemList[p], VARIATION_NORM_DEPTH_SPEC, false, true );
  3099. }
  3100. // Submit
  3101. m_pRenderViews[ RTB_DEFERRED_DEPTH_NORM_SPEC ].EndRender( pRenderContext );
  3102. }
  3103. // Clear low -res lighting
  3104. {
  3105. Vector4D vLightingClear(0,0,0,1);
  3106. m_pRenderViews[ RTB_LIGHTING_LOWRES ].Clear( pRenderContext, vLightingClear, 0 );
  3107. }
  3108. // Decals
  3109. {
  3110. m_pRenderViews[ RTB_DEFERRED_NORM_SPEC ].BeginRender( pRenderContext );
  3111. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  3112. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  3113. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
  3114. // Render decals into normal map... using depth
  3115. if ( IsPlatformX360() )
  3116. {
  3117. pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] );
  3118. }
  3119. else
  3120. {
  3121. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  3122. }
  3123. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT );
  3124. RenderDecals( pRenderContext, 0 );
  3125. // Submit
  3126. m_pRenderViews[ RTB_DEFERRED_NORM_SPEC ].EndRender( pRenderContext );
  3127. }
  3128. // Scale depth and normal buffers
  3129. ScaleDepthAndNormalBuffers();
  3130. // SSAO only requires depth (and normal later)
  3131. if ( m_bSSAO )
  3132. {
  3133. RenderSSAO();
  3134. }
  3135. // Low res lighting requires depth and normal
  3136. {
  3137. m_pRenderViews[ RTB_LIGHTING_LOWRES ].BeginRender( pRenderContext );
  3138. if ( m_bDrawBouncedLight )
  3139. {
  3140. RenderBouncedLight( pRenderContext );
  3141. }
  3142. // Submit
  3143. m_pRenderViews[ RTB_LIGHTING_LOWRES ].EndRender( pRenderContext );
  3144. }
  3145. // Upsample
  3146. BilateralUpsample();
  3147. // Clear specular buffer
  3148. {
  3149. Vector4D vSpecClear(0,0,0,0);
  3150. m_pRenderViews[ RTB_CLEAR_SPEC_HIGHRES ].Clear( pRenderContext, vSpecClear, 0 );
  3151. }
  3152. // Do lighting
  3153. {
  3154. m_pRenderViews[ RTB_LIGHTING_HIGHRES ].BeginRender( pRenderContext );
  3155. RenderSunShadowFrustums( pRenderContext );
  3156. if ( m_bDrawDirectLight )
  3157. {
  3158. RenderDirectLight( pRenderContext );
  3159. }
  3160. // Submit
  3161. m_pRenderViews[ RTB_LIGHTING_HIGHRES ].EndRender( pRenderContext );
  3162. }
  3163. // Blur the light buffer
  3164. if ( m_bBlurLighting )
  3165. {
  3166. BlurLightBuffer();
  3167. }
  3168. if ( m_bLightingOnly )
  3169. {
  3170. m_pRenderViews[ RTB_SAMPLE_LIGHTING ].BeginRender( pRenderContext );
  3171. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  3172. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  3173. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
  3174. pRenderContext->BindTexture( 0, m_pRenderTargets[ m_nViewBuffer ] );
  3175. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  3176. if ( m_nViewBuffer == RT_LIGHTING_HIGHRES )
  3177. {
  3178. pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SPECULAR_HIGHRES ] );
  3179. pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
  3180. }
  3181. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  3182. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  3183. pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) );
  3184. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
  3185. pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
  3186. if ( m_nViewBuffer == RT_LIGHTING_LOWRES )
  3187. {
  3188. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hCopyTexture[2] );
  3189. }
  3190. else if ( m_nViewBuffer == RT_LIGHTING_HIGHRES )
  3191. {
  3192. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hCopyTexture[3] );
  3193. }
  3194. else
  3195. {
  3196. pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hCopyTexture[1] );
  3197. }
  3198. RenderScreenQuad( pRenderContext, m_vEyeRays, "lightingonly" );
  3199. // Submit
  3200. m_pRenderViews[ RTB_SAMPLE_LIGHTING ].EndRender( pRenderContext );
  3201. }
  3202. // Render forward pass while sampling lighting
  3203. else
  3204. {
  3205. Vector4D vForwardClear(0,0,0,0);
  3206. m_pRenderViews[ RTB_SAMPLE_LIGHTING ].Clear( pRenderContext, vForwardClear, 0 );
  3207. RenderView( m_pRenderViews[ RTB_SAMPLE_LIGHTING ] );
  3208. // Render spheres
  3209. m_pRenderViews[ RTB_SAMPLE_LIGHTING ].BeginRender( pRenderContext );
  3210. pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) );
  3211. pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
  3212. int nParticleSystems = m_sphereSystemList.Count();
  3213. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  3214. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_EQUAL_NO_WRITE );
  3215. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  3216. pRenderContext->BindTexture( 4, m_pRenderTargets[ RT_LIGHTING_HIGHRES ] );
  3217. pRenderContext->SetSamplerStatePS( 4, RS_FILTER_MIN_MAG_MIP_POINT );
  3218. pRenderContext->BindTexture( 5, m_pRenderTargets[ RT_SPECULAR_HIGHRES ] );
  3219. pRenderContext->SetSamplerStatePS( 5, RS_FILTER_MIN_MAG_MIP_POINT );
  3220. for ( int p=0; p<nParticleSystems; ++p )
  3221. {
  3222. RenderParticleLights( pRenderContext, m_sphereSystemList[p], VARIATION_SAMPLE_LIGHTING, false, false );
  3223. }
  3224. // Decals
  3225. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
  3226. if ( IsPlatformX360() )
  3227. {
  3228. pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] );
  3229. }
  3230. else
  3231. {
  3232. pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
  3233. }
  3234. pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT );
  3235. pRenderContext->BindTexture( 2, m_pRenderTargets[ RT_LIGHTING_HIGHRES ] );
  3236. pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT );
  3237. pRenderContext->BindTexture( 3, m_pRenderTargets[ RT_SPECULAR_HIGHRES ] );
  3238. pRenderContext->SetSamplerStatePS( 3, RS_FILTER_MIN_MAG_MIP_POINT );
  3239. RenderDecals( pRenderContext, 1 );
  3240. // Render pointlights
  3241. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  3242. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  3243. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE );
  3244. nParticleSystems = m_lightSystemList.Count();
  3245. for ( int p=0; p<nParticleSystems; ++p )
  3246. {
  3247. RenderParticleLights( pRenderContext, m_lightSystemList[p], 4, false, false );
  3248. }
  3249. // Submit
  3250. m_pRenderViews[ RTB_SAMPLE_LIGHTING ].EndRender( pRenderContext );
  3251. }
  3252. // Render aerial perspective
  3253. if ( m_bDrawAerialPerspective )
  3254. {
  3255. RenderAerialPerspective();
  3256. }
  3257. }
  3258. else
  3259. {
  3260. VPROF_SCOPE_BEGIN("RenderWorldNodes");
  3261. Vector4D c(0,1,0,0);
  3262. m_pRenderViews[ RTB_FORWARD ].Clear( pRenderContext, c, RENDER_CLEAR_FLAGS_CLEAR_DEPTH );
  3263. RenderView( m_pRenderViews[ RTB_FORWARD ] );
  3264. // Submit
  3265. m_pRenderViews[ RTB_FORWARD ].EndRender( pRenderContext );
  3266. VPROF_SCOPE_END();
  3267. }
  3268. if ( m_bRenderSky )
  3269. {
  3270. RenderSky();
  3271. }
  3272. // Unbind the render targets
  3273. for ( int s=0; s<NUM_SHADOW_SPLITS; ++s )
  3274. {
  3275. pRenderContext->BindTexture( 4 + s, RENDER_TEXTURE_HANDLE_INVALID );
  3276. }
  3277. pRenderContext->Submit();
  3278. for ( int v=0; v<MAX_VIEW_BINDING_TYPES; ++v )
  3279. {
  3280. m_pRenderViews[ v ].EndRender( NULL );
  3281. }
  3282. // Update resources phase (arbitrarily only allow 10 resources to be updated)
  3283. m_pWorldRenderer->UpdateResources( g_pRenderDevice, pRenderContext, 10 );
  3284. m_nGlobalDecalPos3 = 0;
  3285. m_nCurrentFrameNumber++;
  3286. }
  3287. void CWorldRendererTest::SimulateFrame( float flTimeStep )
  3288. {
  3289. UpdateDroppedRenderables( flTimeStep );
  3290. const float forwardSpeed = 500.0f;
  3291. const float sideSpeed = 500.0f;
  3292. const float yawSpeed = 90.0f;
  3293. const float pitchSpeed = 45.0f;
  3294. #if defined( _X360 )
  3295. const float flYawSensitivity = -0.04f;
  3296. const float flPitchSensitivity = 0.04f;
  3297. #else
  3298. const float flYawSensitivity = -0.2f;
  3299. const float flPitchSensitivity = 0.2f;
  3300. #endif
  3301. float flForward = forwardSpeed;
  3302. float flSide = sideSpeed;
  3303. if ( m_cmd.m_nKeys & FKEY_FAST )
  3304. {
  3305. flForward *= 5;
  3306. flSide *= 5;
  3307. }
  3308. if ( m_cmd.m_nKeys & FKEY_ENABLE_VIS )
  3309. {
  3310. m_bEnableVis = true;
  3311. Msg( "Vis enabled\n" );
  3312. }
  3313. else if( m_cmd.m_nKeys & FKEY_DISABLE_VIS )
  3314. {
  3315. m_bEnableVis = false;
  3316. Msg( "Vis disabled\n" );
  3317. }
  3318. if ( m_cmd.m_nKeys & FKEY_DROP_FRUSTUM )
  3319. {
  3320. Q_memcpy( m_pDropFrustum, m_pFrustum, sizeof( CWorldRenderFrustum ) );
  3321. m_bDropFrustum = !m_bDropFrustum;
  3322. m_vCullPos = m_pFrustum->GetCameraPosition();
  3323. if ( m_bDropFrustum )
  3324. Msg( "Drop frustum\n" );
  3325. else
  3326. Msg( "no drop\n" );
  3327. ThreadSleep( 200 );
  3328. }
  3329. if ( m_cmd.m_nKeys & FKEY_TOGGLE_AERIAL )
  3330. {
  3331. m_bDrawAerialPerspective = !m_bDrawAerialPerspective;
  3332. if ( m_bDrawAerialPerspective )
  3333. Msg( "Aerial Perspective: On\n" );
  3334. else
  3335. Msg( "Aerial Perspective: Off\n" );
  3336. ThreadSleep( 200 );
  3337. }
  3338. if ( m_cmd.m_nKeys & FKEY_TOGGLE_BOUNCE )
  3339. {
  3340. m_bDrawBouncedLight = !m_bDrawBouncedLight;
  3341. if ( m_bDrawBouncedLight )
  3342. Msg( "Bounced light: On\n" );
  3343. else
  3344. Msg( "Bounced light: Off\n" );
  3345. ThreadSleep( 200 );
  3346. }
  3347. if ( m_cmd.m_nKeys & FKEY_TOGGLE_DIRECT )
  3348. {
  3349. m_bDrawDirectLight = !m_bDrawDirectLight;
  3350. if ( m_bDrawDirectLight )
  3351. Msg( "Direct light: On\n" );
  3352. else
  3353. Msg( "Direct light: Off\n" );
  3354. ThreadSleep( 200 );
  3355. }
  3356. if ( m_cmd.m_nKeys & FKEY_TOGGLE_LIGHTING_ONLY )
  3357. {
  3358. m_bLightingOnly = !m_bLightingOnly;
  3359. if ( m_bLightingOnly )
  3360. Msg( "Lighting Only: On\n" );
  3361. else
  3362. Msg( "Lighting Only: Off\n" );
  3363. ThreadSleep( 200 );
  3364. }
  3365. if ( m_cmd.m_nKeys & FKEY_SSAO )
  3366. {
  3367. m_bSSAO = !m_bSSAO;
  3368. if ( m_bSSAO )
  3369. Msg( "SSAO: On\n" );
  3370. else
  3371. Msg( "SSAO: Off\n" );
  3372. ThreadSleep( 200 );
  3373. }
  3374. if ( m_cmd.m_nKeys & FKEY_BLUR_LIGHTING )
  3375. {
  3376. m_bBlurLighting = !m_bBlurLighting;
  3377. if ( m_bBlurLighting )
  3378. Msg( "Blur Lighting: On\n" );
  3379. else
  3380. Msg( "Blur Lighting: Off\n" );
  3381. ThreadSleep( 200 );
  3382. }
  3383. if ( m_cmd.m_nKeys & FKEY_BLUR_SHADOWS )
  3384. {
  3385. m_bBlurShadows = !m_bBlurShadows;
  3386. if ( m_bBlurShadows )
  3387. Msg( "Blur Shadows: On\n" );
  3388. else
  3389. Msg( "Blur Shadows: Off\n" );
  3390. ThreadSleep( 200 );
  3391. }
  3392. m_cmd.m_flForwardMove = (m_cmd.m_nKeys & (FKEY_FORWARD|FKEY_BACK)) ? ( (m_cmd.m_nKeys & FKEY_FORWARD) ? flForward : -flForward) : 0;
  3393. m_cmd.m_flRightMove = (m_cmd.m_nKeys & (FKEY_LEFT|FKEY_RIGHT)) ? ( (m_cmd.m_nKeys & FKEY_RIGHT) ? flSide : -flSide) : 0;
  3394. float flYawMove = (m_cmd.m_nKeys & (FKEY_TURNLEFT|FKEY_TURNRIGHT)) ? ( (m_cmd.m_nKeys & FKEY_TURNLEFT) ? yawSpeed : -yawSpeed) : 0;
  3395. float flPitchMove = (m_cmd.m_nKeys & (FKEY_TURNUP|FKEY_TURNDOWN)) ? ( (m_cmd.m_nKeys & FKEY_TURNDOWN) ? pitchSpeed : -pitchSpeed) : 0;
  3396. if ( m_nCursorDeltaX || m_nCursorDeltaY )
  3397. {
  3398. m_cmd.m_flYawMove = m_nCursorDeltaX * flYawSensitivity;
  3399. m_cmd.m_flPitchMove = m_nCursorDeltaY * flPitchSensitivity;
  3400. m_nCursorDeltaX = m_nCursorDeltaResetX;
  3401. m_nCursorDeltaY = m_nCursorDeltaResetY;
  3402. if ( !IsPlatformX360() )
  3403. {
  3404. g_pInputStackSystem->SetCursorPosition( GetInputContext(), m_nWindowCenterX, m_nWindowCenterY );
  3405. }
  3406. }
  3407. m_cmd.m_flPitchMove += flPitchMove * flTimeStep;
  3408. m_cmd.m_flYawMove += flYawMove * flTimeStep;
  3409. Vector vMoveAmount = ((m_pFrustum->Forward() * m_cmd.m_flForwardMove ) - ( m_pFrustum->Left() * m_cmd.m_flRightMove )) * flTimeStep;
  3410. Vector eyePos = m_pFrustum->GetCameraPosition() + vMoveAmount;
  3411. m_pFrustum->SetCameraPosition( eyePos );
  3412. QAngle angles = m_pFrustum->GetCameraAngles();
  3413. angles.y += m_cmd.m_flYawMove;
  3414. angles.x += m_cmd.m_flPitchMove;
  3415. angles.x = clamp( angles.x, -89.0f, 89.0f );
  3416. m_cmd.m_flYawMove = 0;
  3417. m_cmd.m_flPitchMove = 0;
  3418. if ( angles.y > 180.0f )
  3419. {
  3420. angles.y -= 360.0f;
  3421. }
  3422. if ( angles.y < -180.0f )
  3423. {
  3424. angles.y += 360.0f;
  3425. }
  3426. m_pFrustum->SetCameraAngles( angles );
  3427. // Update light
  3428. VMatrix mLight,mLightAngle, mLightElevation;
  3429. mLightAngle.Identity();
  3430. mLightElevation.Identity();
  3431. mLight.Identity();
  3432. MatrixRotate( mLightElevation, Vector(1,0,0), m_vLightAngleElevation.y );
  3433. MatrixRotate( mLightAngle, Vector(0,0,1), m_vLightAngleElevation.x );
  3434. mLight = mLightElevation * mLightAngle;
  3435. Vector vLightStart(1,0,0);
  3436. matrix3x4_t mLight3x4 = mLight.As3x4();
  3437. VectorRotate( vLightStart, mLight3x4, m_vLightDir );
  3438. m_vLightDir.NormalizeInPlace();
  3439. float flLerp = sinf( DEG2RAD( m_vLightAngleElevation.x ) );
  3440. Vector4D vColorRed( 1.0, 0.7, 0.6, 1 );
  3441. Vector4D vColorYellow( 1.0, 0.9, 0.7, 1 );
  3442. m_skyData.m_vLightColor = Lerp( flLerp, vColorRed, vColorYellow );
  3443. Vector4D vRenderColorRed( 1.0, 0.6, 0.4, 1 );
  3444. Vector4D vRenderColorYellow( 1.0, 0.9, 0.7, 1 );
  3445. m_vRenderLightColor = Lerp( flLerp, vRenderColorRed, vRenderColorYellow );
  3446. Vector4D vBmRed( 1.0e-4, 0.4e-4, 0.3e-4, 1 );
  3447. Vector4D vBmYellow( 1.0e-4, 0.7e-4, 0.3e-4, 1 );
  3448. m_skyData.m_vBm = Lerp( flLerp, vBmRed, vBmYellow );
  3449. float flGRed = 0.90f;
  3450. float flGYellow = 0.99f;
  3451. m_skyData.m_flG.x = Lerp( flLerp, flGRed, flGYellow );
  3452. if ( m_cmd.m_nKeys & FKEY_LIGHTANG_POS )
  3453. {
  3454. m_vLightAngleElevation.x += m_flLightAngSpeed * flTimeStep;
  3455. }
  3456. else if ( m_cmd.m_nKeys & FKEY_LIGHTANG_NEG )
  3457. {
  3458. m_vLightAngleElevation.x -= m_flLightAngSpeed * flTimeStep;
  3459. }
  3460. if ( m_cmd.m_nKeys & FKEY_LIGHTELV )
  3461. {
  3462. m_vLightAngleElevation.y += m_flLightElvSpeed * flTimeStep;
  3463. if ( m_vLightAngleElevation.y > 88.0f || m_vLightAngleElevation.y < 30.0f )
  3464. {
  3465. m_flLightElvSpeed = -m_flLightElvSpeed;
  3466. }
  3467. }
  3468. // Shooting decals
  3469. if ( m_cmd.m_nKeys & FKEY_SHOOTDECAL )
  3470. {
  3471. if ( m_flDecalCountdown <= 0 )
  3472. {
  3473. Vector vEye = m_pFrustum->GetCameraPosition();
  3474. Vector vDir = m_pFrustum->Forward();
  3475. Vector vSurfaceNormal;
  3476. float flDistance = m_pWorldRenderer->CastRay( &vSurfaceNormal, vEye, vDir );
  3477. if ( flDistance > 0 )
  3478. {
  3479. float flSize = RPercentABS() * 40.0f + 70.0f;
  3480. CRenderContextPtr pRenderContext( g_pRenderDevice );
  3481. Vector vPos = vEye + vDir * flDistance;
  3482. AddDecal( pRenderContext, vPos, vSurfaceNormal,
  3483. flSize, flSize, //size x,y
  3484. 6.0f, 12.0f, false ); // intersection, length
  3485. }
  3486. m_flDecalCountdown = 0.1f;
  3487. }
  3488. m_flDecalCountdown -= flTimeStep;
  3489. }
  3490. // Shooting blood decals
  3491. if ( m_cmd.m_nKeys & FKEY_SHOOTDECAL2 )
  3492. {
  3493. if ( m_flDecalCountdown <= 0 )
  3494. {
  3495. Vector vEye = m_pFrustum->GetCameraPosition();
  3496. Vector vDir = m_pFrustum->Forward();
  3497. Vector vSurfaceNormal;
  3498. float flDistance = m_pWorldRenderer->CastRay( &vSurfaceNormal, vEye, vDir );
  3499. if ( flDistance > 0 )
  3500. {
  3501. float flSize = RPercentABS() * 50.0f + 80.0f;
  3502. CRenderContextPtr pRenderContext( g_pRenderDevice );
  3503. Vector vPos = vEye + vDir * flDistance;
  3504. AddDecal( pRenderContext, vPos, vSurfaceNormal,
  3505. flSize, flSize, //size x,y
  3506. 20.0f, 40.0f, true ); // intersection, length
  3507. }
  3508. m_flDecalCountdown = 0.05f;
  3509. }
  3510. m_flDecalCountdown -= flTimeStep;
  3511. }
  3512. // Shooting the wall-monster decal
  3513. if ( m_cmd.m_nKeys & FKEY_SHOOTWALLMONSTER )
  3514. {
  3515. Vector vEye = m_pFrustum->GetCameraPosition();
  3516. Vector vDir = m_pFrustum->Forward();
  3517. Vector vSurfaceNormal;
  3518. float flDistance = m_pWorldRenderer->CastRay( &vSurfaceNormal, vEye, vDir );
  3519. if ( flDistance > 0 )
  3520. {
  3521. float flSize = 100.0f;
  3522. CRenderContextPtr pRenderContext( g_pRenderDevice );
  3523. Vector vPos = vEye + vDir * flDistance;
  3524. Vector vMonsterNormal = m_vPreviousMonsterNormal + vSurfaceNormal * 4;
  3525. vMonsterNormal.NormalizeInPlace();
  3526. AddWallMonster( pRenderContext, vPos, vMonsterNormal,
  3527. flSize, flSize, //size x,y
  3528. 50.0f, 100.0f ); // intersection, length
  3529. m_vPreviousMonsterNormal = vMonsterNormal;
  3530. if ( m_flWallMonsterTimer < 0 )
  3531. {
  3532. m_nWallMonsterTexture = ( m_nWallMonsterTexture + 1 ) % 3;
  3533. m_flWallMonsterTimer = 0.05f;
  3534. }
  3535. else
  3536. {
  3537. m_flWallMonsterTimer -= MAX( 0.01f, flTimeStep );
  3538. }
  3539. }
  3540. }
  3541. if ( !( m_cmd.m_nKeys & FKEY_SHOOTDECAL || m_cmd.m_nKeys & FKEY_SHOOTDECAL2 ) )
  3542. {
  3543. m_flDecalCountdown = 0.0f;
  3544. }
  3545. // shoot a particle system
  3546. if ( m_cmd.m_nKeys & FKEY_SHOOTPSYSTEM || m_cmd.m_nKeys & FKEY_SHOOTSSYSTEM )
  3547. {
  3548. if ( m_flParticleCountdown <= 0 )
  3549. {
  3550. bool bSphereSystem = ( m_cmd.m_nKeys & FKEY_SHOOTSSYSTEM ) != 0;
  3551. Vector vEye = m_pFrustum->GetCameraPosition();
  3552. Vector vDir = m_pFrustum->Forward();
  3553. Vector vSurfaceNormal;
  3554. float flDistance = m_pWorldRenderer->CastRay( &vSurfaceNormal, vEye, vDir );
  3555. if ( flDistance > 0 )
  3556. {
  3557. Msg( "psystem distance = %f\n", flDistance );
  3558. CParticleCollection *pParticleSystem = g_pSceneSystem->CreateParticleCollection( "wonderinglights" );
  3559. if ( !pParticleSystem )
  3560. Error( "No wondering lights particle system!\n" );
  3561. Vector vPos = vEye + vDir * flDistance;
  3562. vPos += vSurfaceNormal * 100;
  3563. pParticleSystem->SetControlPoint( 0, vPos );
  3564. pParticleSystem->SetControlPointOrientation( 0, Vector(1,0,0), Vector(0,1,0), Vector(0,0,1) );
  3565. if ( bSphereSystem )
  3566. m_sphereSystemList.AddToTail( pParticleSystem );
  3567. else
  3568. m_lightSystemList.AddToTail( pParticleSystem );
  3569. SimulateWorkUnitWorldRender_t workUnit;
  3570. workUnit.m_nNumSystems = 1;
  3571. workUnit.m_pParticles = pParticleSystem;
  3572. m_particleWorkUnits.AddToTail( workUnit );
  3573. }
  3574. m_flParticleCountdown = 0.5f;
  3575. }
  3576. m_flParticleCountdown -= flTimeStep;
  3577. }
  3578. else
  3579. {
  3580. m_flParticleCountdown = 0.0f;
  3581. }
  3582. // Sim particles
  3583. SimulateParticles( flTimeStep );
  3584. }
  3585. void CWorldRendererTest::AddDecal( IRenderContext *pRenderContext, Vector &vHit, Vector &vDecalDir, float flDecalSizeU, float flDecalSizeV, float flDecalShift, float flDecalInfluenceLength, bool bPaint )
  3586. {
  3587. if ( g_nPlatform == RST_PLATFORM_GL )
  3588. return;
  3589. Vector vUp(RPercent(),RPercent(),RPercent());
  3590. vUp.NormalizeInPlace();
  3591. Vector vNegUp = -vUp;
  3592. if ( DotProduct( vDecalDir, vUp ) > 0.95f || DotProduct( vDecalDir, vNegUp ) > 0.95f )
  3593. vUp = Vector(0,1,0);
  3594. Vector vRight;
  3595. vRight = CrossProduct( vUp, vDecalDir );
  3596. vUp = CrossProduct( vDecalDir, vRight );
  3597. vRight.NormalizeInPlace();
  3598. vUp.NormalizeInPlace();
  3599. vRight *= flDecalSizeU;
  3600. vUp *= flDecalSizeV;
  3601. vDecalDir.NormalizeInPlace();
  3602. Vector vStartCorner = vHit;
  3603. vStartCorner -= vRight * 0.5f;
  3604. vStartCorner -= vUp * 0.5f;
  3605. vStartCorner -= vDecalDir * flDecalShift;
  3606. vDecalDir *= flDecalInfluenceLength;
  3607. // Create the 8 corners of a box surrounding our decal
  3608. Vector vCorners[8];
  3609. vCorners[0] = vStartCorner;
  3610. vCorners[1] = vStartCorner + vRight;
  3611. vCorners[2] = vStartCorner + vRight + vUp;
  3612. vCorners[3] = vStartCorner + vUp;
  3613. vCorners[4] = vStartCorner + vDecalDir;
  3614. vCorners[5] = vCorners[4] + vRight;
  3615. vCorners[6] = vCorners[4] + vRight + vUp;
  3616. vCorners[7] = vCorners[4] + vUp;
  3617. float fRMul = 1.0f / ( flDecalSizeU * flDecalSizeU );
  3618. float fUMul = 1.0f / ( flDecalSizeV * flDecalSizeV );
  3619. vRight = fRMul * vRight;
  3620. vUp = fUMul * vUp;
  3621. if ( bPaint )
  3622. {
  3623. DecalVertex_t *pVertices = &m_pDecalBackingStore2[ m_nGlobalDecalPos2 * 8 ];
  3624. for ( int i=0; i<8; ++i )
  3625. {
  3626. pVertices[i].m_vPos = vCorners[i];
  3627. pVertices[i].m_vDecalRight = vRight;
  3628. pVertices[i].m_vDecalUpAndInfluence = Vector4D( vUp.x, vUp.y, vUp.z, flDecalInfluenceLength );
  3629. pVertices[i].m_vDecalOrigin = vStartCorner;
  3630. }
  3631. LockDesc_t lockDesc;
  3632. pRenderContext->LockVertexBuffer( m_hDecalVB2, m_nMaxDecals * 8 * sizeof( DecalVertex_t ), &lockDesc );
  3633. Q_memcpy( lockDesc.m_pMemory, m_pDecalBackingStore2, m_nMaxDecals * 8 * sizeof( DecalVertex_t ) );
  3634. pRenderContext->UnlockVertexBuffer( m_hDecalVB2, m_nMaxDecals * 8 * sizeof( DecalVertex_t ), &lockDesc );
  3635. // Go to the next decal
  3636. m_nGlobalDecalPos2 ++;
  3637. if ( m_nGlobalDecalPos2 >= m_nMaxDecals )
  3638. {
  3639. m_bFullBuffer2 = true;
  3640. m_nGlobalDecalPos2 = 0;
  3641. }
  3642. }
  3643. else
  3644. {
  3645. DecalVertex_t *pVertices = &m_pDecalBackingStore[ m_nGlobalDecalPos * 8 ];
  3646. for ( int i=0; i<8; ++i )
  3647. {
  3648. pVertices[i].m_vPos = vCorners[i];
  3649. pVertices[i].m_vDecalRight = vRight;
  3650. pVertices[i].m_vDecalUpAndInfluence = Vector4D( vUp.x, vUp.y, vUp.z, flDecalInfluenceLength );
  3651. pVertices[i].m_vDecalOrigin = vStartCorner;
  3652. }
  3653. LockDesc_t lockDesc;
  3654. pRenderContext->LockVertexBuffer( m_hDecalVB, m_nMaxDecals * 8 * sizeof( DecalVertex_t ), &lockDesc );
  3655. Q_memcpy( lockDesc.m_pMemory, m_pDecalBackingStore, m_nMaxDecals * 8 * sizeof( DecalVertex_t ) );
  3656. pRenderContext->UnlockVertexBuffer( m_hDecalVB, m_nMaxDecals * 8 * sizeof( DecalVertex_t ), &lockDesc );
  3657. // Go to the next decal
  3658. m_nGlobalDecalPos ++;
  3659. if ( m_nGlobalDecalPos >= m_nMaxDecals )
  3660. {
  3661. m_bFullBuffer = true;
  3662. m_nGlobalDecalPos = 0;
  3663. }
  3664. }
  3665. }
  3666. void CWorldRendererTest::AddWallMonster( IRenderContext *pRenderContext, Vector &vHit, Vector &vDecalDir, float flDecalSizeU, float flDecalSizeV, float flDecalShift, float flDecalInfluenceLength )
  3667. {
  3668. if ( g_nPlatform == RST_PLATFORM_GL )
  3669. return;
  3670. Vector vUp(0,0,1);
  3671. Vector vNegUp = -vUp;
  3672. if ( DotProduct( vDecalDir, vUp ) > 0.95f || DotProduct( vDecalDir, vNegUp ) > 0.95f )
  3673. vUp = m_pFrustum->Up();
  3674. Vector vRight;
  3675. vRight = CrossProduct( vUp, vDecalDir );
  3676. vUp = CrossProduct( vDecalDir, vRight );
  3677. vRight.NormalizeInPlace();
  3678. vUp.NormalizeInPlace();
  3679. vRight *= flDecalSizeU;
  3680. vUp *= flDecalSizeV;
  3681. vDecalDir.NormalizeInPlace();
  3682. Vector vStartCorner = vHit;
  3683. vStartCorner -= vRight * 0.5f;
  3684. vStartCorner -= vUp * 0.5f;
  3685. vStartCorner -= vDecalDir * flDecalShift;
  3686. vDecalDir *= flDecalInfluenceLength;
  3687. // Create the 8 corners of a box surrounding our decal
  3688. Vector vCorners[8];
  3689. vCorners[0] = vStartCorner;
  3690. vCorners[1] = vStartCorner + vRight;
  3691. vCorners[2] = vStartCorner + vRight + vUp;
  3692. vCorners[3] = vStartCorner + vUp;
  3693. vCorners[4] = vStartCorner + vDecalDir;
  3694. vCorners[5] = vCorners[4] + vRight;
  3695. vCorners[6] = vCorners[4] + vRight + vUp;
  3696. vCorners[7] = vCorners[4] + vUp;
  3697. float fRMul = 1.0f / ( flDecalSizeU * flDecalSizeU );
  3698. float fUMul = 1.0f / ( flDecalSizeV * flDecalSizeV );
  3699. vRight = fRMul * vRight;
  3700. vUp = fUMul * vUp;
  3701. DecalVertex_t pVertices[8];
  3702. for ( int i=0; i<8; ++i )
  3703. {
  3704. pVertices[i].m_vPos = vCorners[i];
  3705. pVertices[i].m_vDecalRight = vRight;
  3706. pVertices[i].m_vDecalUpAndInfluence = Vector4D( vUp.x, vUp.y, vUp.z, flDecalInfluenceLength );
  3707. pVertices[i].m_vDecalOrigin = vStartCorner;
  3708. }
  3709. LockDesc_t lockDesc;
  3710. pRenderContext->LockVertexBuffer( m_hDecalVB3, 8 * sizeof( DecalVertex_t ), &lockDesc );
  3711. Q_memcpy( lockDesc.m_pMemory, pVertices, 8 * sizeof( DecalVertex_t ) );
  3712. pRenderContext->UnlockVertexBuffer( m_hDecalVB3, 8 * sizeof( DecalVertex_t ), &lockDesc );
  3713. // Go to the next decal
  3714. m_nGlobalDecalPos3 = 1;
  3715. }
  3716. void CWorldRendererTest::DropRenderable()
  3717. {
  3718. Vector vOrigin = m_pFrustum->GetCameraPosition();
  3719. vOrigin.z -= 32.0f;
  3720. int index = m_dynRenderableList.AddToTail();
  3721. VMatrix mRot;
  3722. Vector vAxis( 0, 0, 1 );
  3723. MatrixBuildRotationAboutAxis( mRot, vAxis, 90.0f );
  3724. vAxis.Init( 1, 0, 0 );
  3725. MatrixRotate( mRot, vAxis, 90.0f );
  3726. m_dynRenderableList[ index ].m_vOrigin = vOrigin;
  3727. m_dynRenderableList[ index ].m_mWorld = mRot;
  3728. m_dynRenderableList[ index ].m_hRenderable = g_pMeshSystem->FindOrCreateFileRenderable( g_pRenderableList[ g_nCurrentModel ] );
  3729. g_nCurrentModel ++;
  3730. if ( g_nCurrentModel >= MAX_MESH_SYSTEM_MODELS )
  3731. g_nCurrentModel = 0;
  3732. }
  3733. Vector Evaluate( float flU, float flV, Vector vRadius )
  3734. {
  3735. flU *= 2.0 * M_PI;
  3736. flV *= 2.0 * M_PI;
  3737. return Vector(
  3738. vRadius.x * cos( flU ) * sin( flV ),
  3739. vRadius.y * sin( flU ) * sin( flV ),
  3740. vRadius.z * cos ( flV ) );
  3741. }
  3742. void CWorldRendererTest::CreateSphere( int nTessellationRes )
  3743. {
  3744. Vector vRadius(1,1,1);
  3745. CRenderContextPtr pRenderContext( g_pRenderDevice );
  3746. // create the static index buffer
  3747. BufferDesc_t indexDesc;
  3748. indexDesc.m_nElementSizeInBytes = sizeof(uint16);
  3749. indexDesc.m_nElementCount = 2 * 3 * ( nTessellationRes * nTessellationRes );
  3750. indexDesc.m_pDebugName = "sphereib";
  3751. indexDesc.m_pBudgetGroupName = "shapes";
  3752. m_hSphereIB = g_pRenderDevice->CreateIndexBuffer( RENDER_BUFFER_TYPE_STATIC, indexDesc );
  3753. // fill in the index buffer
  3754. CIndexData<uint16> ib( pRenderContext, m_hSphereIB );
  3755. ib.Lock( indexDesc.m_nElementCount );
  3756. m_nNumTriangles = 0;
  3757. // generate the fixed tesselation
  3758. for( int u = 0; u < nTessellationRes; u += 1 )
  3759. {
  3760. int nu = ( u + 1 ) % nTessellationRes;
  3761. for( int v = 0; v < nTessellationRes; v++ )
  3762. {
  3763. int nv = ( v + 1 ) % nTessellationRes;
  3764. ib.Index2( u * nTessellationRes + v, nu * nTessellationRes + v );
  3765. ib.Index2( u * nTessellationRes + nv, nu * nTessellationRes + v);
  3766. ib.Index2( nu * nTessellationRes + nv, u * nTessellationRes + nv );
  3767. m_nNumTriangles += 2;
  3768. }
  3769. }
  3770. ib.Unlock( );
  3771. m_nSphereIndices = indexDesc.m_nElementCount;
  3772. // VB
  3773. int nVertices = ( nTessellationRes ) * ( nTessellationRes );
  3774. BufferDesc_t vertexDesc;
  3775. vertexDesc.m_nElementSizeInBytes = sizeof(SphereVertex_t);
  3776. vertexDesc.m_nElementCount = nVertices;
  3777. vertexDesc.m_pDebugName = "spherevb";
  3778. vertexDesc.m_pBudgetGroupName = "shapes";
  3779. m_hSphereVB = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_STATIC, vertexDesc );
  3780. CVertexData<SphereVertex_t> vb( pRenderContext, m_hSphereVB );
  3781. vb.Lock( nVertices );
  3782. for( int u = 0 ; u < nTessellationRes; u++ )
  3783. {
  3784. float flU = u * ( 1.0 / nTessellationRes );
  3785. for( int v = 0; v < nTessellationRes; v++ )
  3786. {
  3787. float flV = v * ( 1.0 / nTessellationRes );
  3788. Vector pos1 = Evaluate( flU + 0.5 / nTessellationRes, flV, vRadius );
  3789. vb->m_vPos = pos1;
  3790. vb.AdvanceVertex();
  3791. }
  3792. }
  3793. vb.Unlock( );
  3794. static RenderInputLayoutField_t sphereLayout[] =
  3795. {
  3796. DEFINE_PER_VERTEX_FIELD( 0, "position", 0, SphereVertex_t, m_vPos )
  3797. };
  3798. m_hSphereLayout = g_pRenderDevice->CreateInputLayout( "spherelayout", ARRAYSIZE( sphereLayout ), sphereLayout );
  3799. pRenderContext->Submit();
  3800. }
  3801. void CWorldRendererTest::CreateHemi( int nTessellationRes )
  3802. {
  3803. Vector vRadius(1,1,1);
  3804. CRenderContextPtr pRenderContext( g_pRenderDevice );
  3805. // create the static index buffer
  3806. BufferDesc_t indexDesc;
  3807. indexDesc.m_nElementSizeInBytes = sizeof(uint16);
  3808. indexDesc.m_nElementCount = 2 * 3 * ( nTessellationRes * nTessellationRes );
  3809. indexDesc.m_pDebugName = "hemiIB";
  3810. indexDesc.m_pBudgetGroupName = "shapes";
  3811. m_hHemiIB = g_pRenderDevice->CreateIndexBuffer( RENDER_BUFFER_TYPE_STATIC, indexDesc );
  3812. // fill in the index buffer
  3813. CIndexData<uint16> ib( pRenderContext, m_hHemiIB );
  3814. ib.Lock( indexDesc.m_nElementCount );
  3815. // generate the fixed tesselation
  3816. for( int u = 0; u < nTessellationRes; u += 1 )
  3817. {
  3818. int nu = ( u + 1 ) % nTessellationRes;
  3819. for( int v = 0; v < nTessellationRes; v++ )
  3820. {
  3821. int nv = ( v + 1 ) % nTessellationRes;
  3822. ib.Index2( u * nTessellationRes + v, nu * nTessellationRes + v );
  3823. ib.Index2( u * nTessellationRes + nv, nu * nTessellationRes + v);
  3824. ib.Index2( nu * nTessellationRes + nv, u * nTessellationRes + nv );
  3825. }
  3826. }
  3827. ib.Unlock( );
  3828. m_nHemiIndices = indexDesc.m_nElementCount;
  3829. // VB
  3830. int nVertices = ( nTessellationRes ) * ( nTessellationRes );
  3831. BufferDesc_t vertexDesc;
  3832. vertexDesc.m_nElementSizeInBytes = sizeof(SphereVertex_t);
  3833. vertexDesc.m_nElementCount = nVertices;
  3834. vertexDesc.m_pDebugName = "hemiVB";
  3835. vertexDesc.m_pBudgetGroupName = "shapes";
  3836. m_hHemiVB = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_STATIC, vertexDesc );
  3837. CVertexData<SphereVertex_t> vb( pRenderContext, m_hHemiVB );
  3838. vb.Lock( nVertices );
  3839. for( int u = 0 ; u < nTessellationRes; u++ )
  3840. {
  3841. float flU = u * ( 1.0 / nTessellationRes );
  3842. for( int v = 0; v < nTessellationRes; v++ )
  3843. {
  3844. float flV = v * ( 1.0 / nTessellationRes );
  3845. Vector pos1 = Evaluate( flU + 0.5 / nTessellationRes, flV, vRadius );
  3846. if ( pos1.z < 0 )
  3847. pos1.z = 0;
  3848. vb->m_vPos = pos1;
  3849. vb.AdvanceVertex();
  3850. }
  3851. }
  3852. vb.Unlock( );
  3853. pRenderContext->Submit();
  3854. }
  3855. void CWorldRendererTest::CreateCone( int nTessellationRes )
  3856. {
  3857. CRenderContextPtr pRenderContext( g_pRenderDevice );
  3858. Vector vTop(0,0,0);
  3859. int nVertices = nTessellationRes + 1;
  3860. int nIndices = ( nTessellationRes + nTessellationRes - 2 ) * 3;
  3861. // create the static index buffer
  3862. BufferDesc_t indexDesc;
  3863. indexDesc.m_nElementSizeInBytes = sizeof(uint16);
  3864. indexDesc.m_nElementCount = nIndices;
  3865. indexDesc.m_pDebugName = "coneib";
  3866. indexDesc.m_pBudgetGroupName = "shapes";
  3867. m_hConeIB = g_pRenderDevice->CreateIndexBuffer( RENDER_BUFFER_TYPE_STATIC, indexDesc );
  3868. // create the static vertex buffer
  3869. BufferDesc_t vertexDesc;
  3870. vertexDesc.m_nElementSizeInBytes = sizeof(SphereVertex_t);
  3871. vertexDesc.m_nElementCount = nVertices;
  3872. vertexDesc.m_pDebugName = "conevb";
  3873. vertexDesc.m_pBudgetGroupName = "shapes";
  3874. m_hConeVB = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_STATIC, vertexDesc );
  3875. m_nConeIndices = nIndices;
  3876. CVertexData<SphereVertex_t> vb( pRenderContext, m_hConeVB );
  3877. vb.Lock( nVertices );
  3878. vb->m_vPos = vTop;
  3879. vb.AdvanceVertex();
  3880. float flTesRes = (float)nTessellationRes;
  3881. for ( int i=0; i<nTessellationRes; ++i )
  3882. {
  3883. float flU = ( i / flTesRes ) * (2.0 * M_PI);
  3884. Vector vPos = Vector( 1.1f * cos( flU ), 1.1f * sin( flU ), 1 );
  3885. vb->m_vPos = vPos;
  3886. vb.AdvanceVertex();
  3887. }
  3888. vb.Unlock();
  3889. CIndexData<uint16> ib( pRenderContext, m_hConeIB );
  3890. ib.Lock( indexDesc.m_nElementCount );
  3891. // Cone
  3892. for ( int i=1; i<nTessellationRes+1; ++i )
  3893. {
  3894. ib.Index( 0 );
  3895. ib.Index( i );
  3896. ib.Index( ( i % nTessellationRes ) + 1 );
  3897. }
  3898. // Cap
  3899. for ( int i=2; i<nTessellationRes; ++i )
  3900. {
  3901. ib.Index( ( i + 1 ) );
  3902. ib.Index( i );
  3903. ib.Index( 1 );
  3904. }
  3905. ib.Unlock();
  3906. }
  3907. bool LoadFile( char *pFileName, CUtlBuffer &buffer, const char *pShaderVersion )
  3908. {
  3909. Assert( pFileName && pShaderVersion );
  3910. char pLocalFileName[260];
  3911. Q_snprintf( pLocalFileName, 260, "%s.%s", pFileName, pShaderVersion );
  3912. if ( !g_pFullFileSystem->ReadFile( pLocalFileName, NULL, buffer ) )
  3913. {
  3914. Error( "Couldn't load %s!\n", pFileName );
  3915. return false;
  3916. }
  3917. return true;
  3918. }
  3919. RenderShaderHandle_t CWorldRendererTest::GetVertexShader( char *pShaderName, IRenderDevice *pDevice, const char *pShaderVersion, const char *pDefineText )
  3920. {
  3921. CUtlBuffer buffer;
  3922. char pLevelText[100];
  3923. if ( 0 == Q_strncmp( pShaderVersion, "vs_3_0", 6 ) ||
  3924. 0 == Q_strncmp( pShaderVersion, "ps_3_0", 6 ) )
  3925. Q_snprintf( pLevelText, 100, "#define SHADER_LEVEL 3\n" );
  3926. else
  3927. Q_snprintf( pLevelText, 100, "#define SHADER_LEVEL 4\n" );
  3928. buffer.Put( pLevelText, strlen( pLevelText ) );
  3929. if ( pDefineText )
  3930. buffer.Put( pDefineText, strlen( pDefineText ) );
  3931. if ( !LoadFile( pShaderName, buffer, "vs_3_0" ) )
  3932. {
  3933. return RENDER_SHADER_HANDLE_INVALID;
  3934. }
  3935. char *pText = (char*)buffer.Base();
  3936. int nBytes = buffer.TellPut();
  3937. if ( nBytes < 1 )
  3938. return RENDER_SHADER_HANDLE_INVALID;
  3939. // Create the shader
  3940. return pDevice->CreateShader( RENDER_VERTEX_SHADER, pText, nBytes, pShaderVersion );
  3941. }
  3942. RenderShaderHandle_t CWorldRendererTest::GetPixelShader( char *pShaderName, IRenderDevice *pDevice, const char *pShaderVersion, const char *pDefineText )
  3943. {
  3944. CUtlBuffer buffer;
  3945. char pLevelText[100];
  3946. if ( 0 == Q_strncmp( pShaderVersion, "ps_3_0", 6 ) )
  3947. Q_snprintf( pLevelText, 100, "#define SHADER_LEVEL 3\n" );
  3948. else
  3949. Q_snprintf( pLevelText, 100, "#define SHADER_LEVEL 4\n" );
  3950. buffer.Put( pLevelText, strlen( pLevelText ) );
  3951. if ( pDefineText )
  3952. buffer.Put( pDefineText, strlen( pDefineText ) );
  3953. if ( !LoadFile( pShaderName, buffer, "ps_3_0" ) )
  3954. {
  3955. return RENDER_SHADER_HANDLE_INVALID;
  3956. }
  3957. char *pText = (char*)buffer.Base();
  3958. int nBytes = buffer.TellPut();
  3959. if ( nBytes < 1 )
  3960. return RENDER_SHADER_HANDLE_INVALID;
  3961. // Create the shader
  3962. return pDevice->CreateShader( RENDER_PIXEL_SHADER, pText, nBytes, pShaderVersion );
  3963. }
  3964. intp g_nMagicNumber = 1234567;
  3965. HRenderTexture CWorldRendererTest::CreateRenderTarget( RenderTargetType_t type, const RenderViewport_t &viewport )
  3966. {
  3967. HRenderTexture hRetHandle = RENDER_TEXTURE_HANDLE_INVALID;
  3968. TextureHeader_t spec;
  3969. spec.m_nNumMipLevels = 1;
  3970. spec.m_nDepth = 1;
  3971. spec.m_Reflectivity.Init( 1, 1, 1 );
  3972. int nLowResWidth = (int)( viewport.m_nWidth * m_flLowResBufferScale );
  3973. int nLowResHeight = (int)( viewport.m_nHeight * m_flLowResBufferScale );
  3974. ImageFormat ssaoFormat = IMAGE_FORMAT_A8;
  3975. if ( g_nPlatform == RST_PLATFORM_DX11 )
  3976. ssaoFormat = IMAGE_FORMAT_RGBA8888;
  3977. switch ( type )
  3978. {
  3979. case DS_SHADOW_DEPTH0:
  3980. case DS_SHADOW_DEPTH1:
  3981. case DS_SHADOW_DEPTH2:
  3982. {
  3983. spec.m_nWidth = m_nShadowSize;
  3984. spec.m_nHeight = m_nShadowSize;
  3985. spec.m_nFlags = TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  3986. spec.m_nImageFormat = IMAGE_FORMAT_D24X8/*IMAGE_FORMAT_D16*/;
  3987. }
  3988. break;
  3989. case DS_SHADOW_DEPTH_MULTIPLE:
  3990. {
  3991. spec.m_nWidth = m_nShadowSize;
  3992. spec.m_nHeight = m_nShadowSize;
  3993. spec.m_nFlags = TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  3994. spec.m_nImageFormat = IMAGE_FORMAT_D24X8/*IMAGE_FORMAT_D16*/;
  3995. }
  3996. break;
  3997. case RT_SHADOW_MULTIPLE_0:
  3998. case RT_SHADOW_MULTIPLE_1:
  3999. case RT_SHADOW_BLUR_TEMP:
  4000. {
  4001. spec.m_nWidth = m_nShadowSize;
  4002. spec.m_nHeight = m_nShadowSize;
  4003. spec.m_nFlags = TSPEC_RENDER_TARGET;
  4004. spec.m_nImageFormat = IMAGE_FORMAT_RG1616F;
  4005. }
  4006. break;
  4007. case DS_DEPTH_HIGHRES:
  4008. {
  4009. spec.m_nWidth = viewport.m_nWidth;
  4010. spec.m_nHeight = viewport.m_nHeight;
  4011. spec.m_nFlags = TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4012. spec.m_nImageFormat = IMAGE_FORMAT_D24S8;
  4013. }
  4014. break;
  4015. case RT_VIEW_DEPTH_HIGHRES:
  4016. {
  4017. spec.m_nWidth = viewport.m_nWidth;
  4018. spec.m_nHeight = viewport.m_nHeight;
  4019. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4020. spec.m_nImageFormat = IMAGE_FORMAT_R32F;
  4021. }
  4022. break;
  4023. case RT_VIEW_NORMAL_HIGHRES:
  4024. {
  4025. spec.m_nWidth = viewport.m_nWidth;
  4026. spec.m_nHeight = viewport.m_nHeight;
  4027. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4028. spec.m_nImageFormat = IMAGE_FORMAT_RGBA1010102;
  4029. }
  4030. break;
  4031. case RT_VIEW_SPEC_HIGHRES:
  4032. {
  4033. spec.m_nWidth = viewport.m_nWidth;
  4034. spec.m_nHeight = viewport.m_nHeight;
  4035. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4036. spec.m_nImageFormat = IMAGE_FORMAT_BGRA8888;
  4037. if ( g_nPlatform == RST_PLATFORM_DX11 )
  4038. {
  4039. spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888;
  4040. }
  4041. }
  4042. break;
  4043. case RT_LIGHTING_HIGHRES:
  4044. {
  4045. spec.m_nWidth = viewport.m_nWidth;
  4046. spec.m_nHeight = viewport.m_nHeight;
  4047. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4048. spec.m_nImageFormat = IMAGE_FORMAT_RGBA16161616F;
  4049. /*
  4050. if ( g_nPlatform == RST_PLATFORM_DX11 )
  4051. {
  4052. spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888;
  4053. }
  4054. */
  4055. }
  4056. break;
  4057. case RT_SPECULAR_HIGHRES:
  4058. {
  4059. spec.m_nWidth = viewport.m_nWidth;
  4060. spec.m_nHeight = viewport.m_nHeight;
  4061. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4062. spec.m_nImageFormat = IMAGE_FORMAT_BGRA8888;
  4063. if ( g_nPlatform == RST_PLATFORM_DX11 )
  4064. {
  4065. spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888;
  4066. }
  4067. }
  4068. break;
  4069. case DS_DEPTH_LOWRES:
  4070. {
  4071. spec.m_nWidth = nLowResWidth;
  4072. spec.m_nHeight = nLowResHeight;
  4073. spec.m_nFlags = 0;
  4074. spec.m_nImageFormat = IMAGE_FORMAT_D24S8;
  4075. }
  4076. break;
  4077. case RT_VIEW_DEPTH_LOWRES:
  4078. {
  4079. spec.m_nWidth = nLowResWidth;
  4080. spec.m_nHeight = nLowResHeight;
  4081. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4082. spec.m_nImageFormat = IMAGE_FORMAT_R32F;
  4083. }
  4084. break;
  4085. case RT_VIEW_NORMAL_LOWRES:
  4086. {
  4087. spec.m_nWidth = nLowResWidth;
  4088. spec.m_nHeight = nLowResHeight;
  4089. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4090. spec.m_nImageFormat = IMAGE_FORMAT_RGBA1010102;
  4091. }
  4092. break;
  4093. case RT_LIGHTING_LOWRES:
  4094. {
  4095. spec.m_nWidth = nLowResWidth;
  4096. spec.m_nHeight = nLowResHeight;
  4097. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4098. spec.m_nImageFormat = IMAGE_FORMAT_BGRA8888;
  4099. if ( g_nPlatform == RST_PLATFORM_DX11 )
  4100. {
  4101. spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888;
  4102. }
  4103. }
  4104. break;
  4105. case RT_LIGHTING_TEMP_LOWRES:
  4106. {
  4107. spec.m_nWidth = nLowResWidth;
  4108. spec.m_nHeight = nLowResHeight;
  4109. spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE;
  4110. spec.m_nImageFormat = IMAGE_FORMAT_BGRA8888;
  4111. if ( g_nPlatform == RST_PLATFORM_DX11 )
  4112. {
  4113. spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888;
  4114. }
  4115. }
  4116. break;
  4117. default:
  4118. return RENDER_TEXTURE_HANDLE_INVALID;
  4119. }
  4120. char pResourceName[16];
  4121. Q_snprintf( pResourceName, sizeof(pResourceName), "%d", g_nMagicNumber );
  4122. ++g_nMagicNumber;
  4123. hRetHandle = g_pRenderDevice->FindOrCreateTexture( "worldrenderer", pResourceName, &spec );
  4124. return hRetHandle;
  4125. }
  4126. RenderTargetBinding_t CWorldRendererTest::CreateRenderTargetBinding( ViewBindingType_t type, const RenderViewport_t &viewport )
  4127. {
  4128. RenderTargetBinding_t hRetHandle = RENDER_TARGET_BINDING_INVALID;
  4129. HRenderTexture pRenderTargets[ 4 ] = { RENDER_TEXTURE_HANDLE_INVALID, RENDER_TEXTURE_HANDLE_INVALID, RENDER_TEXTURE_HANDLE_INVALID, RENDER_TEXTURE_HANDLE_INVALID };
  4130. HRenderTexture hDepthStencil;
  4131. int nTargets = 0;
  4132. int nFlags = 0;
  4133. RenderViewport_t lowResViewport = viewport;
  4134. lowResViewport.m_nWidth = (int)( viewport.m_nWidth * m_flLowResBufferScale );
  4135. lowResViewport.m_nHeight = (int)( viewport.m_nHeight * m_flLowResBufferScale );
  4136. CWorldRenderFrustum *pFrustum = NULL;
  4137. RenderViewport_t targetViewport;
  4138. int nViewFlags = VIEW_PLAYER_CAMERA;
  4139. int nViewPass = 0;
  4140. switch ( type )
  4141. {
  4142. case RTB_SHADOW_DEPTH0:
  4143. case RTB_SHADOW_DEPTH1:
  4144. case RTB_SHADOW_DEPTH2:
  4145. {
  4146. nTargets = 1;
  4147. pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ];
  4148. hDepthStencil = m_pRenderTargets[ type - DS_SHADOW_DEPTH0 ];
  4149. nFlags = DISCARD_CONTENTS;
  4150. pFrustum = m_pSplitFrustums[ type - DS_SHADOW_DEPTH0 ];
  4151. targetViewport = m_shadowViewport;
  4152. nViewFlags = VIEW_LIGHT_SHADOW;
  4153. nViewPass = VARIATION_DEPTH;
  4154. }
  4155. break;
  4156. case RTB_SHADOW_DEPTH_MULTIPLE_0:
  4157. case RTB_SHADOW_DEPTH_MULTIPLE_1:
  4158. case RTB_SHADOW_DEPTH_MULTIPLE_2:
  4159. case RTB_SHADOW_DEPTH_MULTIPLE_3:
  4160. case RTB_SHADOW_DEPTH_MULTIPLE_4:
  4161. case RTB_SHADOW_DEPTH_MULTIPLE_5:
  4162. case RTB_SHADOW_DEPTH_MULTIPLE_6:
  4163. case RTB_SHADOW_DEPTH_MULTIPLE_7:
  4164. case RTB_SHADOW_DEPTH_MULTIPLE_8:
  4165. case RTB_SHADOW_DEPTH_MULTIPLE_9:
  4166. case RTB_SHADOW_DEPTH_MULTIPLE_10:
  4167. case RTB_SHADOW_DEPTH_MULTIPLE_11:
  4168. case RTB_SHADOW_DEPTH_MULTIPLE_12:
  4169. case RTB_SHADOW_DEPTH_MULTIPLE_13:
  4170. case RTB_SHADOW_DEPTH_MULTIPLE_14:
  4171. case RTB_SHADOW_DEPTH_MULTIPLE_15:
  4172. case RTB_SHADOW_DEPTH_MULTIPLE_16:
  4173. case RTB_SHADOW_DEPTH_MULTIPLE_17:
  4174. case RTB_SHADOW_DEPTH_MULTIPLE_18:
  4175. case RTB_SHADOW_DEPTH_MULTIPLE_19:
  4176. case RTB_SHADOW_DEPTH_MULTIPLE_20:
  4177. case RTB_SHADOW_DEPTH_MULTIPLE_21:
  4178. case RTB_SHADOW_DEPTH_MULTIPLE_22:
  4179. case RTB_SHADOW_DEPTH_MULTIPLE_23:
  4180. case RTB_SHADOW_DEPTH_MULTIPLE_24:
  4181. case RTB_SHADOW_DEPTH_MULTIPLE_25:
  4182. case RTB_SHADOW_DEPTH_MULTIPLE_26:
  4183. case RTB_SHADOW_DEPTH_MULTIPLE_27:
  4184. case RTB_SHADOW_DEPTH_MULTIPLE_28:
  4185. case RTB_SHADOW_DEPTH_MULTIPLE_29:
  4186. case RTB_SHADOW_DEPTH_MULTIPLE_30:
  4187. case RTB_SHADOW_DEPTH_MULTIPLE_31:
  4188. {
  4189. int nFrustum = type - RTB_SHADOW_DEPTH_MULTIPLE_0;
  4190. nTargets = 1;
  4191. if ( nFrustum < NUM_HIGH_RES_SHADOWS )
  4192. pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ];
  4193. else
  4194. pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_1 ];
  4195. hDepthStencil = m_pRenderTargets[ DS_SHADOW_DEPTH_MULTIPLE ];
  4196. nFlags = PRESERVE_DEPTHSTENCIL;//DISCARD_CONTENTS;
  4197. if ( nFrustum < NUM_MULTI_SHADOWS )
  4198. {
  4199. pFrustum = m_pMultiShadowFrustums[ nFrustum ];
  4200. targetViewport = m_multiShadowViewport[ nFrustum ];
  4201. }
  4202. else
  4203. {
  4204. pFrustum = NULL;
  4205. targetViewport = viewport;
  4206. }
  4207. nViewFlags = VIEW_LIGHT_SHADOW;
  4208. nViewPass = VARIATION_DEPTH;
  4209. }
  4210. break;
  4211. case RTB_DEFERRED_DEPTH_NORM_SPEC:
  4212. {
  4213. nTargets = 3;
  4214. pRenderTargets[0] = m_pRenderTargets[ RT_VIEW_NORMAL_HIGHRES ];
  4215. pRenderTargets[1] = m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ];
  4216. pRenderTargets[2] = m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ];
  4217. hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ];
  4218. nFlags = DISCARD_CONTENTS;
  4219. pFrustum = m_pFrustum;
  4220. targetViewport = viewport;
  4221. nViewFlags = VIEW_PLAYER_CAMERA;
  4222. nViewPass = VARIATION_NORM_DEPTH_SPEC;
  4223. }
  4224. break;
  4225. case RTB_DEFERRED_SCALE_DOWN:
  4226. {
  4227. nTargets = 2;
  4228. pRenderTargets[0] = m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ];
  4229. pRenderTargets[1] = m_pRenderTargets[ RT_VIEW_NORMAL_LOWRES ];
  4230. hDepthStencil = m_pRenderTargets[ DS_DEPTH_LOWRES ];
  4231. nFlags = PRESERVE_DEPTHSTENCIL;
  4232. pFrustum = m_pFrustum;
  4233. targetViewport = lowResViewport;
  4234. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS;
  4235. nViewPass = VARIATION_DEFAULT;
  4236. }
  4237. break;
  4238. case RTB_DEFERRED_NORM_SPEC:
  4239. {
  4240. nTargets = 2;
  4241. pRenderTargets[0] = m_pRenderTargets[ RT_VIEW_NORMAL_HIGHRES ];
  4242. pRenderTargets[1] = m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ];
  4243. hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ];
  4244. nFlags = PRESERVE_CONTENTS;
  4245. pFrustum = m_pFrustum;
  4246. targetViewport = viewport;
  4247. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_DECALS;
  4248. nViewPass = 0;
  4249. }
  4250. break;
  4251. case RTB_CLEAR_SPEC_HIGHRES:
  4252. {
  4253. nTargets = 1;
  4254. pRenderTargets[0] = m_pRenderTargets[ RT_SPECULAR_HIGHRES ];
  4255. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4256. nFlags = 0;
  4257. pFrustum = m_pFrustum;
  4258. targetViewport = viewport;
  4259. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_LIGHTING;
  4260. nViewPass = VARIATION_DEFAULT;
  4261. }
  4262. break;
  4263. case RTB_LIGHTING_HIGHRES:
  4264. {
  4265. nTargets = 2;
  4266. pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_HIGHRES ];
  4267. pRenderTargets[1] = m_pRenderTargets[ RT_SPECULAR_HIGHRES ];
  4268. hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ];
  4269. nFlags = PRESERVE_DEPTHSTENCIL;
  4270. pFrustum = m_pFrustum;
  4271. targetViewport = viewport;
  4272. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_LIGHTING;
  4273. nViewPass = VARIATION_DEFAULT;
  4274. }
  4275. break;
  4276. case RTB_LIGHTING_LOWRES:
  4277. {
  4278. nTargets = 1;
  4279. pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_LOWRES ];
  4280. hDepthStencil = m_pRenderTargets[ DS_DEPTH_LOWRES ];
  4281. nFlags = PRESERVE_DEPTHSTENCIL;
  4282. pFrustum = m_pFrustum;
  4283. targetViewport = lowResViewport;
  4284. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_LIGHTING;
  4285. nViewPass = VARIATION_DEFAULT;
  4286. }
  4287. break;
  4288. case RTB_SSAO_LOWRES:
  4289. {
  4290. nTargets = 1;
  4291. pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_LOWRES ];
  4292. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4293. nFlags = 0;
  4294. pFrustum = NULL;
  4295. targetViewport = lowResViewport;
  4296. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS;
  4297. nViewPass = VARIATION_DEFAULT;
  4298. }
  4299. break;
  4300. case RTB_BILAT_UPSAMPLE_0:
  4301. {
  4302. nTargets = 1;
  4303. pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_TEMP_LOWRES ];
  4304. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4305. nFlags = 0;
  4306. pFrustum = NULL;
  4307. targetViewport = lowResViewport;
  4308. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS;
  4309. nViewPass = VARIATION_DEFAULT;
  4310. }
  4311. break;
  4312. case RTB_BILAT_UPSAMPLE_1:
  4313. {
  4314. nTargets = 1;
  4315. pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_HIGHRES ];
  4316. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4317. nFlags = 0;
  4318. pFrustum = NULL;
  4319. targetViewport = viewport;
  4320. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS;
  4321. nViewPass = VARIATION_DEFAULT;
  4322. }
  4323. break;
  4324. case RTB_LIGHT_BLUR_0:
  4325. {
  4326. nTargets = 1;
  4327. pRenderTargets[0] = m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ];
  4328. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4329. nFlags = 0;
  4330. pFrustum = NULL;
  4331. targetViewport = viewport;
  4332. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS;
  4333. nViewPass = VARIATION_DEFAULT;
  4334. }
  4335. break;
  4336. case RTB_LIGHT_BLUR_1:
  4337. {
  4338. nTargets = 1;
  4339. pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_HIGHRES ];
  4340. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4341. nFlags = 0;
  4342. pFrustum = NULL;
  4343. targetViewport = viewport;
  4344. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS;
  4345. nViewPass = VARIATION_DEFAULT;
  4346. }
  4347. break;
  4348. case RTB_SHADOW_BLUR_0:
  4349. {
  4350. nTargets = 1;
  4351. pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_BLUR_TEMP ];
  4352. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4353. nFlags = 0;
  4354. pFrustum = NULL;
  4355. targetViewport = m_shadowViewport;
  4356. nViewFlags = VIEW_LIGHT_SHADOW | VIEW_POST_PROCESS;
  4357. nViewPass = VARIATION_DEFAULT;
  4358. }
  4359. break;
  4360. case RTB_SHADOW_BLUR_1:
  4361. {
  4362. nTargets = 1;
  4363. pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ];
  4364. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4365. nFlags = 0;
  4366. pFrustum = NULL;
  4367. targetViewport = m_shadowViewport;
  4368. nViewFlags = VIEW_LIGHT_SHADOW | VIEW_POST_PROCESS;
  4369. nViewPass = VARIATION_DEFAULT;
  4370. }
  4371. break;
  4372. case RTB_SHADOW_BLUR_2:
  4373. {
  4374. nTargets = 1;
  4375. pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_1 ];
  4376. hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID;
  4377. nFlags = 0;
  4378. pFrustum = NULL;
  4379. targetViewport = m_shadowViewport;
  4380. nViewFlags = VIEW_LIGHT_SHADOW | VIEW_POST_PROCESS;
  4381. nViewPass = VARIATION_DEFAULT;
  4382. }
  4383. break;
  4384. case RTB_SAMPLE_LIGHTING:
  4385. {
  4386. nTargets = 1;
  4387. pRenderTargets[0] = RENDER_TEXTURE_DEFAULT_RENDER_TARGET;
  4388. hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ];
  4389. nFlags = PRESERVE_DEPTHSTENCIL;
  4390. pFrustum = m_pFrustum;
  4391. targetViewport = viewport;
  4392. nViewFlags = VIEW_PLAYER_CAMERA;
  4393. nViewPass = VARIATION_SAMPLE_LIGHTING;
  4394. }
  4395. break;
  4396. case RTB_AERIAL_PERSPECTIVE:
  4397. {
  4398. nTargets = 1;
  4399. pRenderTargets[0] = RENDER_TEXTURE_DEFAULT_RENDER_TARGET;
  4400. hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ];
  4401. nFlags = PRESERVE_DEPTHSTENCIL;
  4402. pFrustum = NULL;
  4403. targetViewport = viewport;
  4404. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS;
  4405. nViewPass = VARIATION_DEFAULT;
  4406. }
  4407. break;
  4408. case RTB_SKY:
  4409. {
  4410. nTargets = 1;
  4411. pRenderTargets[0] = RENDER_TEXTURE_DEFAULT_RENDER_TARGET;
  4412. hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ];
  4413. nFlags = PRESERVE_DEPTHSTENCIL;
  4414. pFrustum = m_pFrustum;
  4415. targetViewport = viewport;
  4416. nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS;
  4417. nViewPass = VARIATION_DEFAULT;
  4418. }
  4419. break;
  4420. case RTB_FORWARD:
  4421. {
  4422. nTargets = 1;
  4423. pRenderTargets[0] = RENDER_TEXTURE_DEFAULT_RENDER_TARGET;
  4424. hDepthStencil = RENDER_TEXTURE_DEFAULT_RENDER_TARGET;
  4425. nFlags = PRESERVE_DEPTHSTENCIL;
  4426. pFrustum = m_pFrustum;
  4427. targetViewport = viewport;
  4428. nViewFlags = VIEW_PLAYER_CAMERA;
  4429. nViewPass = VARIATION_DEFAULT;
  4430. }
  4431. break;
  4432. default:
  4433. return RENDER_TARGET_BINDING_INVALID;
  4434. }
  4435. hRetHandle = g_pRenderDevice->CreateRenderTargetBinding( nFlags, nTargets, pRenderTargets, hDepthStencil );
  4436. m_pRenderViews[ type ].Init( g_pRenderDevice, pFrustum, hRetHandle, targetViewport, (RenderViewFlags_t)nViewFlags, nViewPass, type );
  4437. return hRetHandle;
  4438. }
  4439. void CWorldRendererTest::SetStateForRenderViewType( IRenderContext *pRenderContext, int nRenderView )
  4440. {
  4441. switch ( nRenderView )
  4442. {
  4443. case RTB_SHADOW_DEPTH0:
  4444. case RTB_SHADOW_DEPTH1:
  4445. case RTB_SHADOW_DEPTH2:
  4446. {
  4447. pRenderContext->SetBlendMode( RENDER_BLEND_NOPIXELWRITE );
  4448. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE );
  4449. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_NONE );
  4450. }
  4451. break;
  4452. case RTB_SHADOW_DEPTH_MULTIPLE_0:
  4453. case RTB_SHADOW_DEPTH_MULTIPLE_1:
  4454. case RTB_SHADOW_DEPTH_MULTIPLE_2:
  4455. case RTB_SHADOW_DEPTH_MULTIPLE_3:
  4456. case RTB_SHADOW_DEPTH_MULTIPLE_4:
  4457. case RTB_SHADOW_DEPTH_MULTIPLE_5:
  4458. case RTB_SHADOW_DEPTH_MULTIPLE_6:
  4459. case RTB_SHADOW_DEPTH_MULTIPLE_7:
  4460. case RTB_SHADOW_DEPTH_MULTIPLE_8:
  4461. case RTB_SHADOW_DEPTH_MULTIPLE_9:
  4462. case RTB_SHADOW_DEPTH_MULTIPLE_10:
  4463. case RTB_SHADOW_DEPTH_MULTIPLE_11:
  4464. case RTB_SHADOW_DEPTH_MULTIPLE_12:
  4465. case RTB_SHADOW_DEPTH_MULTIPLE_13:
  4466. case RTB_SHADOW_DEPTH_MULTIPLE_14:
  4467. case RTB_SHADOW_DEPTH_MULTIPLE_15:
  4468. case RTB_SHADOW_DEPTH_MULTIPLE_16:
  4469. case RTB_SHADOW_DEPTH_MULTIPLE_17:
  4470. case RTB_SHADOW_DEPTH_MULTIPLE_18:
  4471. case RTB_SHADOW_DEPTH_MULTIPLE_19:
  4472. case RTB_SHADOW_DEPTH_MULTIPLE_20:
  4473. case RTB_SHADOW_DEPTH_MULTIPLE_21:
  4474. case RTB_SHADOW_DEPTH_MULTIPLE_22:
  4475. case RTB_SHADOW_DEPTH_MULTIPLE_23:
  4476. case RTB_SHADOW_DEPTH_MULTIPLE_24:
  4477. case RTB_SHADOW_DEPTH_MULTIPLE_25:
  4478. case RTB_SHADOW_DEPTH_MULTIPLE_26:
  4479. case RTB_SHADOW_DEPTH_MULTIPLE_27:
  4480. case RTB_SHADOW_DEPTH_MULTIPLE_28:
  4481. case RTB_SHADOW_DEPTH_MULTIPLE_29:
  4482. case RTB_SHADOW_DEPTH_MULTIPLE_30:
  4483. case RTB_SHADOW_DEPTH_MULTIPLE_31:
  4484. {
  4485. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  4486. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE );
  4487. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  4488. }
  4489. break;
  4490. case RTB_DEFERRED_DEPTH_NORM_SPEC:
  4491. {
  4492. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  4493. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE_STENCIL_SET1 );
  4494. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  4495. }
  4496. break;
  4497. case RTB_DEFERRED_SCALE_DOWN:
  4498. {
  4499. }
  4500. break;
  4501. case RTB_DEFERRED_NORM_SPEC:
  4502. {
  4503. }
  4504. break;
  4505. case RTB_LIGHTING_HIGHRES:
  4506. {
  4507. }
  4508. break;
  4509. case RTB_LIGHTING_LOWRES:
  4510. {
  4511. }
  4512. break;
  4513. case RTB_SSAO_LOWRES:
  4514. {
  4515. }
  4516. break;
  4517. case RTB_BILAT_UPSAMPLE_0:
  4518. {
  4519. }
  4520. break;
  4521. case RTB_BILAT_UPSAMPLE_1:
  4522. {
  4523. }
  4524. break;
  4525. case RTB_LIGHT_BLUR_0:
  4526. {
  4527. }
  4528. break;
  4529. case RTB_LIGHT_BLUR_1:
  4530. {
  4531. }
  4532. break;
  4533. case RTB_SAMPLE_LIGHTING:
  4534. {
  4535. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  4536. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_EQUAL_NO_WRITE );
  4537. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  4538. pRenderContext->BindTexture( 4, m_pRenderTargets[ RT_LIGHTING_HIGHRES ] );
  4539. pRenderContext->SetSamplerStatePS( 4, RS_FILTER_MIN_MAG_MIP_POINT );
  4540. pRenderContext->BindTexture( 5, m_pRenderTargets[ RT_SPECULAR_HIGHRES ] );
  4541. pRenderContext->SetSamplerStatePS( 5, RS_FILTER_MIN_MAG_MIP_POINT );
  4542. }
  4543. break;
  4544. case RTB_AERIAL_PERSPECTIVE:
  4545. {
  4546. }
  4547. break;
  4548. case RTB_SKY:
  4549. {
  4550. }
  4551. break;
  4552. case RTB_FORWARD:
  4553. {
  4554. // viewport and state
  4555. pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
  4556. pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE );
  4557. pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
  4558. // Bind
  4559. for ( int s=0; s<NUM_SHADOW_SPLITS; ++s )
  4560. {
  4561. m_forwardLightingData.m_mShadowMatrices[s] = m_pShadowMatrices[s];
  4562. pRenderContext->BindTexture( 4 + s, m_pRenderTargets[ DS_SHADOW_DEPTH0 + s ] );
  4563. pRenderContext->SetSamplerStatePS( 4 + s, RS_FILTER_MIN_MAG_MIP_POINT );
  4564. }
  4565. pRenderContext->SetConstantBufferData( m_hLightingRelated, (void*)&m_forwardLightingData, sizeof( LightingConstants_t ) );
  4566. pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hLightingRelated, 0, 0 );
  4567. }
  4568. break;
  4569. }
  4570. }
  4571. void CWorldRendererTest::InitRenderTargetsAndViews( const RenderViewport_t &viewport )
  4572. {
  4573. for ( int i=0; i<MAX_RENDER_TARGET_TYPES; ++i )
  4574. {
  4575. m_pRenderTargets[i] = CreateRenderTarget( (RenderTargetType_t)i, viewport );
  4576. }
  4577. for ( int i=0; i<MAX_VIEW_BINDING_TYPES; ++i )
  4578. {
  4579. m_pViewBindings[i] = CreateRenderTargetBinding( (ViewBindingType_t)i, viewport );
  4580. }
  4581. m_bRenderTargetsInit = true;
  4582. }
  4583. void CWorldRendererTest::GetDescription( char *pNameBufferOut, size_t nBufLen )
  4584. {
  4585. if ( m_nVariant )
  4586. {
  4587. Q_snprintf( pNameBufferOut, nBufLen, "Render the world (deferred) (Press Space to Continue)" );
  4588. }
  4589. else
  4590. {
  4591. Q_snprintf( pNameBufferOut, nBufLen, "Render the world (forward) (Press Space to Continue)" );
  4592. }
  4593. }
  4594. //-----------------------------------------------------------------------------
  4595. // Can this test be run?
  4596. //-----------------------------------------------------------------------------
  4597. bool CWorldRendererTest::CanBeRun()
  4598. {
  4599. return ( g_pWorldRendererMgr != NULL ) && m_bWorldLoaded;
  4600. }
  4601. //-----------------------------------------------------------------------------
  4602. // check for a keypress
  4603. //-----------------------------------------------------------------------------
  4604. bool CWorldRendererTest::ProcessUserInput( const InputEvent_t &ie )
  4605. {
  4606. if ( ie.m_nType == IE_AnalogValueChanged )
  4607. {
  4608. switch( ie.m_nData )
  4609. {
  4610. case MOUSE_XY:
  4611. if ( m_nWindowCenterX > 0 && m_nWindowCenterY > 0 )
  4612. {
  4613. m_nCursorDeltaX += ie.m_nData2 - m_nWindowCenterX;
  4614. m_nCursorDeltaY += ie.m_nData3 - m_nWindowCenterY;
  4615. }
  4616. break;
  4617. case JOYSTICK_AXIS( 0, JOY_AXIS_U ):
  4618. m_nCursorDeltaResetX = ie.m_nData2 / 300;
  4619. m_nCursorDeltaX += m_nCursorDeltaResetX;
  4620. break;
  4621. case JOYSTICK_AXIS( 0, JOY_AXIS_R ):
  4622. m_nCursorDeltaResetY = -ie.m_nData2 / 300;
  4623. m_nCursorDeltaY += m_nCursorDeltaResetY;
  4624. break;
  4625. case JOYSTICK_AXIS( 0, JOY_AXIS_X ):
  4626. if ( abs( ie.m_nData2 ) < 2 )
  4627. {
  4628. m_cmd.m_nKeys &= ~FKEY_RIGHT;
  4629. m_cmd.m_nKeys &= ~FKEY_LEFT;
  4630. }
  4631. else if ( ie.m_nData2 > 0 )
  4632. {
  4633. m_cmd.m_nKeys |= FKEY_RIGHT;
  4634. m_cmd.m_nKeys &= ~FKEY_LEFT;
  4635. }
  4636. else
  4637. {
  4638. m_cmd.m_nKeys &= ~FKEY_RIGHT;
  4639. m_cmd.m_nKeys |= FKEY_LEFT;
  4640. }
  4641. break;
  4642. case JOYSTICK_AXIS( 0, JOY_AXIS_Y ):
  4643. if ( abs( ie.m_nData2 ) < 2 )
  4644. {
  4645. m_cmd.m_nKeys &= ~FKEY_FORWARD;
  4646. m_cmd.m_nKeys &= ~FKEY_BACK;
  4647. }
  4648. else if ( ie.m_nData2 > 0 )
  4649. {
  4650. m_cmd.m_nKeys |= FKEY_FORWARD;
  4651. m_cmd.m_nKeys &= ~FKEY_BACK;
  4652. }
  4653. else
  4654. {
  4655. m_cmd.m_nKeys &= ~FKEY_FORWARD;
  4656. m_cmd.m_nKeys |= FKEY_BACK;
  4657. }
  4658. break;
  4659. }
  4660. }
  4661. else if ( ie.m_nType == IE_ButtonPressed || ie.m_nType == IE_ButtonReleased )
  4662. {
  4663. bool bDown = (ie.m_nType == IE_ButtonPressed) ? true : false;
  4664. ButtonCode_t code = (ButtonCode_t)ie.m_nData;
  4665. uint nFlag = 0;
  4666. switch( code )
  4667. {
  4668. case KEY_W: nFlag = FKEY_FORWARD; break;
  4669. case KEY_S: nFlag = FKEY_BACK; break;
  4670. case KEY_A: nFlag = FKEY_LEFT; break;
  4671. case KEY_D: nFlag = FKEY_RIGHT; break;
  4672. case KEY_UP: nFlag = FKEY_TURNUP; break;
  4673. case KEY_DOWN: nFlag = FKEY_TURNDOWN; break;
  4674. case KEY_LEFT: nFlag = FKEY_TURNLEFT; break;
  4675. case KEY_RIGHT: nFlag = FKEY_TURNRIGHT; break;
  4676. case KEY_XBUTTON_X: case MOUSE_LEFT: nFlag = FKEY_SHOOTDECAL; break;
  4677. case KEY_XBUTTON_B: case KEY_N: nFlag = FKEY_SHOOTPSYSTEM; break;
  4678. case KEY_XBUTTON_Y: case KEY_M: nFlag = FKEY_SHOOTSSYSTEM; break;
  4679. case KEY_O: nFlag = FKEY_LIGHTELV; break;
  4680. case KEY_XBUTTON_UP: case KEY_K: nFlag = FKEY_LIGHTANG_POS; break;
  4681. case KEY_XBUTTON_DOWN: case KEY_L: nFlag = FKEY_LIGHTANG_NEG; break;
  4682. case KEY_XBUTTON_LEFT_SHOULDER: case KEY_LSHIFT: nFlag = FKEY_FAST; break;
  4683. case KEY_HOME: nFlag = FKEY_ENABLE_VIS; break;
  4684. case KEY_END: nFlag = FKEY_DISABLE_VIS; break;
  4685. case KEY_RSHIFT: nFlag = FKEY_DROP_FRUSTUM; break;
  4686. case KEY_P: nFlag = FKEY_TOGGLE_AERIAL; break;
  4687. case KEY_V: nFlag = FKEY_TOGGLE_BOUNCE; break;
  4688. case KEY_C: nFlag = FKEY_TOGGLE_DIRECT; break;
  4689. case KEY_B: nFlag = FKEY_TOGGLE_LIGHTING_ONLY; break;
  4690. case KEY_PAD_ENTER: nFlag = FKEY_SSAO; break;
  4691. case KEY_PAD_8: nFlag = FKEY_BLUR_LIGHTING; break;
  4692. case KEY_PAD_9: nFlag = FKEY_BLUR_SHADOWS; break;
  4693. case MOUSE_RIGHT: nFlag = FKEY_SHOOTDECAL2; break;
  4694. case MOUSE_MIDDLE: nFlag = FKEY_SHOOTWALLMONSTER; break;
  4695. case KEY_X:
  4696. {
  4697. if ( !bDown )
  4698. {
  4699. m_bViewLowTexture = !m_bViewLowTexture;
  4700. if ( m_bViewLowTexture )
  4701. Msg( "Low Texture Mode: On\n" );
  4702. else
  4703. Msg( "Low Texture Mode: Off\n" );
  4704. }
  4705. break;
  4706. }
  4707. case KEY_F:
  4708. {
  4709. if ( !bDown )
  4710. {
  4711. m_bFlashlight = !m_bFlashlight;
  4712. if ( m_bFlashlight )
  4713. Msg( "Flashlight: On\n" );
  4714. else
  4715. Msg( "Flashlight: Off\n" );
  4716. }
  4717. break;
  4718. }
  4719. case KEY_G:
  4720. {
  4721. if ( !bDown )
  4722. {
  4723. Msg( "Dropped Renderable\n" );
  4724. DropRenderable();
  4725. }
  4726. break;
  4727. }
  4728. case KEY_0:
  4729. {
  4730. // Reload shaders
  4731. if ( ie.m_nType == IE_ButtonPressed )
  4732. {
  4733. g_pMaterialSystem2->DynamicShaderCompile_ReloadAllShaders();
  4734. return false;
  4735. }
  4736. break;
  4737. }
  4738. case KEY_PAD_PLUS:
  4739. {
  4740. m_flSampleRadius += 1.0f;
  4741. Msg( "SSAO Sample Radius: %f\n", m_flSampleRadius );
  4742. break;
  4743. }
  4744. case KEY_PAD_MINUS:
  4745. {
  4746. m_flSampleRadius -= 1.0f;
  4747. m_flSampleRadius = MAX( 1, m_flSampleRadius );
  4748. Msg( "SSAO Sample Radius: %f\n", m_flSampleRadius );
  4749. break;
  4750. }
  4751. case KEY_PAD_DIVIDE:
  4752. {
  4753. if ( !bDown )
  4754. {
  4755. m_nViewBuffer = (RenderTargetType_t)( m_nViewBuffer + 1 );
  4756. if ( m_nViewBuffer >= MAX_RENDER_TARGET_TYPES )
  4757. {
  4758. m_nViewBuffer = (RenderTargetType_t)0;
  4759. }
  4760. Msg( "%s\n", g_pRenderTargetName[ m_nViewBuffer ] );
  4761. }
  4762. break;
  4763. }
  4764. case KEY_PAD_MULTIPLY:
  4765. {
  4766. if ( !bDown )
  4767. {
  4768. m_nViewBuffer = (RenderTargetType_t)( m_nViewBuffer - 1 );
  4769. if ( m_nViewBuffer < 0 )
  4770. {
  4771. m_nViewBuffer = (RenderTargetType_t)( MAX_RENDER_TARGET_TYPES - 1 );
  4772. }
  4773. Msg( "%s\n", g_pRenderTargetName[ m_nViewBuffer ] );
  4774. }
  4775. break;
  4776. }
  4777. case KEY_TAB:
  4778. {
  4779. m_nReportLevel = bDown ? 1 : 3;
  4780. break;
  4781. }
  4782. case KEY_Z:
  4783. {
  4784. if ( !bDown )
  4785. {
  4786. Vector vCameraOrigin( 100, 24975, 250 );
  4787. QAngle vCameraAngles( 9.6, -27, 0 );
  4788. m_pFrustum->SetCameraPosition( vCameraOrigin );
  4789. m_pFrustum->SetCameraAngles( vCameraAngles );
  4790. m_pWorldRenderer->ClearOutstandingLoadRequests();
  4791. }
  4792. }
  4793. break;
  4794. }
  4795. if ( nFlag )
  4796. {
  4797. if ( bDown )
  4798. {
  4799. m_cmd.m_nKeys |= nFlag;
  4800. }
  4801. else
  4802. {
  4803. m_cmd.m_nKeys &= ~nFlag;
  4804. }
  4805. return false;
  4806. }
  4807. }
  4808. return BaseClass::ProcessUserInput( ie );
  4809. }
  4810. static void PerformWorkUnit( SimulateWorkUnitWorldRender_t & job )
  4811. {
  4812. for( int i =0; i < job.m_nNumSystems; i++ )
  4813. {
  4814. job.m_pParticles->Simulate( job.m_flTimeStep );
  4815. }
  4816. }
  4817. void CWorldRendererTest::SimulateParticles( float flTimeStep )
  4818. {
  4819. int nSystems = m_particleWorkUnits.Count();
  4820. for( int i = 0; i < nSystems; i++ )
  4821. {
  4822. m_particleWorkUnits[i].m_flTimeStep = flTimeStep;
  4823. }
  4824. ParallelProcess( m_particleWorkUnits.Base(), nSystems, PerformWorkUnit );
  4825. }