|
|
//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// $Header: $
// $NoKeywords: $
//
// Render system unit test
//=============================================================================
#include "rendersystemtest.h"
#include "inputsystem/iinputsystem.h"
#include "materialsystem2/imaterialsystem2.h"
#include "worldrenderer/iworldrenderermgr.h"
#include "meshsystem/imeshsystem.h"
#include "filesystem.h"
#include "vstdlib/jobthread.h"
#include "particles/particles.h"
#include "dynamicdrawhelper.h"
#include "tier0/vprof.h"
#include "keyvalues.h"
#include "scenesystem/iscenesystem.h"
#include "icommandline.h"
#include "inputsystem/iinputstacksystem.h"
struct usercmd_t { float m_flForwardMove; float m_flRightMove; float m_flYawMove; float m_flPitchMove; uint32 m_nKeys; };
struct BoxVertex_t { Vector m_vPos; };
#define FKEY_FORWARD 0x00000001
#define FKEY_BACK 0x00000002
#define FKEY_LEFT 0x00000004
#define FKEY_RIGHT 0x00000008
#define FKEY_TURNLEFT 0x00000010
#define FKEY_TURNRIGHT 0x00000020
#define FKEY_TURNUP 0x00000040
#define FKEY_TURNDOWN 0x00000080
#define FKEY_SHOOTDECAL 0x00000100
#define FKEY_SHOOTPSYSTEM 0x00000200
#define FKEY_SHOOTSSYSTEM 0x00000400
#define FKEY_LIGHTELV 0x00000800
#define FKEY_LIGHTANG_POS 0x00001000
#define FKEY_LIGHTANG_NEG 0x00002000
#define FKEY_FAST 0x00004000
#define FKEY_ENABLE_VIS 0x00008000
#define FKEY_DISABLE_VIS 0x00010000
#define FKEY_DROP_FRUSTUM 0x00020000
#define FKEY_TOGGLE_AERIAL 0x00040000
#define FKEY_TOGGLE_BOUNCE 0x00080000
#define FKEY_TOGGLE_DIRECT 0x00100000
#define FKEY_TOGGLE_LIGHTING_ONLY 0x00200000
#define FKEY_SSAO 0x00400000
#define FKEY_BLUR_LIGHTING 0x00800000
#define FKEY_BLUR_SHADOWS 0x01000000
#define FKEY_FLASHLIGHT 0x02000000
#define FKEY_SHOOTDECAL2 0x04000000
#define FKEY_SHOOTWALLMONSTER 0x08000000
#define NUM_SHADOW_SPLITS 3
#define NUM_MULTI_SHADOWS 20
#define NUM_HIGH_RES_SHADOWS 4
#define SQRT_NUM_HIGH_RES_SHADOWS 2
#define NUM_LOW_RES_SHADOWS 16
#define SQRT_NUM_LOW_RES_SHADOWS 4
#define MAX_LIGHT_DISTANCE 2000.0f
#define MAX_MESH_SYSTEM_MODELS 5
char *g_pRenderableList[ MAX_MESH_SYSTEM_MODELS ] = { "models/w_minigun_reference.dmx", "models/pm_heavy_reference.dmx", "models/w_bonesaw_reference.dmx", "models/w_guitar_reference.dmx", "models/w_harpahorn.dmx", }; int g_nCurrentModel = 0;
struct DecalVertex_t { Vector m_vPos; Vector m_vDecalOrigin; Vector m_vDecalRight; Vector4D m_vDecalUpAndInfluence; };
struct SphereVertex_t { Vector m_vPos; };
struct QuadVertex_t { Vector m_vPos; Vector m_vEyeRay; };
struct ViewRelatedConstants_t { VMatrix m_mViewProjection; Vector4D m_vEyePt; Vector4D m_vEyeDir; Vector4D m_flFarPlane; };
struct LightingConstants_t { Vector4D m_vLightDir; Vector4D m_vLightColor; VMatrix m_mShadowMatrices[NUM_SHADOW_SPLITS]; };
struct DeferredLightingConstants_t { Vector4D m_vLightDir; Vector4D m_vLightColor; Vector4D m_vInvScreenExtents; Vector4D m_vEyePt; VMatrix m_mInvViewProj; VMatrix m_mShadowMatrix[NUM_SHADOW_SPLITS]; };
struct AerialPerspectiveConstants_t { Vector4D m_vLightDir; Vector4D m_vLightColor; Vector4D m_vInvScreenExtents; Vector4D m_vBm; Vector4D m_flG; Vector4D m_vNearAndFar; Vector4D m_vEyePt; VMatrix m_mInvViewProj; };
struct DecalScreenData_t { Vector4D m_vInvScreenExtents; VMatrix m_mInvViewProj; Vector4D m_vEyePt; Vector4D m_vEyeDir; };
struct BlurParams_t { Vector4D m_flBlurFalloff; Vector4D m_flSharpness; Vector4D m_flFarPlane; };
#define NUM_SSAO_SAMPLES 16
struct SampleSphereData_t { VMatrix m_mViewProj; Vector4D m_vRandSampleScale; Vector4D m_vSampleRadiusNBias; Vector4D m_vSphereSamples[ NUM_SSAO_SAMPLES ]; };
struct LightBufferData_t { Vector4D m_vInvScreenExtents; };
struct SkyVSCB_t { VMatrix m_mViewProj; Vector4D m_vSkyScale; };
struct SkyPSCB_t { Vector4D m_vLightDir; Vector4D m_vEyePt; Vector4D m_vLightColor; Vector4D m_vBm; Vector4D m_flG; };
struct PerParticleData_t { Vector4D m_vPosRadius; Vector4D m_vColor; };
struct SimulateWorkUnitWorldRender_t { CParticleCollection *m_pParticles; int m_nNumSystems; float m_flTimeStep; };
const int g_nNothingRenderedStencilRef = 0; const int g_nCanSeeSkyStencilRef = 1; const int g_nCannotSeeSkyStencilRef = 2;
// Globalizing these so we can render nodes in parallel
class CWorldRendererTest; CWorldRendererTest *g_pWorldRendererTest = NULL;
enum RenderViewFlags_t { VIEW_PLAYER_CAMERA = 0x00000001, VIEW_LIGHT_SHADOW = 0x00000002, VIEW_REFLECTION = 0x00000004, VIEW_MONITOR = 0x00000008, VIEW_POST_PROCESS = 0x00000010, VIEW_LIGHTING = 0x00000020, VIEW_DECALS = 0x00000040 };
enum RenderTargetType_t { DS_SHADOW_DEPTH0 = 0x0, DS_SHADOW_DEPTH1, DS_SHADOW_DEPTH2, DS_SHADOW_DEPTH_MULTIPLE, RT_SHADOW_MULTIPLE_0, RT_SHADOW_MULTIPLE_1, RT_SHADOW_BLUR_TEMP,
DS_DEPTH_HIGHRES, RT_VIEW_DEPTH_HIGHRES, RT_VIEW_NORMAL_HIGHRES, RT_VIEW_SPEC_HIGHRES, RT_LIGHTING_HIGHRES, // Alpha contains occlusion
RT_SPECULAR_HIGHRES,
DS_DEPTH_LOWRES, RT_VIEW_DEPTH_LOWRES, RT_VIEW_NORMAL_LOWRES, RT_LIGHTING_LOWRES,
RT_LIGHTING_TEMP_LOWRES,
MAX_RENDER_TARGET_TYPES };
char *g_pRenderTargetName[] = { {"DS_SHADOW_DEPTH0"}, {"DS_SHADOW_DEPTH1"}, {"DS_SHADOW_DEPTH2"}, {"DS_SHADOW_DEPTH_MULTIPLE"}, {"RT_SHADOW_MULTIPLE_1"}, {"RT_SHADOW_MULTIPLE_2"}, {"RT_SHADOW_BLUR_TEMP"},
{"DS_DEPTH_HIGHRES"}, {"RT_VIEW_DEPTH_HIGHRES"}, {"RT_VIEW_NORMAL_HIGHRES"}, {"RT_VIEW_SPEC_HIGHRES"}, {"RT_LIGHTING_HIGHRES"}, {"RT_SPECULAR_HIGHRES"},
{"DS_DEPTH_LOWRES"}, {"RT_VIEW_DEPTH_LOWRES"}, {"RT_VIEW_NORMAL_LOWRES"}, {"RT_LIGHTING_LOWRES"},
{"RT_LIGHTING_TEMP_LOWRES"},
{"MAX_RENDER_TARGET_TYPES"} };
enum ViewBindingType_t { RTB_SHADOW_DEPTH0 = 0x0, RTB_SHADOW_DEPTH1, RTB_SHADOW_DEPTH2,
RTB_SHADOW_DEPTH_MULTIPLE_0, RTB_SHADOW_DEPTH_MULTIPLE_1, RTB_SHADOW_DEPTH_MULTIPLE_2, RTB_SHADOW_DEPTH_MULTIPLE_3,
RTB_SHADOW_DEPTH_MULTIPLE_4, RTB_SHADOW_DEPTH_MULTIPLE_5, RTB_SHADOW_DEPTH_MULTIPLE_6, RTB_SHADOW_DEPTH_MULTIPLE_7,
RTB_SHADOW_DEPTH_MULTIPLE_8, RTB_SHADOW_DEPTH_MULTIPLE_9, RTB_SHADOW_DEPTH_MULTIPLE_10, RTB_SHADOW_DEPTH_MULTIPLE_11,
RTB_SHADOW_DEPTH_MULTIPLE_12, RTB_SHADOW_DEPTH_MULTIPLE_13, RTB_SHADOW_DEPTH_MULTIPLE_14, RTB_SHADOW_DEPTH_MULTIPLE_15,
RTB_SHADOW_DEPTH_MULTIPLE_16, RTB_SHADOW_DEPTH_MULTIPLE_17, RTB_SHADOW_DEPTH_MULTIPLE_18, RTB_SHADOW_DEPTH_MULTIPLE_19,
RTB_SHADOW_DEPTH_MULTIPLE_20, RTB_SHADOW_DEPTH_MULTIPLE_21, RTB_SHADOW_DEPTH_MULTIPLE_22, RTB_SHADOW_DEPTH_MULTIPLE_23,
RTB_SHADOW_DEPTH_MULTIPLE_24, RTB_SHADOW_DEPTH_MULTIPLE_25, RTB_SHADOW_DEPTH_MULTIPLE_26, RTB_SHADOW_DEPTH_MULTIPLE_27,
RTB_SHADOW_DEPTH_MULTIPLE_28, RTB_SHADOW_DEPTH_MULTIPLE_29, RTB_SHADOW_DEPTH_MULTIPLE_30, RTB_SHADOW_DEPTH_MULTIPLE_31,
RTB_DEFERRED_DEPTH_NORM_SPEC, RTB_DEFERRED_SCALE_DOWN, RTB_DEFERRED_NORM_SPEC, RTB_CLEAR_SPEC_HIGHRES, RTB_LIGHTING_HIGHRES, RTB_LIGHTING_LOWRES, RTB_SSAO_LOWRES, RTB_BILAT_UPSAMPLE_0, RTB_BILAT_UPSAMPLE_1, RTB_LIGHT_BLUR_0, RTB_LIGHT_BLUR_1, RTB_SHADOW_BLUR_0, RTB_SHADOW_BLUR_1, RTB_SHADOW_BLUR_2, RTB_SAMPLE_LIGHTING, RTB_AERIAL_PERSPECTIVE, RTB_SKY,
RTB_FORWARD,
MAX_VIEW_BINDING_TYPES };
ViewRelatedConstants_t CreateViewConstantsForFrustum( CWorldRenderFrustum* pFrustum ) { const Vector vEyePt = pFrustum->GetCameraPosition(); Vector vEyeDir = pFrustum->Forward(); float flFarPlane = pFrustum->GetFarPlane(); vEyeDir /= flFarPlane;
ViewRelatedConstants_t viewConstants; viewConstants.m_mViewProjection = pFrustum->GetViewProj(); viewConstants.m_vEyePt.Init( vEyePt.x, vEyePt.y, vEyePt.z, 1 ); viewConstants.m_flFarPlane.Init( flFarPlane, flFarPlane, flFarPlane, 1 ); viewConstants.m_vEyeDir.Init( vEyeDir.x, vEyeDir.y, vEyeDir.z, 1 ); return viewConstants; }
#define MAX_SIMUL_VIEWS 5
class CRenderView;
class CStaticMeshRenderable { public: CStaticMeshRenderable() {} ~CStaticMeshRenderable() {}
inline bool operator==( const CStaticMeshRenderable& src ) const { return src.m_pDrawCall == m_pDrawCall; }
IBVHNode *m_pNode; CBVHDrawCall *m_pDrawCall; };
class CDynamicRenderable { public: CDynamicRenderable() {} ~CDynamicRenderable() {}
inline bool operator==( const CDynamicRenderable &src ) const { return src.m_hRenderable == m_hRenderable; }
HRenderableStrong m_hRenderable; VMatrix m_mWorld; Vector m_vOrigin; };
class CPointLightRenderable { public: CPointLightRenderable() {} ~CPointLightRenderable() {}
inline bool operator==( const CPointLightRenderable& src ) const { return src.m_pLight == m_pLight; }
PointLightData_t *m_pLight; Vector m_vOrigin; };
class CSpotLightRenderable { public: CSpotLightRenderable() {} ~CSpotLightRenderable() {}
inline bool operator==( const CSpotLightRenderable& src ) const { return src.m_pLight == m_pLight; }
SpotLightData_t *m_pLight; Vector m_vOrigin; float m_flSquaredDistToEye; bool m_bInterior; bool m_bValid; };
class CHemiLightRenderable { public: CHemiLightRenderable() {} ~CHemiLightRenderable() {}
inline bool operator==( const CHemiLightRenderable& src ) const { return src.m_pLight == m_pLight; }
HemiLightData_t *m_pLight; Vector m_vOrigin; };
struct RenderJob_t { CWorldRendererTest *m_pTestApp; CRenderView *m_pRenderView; int m_nStartStatic; int m_nCountStatic;
int m_nStartDynamic; int m_nCountDynamic;
int m_nIndex; };
class CRenderView { public: CRenderView() {} ~CRenderView() { g_pRenderDevice->DestroyRenderTargetBinding( m_hRenderTargetBinding ); }
void Init( IRenderDevice* pRenderDevice, CWorldRenderFrustum *pFrustum, RenderTargetBinding_t hRenderTargetBinding, RenderViewport_t &viewport, RenderViewFlags_t nFlags, int nPass, int nViewType ) { g_pRenderDevice = pRenderDevice; m_pFrustum = pFrustum; m_hRenderTargetBinding = hRenderTargetBinding; m_viewport = viewport; m_nFlags = nFlags; m_nPass = nPass; m_nViewType = nViewType; m_bValid = true; }
RenderTargetBinding_t GetRenderTargetBinding() { return m_hRenderTargetBinding; } RenderViewFlags_t GetViewFlags() { return m_nFlags; } int GetRenderPass() { return m_nPass; } int GetViewType() { return m_nViewType; } CWorldRenderFrustum *GetFrustum() { return m_pFrustum; } IRenderDevice *GetRenderDevice() { return g_pRenderDevice; } bool IsValid() { return m_bValid; } void SetValid( bool bValid ) { m_bValid = bValid; }
void UpdateFrustum( CWorldRenderFrustum *pFrustum ) { m_pFrustum = pFrustum; }
void Clear( IRenderContext *pRenderContext, Vector4D &vClearColor, int nFlags ) { Assert( pRenderContext );
BeginRender( pRenderContext );
pRenderContext->Clear( vClearColor, nFlags );
// don't call endrender because it clears the rendercontext and the renderable list
pRenderContext->Submit(); }
void BeginRender( IRenderContext *pRenderContext ) { pRenderContext->BindRenderTargets( m_hRenderTargetBinding ); pRenderContext->SetViewports( 1, &m_viewport ); }
void EndRender( IRenderContext *pRenderContext, bool bClearList = true ) { if ( pRenderContext ) { pRenderContext->Submit(); }
if ( bClearList ) { if ( m_renderableList.Count() > 0 ) { m_renderableList.SetCountNonDestructively( 0 ); } if ( m_dynList.Count() > 0 ) { m_dynList.SetCountNonDestructively( 0 ); } } }
void AddStaticMeshRenderable( CStaticMeshRenderable *pRenderable ) { m_renderableList.AddToTail( pRenderable ); }
void AddDynamicRenderable( CDynamicRenderable *pRenderable ) { m_dynList.AddToTail( pRenderable ); }
bool HasRenderables() { return ( ( m_renderableList.Count() != 0 ) || ( m_dynList.Count() != 0 ) ); }
CUtlVector< CStaticMeshRenderable* > &GetRenderableList() { return m_renderableList; } CUtlVector< CDynamicRenderable* > &GetDynamicList() { return m_dynList; } private: RenderTargetBinding_t m_hRenderTargetBinding; RenderViewport_t m_viewport; RenderViewFlags_t m_nFlags; int m_nPass; int m_nViewType; bool m_bValid;
IRenderDevice *g_pRenderDevice; CWorldRenderFrustum *m_pFrustum; CUtlVector< CStaticMeshRenderable* > m_renderableList; CUtlVector< CDynamicRenderable* > m_dynList; };
float RPercent() { return float( rand() - (RAND_MAX/2) ) / (float)(RAND_MAX/2); }
float RPercentABS() { return float( rand() ) / (float)(RAND_MAX); }
//-----------------------------------------------------------------------------
// Tests the world renderer
//-----------------------------------------------------------------------------
class CWorldRendererTest : public CRenderSystemBenchmarkTest { typedef CRenderSystemBenchmarkTest BaseClass;
public: CWorldRendererTest( int nVariant ); virtual ~CWorldRendererTest( void ); virtual void RenderFrame( const RenderViewport_t &viewport, PlatWindow_t hWnd ); virtual void RenderFrame_Internal( const RenderViewport_t &viewport ); virtual void SimulateFrame( float flTimeStep ); virtual void GetDescription( char *pNameBufferOut, size_t nBufLen ); virtual bool ProcessUserInput( const InputEvent_t &ie ); virtual bool CanBeRun();
void RenderViewStatic( CRenderView *pRenderView, int nStart, int nCount, int nIndex ); void RenderViewDynamic( CRenderView *pRenderView, int nStart, int nCount, int nIndex ); void SetStateForRenderViewType( IRenderContext *pRenderContext, int nRenderView ); ConstantBufferHandle_t GetViewRelated() { return m_hViewRelated; } ConstantBufferHandle_t GetLightBufferRelated() { return m_hLightBufferData; } IResourceDictionary *GetResourceDictionary() { return m_pResourceDictionary; } RsDepthStencilStateHandle_t GetSetStencilDS() { return m_hSetStencilDS; } LightBufferData_t *GetLightBufferData() { return &m_lightBufferData; }
private: void SetupMultiShadowMatrices( int nViewportStart, int nSqrtNumShadows, float flBias ); void SetupShadowMatrices(); void CullRenderablesAgainstView( CRenderView &renderView, CUtlVector<CStaticMeshRenderable> &renderableList, CUtlVector<CDynamicRenderable> &dynList ); void RenderView( CRenderView &renderView ); void UpdateShadowData(); void UpdateFlashlightData(); void UpdateViewModelData(); void UpdateDroppedRenderables( float flElapsedTime ); void GenerateRenderables( Vector &vCameraPos ); void GeneratePointLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye ); void GenerateSpotLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye ); void GenerateHemiLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye );
void BilateralUpsample(); void RenderSSAO(); void ScaleDepthAndNormalBuffers(); void RenderAerialPerspective(); void RenderSky();
void RenderShadowDepthBuffers( IRenderContext *pRenderContext ); void RenderSunShadowFrustums( IRenderContext *pRenderContext ); void RenderBouncedLight( IRenderContext *pRenderContext ); void RenderDirectLight( IRenderContext *pRenderContext ); void BlurLightBuffer( ); void BlurShadowBuffers( );
void RenderDecals( IRenderContext *pRenderContext, int nVariation ); void RenderDynamic( IRenderContext *pRenderContext, CDynamicRenderable *pRenderable, int nVariation, bool bSunDepth, bool bSetStencil ); void RenderParticleLights( IRenderContext *pRenderContext, CParticleCollection *pParticles, int nVariation, bool bSunDepth, bool bSetStencil ); void RenderScenePointLights( IRenderContext *pRenderContext, CUtlVector<CPointLightRenderable> &lightVector, bool bInterior ); void RenderSceneHemiLights( IRenderContext *pRenderContext, CUtlVector<CHemiLightRenderable> &lightVector, bool bInterior ); void RenderSceneSpotLights( IRenderContext *pRenderContext, CUtlVector<CSpotLightRenderable> &lightVector, bool bInterior ); void RenderShadowedSpotLights( IRenderContext *pRenderContext, CUtlVector<CSpotLightRenderable> &lightVector ); void SimulateParticles( float flTimeStep ); void CalculateEyeRays( float flFarPlane ); void InitDeferredData( const RenderViewport_t &viewport ); void InitParticleData(); void InitRenderableData(); void UpdateFrustum( int nWidth, int nHeight ); void AddDecal( IRenderContext *pRenderContext, Vector &vHit, Vector &vDecalDir, float flDecalSizeU, float flDecalSizeV, float flDecalShift, float flDecalInfluenceLength, bool bPaint ); void AddWallMonster( IRenderContext *pRenderContext, Vector &vHit, Vector &vDecalDir, float flDecalSizeU, float flDecalSizeV, float flDecalShift, float flDecalInfluenceLength ); void DropRenderable(); void CreateSphere( int nTessellation ); void CreateHemi( int nTessellationRes ); void CreateCone( int nTessellation ); void RenderScreenQuad( IRenderContext *pRenderContext, Vector *pEyeRays, const char *pDebugName ); RenderShaderHandle_t GetVertexShader( char *pShaderName, IRenderDevice *pDevice, const char *pShaderVersion, const char *pDefineText = NULL ); RenderShaderHandle_t GetPixelShader( char *pShaderName, IRenderDevice *pDevice, const char *pShaderVersion, const char *pDefineText = NULL ); HRenderTexture CreateRenderTarget( RenderTargetType_t type, const RenderViewport_t &viewport ); RenderTargetBinding_t CreateRenderTargetBinding( ViewBindingType_t type, const RenderViewport_t &viewport ); void InitRenderTargetsAndViews( const RenderViewport_t &viewport );
CWorldRenderFrustum *m_pFrustum; CWorldRenderFrustum *m_pDropFrustum; Vector m_vCullPos; usercmd_t m_cmd;
HRenderTextureStrong m_pRenderTargets[ MAX_RENDER_TARGET_TYPES ]; RenderTargetBinding_t m_pViewBindings[ MAX_VIEW_BINDING_TYPES ]; CRenderView m_pRenderViews[ MAX_VIEW_BINDING_TYPES ]; int m_nRenderThreads; RenderJob_t *m_pRenderJobs;
// Resources
ConstantBufferHandle_t m_hViewRelated; ConstantBufferHandle_t m_hSingleMatrixRelated; ConstantBufferHandle_t m_hLightingRelated; ConstantBufferHandle_t m_hDeferredLightingRelated; ConstantBufferHandle_t m_hLightBufferData; ConstantBufferHandle_t m_hDecalScreenData; ConstantBufferHandle_t m_hBlurParams; ConstantBufferHandle_t m_hSphereSampleData;
CWorldRenderFrustum *m_pSplitFrustums[ NUM_SHADOW_SPLITS ]; VMatrix m_pShadowMatrices[ NUM_SHADOW_SPLITS ]; CWorldRenderFrustum *m_pMultiShadowFrustums[ NUM_MULTI_SHADOWS ]; VMatrix m_pMultiShadowMatrices[ NUM_MULTI_SHADOWS ];
LightingConstants_t m_forwardLightingData; DeferredLightingConstants_t m_deferredLightingData; BlurParams_t m_blurParams; LightBufferData_t m_lightBufferData; AerialPerspectiveConstants_t m_aerialPerspectiveData; SampleSphereData_t m_sphereSampleData; float m_flSampleRadius;
// Render list and renderable lists
CUtlVector<IBVHNode*> m_renderList; CUtlVector<CStaticMeshRenderable> m_renderableList; CUtlVector<CDynamicRenderable> m_dynRenderableList; CUtlVector<CPointLightRenderable> m_exteriorPointLights; CUtlVector<CPointLightRenderable> m_interiorPointLights; CUtlVector<CSpotLightRenderable> m_exteriorSpotLights; CUtlVector<CSpotLightRenderable> m_interiorSpotLights; CUtlVector<CHemiLightRenderable> m_exteriorHemiLights; CUtlVector<CHemiLightRenderable> m_interiorHemiLights; CUtlVector<CSpotLightRenderable> m_shadowedSpotLights; SpotLightData_t m_flashlight; float m_flMaxLightEncompassingFarPlane;
bool m_bEnableVis; bool m_bDropFrustum; bool m_bSSAO; bool m_bBlurLighting; bool m_bBlurShadows; bool m_bDrawAerialPerspective; bool m_bDrawBouncedLight; bool m_bDrawDirectLight; bool m_bLightingOnly; bool m_bFlashlight; bool m_bViewLowTexture;
// Deferred resources
bool m_bMultiThreaded; bool m_bDeferred; bool m_bDeferredInit; bool m_bRenderTargetsInit; RenderTargetType_t m_nViewBuffer;
float m_flLowResBufferScale;
RenderShaderHandle_t m_hCopyTexture[4]; RenderShaderHandle_t m_hBilateralBlur[4]; RenderShaderHandle_t m_hShadowBlur[4];
RenderInputLayout_t m_hQuadLayout; Vector m_vEyeRays[4]; Vector m_vEyeLocalRays[4];
int m_nRandTextureSize; HRenderTextureStrong m_hFlashlightCookie[2]; HRenderTextureStrong m_hRandomTexture; RenderShaderHandle_t m_hSSAOPS; RenderShaderHandle_t m_hAerialPerspectivePS[2]; ConstantBufferHandle_t m_hAerialPerspectivePSCB; RsBlendStateHandle_t m_hExtinctionBS; RsBlendStateHandle_t m_hInscatteringBS; RsBlendStateHandle_t m_hAdditiveBS; RsBlendStateHandle_t m_hWriteAlphaBS; RsBlendStateHandle_t m_hWriteAllBS; RsDepthStencilStateHandle_t m_hSetStencilDS; RsDepthStencilStateHandle_t m_hZWriteNoTestDS;
RenderShaderHandle_t m_hShadowFrustumVS[3]; RenderShaderHandle_t m_hShadowFrustumPS[3];
int m_nSphereIndices; int m_nHemiIndices; int m_nConeIndices; HRenderBufferStrong m_hSphereVB; HRenderBufferStrong m_hSphereIB; HRenderBufferStrong m_hHemiVB; HRenderBufferStrong m_hHemiIB; HRenderBufferStrong m_hConeVB; HRenderBufferStrong m_hConeIB;
RenderShaderHandle_t m_hSceneLightVS[3]; RenderShaderHandle_t m_hSceneLightPS[6]; RenderInputLayout_t m_hSceneLightLayout[3];
// Sky
RenderInputLayout_t m_hSphereLayout; RenderShaderHandle_t m_hSkyVS; RenderShaderHandle_t m_hSkyPS; ConstantBufferHandle_t m_hSkyVSCB; ConstantBufferHandle_t m_hSkyPSCB; SkyPSCB_t m_skyData; Vector4D m_vRenderLightColor; bool m_bRenderSky; RsDepthStencilStateHandle_t m_hZTestAndStencilTestDS; RsDepthStencilStateHandle_t m_hStencilTestDS;
// Decals
RenderInputLayout_t m_hDecalLayout; HRenderBufferStrong m_hDecalVB; HRenderBufferStrong m_hDecalVB2; HRenderBufferStrong m_hDecalVB3; HRenderBufferStrong m_hDecalIB; RenderShaderHandle_t m_hDecalVS[2]; RenderShaderHandle_t m_hDecalPS[2]; HRenderTextureStrong m_hDecalAlbedo; HRenderTextureStrong m_hDecalAlbedo2; HRenderTextureStrong m_hDecalNormal; HRenderTextureStrong m_hDecalNormal2; HRenderTextureStrong m_hDecalNormal3[3]; DecalScreenData_t m_decalScreenData; DecalScreenData_t m_lowResScreenData; DecalScreenData_t m_shadowScreenData; DecalVertex_t *m_pDecalBackingStore; DecalVertex_t *m_pDecalBackingStore2; int m_nMaxDecals; bool m_bFullBuffer; bool m_bFullBuffer2; int m_nGlobalDecalPos; int m_nGlobalDecalPos2; int m_nGlobalDecalPos3; Vector m_vPreviousMonsterNormal; int m_nWallMonsterTexture; float m_flWallMonsterTimer; int m_nNumTriangles;
// Particles
CUtlVector<CParticleCollection*> m_lightSystemList; CUtlVector<CParticleCollection*> m_sphereSystemList; CUtlVector<SimulateWorkUnitWorldRender_t> m_particleWorkUnits; RenderInputLayout_t m_hPointLightLayout; RenderShaderHandle_t m_hPointLightVS[5]; RenderShaderHandle_t m_hPointLightPS[5];
// Renderable test
RenderShaderHandle_t m_hSimpleMeshVS[4]; RenderShaderHandle_t m_hSimpleMeshPS[4];
Vector m_vLightDir; Vector2D m_vLightAngleElevation; float m_flLightAngSpeed; float m_flLightElvSpeed; int m_nShadowSplits; RenderViewport_t m_shadowViewport; RenderViewport_t m_multiShadowViewport[ NUM_MULTI_SHADOWS ]; VMatrix m_splitScaleBiasMatrices[ NUM_SHADOW_SPLITS ]; VMatrix m_multiShadowScaleBiasMatrices[ NUM_MULTI_SHADOWS ]; int m_nCurrentFrameNumber; int m_nShadowSize; int m_nLastFrustumWidth; int m_nLastFrustumHeight; int m_nWindowCenterX; int m_nWindowCenterY; int m_nCursorDeltaX; int m_nCursorDeltaY; int m_nCursorDeltaResetX; int m_nCursorDeltaResetY; int m_nReportLevel; float m_flDecalCountdown; float m_flParticleCountdown;
float m_flNearPlane; float m_flFarPlane;
// WorldRenderer
IWorldRendererMgr *m_pWorldRendererMgr; IWorldRenderer *m_pWorldRenderer; IResourceDictionary *m_pResourceDictionary; bool m_bWorldLoaded; };
DECLARE_TEST( CWorldRendererTest );
static void PerformStaticMeshWorkUnit( RenderJob_t & job ) { job.m_pTestApp->RenderViewStatic( job.m_pRenderView, job.m_nStartStatic, job.m_nCountStatic, job.m_nIndex ); job.m_pTestApp->RenderViewDynamic( job.m_pRenderView, job.m_nStartDynamic, job.m_nCountDynamic, job.m_nIndex ); }
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 };
//-----------------------------------------------------------------------------
// Constructor, destructor
//-----------------------------------------------------------------------------
CWorldRendererTest::CWorldRendererTest( int nVariant ) : BaseClass( nVariant ) { if ( !g_pWorldRendererMgr ) return;
g_pWorldRendererTest = this;
// Disable HW instancing on GL for now
if ( g_nPlatform == RST_PLATFORM_GL ) g_pWorldRendererMgr->SetHWInstancingEnabled( false );
CRenderContextPtr pRenderContext( g_pRenderDevice );
m_flDecalCountdown = 0.0f; m_flParticleCountdown = 0.0f;
if ( IsPlatformX360() ) { m_nShadowSize = 512; } else { m_nShadowSize = 1024; }
m_shadowViewport.Init( 0, 0, m_nShadowSize, m_nShadowSize, 0, 1 );
SetupShadowMatrices();
m_nViewBuffer = RT_LIGHTING_HIGHRES;
m_nRenderThreads = g_pThreadPool->NumThreads(); m_pRenderJobs = new RenderJob_t[ m_nRenderThreads ];
m_nCurrentFrameNumber = 0; m_hViewRelated = g_pRenderDevice->CreateConstantBuffer( sizeof( ViewRelatedConstants_t ) ); m_hSingleMatrixRelated = g_pRenderDevice->CreateConstantBuffer( sizeof( VMatrix ) ); m_hLightingRelated = g_pRenderDevice->CreateConstantBuffer( sizeof( LightingConstants_t ) ); m_hSkyVSCB = g_pRenderDevice->CreateConstantBuffer( sizeof( SkyVSCB_t ) ); m_hSkyPSCB = g_pRenderDevice->CreateConstantBuffer( sizeof( SkyPSCB_t ) );
//m_flLowResBufferScale = 0.5f;
m_flLowResBufferScale = 0.5f; m_bEnableVis = true; m_bDropFrustum = false; m_bSSAO = true; m_bBlurLighting = false; m_bBlurShadows = true; m_bDrawAerialPerspective = true; m_bDrawBouncedLight = true; m_bDrawDirectLight = true; m_bLightingOnly = false; m_bFlashlight = false; m_bViewLowTexture = false;
// Deferred
m_bDeferred = true; m_bDeferredInit = false; m_bRenderTargetsInit = false; m_bMultiThreaded = true;
// No deferred on GL yet
if ( g_nPlatform == RST_PLATFORM_GL || g_nPlatform == RST_PLATFORM_X360 ) m_bDeferred = false;
m_bWorldLoaded = true; // Create a world renderer
m_pWorldRenderer = g_pWorldRendererMgr->CreateWorldRenderer();
// Load the world
const char *pWorldName = CommandLine()->ParmValue( "-map", "maps/ep2_outland_10" ); if ( !m_pWorldRenderer->Unserialize( pWorldName ) ) { Error( "Cannot load world!\n" ); m_bWorldLoaded = false; return; }
m_pResourceDictionary = m_pWorldRenderer->GetResourceDictionary();
// Initialization
static const uint64 sMegabyte = 1024 * 1024; uint64 nMaxGPUMemory = 768 * sMegabyte; uint64 nMaxSysMemory = 512 * sMegabyte;
if ( IsPlatformX360() ) { // Set this low until texture eviction works on the 360
nMaxGPUMemory = 256 * sMegabyte; nMaxSysMemory = 32 * sMegabyte; } m_pWorldRenderer->Initialize( g_pRenderDevice, nMaxGPUMemory, nMaxSysMemory );
// Alloc split frustums
for ( int s=0; s<NUM_SHADOW_SPLITS; ++s ) { m_pSplitFrustums[s] = (CWorldRenderFrustum*)MemAlloc_AllocAligned( sizeof( CWorldRenderFrustum ), 16 ); }
// Alloc multi-shadow frustums
for ( int s=0; s<NUM_MULTI_SHADOWS; ++s ) { m_pMultiShadowFrustums[s] = (CWorldRenderFrustum*)MemAlloc_AllocAligned( sizeof( CWorldRenderFrustum ), 16 ); }
// Build up a frustum
m_pFrustum = (CWorldRenderFrustum*)MemAlloc_AllocAligned( sizeof( CWorldRenderFrustum ), 16 ); m_pDropFrustum = (CWorldRenderFrustum*)MemAlloc_AllocAligned( sizeof( CWorldRenderFrustum ), 16 );
m_nLastFrustumWidth = 1024; m_nLastFrustumHeight = 768; float flFOVY = 90.0f; float flAspect = m_nLastFrustumWidth / (float)m_nLastFrustumHeight;
// Find the player start
Vector vEyePos( 0, 0, 0 ); QAngle vAngles( -64, 90, 0 );
CUtlVector< KeyValues* > playerstarts; m_pWorldRenderer->GetEntities( "info_player_start", playerstarts ); if ( playerstarts.Count() ) { const char *pEye = playerstarts[0]->GetString( "origin" ); const char *pAngles = playerstarts[0]->GetString( "angles" );
sscanf( pEye, "%f %f %f", &vEyePos.x, &vEyePos.y, &vEyePos.z ); sscanf( pAngles, "%f %f %f", &vAngles.x, &vAngles.y, &vAngles.z ); vEyePos.z += 64; }
// eyepos, eyeangles, znear, zfar, fov, aspect ratio
m_flNearPlane = 10.0f; m_flFarPlane = 18000.0f; m_pFrustum->InitCamera( vEyePos, vAngles, m_flNearPlane, m_flFarPlane, CalcFovX(flFOVY, flAspect), flAspect ); m_pFrustum->UpdateFrustumFromCamera();
// parallel spit shadow maps
m_vLightAngleElevation.x = 120.0f; m_vLightAngleElevation.y = 70.0f; m_vLightDir = Vector(0,0,1); Q_memset( &m_skyData, 0, sizeof( SkyPSCB_t ) ); m_vRenderLightColor = Vector4D(1,1,1,1); m_flLightAngSpeed = 20.0f; m_flLightElvSpeed = 20.0f;
m_nShadowSplits = NUM_SHADOW_SPLITS;
const char *pVertexShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_VERTEX_SHADER ); const char *pPixelShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_PIXEL_SHADER );
// sphere and cone primitives
CreateSphere( 10 ); CreateHemi( 10 ); CreateCone( 10 );
if ( m_bDeferred ) { // Decals
m_nMaxDecals = 2000; m_bFullBuffer = false; m_nGlobalDecalPos = 0; m_bFullBuffer2 = false; m_nGlobalDecalPos2 = 0; m_nGlobalDecalPos3 = 0; m_vPreviousMonsterNormal.Init( 0, 0, 1 ); m_nWallMonsterTexture = 0; m_flWallMonsterTimer = 0.0f;
static RenderInputLayoutField_t decalLayout[] = { DEFINE_PER_VERTEX_FIELD( 0, "position", 0, DecalVertex_t, m_vPos ) DEFINE_PER_VERTEX_FIELD( 0, "texcoord", 0, DecalVertex_t, m_vDecalOrigin ) DEFINE_PER_VERTEX_FIELD( 0, "texcoord", 1, DecalVertex_t, m_vDecalRight ) DEFINE_PER_VERTEX_FIELD( 0, "texcoord", 2, DecalVertex_t, m_vDecalUpAndInfluence ) };
m_hDecalLayout = g_pRenderDevice->CreateInputLayout( "decallayout", ARRAYSIZE( decalLayout ), decalLayout );
BufferDesc_t decalDesc; decalDesc.m_nElementCount = m_nMaxDecals * 8; decalDesc.m_nElementSizeInBytes = sizeof( DecalVertex_t ); decalDesc.m_pBudgetGroupName = "decals"; decalDesc.m_pDebugName = "decalVB"; m_hDecalVB = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_SEMISTATIC, decalDesc ); decalDesc.m_pDebugName = "decalVB2"; m_hDecalVB2 = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_SEMISTATIC, decalDesc ); decalDesc.m_nElementCount = 8; decalDesc.m_pDebugName = "decalVB3"; m_hDecalVB3 = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_SEMISTATIC, decalDesc ); decalDesc.m_nElementCount = m_nMaxDecals * 36; decalDesc.m_nElementSizeInBytes = sizeof( uint16 ); decalDesc.m_pDebugName = "decalIB"; m_hDecalIB = g_pRenderDevice->CreateIndexBuffer( RENDER_BUFFER_TYPE_STATIC, decalDesc );
LockDesc_t lockDesc; pRenderContext->LockIndexBuffer( m_hDecalIB, m_nMaxDecals * 36 * sizeof( uint16 ), &lockDesc ); uint16 *pIndices = (uint16*)lockDesc.m_pMemory; int nOffset = 0; for ( int d=0; d<m_nMaxDecals; ++d ) { for ( int i=0; i<36; ++i ) { pIndices[i] = g_pBoxIndices[i] + nOffset; } nOffset += 8; pIndices += 36; } pRenderContext->UnlockIndexBuffer( m_hDecalIB, m_nMaxDecals * 36 * sizeof( uint16 ), &lockDesc );
m_hDecalVS[0] = GetVertexShader( "maps/decalsvs", g_pRenderDevice, pVertexShaderVersion, "#define SHADER_VARIATION 0\n" ); m_hDecalPS[0] = GetPixelShader( "maps/decalsps", g_pRenderDevice, pPixelShaderVersion, "#define SHADER_VARIATION 0\n" ); m_hDecalVS[1] = GetVertexShader( "maps/decalsvs", g_pRenderDevice, pVertexShaderVersion, "#define SHADER_VARIATION 1\n" ); m_hDecalPS[1] = GetPixelShader( "maps/decalsps", g_pRenderDevice, pPixelShaderVersion, "#define SHADER_VARIATION 1\n" );
m_hDecalScreenData = g_pRenderDevice->CreateConstantBuffer( sizeof( DecalScreenData_t ) );
m_hDecalAlbedo = RENDER_TEXTURE_HANDLE_INVALID;//g_pRenderDevice->FindOrCreateFileTexture( "maps/decaltest_albedo.vtf" );
//m_hDecalNormal = g_pRenderDevice->FindOrCreateFileTexture( "maps/decaltest_normal.vtf" );
m_hDecalNormal = g_pRenderDevice->FindOrCreateFileTexture( "materials/plastercrack.vtf" ); m_hDecalAlbedo2 = g_pRenderDevice->FindOrCreateFileTexture( "materials/paintdecal.vtf" ); m_hDecalNormal2 = g_pRenderDevice->FindOrCreateFileTexture( "materials/paintdecalnorm.vtf" ); m_hDecalNormal3[0] = g_pRenderDevice->FindOrCreateFileTexture( "materials/gearhead1.vtf" ); m_hDecalNormal3[1] = g_pRenderDevice->FindOrCreateFileTexture( "materials/gearhead2.vtf" ); m_hDecalNormal3[2] = g_pRenderDevice->FindOrCreateFileTexture( "materials/gearhead3.vtf" );
m_pDecalBackingStore = new DecalVertex_t[ m_nMaxDecals * 8 ]; m_pDecalBackingStore2 = new DecalVertex_t[ m_nMaxDecals * 8 ]; }
m_bRenderSky = true; if ( m_bRenderSky ) { // Load shaders
m_hSkyVS = GetVertexShader( "maps/skyvs", g_pRenderDevice, pVertexShaderVersion ); m_hSkyPS = GetPixelShader( "maps/skyps", g_pRenderDevice, pPixelShaderVersion ); }
if ( m_bDeferred ) { // particle system
InitParticleData(); }
InitRenderableData();
// Input
Q_memset( &m_cmd, 0, sizeof( usercmd_t ) ); m_nWindowCenterX = -1; m_nWindowCenterY = -1; m_nCursorDeltaX = 0; m_nCursorDeltaY = 0; m_nCursorDeltaResetX = 0; m_nCursorDeltaResetY = 0; m_nReportLevel = 0;
g_pInputStackSystem->SetCursorVisible( GetInputContext(), false ); }
CWorldRendererTest::~CWorldRendererTest( void ) { if ( !g_pWorldRendererMgr ) return;
g_pInputStackSystem->SetCursorVisible( GetInputContext(), true );
g_pRenderDevice->DestroyConstantBuffer( m_hViewRelated ); g_pRenderDevice->DestroyConstantBuffer( m_hLightingRelated );
m_pWorldRenderer->DestroyResources( g_pRenderDevice ); g_pWorldRendererMgr->DestroyWorldRenderer( m_pWorldRenderer );
m_dynRenderableList.RemoveAll();
for ( int s=0; s<NUM_SHADOW_SPLITS; ++s ) { MemAlloc_FreeAligned( m_pSplitFrustums[s] ); } for ( int s=0; s<NUM_MULTI_SHADOWS; ++s ) { MemAlloc_FreeAligned( m_pMultiShadowFrustums[s] ); }
MemAlloc_FreeAligned( m_pFrustum ); }
class CUniformSampler { private: Vector* m_pvDirections; int m_NumSamples; int m_NumVariations;
public: CUniformSampler() : m_pvDirections( NULL ), m_NumSamples( 0 ), m_NumVariations( 0 ) { } ~CUniformSampler() { if ( m_pvDirections ) { delete []m_pvDirections; }; }
int GetNumVariations() { return m_NumVariations; } int GetNumSamples() { return m_NumSamples; } bool InitSamples( int SqrtNumSamples, int NumVariations ); Vector GetSampleDirection( int Sample, int Variation ); };
bool CUniformSampler::InitSamples( int SqrtNumSamples, int NumVariations ) { m_NumSamples = SqrtNumSamples * SqrtNumSamples; m_NumVariations = NumVariations;
m_pvDirections = new Vector[ m_NumSamples * m_NumVariations ]; if ( !m_pvDirections ) return false; #if 1
int i=0; // array index
float oneoverN = 1.0f/(float)SqrtNumSamples;
for ( int n=0; n<m_NumVariations; n++ ) { // fill an N*N*2 array with uniformly distributed
// samples across the sphere using jittered stratification
for ( int a=0; a<SqrtNumSamples; a++ ) { for ( int b=0; b<SqrtNumSamples; b++ ) { // generate unbiased distribution of spherical coords
float x = ( a + fabs( RPercent() ) ) * oneoverN; // do not reuse results
float y = ( b + fabs( RPercent() ) ) * oneoverN; // each sample must be random
float theta = 2.0f * acosf(sqrtf(1.0f - x)); float phi = 2.0f * M_PI * y;
// convert spherical coords to unit vector
Vector vec(sinf(theta)*cosf(phi), sinf(theta)*sinf(phi), cosf(theta)); m_pvDirections[i] = vec;
++i; } } } #else
int i=0; for ( int n=0; n<m_NumVariations; n++ ) { // fill an N*N*2 array with uniformly distributed
// samples across the sphere using jittered stratification
for ( int a=0; a<SqrtNumSamples * SqrtNumSamples; a++ ) { m_pvDirections[i].x = RPercent(); m_pvDirections[i].y = RPercent(); m_pvDirections[i].z = RPercent(); m_pvDirections[i].NormalizeInPlace(); i++; } } #endif
return true; }
Vector CUniformSampler::GetSampleDirection( int Sample, int Variation ) { int Start = m_NumSamples * Variation; return m_pvDirections[ Start + Sample ]; }
void CWorldRendererTest::InitDeferredData( const RenderViewport_t &viewport ) { CRenderContextPtr pRenderContext( g_pRenderDevice );
static RenderInputLayoutField_t quadLayout[] = { DEFINE_PER_VERTEX_FIELD( 0, "position", 0, QuadVertex_t, m_vPos ) DEFINE_PER_VERTEX_FIELD( 0, "texcoord", 0, QuadVertex_t, m_vEyeRay ) }; m_hQuadLayout = g_pRenderDevice->CreateInputLayout( "quadlayout", ARRAYSIZE( quadLayout ), quadLayout );
// Constants
m_hDeferredLightingRelated = g_pRenderDevice->CreateConstantBuffer( sizeof( DeferredLightingConstants_t ) ); m_hLightBufferData = g_pRenderDevice->CreateConstantBuffer( sizeof( LightBufferData_t ) );
const char *pVertexShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_VERTEX_SHADER ); const char *pPixelShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_PIXEL_SHADER );
// Shaders for low-res buffers
//float flBlurFalloff = 0.0005f;
float flBlurFalloff = 0.005f; float flSharpness = 1000.0f; m_blurParams.m_flBlurFalloff.Init( flBlurFalloff, flBlurFalloff, flBlurFalloff, flBlurFalloff ); m_blurParams.m_flSharpness.Init( flSharpness, flSharpness, flSharpness, flSharpness ); m_blurParams.m_flFarPlane.Init( 1, 1, 1, 1 ); m_hBlurParams = g_pRenderDevice->CreateConstantBuffer( sizeof( BlurParams_t ) ); 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" ); 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" ); 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" ); 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" ); m_hBilateralBlur[0] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 1\n#define HORZ_BLUR 1\n#define BLUR_RADIUS 8\n" ); m_hBilateralBlur[1] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 1\n#define HORZ_BLUR 0\n#define BLUR_RADIUS 8\n" ); 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" ); m_hBilateralBlur[3] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 1\n#define HORZ_BLUR 0\n#define BLUR_RADIUS 6\n" );
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" ); m_hShadowBlur[1] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 0\n#define HORZ_BLUR 0\n#define BLUR_RADIUS 3\n" ); 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" ); m_hShadowBlur[3] = GetPixelShader( "maps/bilateralblur", g_pRenderDevice, pPixelShaderVersion, "#define BILAT_BLUR 0\n#define HORZ_BLUR 0\n#define BLUR_RADIUS 2\n" );
// Shaders for deferred ligthing
m_hShadowFrustumVS[0] = GetVertexShader( "maps/shadowfrustumvs", g_pRenderDevice, pVertexShaderVersion, "#define DISCARD_OUTSIDE 1\n#define ALL_FRUSTUMS 0\n" ); m_hShadowFrustumPS[0] = GetPixelShader( "maps/shadowfrustumps", g_pRenderDevice, pPixelShaderVersion, "#define DISCARD_OUTSIDE 1\n#define ALL_FRUSTUMS 0\n" ); m_hShadowFrustumVS[1] = GetVertexShader( "maps/shadowfrustumvs", g_pRenderDevice, pVertexShaderVersion, "#define ALL_FRUSTUMS 0\n" ); m_hShadowFrustumPS[1] = GetPixelShader( "maps/shadowfrustumps", g_pRenderDevice, pPixelShaderVersion, "#define ALL_FRUSTUMS 0\n" ); m_hShadowFrustumVS[2] = GetVertexShader( "maps/shadowfrustumvs", g_pRenderDevice, pVertexShaderVersion, "#define ALL_FRUSTUMS 1\n" ); m_hShadowFrustumPS[2] = GetPixelShader( "maps/shadowfrustumps", g_pRenderDevice, pPixelShaderVersion, "#define ALL_FRUSTUMS 1\n" );
// Scene light shaders
m_hSceneLightVS[0] = GetVertexShader( "maps/scenelightvs", g_pRenderDevice, pVertexShaderVersion, "#define LIGHT_TYPE 0\n" ); m_hSceneLightVS[1] = GetVertexShader( "maps/scenelightvs", g_pRenderDevice, pVertexShaderVersion, "#define LIGHT_TYPE 1\n" ); m_hSceneLightVS[2] = GetVertexShader( "maps/scenelightvs", g_pRenderDevice, pVertexShaderVersion, "#define LIGHT_TYPE 2\n" );
m_hSceneLightPS[0] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 0\n#define LIGHT_SHADOWED 0\n" ); m_hSceneLightPS[1] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 1\n#define LIGHT_SHADOWED 0\n" ); m_hSceneLightPS[2] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 2\n#define LIGHT_SHADOWED 0\n" ); m_hSceneLightPS[3] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 0\n#define LIGHT_SHADOWED 1\n" ); m_hSceneLightPS[4] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 1\n#define LIGHT_SHADOWED 1\n" ); m_hSceneLightPS[5] = GetPixelShader( "maps/scenelightps", g_pRenderDevice, pPixelShaderVersion, "#define LIGHT_TYPE 2\n#define LIGHT_SHADOWED 1\n" );
static RenderInputLayoutField_t pointLightLayout[] = { DEFINE_PER_VERTEX_FIELD( 0, "position", 0, SphereVertex_t, m_vPos ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 0, PointLightData_t, m_vOrigin ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 1, PointLightData_t, m_vColorNRadius ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 2, PointLightData_t, m_vAttenuation ) }; static RenderInputLayoutField_t hemiLightLayout[] = { DEFINE_PER_VERTEX_FIELD( 0, "position", 0, SphereVertex_t, m_vPos ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 0, HemiLightData_t, m_vTransform0 ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 1, HemiLightData_t, m_vTransform1 ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 2, HemiLightData_t, m_vTransform2 ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 3, HemiLightData_t, m_vColorNRadius ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 4, HemiLightData_t, m_vAttenuation ) }; static RenderInputLayoutField_t spotLightLayout[] = { DEFINE_PER_VERTEX_FIELD( 0, "position", 0, SphereVertex_t, m_vPos ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 0, SpotLightData_t, m_vTransform0 ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 1, SpotLightData_t, m_vTransform1 ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 2, SpotLightData_t, m_vTransform2 ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 3, SpotLightData_t, m_vColorNRadius ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 4, SpotLightData_t, m_vAttenuationNCosSpot ) };
m_hSceneLightLayout[0] = g_pRenderDevice->CreateInputLayout( "scenelight_point", ARRAYSIZE( pointLightLayout ), pointLightLayout ); m_hSceneLightLayout[1] = g_pRenderDevice->CreateInputLayout( "scenelight_hemi", ARRAYSIZE( hemiLightLayout ), hemiLightLayout ); m_hSceneLightLayout[2] = g_pRenderDevice->CreateInputLayout( "scenelight_spot", ARRAYSIZE( spotLightLayout ), spotLightLayout );
m_hFlashlightCookie[0] = g_pRenderDevice->FindOrCreateFileTexture( "materials/flashlight4.vtf" ); m_hFlashlightCookie[1] = g_pRenderDevice->FindOrCreateFileTexture( "materials/flashlight16.vtf" );
// SSAO
m_hSSAOPS = GetPixelShader( "maps/ssao", g_pRenderDevice, pPixelShaderVersion );
CUniformSampler ssaoSampler; ssaoSampler.InitSamples( (int)sqrtf( (float)NUM_SSAO_SAMPLES ), 1 );
m_hSphereSampleData = g_pRenderDevice->CreateConstantBuffer( sizeof( SampleSphereData_t ) ); m_flSampleRadius = 16.0f; m_sphereSampleData.m_vRandSampleScale.Init( 1, 1, 1, 1 ); m_sphereSampleData.m_vSampleRadiusNBias.Init( m_flSampleRadius, m_flSampleRadius, m_flSampleRadius, m_flSampleRadius ); for ( int s=0; s<NUM_SSAO_SAMPLES; ++s ) { Vector vSample = ssaoSampler.GetSampleDirection( s, 0 ); //vSample *= 0.2f + 0.8f * RPercentABS();
vSample *= RPercentABS(); m_sphereSampleData.m_vSphereSamples[s].Init( vSample.x, vSample.y, vSample.z, 1 ); } pRenderContext->SetConstantBufferData( m_hSphereSampleData, &m_sphereSampleData, sizeof( SampleSphereData_t ) );
#if 1
// random texture
m_nRandTextureSize = 4; CUniformSampler randTexSampler; randTexSampler.InitSamples( m_nRandTextureSize, 1 );
TextureHeader_t randSpec; memset( &randSpec, 0, sizeof(TextureHeader_t) ); randSpec.m_nWidth = m_nRandTextureSize; randSpec.m_nHeight = m_nRandTextureSize; randSpec.m_nNumMipLevels = 1; randSpec.m_nDepth = 1; randSpec.m_nFlags = TSPEC_UNFILTERABLE_OK; randSpec.m_nImageFormat = IMAGE_FORMAT_BGRA8888; if ( g_nPlatform == RST_PLATFORM_DX11 ) { randSpec.m_nImageFormat = IMAGE_FORMAT_RGBA8888; } m_hRandomTexture = g_pRenderDevice->FindOrCreateTexture( "worldrenderertest", "randomtexture", &randSpec ); int nTotalRands = randSpec.m_nWidth * randSpec.m_nHeight; uint8 *pRandBits = new uint8[ nTotalRands * 4 ]; for ( int r=0; r<nTotalRands; ++r ) { Vector vRandVector = randTexSampler.GetSampleDirection( r, 0 );
pRandBits[ r * 4 ] = (uint8)( ( vRandVector.z * 128.0f ) + 127 ); pRandBits[ r * 4 + 1 ] = (uint8)( ( vRandVector.y * 128.0f ) + 127 ); pRandBits[ r * 4 + 2 ] = (uint8)( ( vRandVector.x * 128.0f ) + 127 ); pRandBits[ r * 4 + 3 ] = 0; }
pRenderContext->SetTextureData( m_hRandomTexture, &randSpec, pRandBits, nTotalRands * 4, false ); delete []pRandBits; #else
// random texture
m_nRandTextureSize = 32; m_hRandomTexture = g_pRenderDevice->FindOrCreateFileTexture( "materials/SSAOReflectionVectors.vtf" ); #endif
// Aerial perspective
m_hAerialPerspectivePS[0] = GetPixelShader( "maps/aerialperspectiveps", g_pRenderDevice, pPixelShaderVersion, "#define SHADER_VARIATION 0\n" ); m_hAerialPerspectivePS[1] = GetPixelShader( "maps/aerialperspectiveps", g_pRenderDevice, pPixelShaderVersion, "#define SHADER_VARIATION 1\n" ); m_hAerialPerspectivePSCB = g_pRenderDevice->CreateConstantBuffer( sizeof( AerialPerspectiveConstants_t ) );
// states for aerial perspective
RsBlendStateDesc_t bd; memset( &bd, 0, sizeof( bd ) ); bd.m_bAlphaToCoverageEnable = false; bd.m_bIndependentBlendEnable = false; for ( int i=0; i<4; ++i ) { bd.m_bBlendEnable[i] = true; bd.m_srcBlend[i] = RS_BLEND_MODE_ZERO; bd.m_destBlend[i] = RS_BLEND_MODE_SRC_COLOR; bd.m_blendOp[i] = RS_BLEND_OP_ADD; bd.m_nRenderTargetWriteMask[i] = RS_COLOR_WRITE_ENABLE_R | RS_COLOR_WRITE_ENABLE_G | RS_COLOR_WRITE_ENABLE_B; } m_hExtinctionBS = pRenderContext->FindOrCreateBlendState( &bd ); for ( int i=0; i<4; ++i ) { bd.m_srcBlend[i] = RS_BLEND_MODE_ONE; bd.m_destBlend[i] = RS_BLEND_MODE_ONE; } m_hInscatteringBS = pRenderContext->FindOrCreateBlendState( &bd );
m_hAdditiveBS = pRenderContext->FindOrCreateBlendState( &bd );
for ( int i=0; i<4; ++i ) { bd.m_bBlendEnable[i] = false; bd.m_srcBlend[i] = RS_BLEND_MODE_ZERO; bd.m_destBlend[i] = RS_BLEND_MODE_SRC_COLOR; bd.m_blendOp[i] = RS_BLEND_OP_ADD; bd.m_nRenderTargetWriteMask[i] = RS_COLOR_WRITE_ENABLE_A; } m_hWriteAlphaBS = pRenderContext->FindOrCreateBlendState( &bd );
for ( int i=0; i<4; ++i ) { bd.m_bBlendEnable[i] = false; bd.m_srcBlend[i] = RS_BLEND_MODE_ZERO; bd.m_destBlend[i] = RS_BLEND_MODE_SRC_COLOR; bd.m_blendOp[i] = RS_BLEND_OP_ADD; bd.m_nRenderTargetWriteMask[i] = RS_COLOR_WRITE_ENABLE_ALL; } m_hWriteAllBS = pRenderContext->FindOrCreateBlendState( &bd );
RsDepthStencilStateDesc_t dsDesc; dsDesc.m_bDepthTestEnable = true; dsDesc.m_bDepthWriteEnable = false; dsDesc.m_depthFunc = RS_CMP_LESS_EQUAL; dsDesc.m_hiZEnable360 = RS_HI_Z_AUTOMATIC; dsDesc.m_hiZWriteEnable360 = RS_HI_Z_AUTOMATIC;
dsDesc.m_bStencilEnable = true; dsDesc.m_nStencilReadMask = 0xFF; dsDesc.m_nStencilWriteMask = 0xFF;
dsDesc.m_frontStencilFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_frontStencilDepthFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_frontStencilPassOp = RS_STENCIL_OP_KEEP; dsDesc.m_frontStencilFunc = RS_CMP_EQUAL;
dsDesc.m_backStencilFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_backStencilDepthFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_backStencilPassOp = RS_STENCIL_OP_KEEP; dsDesc.m_backStencilFunc = RS_CMP_EQUAL;
dsDesc.m_bHiStencilEnable360 = false; dsDesc.m_bHiStencilWriteEnable360 = false; dsDesc.m_hiStencilFunc360 = RS_HI_STENCIL_CMP_EQUAL; dsDesc.m_nHiStencilRef360 = 0;
m_hZTestAndStencilTestDS = pRenderContext->FindOrCreateDepthStencilState( &dsDesc );
dsDesc.m_bDepthTestEnable = false; dsDesc.m_bDepthWriteEnable = false; m_hStencilTestDS = pRenderContext->FindOrCreateDepthStencilState( &dsDesc );
dsDesc.m_bDepthTestEnable = true; dsDesc.m_bDepthWriteEnable = true;
dsDesc.m_frontStencilFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_frontStencilDepthFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_frontStencilPassOp = RS_STENCIL_OP_REPLACE; dsDesc.m_frontStencilFunc = RS_CMP_ALWAYS;
dsDesc.m_backStencilFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_backStencilDepthFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_backStencilPassOp = RS_STENCIL_OP_REPLACE; dsDesc.m_backStencilFunc = RS_CMP_ALWAYS;
m_hSetStencilDS = pRenderContext->FindOrCreateDepthStencilState( &dsDesc );
//
dsDesc.m_bDepthTestEnable = true; dsDesc.m_bDepthWriteEnable = true; dsDesc.m_depthFunc = RS_CMP_ALWAYS; dsDesc.m_hiZEnable360 = RS_HI_Z_AUTOMATIC; dsDesc.m_hiZWriteEnable360 = RS_HI_Z_AUTOMATIC;
dsDesc.m_bStencilEnable = false; dsDesc.m_nStencilReadMask = 0xFF; dsDesc.m_nStencilWriteMask = 0xFF;
dsDesc.m_frontStencilFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_frontStencilDepthFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_frontStencilPassOp = RS_STENCIL_OP_KEEP; dsDesc.m_frontStencilFunc = RS_CMP_EQUAL;
dsDesc.m_backStencilFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_backStencilDepthFailOp = RS_STENCIL_OP_KEEP; dsDesc.m_backStencilPassOp = RS_STENCIL_OP_KEEP; dsDesc.m_backStencilFunc = RS_CMP_EQUAL;
dsDesc.m_bHiStencilEnable360 = false; dsDesc.m_bHiStencilWriteEnable360 = false;
m_hZWriteNoTestDS = pRenderContext->FindOrCreateDepthStencilState( &dsDesc );
m_bDeferredInit = true; }
void CWorldRendererTest::InitParticleData() { CRenderContextPtr pRenderContext( g_pRenderDevice );
struct ParticleVertex_t { Vector m_vPos; };
static RenderInputLayoutField_t pointLightLayout[] = { DEFINE_PER_VERTEX_FIELD( 0, "position", 0, ParticleVertex_t, m_vPos ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 0, PerParticleData_t, m_vPosRadius ) DEFINE_PER_INSTANCE_FIELD( 1, 1, "texcoord", 1, PerParticleData_t, m_vColor ) }; m_hPointLightLayout = g_pRenderDevice->CreateInputLayout( "pointlight", ARRAYSIZE( pointLightLayout ), pointLightLayout );
const char *pVertexShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_VERTEX_SHADER); const char *pPixelShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_PIXEL_SHADER ); for ( int i=0; i<5; ++i ) { char pBuffer[100]; Q_snprintf( pBuffer, 100, "#define SHADER_VARIATION %d\n", i ); m_hPointLightVS[i] = GetVertexShader( "maps/pointlightvs", g_pRenderDevice, pVertexShaderVersion, pBuffer ); m_hPointLightPS[i] = GetPixelShader( "maps/pointlightps", g_pRenderDevice, pPixelShaderVersion, pBuffer ); } }
void CWorldRendererTest::InitRenderableData() { CRenderContextPtr pRenderContext( g_pRenderDevice );
// Load the simple shaders for dynamic renderables
const char *pVertexShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_VERTEX_SHADER); const char *pPixelShaderVersion = g_pRenderDevice->GetShaderVersionString( RENDER_PIXEL_SHADER ); for ( int i=0; i<4; ++i ) { char pBuffer[100]; Q_snprintf( pBuffer, 100, "#define SHADER_VARIATION %d\n#define g_flPhongExp 10\n#define g_flPhongBoost 1.5\n", i ); m_hSimpleMeshVS[i] = GetVertexShader( "maps/meshsimplevs", g_pRenderDevice, pVertexShaderVersion, pBuffer ); m_hSimpleMeshPS[i] = GetPixelShader( "maps/meshsimpleps", g_pRenderDevice, pPixelShaderVersion, pBuffer ); }
// Load the minigun
HRenderable hRenderable = g_pMeshSystem->FindOrCreateFileRenderable( g_pRenderableList[ 0 ] ); int index = m_dynRenderableList.AddToTail();
m_dynRenderableList[ index ].m_hRenderable = hRenderable; m_dynRenderableList[ index ].m_vOrigin.Init( 0, 0, 0 ); m_dynRenderableList[ index ].m_mWorld.Identity(); }
void CWorldRendererTest::UpdateFrustum( int nWidth, int nHeight ) { // Build up a frustum
if ( nWidth == m_nLastFrustumWidth && nHeight == m_nLastFrustumHeight ) return;
m_nLastFrustumWidth = nWidth; m_nLastFrustumHeight = nHeight;
float flAspect = nWidth / (float)nHeight; m_pFrustum->SetAspect( flAspect ); m_pFrustum->SetFOV( CalcFovX(90.0f, flAspect) ); m_pFrustum->UpdateFrustumFromCamera(); }
void CWorldRendererTest::RenderScreenQuad( IRenderContext *pRenderContext, Vector *pEyeRays, const char *pDebugName ) { CDynamicVertexData<QuadVertex_t> vb( pRenderContext, 4, pDebugName, "screenquad" ); vb.Lock( ); vb->m_vPos = Vector( -1, -1, 0.5f ); vb->m_vEyeRay = pEyeRays[0]; vb.AdvanceVertex();
vb->m_vPos = Vector( 1, -1, 0.5f ); vb->m_vEyeRay = pEyeRays[1]; vb.AdvanceVertex();
vb->m_vPos = Vector( -1, 1, 0.5f ); vb->m_vEyeRay = pEyeRays[2]; vb.AdvanceVertex();
vb->m_vPos = Vector( 1, 1, 0.5f ); vb->m_vEyeRay = pEyeRays[3]; vb.AdvanceVertex(); vb.Unlock(); vb.Bind( 0, 0 );
pRenderContext->Draw( RENDER_PRIM_TRIANGLE_STRIP, 0, 4 ); }
void CWorldRendererTest::RenderFrame( const RenderViewport_t &viewport, PlatWindow_t hWnd ) { if ( !m_bRenderTargetsInit ) { InitRenderTargetsAndViews( viewport ); }
if ( !m_bDeferredInit ) { InitDeferredData( viewport ); }
if ( m_nReportLevel == 1 ) { g_VProfCurrentProfile.Reset(); g_VProfCurrentProfile.ResetPeaks(); g_VProfCurrentProfile.Start(); m_nReportLevel++; Msg("VPROF Trace Begin\n"); }
RenderFrame_Internal( viewport );
if ( m_nReportLevel == 3 ) { g_VProfCurrentProfile.Stop(); g_VProfCurrentProfile.OutputReport( VPRT_FULL & ~VPRT_HIERARCHY, NULL ); Msg("VPROF Trace Complete\n"); m_nReportLevel = 0; } else if ( m_nReportLevel ) { g_VProfCurrentProfile.MarkFrame(); } }
void CWorldRendererTest::CullRenderablesAgainstView( CRenderView &renderView, CUtlVector<CStaticMeshRenderable> &renderableList, CUtlVector<CDynamicRenderable> &dynList ) { if ( !renderView.IsValid() ) return;
RenderViewFlags_t nFlags = renderView.GetViewFlags(); if ( !( nFlags & ( VIEW_PLAYER_CAMERA | VIEW_LIGHT_SHADOW | VIEW_REFLECTION ) ) ) return;
if ( nFlags & ( VIEW_POST_PROCESS | VIEW_LIGHTING | VIEW_DECALS ) ) return;
CWorldRenderFrustum *pFrustum = renderView.GetFrustum(); if( !pFrustum ) return;
if ( m_bDropFrustum && pFrustum == m_pFrustum ) pFrustum = m_pDropFrustum;
// Static
int nRenderables = renderableList.Count(); for ( int r=0; r<nRenderables; ++r ) { CStaticMeshRenderable &renderable = renderableList[ r ]; IBVHNode *pNode = renderable.m_pNode; Vector vOriginShift = pNode->GetOrigin().m_vLocal; CBVHDrawCall *pDraw = renderable.m_pDrawCall;
if ( pDraw->m_Flags & DRAW_CULL ) { if ( !pFrustum->BoundingVolumeIntersectsFrustum( pDraw->m_Bounds, vOriginShift ) ) { continue; } }
// Add a renderable
renderView.AddStaticMeshRenderable( &renderable ); }
// Dynamic
nRenderables = dynList.Count(); for ( int r=0; r<nRenderables; ++r ) { CDynamicRenderable &renderable = dynList[ r ]; if ( !g_pMeshSystem->RenderableIntersectsFrustum( renderable.m_hRenderable, pFrustum, -renderable.m_vOrigin ) ) continue;
// Add a renderable
renderView.AddDynamicRenderable( &renderable ); } }
void CWorldRendererTest::SetupMultiShadowMatrices( int nViewportStart, int nSqrtNumShadows, float flBias ) { int nGutterSize = 4; if ( nViewportStart > 0 ) nGutterSize = 2;
float flScale = ( 0.5f / nSqrtNumShadows ) - ( nGutterSize / (float)m_nShadowSize ); int nMultiShadowSize = m_nShadowSize / nSqrtNumShadows; int nTop = 0; int nViewport = nViewportStart;
float frange = 1.0f; if ( IsPlatformX360() ) { frange = -1.0f; flBias = flBias * frange; }
for ( int t=0; t<nSqrtNumShadows; ++t ) { int nLeft = 0; for( int s=0; s<nSqrtNumShadows; ++s ) { int nGutteredLeft = nLeft + nGutterSize; int nGutteredTop = nTop + nGutterSize; int nGutteredMultiShadowedSize = nMultiShadowSize - nGutterSize * 2; m_multiShadowViewport[ nViewport ].Init( nGutteredLeft, nGutteredTop, nGutteredMultiShadowedSize, nGutteredMultiShadowedSize, 0, 1.0f );
float fBiasVal = flBias; if ( IsPlatformX360() ) { fBiasVal = 1.0f - flBias; }
float flShiftX = flScale + ( nGutteredLeft + 0.5f ) / m_nShadowSize; float flShiftY = flScale + ( nGutteredTop + 0.5f ) / m_nShadowSize;
VMatrix texScaleBiasMat( flScale, 0.0f, 0.0f, 0.0f, 0.0f, -flScale, 0.0f, 0.0f, 0.0f, 0.0f, frange, 0.0f, flShiftX, flShiftY, fBiasVal, 1.0f );
m_multiShadowScaleBiasMatrices[ nViewport ] = texScaleBiasMat;
nViewport++; nLeft += nMultiShadowSize; } nTop += nMultiShadowSize; } }
void CWorldRendererTest::SetupShadowMatrices() { // Multiple shadow viewports
float fOffsetX = 0.5f + (0.5f / (float)m_nShadowSize); float fOffsetY = 0.5f + (0.5f / (float)m_nShadowSize); float frange = 1.0f; float fBias = -0.001f * frange; if ( IsPlatformX360() ) { frange = -1.0f; fBias = 0.005f * frange; }
for ( int s=0; s<NUM_SHADOW_SPLITS; ++s ) { //set special texture matrix for shadow mapping
float fBiasVal = fBias; if ( IsPlatformX360() ) { fBiasVal = 1.0f - fBias; }
VMatrix texScaleBiasMat( 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f, 0.0f, 0.0f, 0.0f, 0.0f, frange, 0.0f, fOffsetX, fOffsetY, fBiasVal, 1.0f ); m_splitScaleBiasMatrices[ s ] = texScaleBiasMat;
fBias *= 1.5f; }
SetupMultiShadowMatrices( 0, SQRT_NUM_HIGH_RES_SHADOWS, -0.001f ); if ( SQRT_NUM_LOW_RES_SHADOWS ) { SetupMultiShadowMatrices( NUM_HIGH_RES_SHADOWS, SQRT_NUM_LOW_RES_SHADOWS, -0.003f ); } }
int SortSpotLights( const CSpotLightRenderable *pOne, const CSpotLightRenderable *pTwo ) { if ( pOne->m_flSquaredDistToEye < pTwo->m_flSquaredDistToEye ) return -1; else if ( pOne->m_flSquaredDistToEye > pTwo->m_flSquaredDistToEye ) return 1; return 0; }
void CWorldRendererTest::GenerateRenderables( Vector &vCameraPos ) { // Figure out where we are and if we're interior or not
int nLeafNode = m_pWorldRenderer->GetLeafNodeForPoint( vCameraPos ); bool bCanSeeSky = true; if ( nLeafNode != -1 ) { IBVHNode *pNode = m_pWorldRenderer->GetNode( nLeafNode ); int nFlags = pNode->GetFlags(); bCanSeeSky = ( nFlags & NODE_CAN_SEE_SKY ) != 0; }
// Clear renderables
m_renderList.SetCountNonDestructively( 0 ); m_renderableList.SetCountNonDestructively( 0 ); m_interiorPointLights.SetCountNonDestructively( 0 ); m_exteriorPointLights.SetCountNonDestructively( 0 ); m_interiorSpotLights.SetCountNonDestructively( 0 ); m_exteriorSpotLights.SetCountNonDestructively( 0 ); m_interiorHemiLights.SetCountNonDestructively( 0 ); m_exteriorHemiLights.SetCountNonDestructively( 0 ); m_shadowedSpotLights.SetCountNonDestructively( 0 );
// Clear far plane
m_flMaxLightEncompassingFarPlane = 0.0f;
// Build the render list for this view
BVHNodeFlags_t nSkipFlags = (BVHNodeFlags_t)0x0; if ( bCanSeeSky == false ) nSkipFlags = NODE_CAN_SEE_SKY;
float flLODScale = 1.0f; if ( IsPlatformX360() ) { flLODScale = 0.5f; } float flElapsedTime = 0.0f; m_pWorldRenderer->BuildRenderList( &m_renderList, nSkipFlags, vCameraPos, flLODScale, m_pFrustum->GetFarPlane(), flElapsedTime, m_nCurrentFrameNumber );
// Distance sort render traversals
m_pWorldRenderer->SortRenderList( &m_renderList, vCameraPos );
//Create node requests and dispatch them to the async filesystem
// This can cause eviction of resources.
m_pWorldRenderer->CreateAndDispatchLoadRequests( g_pRenderDevice, m_pFrustum->GetCameraPosition() );
// Create renderables from each draw call encountered
int nNodes = m_renderList.Count(); for ( int n=0; n<nNodes; ++n ) { IBVHNode *pNode = m_renderList[ n ]; Vector vOriginShift = pNode->GetOrigin().m_vLocal;
// Gross cull of the bounds before turning them into renderables
AABB_t bounds = pNode->GetBounds(); if ( !m_pFrustum->BoundingVolumeIntersectsFrustum( bounds, vOriginShift ) ) continue;
// Draw calls
int nDraws = pNode->GetNumDrawCalls(); for ( int d=0; d<nDraws; ++d ) { CBVHDrawCall &draw = pNode->GetDrawCall( d );
CStaticMeshRenderable renderable; renderable.m_pNode = pNode; renderable.m_pDrawCall = &draw; m_renderableList.AddToTail( renderable ); }
// Point Lights
GeneratePointLightRenderables( pNode, vOriginShift, m_pFrustum, vCameraPos );
// Spot lights
GenerateSpotLightRenderables( pNode, vOriginShift, m_pFrustum, vCameraPos );
// Hemi lights
GenerateHemiLightRenderables( pNode, vOriginShift, m_pFrustum, vCameraPos ); }
if ( m_bFlashlight ) { CSpotLightRenderable renderable; renderable.m_vOrigin.Init( 0, 0, 0 ); renderable.m_pLight = &m_flashlight; renderable.m_bValid = true; renderable.m_flSquaredDistToEye = 0.0f;
// We're outside the light
renderable.m_bInterior = false; m_shadowedSpotLights.AddToTail( renderable ); }
// We've been storing squared distance, but we want linear distance
m_flMaxLightEncompassingFarPlane = sqrtf( m_flMaxLightEncompassingFarPlane );
// Sort spot lights and set the NUM_MULTI_SHADOWS closest as shadow casting
m_shadowedSpotLights.Sort( SortSpotLights ); /*
// Artificially limit shadows past a certain point
int nShadows = 0; for ( int s=0; s<m_shadowedSpotLights.Count(); ++s ) { if ( m_shadowedSpotLights[ s ].m_flSquaredDistToEye > MAX_LIGHT_DISTANCE * MAX_LIGHT_DISTANCE ) { break; }
nShadows++; }*/ int nShadows = m_shadowedSpotLights.Count();
nShadows = MIN( nShadows, NUM_MULTI_SHADOWS ); m_shadowedSpotLights.SetCountNonDestructively( nShadows );
for ( int s=0; s<nShadows; ++s ) { int index = m_exteriorSpotLights.Find( m_shadowedSpotLights[s] ); if ( index != -1 ) { m_exteriorSpotLights.FastRemove( index ); }
index = m_interiorSpotLights.Find( m_shadowedSpotLights[s] ); if ( index != -1 ) { m_interiorSpotLights.FastRemove( index ); } } }
void CWorldRendererTest::GeneratePointLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye ) { float flNearPlane = pFrustum->GetNearPlane(); int nLights = pNode->GetNumPointLights(); PointLightData_t *pPointLights = pNode->GetPointLights();
for ( int i=0; i<nLights; ++i ) { float flRadius = pPointLights[i].m_vColorNRadius.w;
AABB_t bounds; Vector vLightOrigin = pPointLights[i].m_vOrigin; bounds.m_vMinBounds = vLightOrigin - Vector( flRadius, flRadius, flRadius ); bounds.m_vMaxBounds = vLightOrigin + Vector( flRadius, flRadius, flRadius );
if ( pFrustum->BoundingVolumeIntersectsFrustum( bounds, vOrigin ) ) { CPointLightRenderable renderable; renderable.m_vOrigin = vOrigin; renderable.m_pLight = &pPointLights[i];
Vector vNewOrigin = vLightOrigin - vOrigin; Vector vDelta = vEye - vNewOrigin; float flSquaredDist = DotProduct( vDelta, vDelta ); float flTargetRad = flRadius * 1.2f + flNearPlane; if ( DotProduct( vDelta, vDelta ) < flTargetRad * flTargetRad ) { // We're inside the light
m_interiorPointLights.AddToTail( renderable ); } else { // We're outside the light
m_exteriorPointLights.AddToTail( renderable ); }
m_flMaxLightEncompassingFarPlane = MAX( m_flMaxLightEncompassingFarPlane, flSquaredDist + flTargetRad * flTargetRad ); } } }
void CWorldRendererTest::GenerateSpotLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye ) { float flNearPlane = pFrustum->GetNearPlane(); Vector vForward = pFrustum->Forward(); Vector vFarEye = vEye + flNearPlane * vForward * 1.2f; int nLights = pNode->GetNumSpotLights(); SpotLightData_t *pSpotLights = pNode->GetSpotLights();
for ( int i=0; i<nLights; ++i ) { float flRadius = pSpotLights[i].m_vColorNRadius.w; float flTargetRad = flRadius * 1.2f + 500.0f + flNearPlane; Vector vLightOrigin = Vector( pSpotLights[i].m_vTransform0.w, pSpotLights[i].m_vTransform1.w, pSpotLights[i].m_vTransform2.w );
AABB_t bounds; bounds.m_vMinBounds = vLightOrigin - Vector( flTargetRad, flTargetRad, flTargetRad ); bounds.m_vMaxBounds = vLightOrigin + Vector( flTargetRad, flTargetRad, flTargetRad );
if ( pFrustum->BoundingVolumeIntersectsFrustum( bounds, vOrigin ) ) { CSpotLightRenderable renderable; renderable.m_vOrigin = vOrigin; renderable.m_pLight = &pSpotLights[i]; renderable.m_bValid = true;
Vector vNewOrigin = vLightOrigin - vOrigin; Vector vDelta = vEye - vNewOrigin; Vector vLightDir = Vector( pSpotLights[i].m_vTransform0.z, pSpotLights[i].m_vTransform1.z, pSpotLights[i].m_vTransform2.z );
float flSquaredDist = DotProduct( vDelta, vDelta ); renderable.m_flSquaredDistToEye = flSquaredDist;
//if ( flRadius > 3000.0f )
// renderable.m_flSquaredDistToEye = FLT_MAX;
Vector vToLightFar = vFarEye - vNewOrigin; Vector vToLightNear = vEye - vNewOrigin; vToLightFar.NormalizeInPlace(); vToLightNear.NormalizeInPlace(); float flDotFar = DotProduct( vToLightFar, vLightDir ); float flDotNear = DotProduct( vToLightNear, vLightDir ); float flCosAngle = pSpotLights[i].m_vAttenuationNCosSpot.w * 0.85f;
bool bInCone = ( flDotFar > flCosAngle || flDotNear > flCosAngle ); if ( flSquaredDist < flTargetRad * flTargetRad && bInCone ) { // We're inside the light
renderable.m_bInterior = true; m_interiorSpotLights.AddToTail( renderable ); } else { // We're outside the light
renderable.m_bInterior = false; m_exteriorSpotLights.AddToTail( renderable ); }
m_shadowedSpotLights.AddToTail( renderable );
m_flMaxLightEncompassingFarPlane = MAX( m_flMaxLightEncompassingFarPlane, flSquaredDist + flTargetRad * flTargetRad + 4000 * 4000 ); } } }
void CWorldRendererTest::GenerateHemiLightRenderables( IBVHNode *pNode, Vector &vOrigin, CFrustum *pFrustum, Vector &vEye ) { float flNearPlane = pFrustum->GetNearPlane(); Vector vForward = pFrustum->Forward(); Vector vFarEye = vEye + flNearPlane * vForward * 1.1f; int nLights = pNode->GetNumHemiLights(); HemiLightData_t *pHemiLights = pNode->GetHemiLights();
for ( int i=0; i<nLights; ++i ) { float flRadius = pHemiLights[i].m_vColorNRadius.w; Vector vLightOrigin = Vector( pHemiLights[i].m_vTransform0.w, pHemiLights[i].m_vTransform1.w, pHemiLights[i].m_vTransform2.w ); AABB_t bounds; bounds.m_vMinBounds = vLightOrigin - Vector( flRadius, flRadius, flRadius ); bounds.m_vMaxBounds = vLightOrigin + Vector( flRadius, flRadius, flRadius );
if ( pFrustum->BoundingVolumeIntersectsFrustum( bounds, vOrigin ) ) { CHemiLightRenderable renderable; renderable.m_vOrigin = vOrigin; renderable.m_pLight = &pHemiLights[i];
Vector vNewOrigin = vLightOrigin - vOrigin; Vector vDelta = vEye - vNewOrigin; float flSquaredDist = DotProduct( vDelta, vDelta ); Vector vLightDir = Vector( pHemiLights[i].m_vTransform0.z, pHemiLights[i].m_vTransform1.z, pHemiLights[i].m_vTransform2.z ); float flTargetRad = flRadius * 1.2f + flNearPlane;
Vector vToLightFar = vFarEye - vNewOrigin; Vector vToLightNear = vEye - vNewOrigin; vToLightFar.NormalizeInPlace(); vToLightNear.NormalizeInPlace(); float flDotFar = DotProduct( vToLightFar, vLightDir ); float flDotNear = DotProduct( vToLightNear, vLightDir ); float flCosAngle = 0.0f;
bool bInHemi = ( flDotFar > flCosAngle || flDotNear > flCosAngle ); if ( DotProduct( vDelta, vDelta ) < flTargetRad * flTargetRad && bInHemi ) { // We're inside the light
m_interiorHemiLights.AddToTail( renderable ); } else { // We're outside the light
m_exteriorHemiLights.AddToTail( renderable ); }
m_flMaxLightEncompassingFarPlane = MAX( m_flMaxLightEncompassingFarPlane, flSquaredDist + flTargetRad * flTargetRad ); } } }
void CWorldRendererTest::RenderViewStatic( CRenderView *pRenderView, int nStart, int nCount, int nIndex ) { CRenderContextPtr pRenderContext( g_pRenderDevice ); pRenderView->BeginRender( pRenderContext );
SetStateForRenderViewType( pRenderContext, pRenderView->GetViewType() );
int nRenderPass = pRenderView->GetRenderPass(); CWorldRenderFrustum *pFrustum = pRenderView->GetFrustum(); CUtlVector< CStaticMeshRenderable* > &renderableList = pRenderView->GetRenderableList();
// Set commonly used constants
ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( pFrustum );
if ( nRenderPass == VARIATION_SAMPLE_LIGHTING ) { pRenderContext->SetConstantBufferData( m_hLightBufferData, (void*)&m_lightBufferData, sizeof( LightBufferData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hLightBufferData, 0, 0 ); }
if ( m_bViewLowTexture && nRenderPass == VARIATION_SAMPLE_LIGHTING ) { nRenderPass = VARIATION_SAMPLE_LIGHTING_LOW_TEXTURE; }
// Render the nodes
Vector vLastOrigin = Vector(0,0,0); bool bFirst = true; bool bSunDepth = false; if ( nRenderPass == VARIATION_DEPTH && pRenderView->GetViewType() < RTB_SHADOW_DEPTH_MULTIPLE_0 ) bSunDepth = true; bool bSetStencil = false; if ( nRenderPass == VARIATION_NORM_DEPTH_SPEC ) bSetStencil = true;
for ( int r=0; r<nCount; ++r ) { CStaticMeshRenderable *pRenderable = renderableList[ nStart + r ];
IBVHNode *pNode = pRenderable->m_pNode; AABB_t bounds = pNode->GetBounds(); Vector vOrigin = pNode->GetOrigin().m_vLocal; int nFlags = pNode->GetFlags(); bool bCanSeeSky = ( nFlags & NODE_CAN_SEE_SKY ) != 0;
// Don't render depth for sun shadow maps if we can't see the sky
if ( bSunDepth && !bCanSeeSky ) continue;
if ( ( vLastOrigin != vOrigin ) || bFirst ) { VMatrix mViewRelated = viewConstants.m_mViewProjection;
VMatrix mTrans; mTrans.Identity(); mTrans.SetTranslation( -vOrigin ); mViewRelated = mTrans.Transpose() * mViewRelated;
ViewRelatedConstants_t newViewConstants = viewConstants; newViewConstants.m_mViewProjection = mViewRelated; newViewConstants.m_vEyePt.x += vOrigin.x; newViewConstants.m_vEyePt.y += vOrigin.y; newViewConstants.m_vEyePt.z += vOrigin.z;
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&newViewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 ); vLastOrigin = vOrigin; bFirst = false; }
if ( bSetStencil ) { if ( bCanSeeSky ) { pRenderContext->SetDepthStencilState( m_hSetStencilDS, g_nCanSeeSkyStencilRef ); } else { pRenderContext->SetDepthStencilState( m_hSetStencilDS, g_nCannotSeeSkyStencilRef ); } }
pNode->Draw( pRenderContext, pRenderable->m_pDrawCall, m_pResourceDictionary, (ShaderComboVariation_t)nRenderPass, m_hSingleMatrixRelated ); }
pRenderView->EndRender( pRenderContext, false ); }
void CWorldRendererTest::RenderViewDynamic( CRenderView *pRenderView, int nStart, int nCount, int nIndex ) { CRenderContextPtr pRenderContext( g_pRenderDevice ); pRenderView->BeginRender( pRenderContext );
// Get view constants
CWorldRenderFrustum *pFrustum = pRenderView->GetFrustum(); ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( pFrustum );
// Init material data
RenderMaterialData_t &materialData = pRenderContext->GetMaterialData(); materialData.Init(); materialData.flTime = Plat_FloatTime(); materialData.mVP = viewConstants.m_mViewProjection; materialData.mWVP = viewConstants.m_mViewProjection; materialData.vCameraPosition = viewConstants.m_vEyePt.AsVector3D(); materialData.vCameraForwardVec = viewConstants.m_vEyeDir.AsVector3D().Normalized(); materialData.flFarPlane = viewConstants.m_flFarPlane.x; materialData.vViewportSize[0] = 1.0f / m_lightBufferData.m_vInvScreenExtents.x; materialData.vViewportSize[1] = 1.0f / m_lightBufferData.m_vInvScreenExtents.y;
materialData.customTextures[0] = m_pRenderTargets[ RT_LIGHTING_HIGHRES ]; materialData.customTextures[1] = m_pRenderTargets[ RT_SPECULAR_HIGHRES ];
int nRenderPass = pRenderView->GetRenderPass(); if ( nRenderPass == VARIATION_DEPTH ) { materialData.nMode = MODE_DEPTH; } else if ( nRenderPass == VARIATION_NORM_DEPTH_SPEC ) { materialData.nMode = MODE_NORMAL_DEPTH_SPEC; } else if ( nRenderPass == VARIATION_SAMPLE_LIGHTING ) { materialData.nMode = MODE_DEFERRED_GATHER; } else { materialData.nMode = MODE_FORWARD; }
// Sun and stencil bools
bool bSunDepth = false; if ( ( nRenderPass == VARIATION_DEPTH ) && ( pRenderView->GetViewType() < RTB_SHADOW_DEPTH_MULTIPLE_0 ) ) { bSunDepth = true; }
bool bSetStencil = false; if ( nRenderPass == VARIATION_NORM_DEPTH_SPEC ) { bSetStencil = true; }
// Render the nodes
CUtlVector< CDynamicRenderable * > &renderableList = pRenderView->GetDynamicList(); for ( int r = 0; r < nCount; r++ ) { CDynamicRenderable *pRenderable = renderableList[ nStart + r ];
// Copy world matrix into material data
memcpy( materialData.mWorldArray[0], &( pRenderable->m_mWorld.m[0] ), sizeof( pRenderable->m_mWorld ) );
RenderDynamic( pRenderContext, pRenderable, ( ShaderComboVariation_t )nRenderPass, bSunDepth, bSetStencil ); }
pRenderView->EndRender( pRenderContext, false ); }
void CWorldRendererTest::RenderView( CRenderView &renderView ) { if ( m_bMultiThreaded ) { CUtlVector< CStaticMeshRenderable* > &renderableList = renderView.GetRenderableList(); CUtlVector< CDynamicRenderable* > &dynList = renderView.GetDynamicList(); int nRenderablesStatic = renderableList.Count(); int nRenderablesDynamic = dynList.Count(); int nCountStatic = nRenderablesStatic / m_nRenderThreads; int nCountDynamic = nRenderablesDynamic / m_nRenderThreads; int nTotalRenderablesStatic = 0; int nTotalRenderablesDynamic = 0; for ( int t=0; t<m_nRenderThreads; ++t ) { m_pRenderJobs[ t ].m_pRenderView = &renderView; m_pRenderJobs[ t ].m_nStartStatic = nTotalRenderablesStatic; m_pRenderJobs[ t ].m_nCountStatic = nCountStatic; m_pRenderJobs[ t ].m_nStartDynamic = nTotalRenderablesDynamic; m_pRenderJobs[ t ].m_nCountDynamic = nCountDynamic;
m_pRenderJobs[ t ].m_pTestApp = this; m_pRenderJobs[ t ].m_nIndex = t; nTotalRenderablesStatic += nCountStatic; nTotalRenderablesDynamic += nCountDynamic; } m_pRenderJobs[ m_nRenderThreads - 1 ].m_nCountStatic = nRenderablesStatic - m_pRenderJobs[ m_nRenderThreads - 1 ].m_nStartStatic; m_pRenderJobs[ m_nRenderThreads - 1 ].m_nCountDynamic = nRenderablesDynamic - m_pRenderJobs[ m_nRenderThreads - 1 ].m_nStartDynamic;
ParallelProcess( m_pRenderJobs, m_nRenderThreads, PerformStaticMeshWorkUnit ); } else { RenderViewStatic( &renderView, 0, renderView.GetRenderableList().Count(), 0 ); RenderViewDynamic( &renderView, 0, renderView.GetDynamicList().Count(), 0 ); } }
void CWorldRendererTest::UpdateShadowData() { for ( int s=0; s<m_nShadowSplits; ++s ) { VMatrix mLightRelated; mLightRelated = m_pSplitFrustums[s]->GetViewProj(); m_pShadowMatrices[s] = mLightRelated * m_splitScaleBiasMatrices[ s ]; m_forwardLightingData.m_mShadowMatrices[s] = m_pShadowMatrices[s]; }
for ( int s=0; s<NUM_MULTI_SHADOWS; ++s ) { m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].SetValid( false ); }
for ( int s=0; s<m_shadowedSpotLights.Count(); ++s ) { CSpotLightRenderable &renderable = m_shadowedSpotLights[s]; Vector vOrigin = Vector( renderable.m_pLight->m_vTransform0.w, renderable.m_pLight->m_vTransform1.w, renderable.m_pLight->m_vTransform2.w ); vOrigin -= renderable.m_vOrigin; Vector vDirection = Vector( renderable.m_pLight->m_vTransform0.z, renderable.m_pLight->m_vTransform1.z, renderable.m_pLight->m_vTransform2.z ); Vector vUp = Vector( renderable.m_pLight->m_vTransform0.y, renderable.m_pLight->m_vTransform1.y, renderable.m_pLight->m_vTransform2.y );
vDirection.NormalizeInPlace(); vUp.NormalizeInPlace(); QAngle vAngles; VectorAngles( vDirection, vUp, vAngles );
float flRadius = renderable.m_pLight->m_vColorNRadius.w; float flFOV = RAD2DEG( acosf( renderable.m_pLight->m_vAttenuationNCosSpot.w ) * 2 );
m_pMultiShadowFrustums[ s ]->InitCamera( vOrigin, vAngles, 20.0f, flRadius + 500.0f, flFOV, 1.0f ); m_pMultiShadowFrustums[ s ]->UpdateFrustumFromCamera();
VMatrix mLightRelated = m_pMultiShadowFrustums[ s ]->GetViewProj(); m_pMultiShadowMatrices[ s ] = mLightRelated * m_multiShadowScaleBiasMatrices[ s ];
m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].SetValid( true ); } }
void CWorldRendererTest::UpdateFlashlightData() { float flFlashlightLength = 1000.0f; float flSpotAngle = DEG2RAD( 45.0f ); Vector vColor( 1,1,0.8f ); vColor *= 100.0f; float flMax = 255.0f;
Vector vAttenuation; vAttenuation.x = 0; vAttenuation.y = flMax / flFlashlightLength; vAttenuation.z = 0; float flTan45 = tanf( M_PI / 4.0f ); float flScale = tanf( flSpotAngle ) / flTan45;
Vector vOrigin = m_pFrustum->GetCameraPosition(); Vector vDirection = m_pFrustum->Forward(); Vector vLeft = m_pFrustum->Left(); Vector vUp = m_pFrustum->Up();
vOrigin -= vUp * 15.0f; vOrigin += vLeft * 25;
Vector vRight = -vLeft; vRight *= flScale * flFlashlightLength; vUp *= flScale * flFlashlightLength; vDirection *= flFlashlightLength;
m_flashlight.m_vTransform0.Init( vRight.x, vUp.x, vDirection.x, vOrigin.x ); m_flashlight.m_vTransform1.Init( vRight.y, vUp.y, vDirection.y, vOrigin.y ); m_flashlight.m_vTransform2.Init( vRight.z, vUp.z, vDirection.z, vOrigin.z ); m_flashlight.m_vColorNRadius.Init( vColor.x, vColor.y, vColor.z, flFlashlightLength ); m_flashlight.m_vAttenuationNCosSpot.Init( vAttenuation.x, vAttenuation.y, vAttenuation.z, cosf( flSpotAngle ) ); }
void CWorldRendererTest::UpdateViewModelData() { if ( m_dynRenderableList.Count() < 1 ) return;
Vector vOrigin = m_pFrustum->GetCameraPosition(); Vector vDirection = m_pFrustum->Forward(); Vector vLeft = m_pFrustum->Left(); Vector vUp = m_pFrustum->Up();
vOrigin -= vUp * 15.0f; vOrigin -= vLeft * 25; vOrigin += vDirection * 30;
VMatrix mWorld; mWorld.Identity(); mWorld.SetForward( vDirection * 0.6f ); mWorld.SetLeft( vLeft ); mWorld.SetUp( vUp );
VMatrix mRot; Vector vAxis( 0, 0, 1 ); MatrixBuildRotationAboutAxis( mRot, vAxis, 90.0f ); vAxis.Init( 1, 0, 0 ); MatrixRotate( mRot, vAxis, 90.0f );
m_dynRenderableList[ 0 ].m_vOrigin = vOrigin; m_dynRenderableList[ 0 ].m_mWorld = mWorld * mRot; m_dynRenderableList[ 0 ].m_mWorld.SetTranslation( vOrigin ); }
void CWorldRendererTest::UpdateDroppedRenderables( float flElapsedTime ) { int nRenderables = m_dynRenderableList.Count(); for ( int i=1; i<nRenderables; ++i ) { Vector vAxis( 0, 1, 0 ); MatrixRotate( m_dynRenderableList[ i ].m_mWorld, vAxis, flElapsedTime * 60.0f ); m_dynRenderableList[ i ].m_mWorld.SetTranslation( m_dynRenderableList[ i ].m_vOrigin ); } }
void CWorldRendererTest::RenderShadowDepthBuffers( IRenderContext *pRenderContext ) { Vector4D vShadowClear(1,1,1,1);
VPROF_SCOPE_BEGIN("RenderSplitShadows"); for ( int s=0; s<m_nShadowSplits; ++s ) { m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ].Clear( pRenderContext, vShadowClear, RENDER_CLEAR_FLAGS_CLEAR_DEPTH );
if ( m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ].HasRenderables() ) { RenderView( m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ] );
// Render spheres
m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ].BeginRender( pRenderContext ); ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pSplitFrustums[s] ); pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetBlendMode( RENDER_BLEND_NOPIXELWRITE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
int nParticleSystems = m_sphereSystemList.Count(); for ( int p=0; p<nParticleSystems; ++p ) { RenderParticleLights( pRenderContext, m_sphereSystemList[p], VARIATION_DEPTH, true, false ); }
// Submit
m_pRenderViews[ RTB_SHADOW_DEPTH0 + s ].EndRender( pRenderContext ); } } VPROF_SCOPE_END(); VPROF_SCOPE_BEGIN("RenderMultiShadows"); for ( int s=0; s<m_shadowedSpotLights.Count(); ++s ) { if ( s == 0 ) { m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].BeginRender( pRenderContext );
pRenderContext->SetViewports( 1, &m_shadowViewport ); pRenderContext->Clear( vShadowClear, RENDER_CLEAR_FLAGS_CLEAR_DEPTH );
m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].EndRender( pRenderContext, false ); }
if ( s == NUM_HIGH_RES_SHADOWS ) { m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].BeginRender( pRenderContext );
pRenderContext->SetViewports( 1, &m_shadowViewport ); pRenderContext->Clear( vShadowClear, RENDER_CLEAR_FLAGS_CLEAR_DEPTH );
m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].EndRender( pRenderContext, false ); } if ( m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].HasRenderables() ) { RenderView( m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ] ); }
// Render spheres
m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].BeginRender( pRenderContext );
ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pMultiShadowFrustums[ s ] ); pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
int nParticleSystems = m_sphereSystemList.Count(); for ( int p=0; p<nParticleSystems; ++p ) { RenderParticleLights( pRenderContext, m_sphereSystemList[p], VARIATION_DEPTH, false, false ); }
// Submit
m_pRenderViews[ RTB_SHADOW_DEPTH_MULTIPLE_0 + s ].EndRender( pRenderContext ); } VPROF_SCOPE_END(); }
void CWorldRendererTest::RenderSunShadowFrustums( IRenderContext *pRenderContext ) { ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetBlendState( m_hAdditiveBS ); pRenderContext->SetDepthStencilState( m_hStencilTestDS, g_nCanSeeSkyStencilRef );
pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_NORMAL_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT );
if ( IsPlatformX360() ) { pRenderContext->BindTexture( 1, m_pRenderTargets[ DS_DEPTH_HIGHRES ] ); } else { pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] ); } pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT );
pRenderContext->BindTexture( 2, m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowFrustumPS[2] );
for ( int s=0; s<NUM_SHADOW_SPLITS; ++s ) { m_deferredLightingData.m_mShadowMatrix[s] = m_pShadowMatrices[s]; pRenderContext->BindTexture( 4 + s, m_pRenderTargets[ DS_SHADOW_DEPTH0 + s ] );
if ( g_nPlatform == RST_PLATFORM_DX11 ) { pRenderContext->SetSamplerStatePS( 4 + s, RS_FILTER_MIN_MAG_MIP_POINT ); } else { pRenderContext->SetSamplerStatePS( 4 + s, RS_FILTER_MIN_MAG_MIP_LINEAR ); } }
pRenderContext->SetConstantBufferData( m_hDeferredLightingRelated, (void*)&m_deferredLightingData, sizeof( DeferredLightingConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDeferredLightingRelated, 0, 0 );
RenderScreenQuad( pRenderContext, m_vEyeRays, "sunshadows" ); }
void CWorldRendererTest::RenderBouncedLight( IRenderContext *pRenderContext ) { ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
pRenderContext->SetBlendState( m_hAdditiveBS ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_NORMAL_LOWRES ] ); pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_lowResScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
RenderSceneHemiLights( pRenderContext, m_exteriorHemiLights, false ); RenderSceneHemiLights( pRenderContext, m_interiorHemiLights, true ); }
void CWorldRendererTest::RenderDirectLight( IRenderContext *pRenderContext ) { ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum ); pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
if ( IsPlatformX360() ) { pRenderContext->BindTexture( 1, m_pRenderTargets[ DS_DEPTH_HIGHRES ] ); } else { pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] ); } pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT );
pRenderContext->BindTexture( 2, m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
// Additive light phase
pRenderContext->SetBlendState( m_hAdditiveBS ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE_STENCIL_TEST_NOTEQUAL ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
int nParticleSystems = m_lightSystemList.Count(); for ( int p=0; p<nParticleSystems; ++p ) { RenderParticleLights( pRenderContext, m_lightSystemList[p], VARIATION_DEFAULT, false, false ); }
// Render scene lights
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
RenderScenePointLights( pRenderContext, m_exteriorPointLights, false ); RenderScenePointLights( pRenderContext, m_interiorPointLights, true ); RenderSceneSpotLights( pRenderContext, m_exteriorSpotLights, false ); RenderSceneSpotLights( pRenderContext, m_interiorSpotLights, true );
RenderShadowedSpotLights( pRenderContext, m_shadowedSpotLights ); }
void CWorldRendererTest::BlurLightBuffer( ) { CRenderContextPtr pRenderContext( g_pRenderDevice ); ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
// Bilat blur ( Horizontal )
{ m_pRenderViews[ RTB_LIGHT_BLUR_0 ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); //pRenderContext->SetBlendState( m_hWriteAllBS );
pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_LIGHTING_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&m_blurParams, sizeof( BlurParams_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hBilateralBlur[2] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "bilatblurhorz" );
// Submit
m_pRenderViews[ RTB_LIGHT_BLUR_0 ].EndRender( pRenderContext ); }
// Bilat upsampling ( Vertical )
{ m_pRenderViews[ RTB_LIGHT_BLUR_1 ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); //pRenderContext->SetBlendState( m_hWriteAllBS );
pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&m_blurParams, sizeof( BlurParams_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hBilateralBlur[3] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "bilatblurvert" );
// Submit
m_pRenderViews[ RTB_LIGHT_BLUR_1 ].EndRender( pRenderContext ); } }
void CWorldRendererTest::BlurShadowBuffers( ) { CRenderContextPtr pRenderContext( g_pRenderDevice ); ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
BlurParams_t highResBlurParams = m_blurParams; BlurParams_t lowResBlurParams = m_blurParams;
// High res shadow blur
{ // blur ( Horizontal )
{ m_pRenderViews[ RTB_SHADOW_BLUR_0 ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_shadowScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&highResBlurParams, sizeof( BlurParams_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowBlur[0] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "blurshadowshorz" );
// Submit
m_pRenderViews[ RTB_SHADOW_BLUR_0 ].EndRender( pRenderContext ); }
// blur ( Vertical )
{ m_pRenderViews[ RTB_SHADOW_BLUR_1 ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SHADOW_BLUR_TEMP ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_shadowScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&highResBlurParams, sizeof( BlurParams_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowBlur[1] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "blurshadowvert" );
// Submit
m_pRenderViews[ RTB_SHADOW_BLUR_1 ].EndRender( pRenderContext ); } }
// Low res shadow blur
{ // blur ( Horizontal )
{ m_pRenderViews[ RTB_SHADOW_BLUR_0 ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SHADOW_MULTIPLE_1 ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_shadowScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&lowResBlurParams, sizeof( BlurParams_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowBlur[2] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "blurshadowhorz2" );
// Submit
m_pRenderViews[ RTB_SHADOW_BLUR_0 ].EndRender( pRenderContext ); }
// blur ( Vertical )
{ m_pRenderViews[ RTB_SHADOW_BLUR_2 ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); pRenderContext->SetBlendMode( RENDER_BLEND_NONE );
pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SHADOW_BLUR_TEMP ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_shadowScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&lowResBlurParams, sizeof( BlurParams_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hShadowBlur[3] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "blurshadowvert2" );
// Submit
m_pRenderViews[ RTB_SHADOW_BLUR_2 ].EndRender( pRenderContext ); } } }
void CWorldRendererTest::RenderDecals( IRenderContext *pRenderContext, int nVariation ) { ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
// Paint Decals
if ( m_bFullBuffer2 || m_nGlobalDecalPos2 ) { pRenderContext->SetBlendMode( RENDER_BLEND_ALPHABLENDING );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
if ( nVariation == 0 ) { pRenderContext->BindTexture( 1, m_hDecalNormal2 ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); } else { pRenderContext->BindTexture( 1, m_hDecalAlbedo2 ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); }
pRenderContext->BindVertexBuffer( 1, 0, 0, 0 );
pRenderContext->BindVertexBuffer( 0, m_hDecalVB2, 0, sizeof( DecalVertex_t ) ); pRenderContext->BindIndexBuffer( m_hDecalIB, 0 ); pRenderContext->BindVertexShader( m_hDecalVS[ nVariation ], m_hDecalLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hDecalPS[ nVariation ] );
int nIndices = 0; if ( m_bFullBuffer2 ) { nIndices = m_nMaxDecals * 36; } else { nIndices = m_nGlobalDecalPos2 * 36; }
pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, nIndices ); }
// Bullet Decals
if ( m_bFullBuffer || m_nGlobalDecalPos ) { bool bDraw = true; pRenderContext->SetBlendMode( RENDER_BLEND_ALPHABLENDING );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
if ( nVariation == 0 ) { pRenderContext->BindTexture( 1, m_hDecalNormal ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); } else { if ( m_hDecalAlbedo == RENDER_TEXTURE_HANDLE_INVALID ) { bDraw = false; } else { pRenderContext->BindTexture( 1, m_hDecalAlbedo ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); } }
if ( bDraw ) { pRenderContext->BindVertexBuffer( 0, m_hDecalVB, 0, sizeof( DecalVertex_t ) ); pRenderContext->BindIndexBuffer( m_hDecalIB, 0 ); pRenderContext->BindVertexShader( m_hDecalVS[ nVariation ], m_hDecalLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hDecalPS[ nVariation ] );
int nIndices = 0; if ( m_bFullBuffer ) { nIndices = m_nMaxDecals * 36; } else { nIndices = m_nGlobalDecalPos * 36; }
pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, nIndices ); } }
// Wall monster decals
if ( m_nGlobalDecalPos3 ) { pRenderContext->SetBlendMode( RENDER_BLEND_ALPHABLENDING );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
if ( nVariation == 0 ) { pRenderContext->BindTexture( 1, m_hDecalNormal3[ m_nWallMonsterTexture ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindVertexBuffer( 0, m_hDecalVB3, 0, sizeof( DecalVertex_t ) ); pRenderContext->BindIndexBuffer( m_hDecalIB, 0 ); pRenderContext->BindVertexShader( m_hDecalVS[ nVariation ], m_hDecalLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hDecalPS[ nVariation ] );
int nIndices = 36; pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, nIndices ); } } }
void CWorldRendererTest::RenderDynamic( IRenderContext *pRenderContext, CDynamicRenderable *pRenderable, int nVariation, bool bSunDepth, bool bSetStencil ) { if ( bSunDepth ) { bool bCanSeeSky = true; int nLeafNode = m_pWorldRenderer->GetLeafNodeForPoint( pRenderable->m_vOrigin ); if ( nLeafNode > -1 ) { IBVHNode *pNode = m_pWorldRenderer->GetNode( nLeafNode ); if ( pNode ) { int nFlags = pNode->GetFlags(); bCanSeeSky = ( nFlags & NODE_CAN_SEE_SKY ) ? true : false; } } if ( !bCanSeeSky ) { return; } }
g_pMeshSystem->DrawRenderable( pRenderContext, pRenderable->m_hRenderable, m_hSimpleMeshVS[ nVariation ], m_hSimpleMeshPS[ nVariation ] ); }
void CWorldRendererTest::RenderParticleLights( IRenderContext *pRenderContext, CParticleCollection *pInputSystem, int nVariation, bool bSunDepth, bool bSetStencil ) { VPROF("RenderParticleLights");
Vector vCenter = pInputSystem->GetControlPointAtCurrentTime( 0 ); int nLeafNode = m_pWorldRenderer->GetLeafNodeForPoint( vCenter ); IBVHNode *pNode = m_pWorldRenderer->GetNode( nLeafNode ); int nFlags = pNode->GetFlags(); bool bCanSeeSky = ( nFlags & NODE_CAN_SEE_SKY ) != 0;
if ( bSunDepth && !bCanSeeSky ) return;
if ( bSetStencil ) { if ( bCanSeeSky ) { pRenderContext->SetDepthStencilState( m_hSetStencilDS, g_nCanSeeSkyStencilRef ); } else { pRenderContext->SetDepthStencilState( m_hSetStencilDS, g_nCannotSeeSkyStencilRef ); } }
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->BindVertexShader( m_hPointLightVS[nVariation], m_hPointLightLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hPointLightPS[nVariation] );
pRenderContext->BindVertexBuffer( 0, m_hSphereVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hSphereIB, 0 );
CDynamicVertexData<PerParticleData_t> vb( pRenderContext, pInputSystem->m_nActiveParticles, "particles", "particles" ); vb.Lock( );
for ( int p=0; p<pInputSystem->m_nActiveParticles; ++p ) { float const *pPos = pInputSystem->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_XYZ, p ); float const *pRadius = pInputSystem->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_RADIUS, p ); float const *pColor = pInputSystem->GetFloatAttributePtr( PARTICLE_ATTRIBUTE_TINT_RGB, p );
switch( nVariation ) { case VARIATION_DEFAULT: vb->m_vPosRadius.Init( pPos[0], pPos[4], pPos[8], pRadius[0] ); break; case 4: vb->m_vPosRadius.Init( pPos[0], pPos[4], pPos[8], pRadius[0] * 0.05f ); break; default: vb->m_vPosRadius.Init( pPos[0], pPos[4], pPos[8], pRadius[0] * 0.10f ); break; }
vb->m_vColor.Init( pColor[0], pColor[4], pColor[8], 1 ); //vb->m_vColor.Init( 0.9, 0.4, 1.0, 1 );
vb->m_vColor.AsVector3D().NormalizeInPlace(); vb.AdvanceVertex(); }
vb.Unlock( ); vb.Bind( 1, 0 );
pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nNumTriangles * 3, pInputSystem->m_nActiveParticles ); }
void CWorldRendererTest::RenderScenePointLights( IRenderContext *pRenderContext, CUtlVector<CPointLightRenderable> &lightVector, bool bInterior ) { if ( bInterior ) { pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE ); } else { pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE ); }
const int nMaxLightsPerDraw = 512; CDynamicVertexData<PointLightData_t> *pVB = NULL;
int nLights = lightVector.Count(); int nLightsDrawn = 0; for ( int i=0; i<nLights; ++i ) { if ( !pVB ) { pVB = new CDynamicVertexData<PointLightData_t>( pRenderContext, nMaxLightsPerDraw, "scenelights_point", "scenelights_point" ); pVB->Lock(); }
Vector vLightOrigin = lightVector[i].m_pLight->m_vOrigin; Vector vNewOrigin = vLightOrigin - lightVector[i].m_vOrigin; (*pVB)->m_vOrigin = vNewOrigin; (*pVB)->m_vColorNRadius = lightVector[i].m_pLight->m_vColorNRadius; (*pVB)->m_vAttenuation = lightVector[i].m_pLight->m_vAttenuation; pVB->AdvanceVertex();
nLightsDrawn ++; if ( nLightsDrawn >= nMaxLightsPerDraw ) { nLightsDrawn = 0; pVB->Unlock();
pRenderContext->BindVertexBuffer( 0, m_hSphereVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hSphereIB, 0 ); pVB->Bind( 1, 0 ); pRenderContext->BindVertexShader( m_hSceneLightVS[0], m_hSceneLightLayout[0] ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[0] );
pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nSphereIndices, nMaxLightsPerDraw ); delete pVB; pVB = NULL; } }
if ( pVB ) { Assert( nLightsDrawn > 0 ); pVB->Unlock();
pRenderContext->BindVertexBuffer( 0, m_hSphereVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hSphereIB, 0 ); pVB->Bind( 1, 0 ); pRenderContext->BindVertexShader( m_hSceneLightVS[0], m_hSceneLightLayout[0] ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[0] );
pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nSphereIndices, nLightsDrawn );
delete pVB; } }
void CWorldRendererTest::RenderSceneHemiLights( IRenderContext *pRenderContext, CUtlVector<CHemiLightRenderable> &lightVector, bool bInterior ) { if ( bInterior ) { pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE ); } else { pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE ); }
const int nMaxLightsPerDraw = 512; CDynamicVertexData<HemiLightData_t> *pVB = NULL;
int nLights = lightVector.Count(); int nLightsDrawn = 0; for ( int i=0; i<nLights; ++i ) { if ( !pVB ) { pVB = new CDynamicVertexData<HemiLightData_t>( pRenderContext, nMaxLightsPerDraw, "scenelights_hemi", "scenelights_hemi" ); pVB->Lock(); } Vector vOrigin = lightVector[i].m_vOrigin;
(*pVB)->m_vTransform0 = lightVector[i].m_pLight->m_vTransform0; (*pVB)->m_vTransform1 = lightVector[i].m_pLight->m_vTransform1; (*pVB)->m_vTransform2 = lightVector[i].m_pLight->m_vTransform2; (*pVB)->m_vTransform0.w -= vOrigin.x; (*pVB)->m_vTransform1.w -= vOrigin.y; (*pVB)->m_vTransform2.w -= vOrigin.z; (*pVB)->m_vColorNRadius = lightVector[i].m_pLight->m_vColorNRadius; (*pVB)->m_vAttenuation = lightVector[i].m_pLight->m_vAttenuation;
pVB->AdvanceVertex();
nLightsDrawn ++; if ( nLightsDrawn >= nMaxLightsPerDraw ) { nLightsDrawn = 0; pVB->Unlock();
pRenderContext->BindVertexBuffer( 0, m_hHemiVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hHemiIB, 0 ); pVB->Bind( 1, 0 ); pRenderContext->BindVertexShader( m_hSceneLightVS[1], m_hSceneLightLayout[1] ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[1] );
pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nHemiIndices, nMaxLightsPerDraw ); delete pVB; pVB = NULL; } }
if ( pVB ) { pVB->Unlock(); if ( nLightsDrawn > 0 ) { pRenderContext->BindVertexBuffer( 0, m_hHemiVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hHemiIB, 0 ); pVB->Bind( 1, 0 ); pRenderContext->BindVertexShader( m_hSceneLightVS[1], m_hSceneLightLayout[1] ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[1] );
pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nHemiIndices, nLightsDrawn ); }
delete pVB; } }
void CWorldRendererTest::RenderSceneSpotLights( IRenderContext *pRenderContext, CUtlVector<CSpotLightRenderable> &lightVector, bool bInterior ) { if ( bInterior ) { pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE ); } else { pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE ); }
const int nMaxLightsPerDraw = 512; CDynamicVertexData<SpotLightData_t> *pVB = NULL;
int nLights = lightVector.Count(); int nLightsDrawn = 0; for ( int i=0; i<nLights; ++i ) { if ( !lightVector[i].m_bValid ) continue;
if ( !pVB ) { pVB = new CDynamicVertexData<SpotLightData_t>( pRenderContext, nMaxLightsPerDraw, "scenelights_spot", "scenelights_spot" ); pVB->Lock(); }
Vector vOrigin = lightVector[i].m_vOrigin;
(*pVB)->m_vTransform0 = lightVector[i].m_pLight->m_vTransform0; (*pVB)->m_vTransform1 = lightVector[i].m_pLight->m_vTransform1; (*pVB)->m_vTransform2 = lightVector[i].m_pLight->m_vTransform2; (*pVB)->m_vTransform0.w -= vOrigin.x; (*pVB)->m_vTransform1.w -= vOrigin.y; (*pVB)->m_vTransform2.w -= vOrigin.z; (*pVB)->m_vColorNRadius = lightVector[i].m_pLight->m_vColorNRadius; (*pVB)->m_vAttenuationNCosSpot = lightVector[i].m_pLight->m_vAttenuationNCosSpot;
pVB->AdvanceVertex();
nLightsDrawn ++; if ( nLightsDrawn >= nMaxLightsPerDraw ) { nLightsDrawn = 0; pVB->Unlock();
pRenderContext->BindVertexBuffer( 0, m_hConeVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hConeIB, 0 ); pVB->Bind( 1, 0 ); pRenderContext->BindVertexShader( m_hSceneLightVS[2], m_hSceneLightLayout[2] ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[2] );
pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nHemiIndices, nMaxLightsPerDraw ); delete pVB; pVB = NULL; } }
if ( pVB ) { pVB->Unlock();
Assert( nLightsDrawn > 0 ); pRenderContext->BindVertexBuffer( 0, m_hConeVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hConeIB, 0 ); pVB->Bind( 1, 0 ); pRenderContext->BindVertexShader( m_hSceneLightVS[2], m_hSceneLightLayout[2] ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[2] );
pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nConeIndices, nLightsDrawn );
delete pVB; } }
void CWorldRendererTest::RenderShadowedSpotLights( IRenderContext *pRenderContext, CUtlVector<CSpotLightRenderable> &lightVector ) { int nLights = lightVector.Count(); if ( nLights == 0 ) return;
const int nMaxLightsPerDraw = NUM_MULTI_SHADOWS; CDynamicVertexData<SpotLightData_t> *pVB = new CDynamicVertexData<SpotLightData_t>( pRenderContext, nMaxLightsPerDraw, "scenelights_shadowspot", "scenelights_shadowspot" ); pVB->Lock();
Assert( nLights <= NUM_MULTI_SHADOWS ); for ( int i=0; i<nLights; ++i ) { Vector vOrigin = lightVector[i].m_vOrigin;
(*pVB)->m_vTransform0 = lightVector[i].m_pLight->m_vTransform0; (*pVB)->m_vTransform1 = lightVector[i].m_pLight->m_vTransform1; (*pVB)->m_vTransform2 = lightVector[i].m_pLight->m_vTransform2; (*pVB)->m_vTransform0.w -= vOrigin.x; (*pVB)->m_vTransform1.w -= vOrigin.y; (*pVB)->m_vTransform2.w -= vOrigin.z; (*pVB)->m_vColorNRadius = lightVector[i].m_pLight->m_vColorNRadius; (*pVB)->m_vAttenuationNCosSpot = lightVector[i].m_pLight->m_vAttenuationNCosSpot;
pVB->AdvanceVertex(); }
pVB->Unlock();
// Bind
pRenderContext->BindVertexShader( m_hSceneLightVS[2], m_hSceneLightLayout[2] ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSceneLightPS[5] );
pRenderContext->BindVertexBuffer( 0, m_hConeVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hConeIB, 0 );
for ( int i=0; i<nLights; ++i ) { if ( i < NUM_HIGH_RES_SHADOWS ) { pRenderContext->BindTexture( 4, m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ] ); pRenderContext->SetSamplerStatePS( 4, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->BindTexture( 3, m_hFlashlightCookie[0] ); pRenderContext->SetSamplerStatePS( 3, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); } else { pRenderContext->BindTexture( 4, m_pRenderTargets[ RT_SHADOW_MULTIPLE_1 ] ); pRenderContext->SetSamplerStatePS( 4, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->BindTexture( 3, m_hFlashlightCookie[1] ); pRenderContext->SetSamplerStatePS( 3, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); }
pRenderContext->SetConstantBufferData( m_hSingleMatrixRelated, &m_pMultiShadowMatrices[ i ], sizeof( VMatrix ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hSingleMatrixRelated, 1, 7 );
if ( lightVector[i].m_bInterior ) { pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_GREATER_NO_WRITE ); } else { pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE ); }
pVB->Bind( 1, i * sizeof( SpotLightData_t ) );
pRenderContext->DrawIndexedInstanced( RENDER_PRIM_TRIANGLES, 0, m_nConeIndices, 1 ); }
delete pVB; }
void CWorldRendererTest::CalculateEyeRays( float flFarPlane ) { Vector vForward = m_pFrustum->Forward(); Vector vUp = m_pFrustum->Up(); Vector vLeft = m_pFrustum->Left();
float flFovX = m_pFrustum->GetFOV(); float flFovY = CalcFovY( flFovX, m_pFrustum->GetAspect() ); flFovX *= 0.5f; flFovY *= 0.5f; Vector vFowardShift = flFarPlane * vForward; Vector vUpShift = flFarPlane * tanf( DEG2RAD( flFovY ) ) * vUp; Vector vRightShift = flFarPlane * tanf( DEG2RAD( flFovX ) ) * -vLeft; m_vEyeRays[0] = vFowardShift + -vRightShift + -vUpShift; m_vEyeRays[1] = vFowardShift + vRightShift + -vUpShift; m_vEyeRays[2] = vFowardShift + -vRightShift + vUpShift; m_vEyeRays[3] = vFowardShift + vRightShift + vUpShift;
vFowardShift = flFarPlane * Vector( 0, 0, 1 ); vUpShift = flFarPlane * tanf( DEG2RAD( flFovY ) ) * Vector( 0, 1, 0 ); vRightShift = flFarPlane * tanf( DEG2RAD( flFovX ) ) * Vector( 1, 0, 0 ); m_vEyeLocalRays[0] = vFowardShift + -vRightShift + -vUpShift; m_vEyeLocalRays[1] = vFowardShift + vRightShift + -vUpShift; m_vEyeLocalRays[2] = vFowardShift + -vRightShift + vUpShift; m_vEyeLocalRays[3] = vFowardShift + vRightShift + vUpShift; }
void CWorldRendererTest::BilateralUpsample( ) { CRenderContextPtr pRenderContext( g_pRenderDevice ); ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
// Bilat upsampling ( Horizontal )
{ m_pRenderViews[ RTB_BILAT_UPSAMPLE_0 ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); pRenderContext->SetBlendState( m_hWriteAllBS );
if ( IsPlatformX360() ) pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_LOWRES ] ); else pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ] ); pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_LIGHTING_LOWRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_lowResScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&m_blurParams, sizeof( BlurParams_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hBilateralBlur[0] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "bilatupsamplehorz" );
// Submit
m_pRenderViews[ RTB_BILAT_UPSAMPLE_0 ].EndRender( pRenderContext ); }
// Bilat upsampling ( Vertical )
{ m_pRenderViews[ RTB_BILAT_UPSAMPLE_1 ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); pRenderContext->SetBlendState( m_hWriteAllBS );
if ( IsPlatformX360() ) pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] ); else pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] );
pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_LIGHTING_TEMP_LOWRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hBlurParams, (void*)&m_blurParams, sizeof( BlurParams_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hBlurParams, 1, 7 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hBilateralBlur[1] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "bilatupsamplevert" );
// Submit
m_pRenderViews[ RTB_BILAT_UPSAMPLE_1 ].EndRender( pRenderContext ); } }
void CWorldRendererTest::RenderSSAO() { CRenderContextPtr pRenderContext( g_pRenderDevice ); ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
m_pRenderViews[ RTB_SSAO_LOWRES ].BeginRender( pRenderContext );
pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetBlendState( m_hWriteAlphaBS );
#if 0
pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ] ); pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_NORMAL_LOWRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_LINEAR, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 2, m_hRandomTexture ); pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_WRAP, RS_TEXTURE_ADDRESS_WRAP, RS_TEXTURE_ADDRESS_WRAP ); #else
pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ] ); pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_NORMAL_LOWRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); pRenderContext->BindTexture( 2, m_hRandomTexture ); pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_WRAP, RS_TEXTURE_ADDRESS_WRAP, RS_TEXTURE_ADDRESS_WRAP ); #endif
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_lowResScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->SetConstantBufferData( m_hSphereSampleData, &m_sphereSampleData, sizeof( SampleSphereData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hSphereSampleData, 1, 7 ); pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSSAOPS ); RenderScreenQuad( pRenderContext, m_vEyeRays/*m_vEyeLocalRays*/, "ssao" );
// Submit
m_pRenderViews[ RTB_SSAO_LOWRES ].EndRender( pRenderContext ); }
void CWorldRendererTest::ScaleDepthAndNormalBuffers() { CRenderContextPtr pRenderContext( g_pRenderDevice ); ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
m_pRenderViews[ RTB_DEFERRED_SCALE_DOWN ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetDepthStencilState( m_hZWriteNoTestDS );
if ( IsPlatformX360() ) { pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] ); } else { pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] ); } pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT/*RENDER_TEXFILTERMODE_LINEAR*/, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_VIEW_NORMAL_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT/*RENDER_TEXFILTERMODE_LINEAR*/, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
DecalScreenData_t lowResCopyData = m_lowResScreenData; lowResCopyData.m_mInvViewProj = viewConstants.m_mViewProjection; pRenderContext->SetConstantBufferData( m_hDecalScreenData, &lowResCopyData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hCopyTexture[0] );
RenderScreenQuad( pRenderContext, m_vEyeRays, "scaledepthnorm" );
// Submit
m_pRenderViews[ RTB_DEFERRED_SCALE_DOWN ].EndRender( pRenderContext ); }
void CWorldRendererTest::RenderAerialPerspective() { CRenderContextPtr pRenderContext( g_pRenderDevice ); ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum );
m_pRenderViews[ RTB_AERIAL_PERSPECTIVE ].BeginRender( pRenderContext );
pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE_STENCIL_TEST_NOTEQUAL ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
if ( IsPlatformX360() ) { pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] ); } else { pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] ); } pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hAerialPerspectivePSCB, (void*)&m_aerialPerspectiveData, sizeof( AerialPerspectiveConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hAerialPerspectivePSCB, 0, 0 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
// Extinction
pRenderContext->SetBlendState( m_hExtinctionBS ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hAerialPerspectivePS[0] ); RenderScreenQuad( pRenderContext, m_vEyeRays, "exinction" );
// In-scattering
pRenderContext->SetDepthStencilState( m_hStencilTestDS, g_nCanSeeSkyStencilRef ); pRenderContext->SetBlendState( m_hInscatteringBS ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hAerialPerspectivePS[1] ); RenderScreenQuad( pRenderContext, m_vEyeRays, "inscattering" );
// Submit
m_pRenderViews[ RTB_AERIAL_PERSPECTIVE ].EndRender( pRenderContext ); }
void CWorldRendererTest::RenderSky() { VPROF("RenderSky");
CRenderContextPtr pRenderContext( g_pRenderDevice );
// Update the camera
m_pFrustum->SetNearFarPlanes( m_flNearPlane, m_flFarPlane ); m_pFrustum->UpdateFrustumFromCamera();
if ( m_bDeferred ) { m_pRenderViews[ RTB_SKY ].BeginRender( pRenderContext ); } else { m_pRenderViews[ RTB_FORWARD ].BeginRender( pRenderContext ); }
// Sky
pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_FRONTFACING );
if ( m_bDeferred ) { pRenderContext->SetDepthStencilState( m_hZTestAndStencilTestDS, g_nNothingRenderedStencilRef ); } else { pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE ); } SkyVSCB_t skyVSCB;
VMatrix mTrans; mTrans.Identity(); mTrans.SetTranslation( m_pFrustum->GetCameraPosition() ); skyVSCB.m_mViewProj = mTrans.Transpose() * m_pFrustum->GetViewProj(); skyVSCB.m_vSkyScale = Vector4D( 17000.0f, 17000.0f, 3000.0f, 0.0f ); m_skyData.m_vEyePt = Vector4D( 0,0,0,0 ); m_skyData.m_vLightDir = Vector4D( m_vLightDir.x, m_vLightDir.y, m_vLightDir.z, 1 );
pRenderContext->SetConstantBufferData( m_hSkyVSCB, (void*)&skyVSCB, sizeof( SkyVSCB_t ) ); pRenderContext->SetConstantBufferData( m_hSkyPSCB, (void*)&m_skyData, sizeof( SkyPSCB_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hSkyVSCB, 0, 0 ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hSkyPSCB, 0, 0 ); pRenderContext->BindVertexShader( m_hSkyVS, m_hSphereLayout ); pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hSkyPS ); pRenderContext->BindVertexBuffer( 0, m_hSphereVB, 0, sizeof( SphereVertex_t ) ); pRenderContext->BindIndexBuffer( m_hSphereIB, 0 ); pRenderContext->DrawIndexed( RENDER_PRIM_TRIANGLES, 0, m_nNumTriangles * 3 );
// Submit
if ( m_bDeferred ) { m_pRenderViews[ RTB_SKY ].EndRender( pRenderContext ); } else { m_pRenderViews[ RTB_FORWARD ].EndRender( pRenderContext ); } }
void CWorldRendererTest::RenderFrame_Internal( const RenderViewport_t &viewport ) { VPROF("RenderFrame_Internal"); if ( !m_bWorldLoaded ) return;
m_nWindowCenterX = viewport.m_nTopLeftX + (viewport.m_nWidth / 2); m_nWindowCenterY = viewport.m_nTopLeftY + (viewport.m_nHeight / 2);
RenderViewport_t lowResViewport; lowResViewport = viewport; lowResViewport.m_nWidth = (int)( lowResViewport.m_nWidth * m_flLowResBufferScale ); lowResViewport.m_nHeight = (int)( lowResViewport.m_nHeight * m_flLowResBufferScale );
UpdateFrustum( viewport.m_nWidth, viewport.m_nHeight );
CRenderContextPtr pRenderContext( g_pRenderDevice ); VMatrix mWorld; mWorld.Identity();
Vector vCameraPos = m_pFrustum->GetCameraPosition();
float flFarPlane = m_pWorldRenderer->GetMaxVisibleDistance( vCameraPos ); float flShiftedFar = m_flFarPlane; if ( m_bEnableVis ) flShiftedFar = MIN( flFarPlane, m_flFarPlane );
CWorldRenderFrustum *pCullFrustum = m_pFrustum; if ( m_bDropFrustum ) { pCullFrustum = m_pDropFrustum; vCameraPos = m_vCullPos; flShiftedFar = m_flFarPlane; }
// Update the camera
m_pFrustum->SetNearFarPlanes( m_flNearPlane, flShiftedFar ); m_pFrustum->UpdateFrustumFromCamera(); VMatrix mViewProj = m_pFrustum->GetViewProj();
// Shadow split frustums
float flLightDistance = 5000.0f; float flLightFarPlane = 8000.0f; float flMaxShadowDistance = 5000.0f; m_pFrustum->CalculateLightFrusta( m_pSplitFrustums, m_nShadowSplits, m_vLightDir, flLightDistance, flLightFarPlane, flMaxShadowDistance );
// Pull flashlight data from the camera
UpdateFlashlightData();
// Pull viewmodel data from the camera
UpdateViewModelData();
// Build renderables list
GenerateRenderables( vCameraPos );
// Update Shadow Data (do this before culling!!!)
UpdateShadowData();
// Culling
if ( m_bDeferred ) { for ( int v=0; v<RTB_FORWARD; ++v ) { CullRenderablesAgainstView( m_pRenderViews[ v ], m_renderableList, m_dynRenderableList ); } } else { for ( int v=RTB_SHADOW_DEPTH0; v<RTB_SHADOW_DEPTH_MULTIPLE_0; ++v ) { CullRenderablesAgainstView( m_pRenderViews[ v ], m_renderableList, m_dynRenderableList ); }
CullRenderablesAgainstView( m_pRenderViews[ RTB_FORWARD ], m_renderableList, m_dynRenderableList ); }
// Update the camera to make sure we shift the far plane out enough to encompass any lights
flShiftedFar = MAX( flShiftedFar, m_flMaxLightEncompassingFarPlane ); m_pFrustum->SetNearFarPlanes( m_flNearPlane, flShiftedFar ); m_pFrustum->UpdateFrustumFromCamera(); mViewProj = m_pFrustum->GetViewProj();
ViewRelatedConstants_t viewConstants = CreateViewConstantsForFrustum( m_pFrustum ); m_forwardLightingData.m_vLightColor = m_vRenderLightColor; m_forwardLightingData.m_vLightDir = Vector4D( m_vLightDir.x, m_vLightDir.y, m_vLightDir.z, 1 ); m_lightBufferData.m_vInvScreenExtents = Vector4D( 1.0f / viewport.m_nWidth, 1.0f / viewport.m_nHeight, 0, 0 );
// Calculate eye rays
CalculateEyeRays( flShiftedFar );
//
// Start of rendering
//
// Shadow depth buffers
RenderShadowDepthBuffers( pRenderContext );
if ( m_bDeferred ) { m_deferredLightingData.m_vLightColor = m_vRenderLightColor; m_deferredLightingData.m_vLightDir = Vector4D( m_vLightDir.x, m_vLightDir.y, m_vLightDir.z, 1 ); m_deferredLightingData.m_vInvScreenExtents = Vector4D( 1.0f / viewport.m_nWidth, 1.0f / viewport.m_nHeight, 0, 0 ); m_deferredLightingData.m_vEyePt = Vector4D( vCameraPos.x, vCameraPos.y, vCameraPos.z, 1 );
m_aerialPerspectiveData.m_vLightDir = m_deferredLightingData.m_vLightDir; m_aerialPerspectiveData.m_vLightColor = m_skyData.m_vLightColor; m_aerialPerspectiveData.m_vInvScreenExtents = m_deferredLightingData.m_vInvScreenExtents; m_aerialPerspectiveData.m_vBm = m_skyData.m_vBm; m_aerialPerspectiveData.m_flG = Vector4D( 0.7f, 0,0,0 ); m_aerialPerspectiveData.m_vNearAndFar = Vector4D( m_flNearPlane, flShiftedFar, 0, 0 ); m_aerialPerspectiveData.m_vEyePt = Vector4D( vCameraPos.x, vCameraPos.y, vCameraPos.z, 1 );
m_sphereSampleData.m_mViewProj = viewConstants.m_mViewProjection; m_sphereSampleData.m_vRandSampleScale.Init( 1 / (float)m_nRandTextureSize, 1 / (float)m_nRandTextureSize, 0.5f + ( 0.5f / lowResViewport.m_nWidth ), 0.5f + ( 0.5f / lowResViewport.m_nHeight ) ); float flSSAOBias = 0.005f; float flSSAOStrenth = 5.0f; m_sphereSampleData.m_vSampleRadiusNBias.Init( m_flSampleRadius, flShiftedFar / ( m_flSampleRadius * flSSAOStrenth ), flShiftedFar, flSSAOBias * flShiftedFar ); m_blurParams.m_flFarPlane.Init( flShiftedFar, flShiftedFar, flShiftedFar, flShiftedFar ); VMatrix mPosLookupViewProj = mViewProj; if ( IsPlatformX360() ) { VMatrix mDepthFlip( 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f ); mPosLookupViewProj = mPosLookupViewProj * mDepthFlip; } if ( !MatrixInverseGeneral( mPosLookupViewProj, m_deferredLightingData.m_mInvViewProj ) ) return;
m_decalScreenData.m_vInvScreenExtents = m_deferredLightingData.m_vInvScreenExtents; m_decalScreenData.m_mInvViewProj = m_deferredLightingData.m_mInvViewProj; m_decalScreenData.m_vEyePt = m_aerialPerspectiveData.m_vEyePt; m_decalScreenData.m_vEyeDir = viewConstants.m_vEyeDir;
m_lowResScreenData.m_vInvScreenExtents = Vector4D( 1.0f / lowResViewport.m_nWidth, 1.0f / lowResViewport.m_nHeight, 0, 0 ); m_lowResScreenData.m_mInvViewProj = m_deferredLightingData.m_mInvViewProj; m_lowResScreenData.m_vEyePt = m_aerialPerspectiveData.m_vEyePt; m_lowResScreenData.m_vEyeDir = viewConstants.m_vEyeDir;
m_shadowScreenData.m_vInvScreenExtents = Vector4D( 1.0f / m_shadowViewport.m_nWidth, 1.0f / m_shadowViewport.m_nHeight, 0, 0 ); m_shadowScreenData.m_mInvViewProj = m_deferredLightingData.m_mInvViewProj; m_shadowScreenData.m_vEyePt = m_aerialPerspectiveData.m_vEyePt; m_shadowScreenData.m_vEyeDir = viewConstants.m_vEyeDir;
m_aerialPerspectiveData.m_mInvViewProj = m_deferredLightingData.m_mInvViewProj;; // Blur shadow buffers
if ( m_bBlurShadows ) { BlurShadowBuffers(); }
// Render depth and normal pass
{ // SetRenderTarget must be the first call in any command list
Vector4D vNormalClear(1,1,1,1); m_pRenderViews[ RTB_DEFERRED_DEPTH_NORM_SPEC ].Clear( pRenderContext, vNormalClear, RENDER_CLEAR_FLAGS_CLEAR_DEPTH | RENDER_CLEAR_FLAGS_CLEAR_STENCIL ); RenderView( m_pRenderViews[ RTB_DEFERRED_DEPTH_NORM_SPEC ] );
// Render spheres
m_pRenderViews[ RTB_DEFERRED_DEPTH_NORM_SPEC ].BeginRender( pRenderContext );
VMatrix mViewRelated; mViewRelated = m_pFrustum->GetViewProj(); pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE_STENCIL_SET1 ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
int nParticleSystems = m_sphereSystemList.Count(); for ( int p=0; p<nParticleSystems; ++p ) { RenderParticleLights( pRenderContext, m_sphereSystemList[p], VARIATION_NORM_DEPTH_SPEC, false, true ); }
// Submit
m_pRenderViews[ RTB_DEFERRED_DEPTH_NORM_SPEC ].EndRender( pRenderContext ); }
// Clear low -res lighting
{ Vector4D vLightingClear(0,0,0,1); m_pRenderViews[ RTB_LIGHTING_LOWRES ].Clear( pRenderContext, vLightingClear, 0 ); }
// Decals
{ m_pRenderViews[ RTB_DEFERRED_NORM_SPEC ].BeginRender( pRenderContext );
pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE );
// Render decals into normal map... using depth
if ( IsPlatformX360() ) { pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] ); } else { pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] ); } pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT );
RenderDecals( pRenderContext, 0 );
// Submit
m_pRenderViews[ RTB_DEFERRED_NORM_SPEC ].EndRender( pRenderContext ); }
// Scale depth and normal buffers
ScaleDepthAndNormalBuffers();
// SSAO only requires depth (and normal later)
if ( m_bSSAO ) { RenderSSAO(); } // Low res lighting requires depth and normal
{ m_pRenderViews[ RTB_LIGHTING_LOWRES ].BeginRender( pRenderContext );
if ( m_bDrawBouncedLight ) { RenderBouncedLight( pRenderContext ); }
// Submit
m_pRenderViews[ RTB_LIGHTING_LOWRES ].EndRender( pRenderContext ); }
// Upsample
BilateralUpsample(); // Clear specular buffer
{ Vector4D vSpecClear(0,0,0,0); m_pRenderViews[ RTB_CLEAR_SPEC_HIGHRES ].Clear( pRenderContext, vSpecClear, 0 ); }
// Do lighting
{ m_pRenderViews[ RTB_LIGHTING_HIGHRES ].BeginRender( pRenderContext );
RenderSunShadowFrustums( pRenderContext );
if ( m_bDrawDirectLight ) { RenderDirectLight( pRenderContext ); }
// Submit
m_pRenderViews[ RTB_LIGHTING_HIGHRES ].EndRender( pRenderContext ); }
// Blur the light buffer
if ( m_bBlurLighting ) { BlurLightBuffer(); }
if ( m_bLightingOnly ) { m_pRenderViews[ RTB_SAMPLE_LIGHTING ].BeginRender( pRenderContext );
pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_NONE );
pRenderContext->BindTexture( 0, m_pRenderTargets[ m_nViewBuffer ] ); pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP );
if ( m_nViewBuffer == RT_LIGHTING_HIGHRES ) { pRenderContext->BindTexture( 1, m_pRenderTargets[ RT_SPECULAR_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 1, RS_FILTER_MIN_MAG_MIP_POINT, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP, RS_TEXTURE_ADDRESS_CLAMP ); }
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
pRenderContext->SetConstantBufferData( m_hDecalScreenData, &m_decalScreenData, sizeof( DecalScreenData_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hDecalScreenData, 0, 0 );
pRenderContext->BindVertexShader( m_hShadowFrustumVS[2], m_hQuadLayout );
if ( m_nViewBuffer == RT_LIGHTING_LOWRES ) { pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hCopyTexture[2] ); } else if ( m_nViewBuffer == RT_LIGHTING_HIGHRES ) { pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hCopyTexture[3] ); } else { pRenderContext->BindShader( RENDER_PIXEL_SHADER, m_hCopyTexture[1] ); }
RenderScreenQuad( pRenderContext, m_vEyeRays, "lightingonly" );
// Submit
m_pRenderViews[ RTB_SAMPLE_LIGHTING ].EndRender( pRenderContext ); } // Render forward pass while sampling lighting
else { Vector4D vForwardClear(0,0,0,0); m_pRenderViews[ RTB_SAMPLE_LIGHTING ].Clear( pRenderContext, vForwardClear, 0 ); RenderView( m_pRenderViews[ RTB_SAMPLE_LIGHTING ] );
// Render spheres
m_pRenderViews[ RTB_SAMPLE_LIGHTING ].BeginRender( pRenderContext );
pRenderContext->SetConstantBufferData( m_hViewRelated, (void*)&viewConstants, sizeof( ViewRelatedConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_VERTEX_SHADER, m_hViewRelated, 0, 0 );
int nParticleSystems = m_sphereSystemList.Count(); pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_EQUAL_NO_WRITE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->BindTexture( 4, m_pRenderTargets[ RT_LIGHTING_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 4, RS_FILTER_MIN_MAG_MIP_POINT );
pRenderContext->BindTexture( 5, m_pRenderTargets[ RT_SPECULAR_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 5, RS_FILTER_MIN_MAG_MIP_POINT );
for ( int p=0; p<nParticleSystems; ++p ) { RenderParticleLights( pRenderContext, m_sphereSystemList[p], VARIATION_SAMPLE_LIGHTING, false, false ); }
// Decals
pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_NO_WRITE ); if ( IsPlatformX360() ) { pRenderContext->BindTexture( 0, m_pRenderTargets[ DS_DEPTH_HIGHRES ] ); } else { pRenderContext->BindTexture( 0, m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ] ); } pRenderContext->SetSamplerStatePS( 0, RS_FILTER_MIN_MAG_MIP_POINT ); pRenderContext->BindTexture( 2, m_pRenderTargets[ RT_LIGHTING_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 2, RS_FILTER_MIN_MAG_MIP_POINT ); pRenderContext->BindTexture( 3, m_pRenderTargets[ RT_SPECULAR_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 3, RS_FILTER_MIN_MAG_MIP_POINT ); RenderDecals( pRenderContext, 1 );
// Render pointlights
pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE );
nParticleSystems = m_lightSystemList.Count(); for ( int p=0; p<nParticleSystems; ++p ) { RenderParticleLights( pRenderContext, m_lightSystemList[p], 4, false, false ); }
// Submit
m_pRenderViews[ RTB_SAMPLE_LIGHTING ].EndRender( pRenderContext ); }
// Render aerial perspective
if ( m_bDrawAerialPerspective ) { RenderAerialPerspective(); } } else { VPROF_SCOPE_BEGIN("RenderWorldNodes");
Vector4D c(0,1,0,0); m_pRenderViews[ RTB_FORWARD ].Clear( pRenderContext, c, RENDER_CLEAR_FLAGS_CLEAR_DEPTH );
RenderView( m_pRenderViews[ RTB_FORWARD ] );
// Submit
m_pRenderViews[ RTB_FORWARD ].EndRender( pRenderContext );
VPROF_SCOPE_END(); }
if ( m_bRenderSky ) { RenderSky(); }
// Unbind the render targets
for ( int s=0; s<NUM_SHADOW_SPLITS; ++s ) { pRenderContext->BindTexture( 4 + s, RENDER_TEXTURE_HANDLE_INVALID ); } pRenderContext->Submit();
for ( int v=0; v<MAX_VIEW_BINDING_TYPES; ++v ) { m_pRenderViews[ v ].EndRender( NULL ); }
// Update resources phase (arbitrarily only allow 10 resources to be updated)
m_pWorldRenderer->UpdateResources( g_pRenderDevice, pRenderContext, 10 );
m_nGlobalDecalPos3 = 0; m_nCurrentFrameNumber++; }
void CWorldRendererTest::SimulateFrame( float flTimeStep ) { UpdateDroppedRenderables( flTimeStep );
const float forwardSpeed = 500.0f; const float sideSpeed = 500.0f; const float yawSpeed = 90.0f; const float pitchSpeed = 45.0f;
#if defined( _X360 )
const float flYawSensitivity = -0.04f; const float flPitchSensitivity = 0.04f; #else
const float flYawSensitivity = -0.2f; const float flPitchSensitivity = 0.2f; #endif
float flForward = forwardSpeed; float flSide = sideSpeed; if ( m_cmd.m_nKeys & FKEY_FAST ) { flForward *= 5; flSide *= 5; }
if ( m_cmd.m_nKeys & FKEY_ENABLE_VIS ) { m_bEnableVis = true; Msg( "Vis enabled\n" ); } else if( m_cmd.m_nKeys & FKEY_DISABLE_VIS ) { m_bEnableVis = false; Msg( "Vis disabled\n" ); }
if ( m_cmd.m_nKeys & FKEY_DROP_FRUSTUM ) { Q_memcpy( m_pDropFrustum, m_pFrustum, sizeof( CWorldRenderFrustum ) ); m_bDropFrustum = !m_bDropFrustum; m_vCullPos = m_pFrustum->GetCameraPosition(); if ( m_bDropFrustum ) Msg( "Drop frustum\n" ); else Msg( "no drop\n" ); ThreadSleep( 200 ); }
if ( m_cmd.m_nKeys & FKEY_TOGGLE_AERIAL ) { m_bDrawAerialPerspective = !m_bDrawAerialPerspective; if ( m_bDrawAerialPerspective ) Msg( "Aerial Perspective: On\n" ); else Msg( "Aerial Perspective: Off\n" ); ThreadSleep( 200 ); }
if ( m_cmd.m_nKeys & FKEY_TOGGLE_BOUNCE ) { m_bDrawBouncedLight = !m_bDrawBouncedLight; if ( m_bDrawBouncedLight ) Msg( "Bounced light: On\n" ); else Msg( "Bounced light: Off\n" ); ThreadSleep( 200 ); }
if ( m_cmd.m_nKeys & FKEY_TOGGLE_DIRECT ) { m_bDrawDirectLight = !m_bDrawDirectLight; if ( m_bDrawDirectLight ) Msg( "Direct light: On\n" ); else Msg( "Direct light: Off\n" ); ThreadSleep( 200 ); }
if ( m_cmd.m_nKeys & FKEY_TOGGLE_LIGHTING_ONLY ) { m_bLightingOnly = !m_bLightingOnly; if ( m_bLightingOnly ) Msg( "Lighting Only: On\n" ); else Msg( "Lighting Only: Off\n" ); ThreadSleep( 200 ); }
if ( m_cmd.m_nKeys & FKEY_SSAO ) { m_bSSAO = !m_bSSAO; if ( m_bSSAO ) Msg( "SSAO: On\n" ); else Msg( "SSAO: Off\n" ); ThreadSleep( 200 ); }
if ( m_cmd.m_nKeys & FKEY_BLUR_LIGHTING ) { m_bBlurLighting = !m_bBlurLighting; if ( m_bBlurLighting ) Msg( "Blur Lighting: On\n" ); else Msg( "Blur Lighting: Off\n" ); ThreadSleep( 200 ); }
if ( m_cmd.m_nKeys & FKEY_BLUR_SHADOWS ) { m_bBlurShadows = !m_bBlurShadows; if ( m_bBlurShadows ) Msg( "Blur Shadows: On\n" ); else Msg( "Blur Shadows: Off\n" ); ThreadSleep( 200 ); }
m_cmd.m_flForwardMove = (m_cmd.m_nKeys & (FKEY_FORWARD|FKEY_BACK)) ? ( (m_cmd.m_nKeys & FKEY_FORWARD) ? flForward : -flForward) : 0; m_cmd.m_flRightMove = (m_cmd.m_nKeys & (FKEY_LEFT|FKEY_RIGHT)) ? ( (m_cmd.m_nKeys & FKEY_RIGHT) ? flSide : -flSide) : 0; float flYawMove = (m_cmd.m_nKeys & (FKEY_TURNLEFT|FKEY_TURNRIGHT)) ? ( (m_cmd.m_nKeys & FKEY_TURNLEFT) ? yawSpeed : -yawSpeed) : 0; float flPitchMove = (m_cmd.m_nKeys & (FKEY_TURNUP|FKEY_TURNDOWN)) ? ( (m_cmd.m_nKeys & FKEY_TURNDOWN) ? pitchSpeed : -pitchSpeed) : 0; if ( m_nCursorDeltaX || m_nCursorDeltaY ) { m_cmd.m_flYawMove = m_nCursorDeltaX * flYawSensitivity; m_cmd.m_flPitchMove = m_nCursorDeltaY * flPitchSensitivity; m_nCursorDeltaX = m_nCursorDeltaResetX; m_nCursorDeltaY = m_nCursorDeltaResetY; if ( !IsPlatformX360() ) { g_pInputStackSystem->SetCursorPosition( GetInputContext(), m_nWindowCenterX, m_nWindowCenterY ); } } m_cmd.m_flPitchMove += flPitchMove * flTimeStep; m_cmd.m_flYawMove += flYawMove * flTimeStep;
Vector vMoveAmount = ((m_pFrustum->Forward() * m_cmd.m_flForwardMove ) - ( m_pFrustum->Left() * m_cmd.m_flRightMove )) * flTimeStep; Vector eyePos = m_pFrustum->GetCameraPosition() + vMoveAmount; m_pFrustum->SetCameraPosition( eyePos ); QAngle angles = m_pFrustum->GetCameraAngles(); angles.y += m_cmd.m_flYawMove; angles.x += m_cmd.m_flPitchMove; angles.x = clamp( angles.x, -89.0f, 89.0f ); m_cmd.m_flYawMove = 0; m_cmd.m_flPitchMove = 0;
if ( angles.y > 180.0f ) { angles.y -= 360.0f; } if ( angles.y < -180.0f ) { angles.y += 360.0f; } m_pFrustum->SetCameraAngles( angles );
// Update light
VMatrix mLight,mLightAngle, mLightElevation; mLightAngle.Identity(); mLightElevation.Identity(); mLight.Identity(); MatrixRotate( mLightElevation, Vector(1,0,0), m_vLightAngleElevation.y ); MatrixRotate( mLightAngle, Vector(0,0,1), m_vLightAngleElevation.x ); mLight = mLightElevation * mLightAngle; Vector vLightStart(1,0,0); matrix3x4_t mLight3x4 = mLight.As3x4(); VectorRotate( vLightStart, mLight3x4, m_vLightDir ); m_vLightDir.NormalizeInPlace();
float flLerp = sinf( DEG2RAD( m_vLightAngleElevation.x ) ); Vector4D vColorRed( 1.0, 0.7, 0.6, 1 ); Vector4D vColorYellow( 1.0, 0.9, 0.7, 1 ); m_skyData.m_vLightColor = Lerp( flLerp, vColorRed, vColorYellow );
Vector4D vRenderColorRed( 1.0, 0.6, 0.4, 1 ); Vector4D vRenderColorYellow( 1.0, 0.9, 0.7, 1 ); m_vRenderLightColor = Lerp( flLerp, vRenderColorRed, vRenderColorYellow );
Vector4D vBmRed( 1.0e-4, 0.4e-4, 0.3e-4, 1 ); Vector4D vBmYellow( 1.0e-4, 0.7e-4, 0.3e-4, 1 ); m_skyData.m_vBm = Lerp( flLerp, vBmRed, vBmYellow );
float flGRed = 0.90f; float flGYellow = 0.99f; m_skyData.m_flG.x = Lerp( flLerp, flGRed, flGYellow );
if ( m_cmd.m_nKeys & FKEY_LIGHTANG_POS ) { m_vLightAngleElevation.x += m_flLightAngSpeed * flTimeStep; } else if ( m_cmd.m_nKeys & FKEY_LIGHTANG_NEG ) { m_vLightAngleElevation.x -= m_flLightAngSpeed * flTimeStep; }
if ( m_cmd.m_nKeys & FKEY_LIGHTELV ) { m_vLightAngleElevation.y += m_flLightElvSpeed * flTimeStep; if ( m_vLightAngleElevation.y > 88.0f || m_vLightAngleElevation.y < 30.0f ) { m_flLightElvSpeed = -m_flLightElvSpeed; } }
// Shooting decals
if ( m_cmd.m_nKeys & FKEY_SHOOTDECAL ) { if ( m_flDecalCountdown <= 0 ) { Vector vEye = m_pFrustum->GetCameraPosition(); Vector vDir = m_pFrustum->Forward(); Vector vSurfaceNormal; float flDistance = m_pWorldRenderer->CastRay( &vSurfaceNormal, vEye, vDir ); if ( flDistance > 0 ) { float flSize = RPercentABS() * 40.0f + 70.0f; CRenderContextPtr pRenderContext( g_pRenderDevice ); Vector vPos = vEye + vDir * flDistance; AddDecal( pRenderContext, vPos, vSurfaceNormal, flSize, flSize, //size x,y
6.0f, 12.0f, false ); // intersection, length
} m_flDecalCountdown = 0.1f; } m_flDecalCountdown -= flTimeStep; }
// Shooting blood decals
if ( m_cmd.m_nKeys & FKEY_SHOOTDECAL2 ) { if ( m_flDecalCountdown <= 0 ) { Vector vEye = m_pFrustum->GetCameraPosition(); Vector vDir = m_pFrustum->Forward(); Vector vSurfaceNormal; float flDistance = m_pWorldRenderer->CastRay( &vSurfaceNormal, vEye, vDir ); if ( flDistance > 0 ) { float flSize = RPercentABS() * 50.0f + 80.0f; CRenderContextPtr pRenderContext( g_pRenderDevice ); Vector vPos = vEye + vDir * flDistance; AddDecal( pRenderContext, vPos, vSurfaceNormal, flSize, flSize, //size x,y
20.0f, 40.0f, true ); // intersection, length
} m_flDecalCountdown = 0.05f; } m_flDecalCountdown -= flTimeStep; }
// Shooting the wall-monster decal
if ( m_cmd.m_nKeys & FKEY_SHOOTWALLMONSTER ) { Vector vEye = m_pFrustum->GetCameraPosition(); Vector vDir = m_pFrustum->Forward(); Vector vSurfaceNormal; float flDistance = m_pWorldRenderer->CastRay( &vSurfaceNormal, vEye, vDir ); if ( flDistance > 0 ) { float flSize = 100.0f; CRenderContextPtr pRenderContext( g_pRenderDevice ); Vector vPos = vEye + vDir * flDistance;
Vector vMonsterNormal = m_vPreviousMonsterNormal + vSurfaceNormal * 4; vMonsterNormal.NormalizeInPlace(); AddWallMonster( pRenderContext, vPos, vMonsterNormal, flSize, flSize, //size x,y
50.0f, 100.0f ); // intersection, length
m_vPreviousMonsterNormal = vMonsterNormal;
if ( m_flWallMonsterTimer < 0 ) { m_nWallMonsterTexture = ( m_nWallMonsterTexture + 1 ) % 3; m_flWallMonsterTimer = 0.05f; } else { m_flWallMonsterTimer -= MAX( 0.01f, flTimeStep ); } } }
if ( !( m_cmd.m_nKeys & FKEY_SHOOTDECAL || m_cmd.m_nKeys & FKEY_SHOOTDECAL2 ) ) { m_flDecalCountdown = 0.0f; }
// shoot a particle system
if ( m_cmd.m_nKeys & FKEY_SHOOTPSYSTEM || m_cmd.m_nKeys & FKEY_SHOOTSSYSTEM ) { if ( m_flParticleCountdown <= 0 ) { bool bSphereSystem = ( m_cmd.m_nKeys & FKEY_SHOOTSSYSTEM ) != 0; Vector vEye = m_pFrustum->GetCameraPosition(); Vector vDir = m_pFrustum->Forward(); Vector vSurfaceNormal;
float flDistance = m_pWorldRenderer->CastRay( &vSurfaceNormal, vEye, vDir ); if ( flDistance > 0 ) { Msg( "psystem distance = %f\n", flDistance );
CParticleCollection *pParticleSystem = g_pSceneSystem->CreateParticleCollection( "wonderinglights" ); if ( !pParticleSystem ) Error( "No wondering lights particle system!\n" );
Vector vPos = vEye + vDir * flDistance;
vPos += vSurfaceNormal * 100; pParticleSystem->SetControlPoint( 0, vPos ); pParticleSystem->SetControlPointOrientation( 0, Vector(1,0,0), Vector(0,1,0), Vector(0,0,1) );
if ( bSphereSystem ) m_sphereSystemList.AddToTail( pParticleSystem ); else m_lightSystemList.AddToTail( pParticleSystem );
SimulateWorkUnitWorldRender_t workUnit; workUnit.m_nNumSystems = 1; workUnit.m_pParticles = pParticleSystem; m_particleWorkUnits.AddToTail( workUnit ); } m_flParticleCountdown = 0.5f; } m_flParticleCountdown -= flTimeStep; } else { m_flParticleCountdown = 0.0f; }
// Sim particles
SimulateParticles( flTimeStep ); }
void CWorldRendererTest::AddDecal( IRenderContext *pRenderContext, Vector &vHit, Vector &vDecalDir, float flDecalSizeU, float flDecalSizeV, float flDecalShift, float flDecalInfluenceLength, bool bPaint ) { if ( g_nPlatform == RST_PLATFORM_GL ) return;
Vector vUp(RPercent(),RPercent(),RPercent()); vUp.NormalizeInPlace();
Vector vNegUp = -vUp; if ( DotProduct( vDecalDir, vUp ) > 0.95f || DotProduct( vDecalDir, vNegUp ) > 0.95f ) vUp = Vector(0,1,0);
Vector vRight; vRight = CrossProduct( vUp, vDecalDir ); vUp = CrossProduct( vDecalDir, vRight ); vRight.NormalizeInPlace(); vUp.NormalizeInPlace(); vRight *= flDecalSizeU; vUp *= flDecalSizeV; vDecalDir.NormalizeInPlace();
Vector vStartCorner = vHit; vStartCorner -= vRight * 0.5f; vStartCorner -= vUp * 0.5f; vStartCorner -= vDecalDir * flDecalShift; vDecalDir *= flDecalInfluenceLength;
// Create the 8 corners of a box surrounding our decal
Vector vCorners[8]; vCorners[0] = vStartCorner; vCorners[1] = vStartCorner + vRight; vCorners[2] = vStartCorner + vRight + vUp; vCorners[3] = vStartCorner + vUp;
vCorners[4] = vStartCorner + vDecalDir; vCorners[5] = vCorners[4] + vRight; vCorners[6] = vCorners[4] + vRight + vUp; vCorners[7] = vCorners[4] + vUp;
float fRMul = 1.0f / ( flDecalSizeU * flDecalSizeU ); float fUMul = 1.0f / ( flDecalSizeV * flDecalSizeV ); vRight = fRMul * vRight; vUp = fUMul * vUp;
if ( bPaint ) { DecalVertex_t *pVertices = &m_pDecalBackingStore2[ m_nGlobalDecalPos2 * 8 ]; for ( int i=0; i<8; ++i ) { pVertices[i].m_vPos = vCorners[i]; pVertices[i].m_vDecalRight = vRight; pVertices[i].m_vDecalUpAndInfluence = Vector4D( vUp.x, vUp.y, vUp.z, flDecalInfluenceLength ); pVertices[i].m_vDecalOrigin = vStartCorner; }
LockDesc_t lockDesc; pRenderContext->LockVertexBuffer( m_hDecalVB2, m_nMaxDecals * 8 * sizeof( DecalVertex_t ), &lockDesc ); Q_memcpy( lockDesc.m_pMemory, m_pDecalBackingStore2, m_nMaxDecals * 8 * sizeof( DecalVertex_t ) ); pRenderContext->UnlockVertexBuffer( m_hDecalVB2, m_nMaxDecals * 8 * sizeof( DecalVertex_t ), &lockDesc );
// Go to the next decal
m_nGlobalDecalPos2 ++; if ( m_nGlobalDecalPos2 >= m_nMaxDecals ) { m_bFullBuffer2 = true; m_nGlobalDecalPos2 = 0; } } else { DecalVertex_t *pVertices = &m_pDecalBackingStore[ m_nGlobalDecalPos * 8 ]; for ( int i=0; i<8; ++i ) { pVertices[i].m_vPos = vCorners[i]; pVertices[i].m_vDecalRight = vRight; pVertices[i].m_vDecalUpAndInfluence = Vector4D( vUp.x, vUp.y, vUp.z, flDecalInfluenceLength ); pVertices[i].m_vDecalOrigin = vStartCorner; }
LockDesc_t lockDesc; pRenderContext->LockVertexBuffer( m_hDecalVB, m_nMaxDecals * 8 * sizeof( DecalVertex_t ), &lockDesc ); Q_memcpy( lockDesc.m_pMemory, m_pDecalBackingStore, m_nMaxDecals * 8 * sizeof( DecalVertex_t ) ); pRenderContext->UnlockVertexBuffer( m_hDecalVB, m_nMaxDecals * 8 * sizeof( DecalVertex_t ), &lockDesc );
// Go to the next decal
m_nGlobalDecalPos ++; if ( m_nGlobalDecalPos >= m_nMaxDecals ) { m_bFullBuffer = true; m_nGlobalDecalPos = 0; } } }
void CWorldRendererTest::AddWallMonster( IRenderContext *pRenderContext, Vector &vHit, Vector &vDecalDir, float flDecalSizeU, float flDecalSizeV, float flDecalShift, float flDecalInfluenceLength ) { if ( g_nPlatform == RST_PLATFORM_GL ) return;
Vector vUp(0,0,1); Vector vNegUp = -vUp; if ( DotProduct( vDecalDir, vUp ) > 0.95f || DotProduct( vDecalDir, vNegUp ) > 0.95f ) vUp = m_pFrustum->Up();
Vector vRight; vRight = CrossProduct( vUp, vDecalDir ); vUp = CrossProduct( vDecalDir, vRight ); vRight.NormalizeInPlace(); vUp.NormalizeInPlace(); vRight *= flDecalSizeU; vUp *= flDecalSizeV; vDecalDir.NormalizeInPlace();
Vector vStartCorner = vHit; vStartCorner -= vRight * 0.5f; vStartCorner -= vUp * 0.5f; vStartCorner -= vDecalDir * flDecalShift; vDecalDir *= flDecalInfluenceLength;
// Create the 8 corners of a box surrounding our decal
Vector vCorners[8]; vCorners[0] = vStartCorner; vCorners[1] = vStartCorner + vRight; vCorners[2] = vStartCorner + vRight + vUp; vCorners[3] = vStartCorner + vUp;
vCorners[4] = vStartCorner + vDecalDir; vCorners[5] = vCorners[4] + vRight; vCorners[6] = vCorners[4] + vRight + vUp; vCorners[7] = vCorners[4] + vUp;
float fRMul = 1.0f / ( flDecalSizeU * flDecalSizeU ); float fUMul = 1.0f / ( flDecalSizeV * flDecalSizeV ); vRight = fRMul * vRight; vUp = fUMul * vUp;
DecalVertex_t pVertices[8]; for ( int i=0; i<8; ++i ) { pVertices[i].m_vPos = vCorners[i]; pVertices[i].m_vDecalRight = vRight; pVertices[i].m_vDecalUpAndInfluence = Vector4D( vUp.x, vUp.y, vUp.z, flDecalInfluenceLength ); pVertices[i].m_vDecalOrigin = vStartCorner; }
LockDesc_t lockDesc; pRenderContext->LockVertexBuffer( m_hDecalVB3, 8 * sizeof( DecalVertex_t ), &lockDesc ); Q_memcpy( lockDesc.m_pMemory, pVertices, 8 * sizeof( DecalVertex_t ) ); pRenderContext->UnlockVertexBuffer( m_hDecalVB3, 8 * sizeof( DecalVertex_t ), &lockDesc );
// Go to the next decal
m_nGlobalDecalPos3 = 1; }
void CWorldRendererTest::DropRenderable() { Vector vOrigin = m_pFrustum->GetCameraPosition(); vOrigin.z -= 32.0f;
int index = m_dynRenderableList.AddToTail();
VMatrix mRot; Vector vAxis( 0, 0, 1 ); MatrixBuildRotationAboutAxis( mRot, vAxis, 90.0f ); vAxis.Init( 1, 0, 0 ); MatrixRotate( mRot, vAxis, 90.0f );
m_dynRenderableList[ index ].m_vOrigin = vOrigin; m_dynRenderableList[ index ].m_mWorld = mRot; m_dynRenderableList[ index ].m_hRenderable = g_pMeshSystem->FindOrCreateFileRenderable( g_pRenderableList[ g_nCurrentModel ] ); g_nCurrentModel ++; if ( g_nCurrentModel >= MAX_MESH_SYSTEM_MODELS ) g_nCurrentModel = 0; }
Vector Evaluate( float flU, float flV, Vector vRadius ) { flU *= 2.0 * M_PI; flV *= 2.0 * M_PI; return Vector( vRadius.x * cos( flU ) * sin( flV ), vRadius.y * sin( flU ) * sin( flV ), vRadius.z * cos ( flV ) ); }
void CWorldRendererTest::CreateSphere( int nTessellationRes ) { Vector vRadius(1,1,1); CRenderContextPtr pRenderContext( g_pRenderDevice );
// create the static index buffer
BufferDesc_t indexDesc; indexDesc.m_nElementSizeInBytes = sizeof(uint16); indexDesc.m_nElementCount = 2 * 3 * ( nTessellationRes * nTessellationRes ); indexDesc.m_pDebugName = "sphereib"; indexDesc.m_pBudgetGroupName = "shapes"; m_hSphereIB = g_pRenderDevice->CreateIndexBuffer( RENDER_BUFFER_TYPE_STATIC, indexDesc );
// fill in the index buffer
CIndexData<uint16> ib( pRenderContext, m_hSphereIB ); ib.Lock( indexDesc.m_nElementCount ); m_nNumTriangles = 0; // generate the fixed tesselation
for( int u = 0; u < nTessellationRes; u += 1 ) { int nu = ( u + 1 ) % nTessellationRes; for( int v = 0; v < nTessellationRes; v++ ) { int nv = ( v + 1 ) % nTessellationRes; ib.Index2( u * nTessellationRes + v, nu * nTessellationRes + v ); ib.Index2( u * nTessellationRes + nv, nu * nTessellationRes + v); ib.Index2( nu * nTessellationRes + nv, u * nTessellationRes + nv ); m_nNumTriangles += 2; } } ib.Unlock( );
m_nSphereIndices = indexDesc.m_nElementCount;
// VB
int nVertices = ( nTessellationRes ) * ( nTessellationRes );
BufferDesc_t vertexDesc; vertexDesc.m_nElementSizeInBytes = sizeof(SphereVertex_t); vertexDesc.m_nElementCount = nVertices; vertexDesc.m_pDebugName = "spherevb"; vertexDesc.m_pBudgetGroupName = "shapes"; m_hSphereVB = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_STATIC, vertexDesc );
CVertexData<SphereVertex_t> vb( pRenderContext, m_hSphereVB ); vb.Lock( nVertices );
for( int u = 0 ; u < nTessellationRes; u++ ) { float flU = u * ( 1.0 / nTessellationRes ); for( int v = 0; v < nTessellationRes; v++ ) { float flV = v * ( 1.0 / nTessellationRes ); Vector pos1 = Evaluate( flU + 0.5 / nTessellationRes, flV, vRadius ); vb->m_vPos = pos1; vb.AdvanceVertex(); } } vb.Unlock( );
static RenderInputLayoutField_t sphereLayout[] = { DEFINE_PER_VERTEX_FIELD( 0, "position", 0, SphereVertex_t, m_vPos ) };
m_hSphereLayout = g_pRenderDevice->CreateInputLayout( "spherelayout", ARRAYSIZE( sphereLayout ), sphereLayout );
pRenderContext->Submit(); }
void CWorldRendererTest::CreateHemi( int nTessellationRes ) { Vector vRadius(1,1,1); CRenderContextPtr pRenderContext( g_pRenderDevice );
// create the static index buffer
BufferDesc_t indexDesc; indexDesc.m_nElementSizeInBytes = sizeof(uint16); indexDesc.m_nElementCount = 2 * 3 * ( nTessellationRes * nTessellationRes ); indexDesc.m_pDebugName = "hemiIB"; indexDesc.m_pBudgetGroupName = "shapes"; m_hHemiIB = g_pRenderDevice->CreateIndexBuffer( RENDER_BUFFER_TYPE_STATIC, indexDesc );
// fill in the index buffer
CIndexData<uint16> ib( pRenderContext, m_hHemiIB ); ib.Lock( indexDesc.m_nElementCount ); // generate the fixed tesselation
for( int u = 0; u < nTessellationRes; u += 1 ) { int nu = ( u + 1 ) % nTessellationRes; for( int v = 0; v < nTessellationRes; v++ ) { int nv = ( v + 1 ) % nTessellationRes; ib.Index2( u * nTessellationRes + v, nu * nTessellationRes + v ); ib.Index2( u * nTessellationRes + nv, nu * nTessellationRes + v); ib.Index2( nu * nTessellationRes + nv, u * nTessellationRes + nv );
} } ib.Unlock( );
m_nHemiIndices = indexDesc.m_nElementCount;
// VB
int nVertices = ( nTessellationRes ) * ( nTessellationRes );
BufferDesc_t vertexDesc; vertexDesc.m_nElementSizeInBytes = sizeof(SphereVertex_t); vertexDesc.m_nElementCount = nVertices; vertexDesc.m_pDebugName = "hemiVB"; vertexDesc.m_pBudgetGroupName = "shapes"; m_hHemiVB = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_STATIC, vertexDesc );
CVertexData<SphereVertex_t> vb( pRenderContext, m_hHemiVB ); vb.Lock( nVertices );
for( int u = 0 ; u < nTessellationRes; u++ ) { float flU = u * ( 1.0 / nTessellationRes ); for( int v = 0; v < nTessellationRes; v++ ) { float flV = v * ( 1.0 / nTessellationRes ); Vector pos1 = Evaluate( flU + 0.5 / nTessellationRes, flV, vRadius ); if ( pos1.z < 0 ) pos1.z = 0; vb->m_vPos = pos1; vb.AdvanceVertex(); } } vb.Unlock( );
pRenderContext->Submit(); }
void CWorldRendererTest::CreateCone( int nTessellationRes ) { CRenderContextPtr pRenderContext( g_pRenderDevice );
Vector vTop(0,0,0);
int nVertices = nTessellationRes + 1; int nIndices = ( nTessellationRes + nTessellationRes - 2 ) * 3;
// create the static index buffer
BufferDesc_t indexDesc; indexDesc.m_nElementSizeInBytes = sizeof(uint16); indexDesc.m_nElementCount = nIndices; indexDesc.m_pDebugName = "coneib"; indexDesc.m_pBudgetGroupName = "shapes"; m_hConeIB = g_pRenderDevice->CreateIndexBuffer( RENDER_BUFFER_TYPE_STATIC, indexDesc );
// create the static vertex buffer
BufferDesc_t vertexDesc; vertexDesc.m_nElementSizeInBytes = sizeof(SphereVertex_t); vertexDesc.m_nElementCount = nVertices; vertexDesc.m_pDebugName = "conevb"; vertexDesc.m_pBudgetGroupName = "shapes"; m_hConeVB = g_pRenderDevice->CreateVertexBuffer( RENDER_BUFFER_TYPE_STATIC, vertexDesc );
m_nConeIndices = nIndices;
CVertexData<SphereVertex_t> vb( pRenderContext, m_hConeVB ); vb.Lock( nVertices );
vb->m_vPos = vTop; vb.AdvanceVertex();
float flTesRes = (float)nTessellationRes; for ( int i=0; i<nTessellationRes; ++i ) { float flU = ( i / flTesRes ) * (2.0 * M_PI);
Vector vPos = Vector( 1.1f * cos( flU ), 1.1f * sin( flU ), 1 );
vb->m_vPos = vPos; vb.AdvanceVertex(); }
vb.Unlock();
CIndexData<uint16> ib( pRenderContext, m_hConeIB ); ib.Lock( indexDesc.m_nElementCount );
// Cone
for ( int i=1; i<nTessellationRes+1; ++i ) { ib.Index( 0 ); ib.Index( i ); ib.Index( ( i % nTessellationRes ) + 1 ); }
// Cap
for ( int i=2; i<nTessellationRes; ++i ) { ib.Index( ( i + 1 ) ); ib.Index( i ); ib.Index( 1 ); }
ib.Unlock(); }
bool LoadFile( char *pFileName, CUtlBuffer &buffer, const char *pShaderVersion ) { Assert( pFileName && pShaderVersion );
char pLocalFileName[260]; Q_snprintf( pLocalFileName, 260, "%s.%s", pFileName, pShaderVersion );
if ( !g_pFullFileSystem->ReadFile( pLocalFileName, NULL, buffer ) ) { Error( "Couldn't load %s!\n", pFileName ); return false; } return true; }
RenderShaderHandle_t CWorldRendererTest::GetVertexShader( char *pShaderName, IRenderDevice *pDevice, const char *pShaderVersion, const char *pDefineText ) { CUtlBuffer buffer;
char pLevelText[100]; if ( 0 == Q_strncmp( pShaderVersion, "vs_3_0", 6 ) || 0 == Q_strncmp( pShaderVersion, "ps_3_0", 6 ) ) Q_snprintf( pLevelText, 100, "#define SHADER_LEVEL 3\n" ); else Q_snprintf( pLevelText, 100, "#define SHADER_LEVEL 4\n" ); buffer.Put( pLevelText, strlen( pLevelText ) );
if ( pDefineText ) buffer.Put( pDefineText, strlen( pDefineText ) );
if ( !LoadFile( pShaderName, buffer, "vs_3_0" ) ) { return RENDER_SHADER_HANDLE_INVALID; }
char *pText = (char*)buffer.Base(); int nBytes = buffer.TellPut(); if ( nBytes < 1 ) return RENDER_SHADER_HANDLE_INVALID;
// Create the shader
return pDevice->CreateShader( RENDER_VERTEX_SHADER, pText, nBytes, pShaderVersion ); }
RenderShaderHandle_t CWorldRendererTest::GetPixelShader( char *pShaderName, IRenderDevice *pDevice, const char *pShaderVersion, const char *pDefineText ) { CUtlBuffer buffer;
char pLevelText[100]; if ( 0 == Q_strncmp( pShaderVersion, "ps_3_0", 6 ) ) Q_snprintf( pLevelText, 100, "#define SHADER_LEVEL 3\n" ); else Q_snprintf( pLevelText, 100, "#define SHADER_LEVEL 4\n" ); buffer.Put( pLevelText, strlen( pLevelText ) );
if ( pDefineText ) buffer.Put( pDefineText, strlen( pDefineText ) );
if ( !LoadFile( pShaderName, buffer, "ps_3_0" ) ) { return RENDER_SHADER_HANDLE_INVALID; }
char *pText = (char*)buffer.Base(); int nBytes = buffer.TellPut(); if ( nBytes < 1 ) return RENDER_SHADER_HANDLE_INVALID;
// Create the shader
return pDevice->CreateShader( RENDER_PIXEL_SHADER, pText, nBytes, pShaderVersion ); }
intp g_nMagicNumber = 1234567; HRenderTexture CWorldRendererTest::CreateRenderTarget( RenderTargetType_t type, const RenderViewport_t &viewport ) { HRenderTexture hRetHandle = RENDER_TEXTURE_HANDLE_INVALID; TextureHeader_t spec; spec.m_nNumMipLevels = 1; spec.m_nDepth = 1; spec.m_Reflectivity.Init( 1, 1, 1 );
int nLowResWidth = (int)( viewport.m_nWidth * m_flLowResBufferScale ); int nLowResHeight = (int)( viewport.m_nHeight * m_flLowResBufferScale );
ImageFormat ssaoFormat = IMAGE_FORMAT_A8; if ( g_nPlatform == RST_PLATFORM_DX11 ) ssaoFormat = IMAGE_FORMAT_RGBA8888;
switch ( type ) { case DS_SHADOW_DEPTH0: case DS_SHADOW_DEPTH1: case DS_SHADOW_DEPTH2: { spec.m_nWidth = m_nShadowSize; spec.m_nHeight = m_nShadowSize; spec.m_nFlags = TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_D24X8/*IMAGE_FORMAT_D16*/; } break;
case DS_SHADOW_DEPTH_MULTIPLE: { spec.m_nWidth = m_nShadowSize; spec.m_nHeight = m_nShadowSize; spec.m_nFlags = TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_D24X8/*IMAGE_FORMAT_D16*/; } break;
case RT_SHADOW_MULTIPLE_0: case RT_SHADOW_MULTIPLE_1: case RT_SHADOW_BLUR_TEMP: { spec.m_nWidth = m_nShadowSize; spec.m_nHeight = m_nShadowSize; spec.m_nFlags = TSPEC_RENDER_TARGET; spec.m_nImageFormat = IMAGE_FORMAT_RG1616F; } break;
case DS_DEPTH_HIGHRES: { spec.m_nWidth = viewport.m_nWidth; spec.m_nHeight = viewport.m_nHeight; spec.m_nFlags = TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_D24S8; } break; case RT_VIEW_DEPTH_HIGHRES: { spec.m_nWidth = viewport.m_nWidth; spec.m_nHeight = viewport.m_nHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_R32F; } break; case RT_VIEW_NORMAL_HIGHRES: { spec.m_nWidth = viewport.m_nWidth; spec.m_nHeight = viewport.m_nHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_RGBA1010102; } break; case RT_VIEW_SPEC_HIGHRES: { spec.m_nWidth = viewport.m_nWidth; spec.m_nHeight = viewport.m_nHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_BGRA8888; if ( g_nPlatform == RST_PLATFORM_DX11 ) { spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888; } } break; case RT_LIGHTING_HIGHRES: { spec.m_nWidth = viewport.m_nWidth; spec.m_nHeight = viewport.m_nHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_RGBA16161616F; /*
if ( g_nPlatform == RST_PLATFORM_DX11 ) { spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888; } */ } break; case RT_SPECULAR_HIGHRES: { spec.m_nWidth = viewport.m_nWidth; spec.m_nHeight = viewport.m_nHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_BGRA8888; if ( g_nPlatform == RST_PLATFORM_DX11 ) { spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888; } } break; case DS_DEPTH_LOWRES: { spec.m_nWidth = nLowResWidth; spec.m_nHeight = nLowResHeight; spec.m_nFlags = 0; spec.m_nImageFormat = IMAGE_FORMAT_D24S8; } break; case RT_VIEW_DEPTH_LOWRES: { spec.m_nWidth = nLowResWidth; spec.m_nHeight = nLowResHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_R32F; } break; case RT_VIEW_NORMAL_LOWRES: { spec.m_nWidth = nLowResWidth; spec.m_nHeight = nLowResHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_RGBA1010102; } break; case RT_LIGHTING_LOWRES: { spec.m_nWidth = nLowResWidth; spec.m_nHeight = nLowResHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_BGRA8888; if ( g_nPlatform == RST_PLATFORM_DX11 ) { spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888; } } break; case RT_LIGHTING_TEMP_LOWRES: { spec.m_nWidth = nLowResWidth; spec.m_nHeight = nLowResHeight; spec.m_nFlags = TSPEC_RENDER_TARGET | TSPEC_UNFILTERABLE_OK | TSPEC_RENDER_TARGET_SAMPLEABLE; spec.m_nImageFormat = IMAGE_FORMAT_BGRA8888; if ( g_nPlatform == RST_PLATFORM_DX11 ) { spec.m_nImageFormat = IMAGE_FORMAT_RGBA8888; } } break;
default: return RENDER_TEXTURE_HANDLE_INVALID; }
char pResourceName[16]; Q_snprintf( pResourceName, sizeof(pResourceName), "%d", g_nMagicNumber ); ++g_nMagicNumber; hRetHandle = g_pRenderDevice->FindOrCreateTexture( "worldrenderer", pResourceName, &spec ); return hRetHandle; }
RenderTargetBinding_t CWorldRendererTest::CreateRenderTargetBinding( ViewBindingType_t type, const RenderViewport_t &viewport ) { RenderTargetBinding_t hRetHandle = RENDER_TARGET_BINDING_INVALID; HRenderTexture pRenderTargets[ 4 ] = { RENDER_TEXTURE_HANDLE_INVALID, RENDER_TEXTURE_HANDLE_INVALID, RENDER_TEXTURE_HANDLE_INVALID, RENDER_TEXTURE_HANDLE_INVALID }; HRenderTexture hDepthStencil; int nTargets = 0; int nFlags = 0;
RenderViewport_t lowResViewport = viewport; lowResViewport.m_nWidth = (int)( viewport.m_nWidth * m_flLowResBufferScale ); lowResViewport.m_nHeight = (int)( viewport.m_nHeight * m_flLowResBufferScale );
CWorldRenderFrustum *pFrustum = NULL; RenderViewport_t targetViewport; int nViewFlags = VIEW_PLAYER_CAMERA; int nViewPass = 0;
switch ( type ) { case RTB_SHADOW_DEPTH0: case RTB_SHADOW_DEPTH1: case RTB_SHADOW_DEPTH2: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ]; hDepthStencil = m_pRenderTargets[ type - DS_SHADOW_DEPTH0 ]; nFlags = DISCARD_CONTENTS;
pFrustum = m_pSplitFrustums[ type - DS_SHADOW_DEPTH0 ]; targetViewport = m_shadowViewport; nViewFlags = VIEW_LIGHT_SHADOW; nViewPass = VARIATION_DEPTH; } break; case RTB_SHADOW_DEPTH_MULTIPLE_0: case RTB_SHADOW_DEPTH_MULTIPLE_1: case RTB_SHADOW_DEPTH_MULTIPLE_2: case RTB_SHADOW_DEPTH_MULTIPLE_3: case RTB_SHADOW_DEPTH_MULTIPLE_4: case RTB_SHADOW_DEPTH_MULTIPLE_5: case RTB_SHADOW_DEPTH_MULTIPLE_6: case RTB_SHADOW_DEPTH_MULTIPLE_7: case RTB_SHADOW_DEPTH_MULTIPLE_8: case RTB_SHADOW_DEPTH_MULTIPLE_9: case RTB_SHADOW_DEPTH_MULTIPLE_10: case RTB_SHADOW_DEPTH_MULTIPLE_11: case RTB_SHADOW_DEPTH_MULTIPLE_12: case RTB_SHADOW_DEPTH_MULTIPLE_13: case RTB_SHADOW_DEPTH_MULTIPLE_14: case RTB_SHADOW_DEPTH_MULTIPLE_15: case RTB_SHADOW_DEPTH_MULTIPLE_16: case RTB_SHADOW_DEPTH_MULTIPLE_17: case RTB_SHADOW_DEPTH_MULTIPLE_18: case RTB_SHADOW_DEPTH_MULTIPLE_19: case RTB_SHADOW_DEPTH_MULTIPLE_20: case RTB_SHADOW_DEPTH_MULTIPLE_21: case RTB_SHADOW_DEPTH_MULTIPLE_22: case RTB_SHADOW_DEPTH_MULTIPLE_23: case RTB_SHADOW_DEPTH_MULTIPLE_24: case RTB_SHADOW_DEPTH_MULTIPLE_25: case RTB_SHADOW_DEPTH_MULTIPLE_26: case RTB_SHADOW_DEPTH_MULTIPLE_27: case RTB_SHADOW_DEPTH_MULTIPLE_28: case RTB_SHADOW_DEPTH_MULTIPLE_29: case RTB_SHADOW_DEPTH_MULTIPLE_30: case RTB_SHADOW_DEPTH_MULTIPLE_31: { int nFrustum = type - RTB_SHADOW_DEPTH_MULTIPLE_0;
nTargets = 1; if ( nFrustum < NUM_HIGH_RES_SHADOWS ) pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ]; else pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_1 ];
hDepthStencil = m_pRenderTargets[ DS_SHADOW_DEPTH_MULTIPLE ]; nFlags = PRESERVE_DEPTHSTENCIL;//DISCARD_CONTENTS;
if ( nFrustum < NUM_MULTI_SHADOWS ) { pFrustum = m_pMultiShadowFrustums[ nFrustum ]; targetViewport = m_multiShadowViewport[ nFrustum ]; } else { pFrustum = NULL; targetViewport = viewport; } nViewFlags = VIEW_LIGHT_SHADOW; nViewPass = VARIATION_DEPTH; } break;
case RTB_DEFERRED_DEPTH_NORM_SPEC: { nTargets = 3; pRenderTargets[0] = m_pRenderTargets[ RT_VIEW_NORMAL_HIGHRES ]; pRenderTargets[1] = m_pRenderTargets[ RT_VIEW_DEPTH_HIGHRES ]; pRenderTargets[2] = m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ]; hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ]; nFlags = DISCARD_CONTENTS;
pFrustum = m_pFrustum; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA; nViewPass = VARIATION_NORM_DEPTH_SPEC; } break; case RTB_DEFERRED_SCALE_DOWN: { nTargets = 2; pRenderTargets[0] = m_pRenderTargets[ RT_VIEW_DEPTH_LOWRES ]; pRenderTargets[1] = m_pRenderTargets[ RT_VIEW_NORMAL_LOWRES ]; hDepthStencil = m_pRenderTargets[ DS_DEPTH_LOWRES ]; nFlags = PRESERVE_DEPTHSTENCIL;
pFrustum = m_pFrustum; targetViewport = lowResViewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_DEFERRED_NORM_SPEC: { nTargets = 2; pRenderTargets[0] = m_pRenderTargets[ RT_VIEW_NORMAL_HIGHRES ]; pRenderTargets[1] = m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ]; hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ]; nFlags = PRESERVE_CONTENTS;
pFrustum = m_pFrustum; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_DECALS; nViewPass = 0; } break; case RTB_CLEAR_SPEC_HIGHRES: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_SPECULAR_HIGHRES ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = m_pFrustum; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_LIGHTING; nViewPass = VARIATION_DEFAULT; } break; case RTB_LIGHTING_HIGHRES: { nTargets = 2; pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_HIGHRES ]; pRenderTargets[1] = m_pRenderTargets[ RT_SPECULAR_HIGHRES ]; hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ]; nFlags = PRESERVE_DEPTHSTENCIL;
pFrustum = m_pFrustum; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_LIGHTING; nViewPass = VARIATION_DEFAULT; } break; case RTB_LIGHTING_LOWRES: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_LOWRES ]; hDepthStencil = m_pRenderTargets[ DS_DEPTH_LOWRES ]; nFlags = PRESERVE_DEPTHSTENCIL;
pFrustum = m_pFrustum; targetViewport = lowResViewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_LIGHTING; nViewPass = VARIATION_DEFAULT; } break; case RTB_SSAO_LOWRES: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_LOWRES ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = NULL; targetViewport = lowResViewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_BILAT_UPSAMPLE_0: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_TEMP_LOWRES ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = NULL; targetViewport = lowResViewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_BILAT_UPSAMPLE_1: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_HIGHRES ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = NULL; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_LIGHT_BLUR_0: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_VIEW_SPEC_HIGHRES ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = NULL; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_LIGHT_BLUR_1: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_LIGHTING_HIGHRES ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = NULL; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_SHADOW_BLUR_0: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_BLUR_TEMP ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = NULL; targetViewport = m_shadowViewport; nViewFlags = VIEW_LIGHT_SHADOW | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_SHADOW_BLUR_1: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_0 ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = NULL; targetViewport = m_shadowViewport; nViewFlags = VIEW_LIGHT_SHADOW | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_SHADOW_BLUR_2: { nTargets = 1; pRenderTargets[0] = m_pRenderTargets[ RT_SHADOW_MULTIPLE_1 ]; hDepthStencil = RENDER_TEXTURE_HANDLE_INVALID; nFlags = 0;
pFrustum = NULL; targetViewport = m_shadowViewport; nViewFlags = VIEW_LIGHT_SHADOW | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_SAMPLE_LIGHTING: { nTargets = 1; pRenderTargets[0] = RENDER_TEXTURE_DEFAULT_RENDER_TARGET; hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ]; nFlags = PRESERVE_DEPTHSTENCIL;
pFrustum = m_pFrustum; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA; nViewPass = VARIATION_SAMPLE_LIGHTING; } break; case RTB_AERIAL_PERSPECTIVE: { nTargets = 1; pRenderTargets[0] = RENDER_TEXTURE_DEFAULT_RENDER_TARGET; hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ]; nFlags = PRESERVE_DEPTHSTENCIL;
pFrustum = NULL; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_SKY: { nTargets = 1; pRenderTargets[0] = RENDER_TEXTURE_DEFAULT_RENDER_TARGET; hDepthStencil = m_pRenderTargets[ DS_DEPTH_HIGHRES ]; nFlags = PRESERVE_DEPTHSTENCIL;
pFrustum = m_pFrustum; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA | VIEW_POST_PROCESS; nViewPass = VARIATION_DEFAULT; } break; case RTB_FORWARD: { nTargets = 1; pRenderTargets[0] = RENDER_TEXTURE_DEFAULT_RENDER_TARGET; hDepthStencil = RENDER_TEXTURE_DEFAULT_RENDER_TARGET; nFlags = PRESERVE_DEPTHSTENCIL;
pFrustum = m_pFrustum; targetViewport = viewport; nViewFlags = VIEW_PLAYER_CAMERA; nViewPass = VARIATION_DEFAULT; } break;
default: return RENDER_TARGET_BINDING_INVALID; }
hRetHandle = g_pRenderDevice->CreateRenderTargetBinding( nFlags, nTargets, pRenderTargets, hDepthStencil ); m_pRenderViews[ type ].Init( g_pRenderDevice, pFrustum, hRetHandle, targetViewport, (RenderViewFlags_t)nViewFlags, nViewPass, type );
return hRetHandle; }
void CWorldRendererTest::SetStateForRenderViewType( IRenderContext *pRenderContext, int nRenderView ) { switch ( nRenderView ) { case RTB_SHADOW_DEPTH0: case RTB_SHADOW_DEPTH1: case RTB_SHADOW_DEPTH2: { pRenderContext->SetBlendMode( RENDER_BLEND_NOPIXELWRITE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_NONE ); } break; case RTB_SHADOW_DEPTH_MULTIPLE_0: case RTB_SHADOW_DEPTH_MULTIPLE_1: case RTB_SHADOW_DEPTH_MULTIPLE_2: case RTB_SHADOW_DEPTH_MULTIPLE_3: case RTB_SHADOW_DEPTH_MULTIPLE_4: case RTB_SHADOW_DEPTH_MULTIPLE_5: case RTB_SHADOW_DEPTH_MULTIPLE_6: case RTB_SHADOW_DEPTH_MULTIPLE_7: case RTB_SHADOW_DEPTH_MULTIPLE_8: case RTB_SHADOW_DEPTH_MULTIPLE_9: case RTB_SHADOW_DEPTH_MULTIPLE_10: case RTB_SHADOW_DEPTH_MULTIPLE_11: case RTB_SHADOW_DEPTH_MULTIPLE_12: case RTB_SHADOW_DEPTH_MULTIPLE_13: case RTB_SHADOW_DEPTH_MULTIPLE_14: case RTB_SHADOW_DEPTH_MULTIPLE_15: case RTB_SHADOW_DEPTH_MULTIPLE_16: case RTB_SHADOW_DEPTH_MULTIPLE_17: case RTB_SHADOW_DEPTH_MULTIPLE_18: case RTB_SHADOW_DEPTH_MULTIPLE_19: case RTB_SHADOW_DEPTH_MULTIPLE_20: case RTB_SHADOW_DEPTH_MULTIPLE_21: case RTB_SHADOW_DEPTH_MULTIPLE_22: case RTB_SHADOW_DEPTH_MULTIPLE_23: case RTB_SHADOW_DEPTH_MULTIPLE_24: case RTB_SHADOW_DEPTH_MULTIPLE_25: case RTB_SHADOW_DEPTH_MULTIPLE_26: case RTB_SHADOW_DEPTH_MULTIPLE_27: case RTB_SHADOW_DEPTH_MULTIPLE_28: case RTB_SHADOW_DEPTH_MULTIPLE_29: case RTB_SHADOW_DEPTH_MULTIPLE_30: case RTB_SHADOW_DEPTH_MULTIPLE_31: { pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); } break;
case RTB_DEFERRED_DEPTH_NORM_SPEC: { pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE_STENCIL_SET1 ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); } break; case RTB_DEFERRED_SCALE_DOWN: { } break; case RTB_DEFERRED_NORM_SPEC: { } break; case RTB_LIGHTING_HIGHRES: { } break; case RTB_LIGHTING_LOWRES: { } break; case RTB_SSAO_LOWRES: { } break; case RTB_BILAT_UPSAMPLE_0: { } break; case RTB_BILAT_UPSAMPLE_1: { } break; case RTB_LIGHT_BLUR_0: { } break; case RTB_LIGHT_BLUR_1: { } break; case RTB_SAMPLE_LIGHTING: { pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_EQUAL_NO_WRITE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING ); pRenderContext->BindTexture( 4, m_pRenderTargets[ RT_LIGHTING_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 4, RS_FILTER_MIN_MAG_MIP_POINT ); pRenderContext->BindTexture( 5, m_pRenderTargets[ RT_SPECULAR_HIGHRES ] ); pRenderContext->SetSamplerStatePS( 5, RS_FILTER_MIN_MAG_MIP_POINT ); } break; case RTB_AERIAL_PERSPECTIVE: { } break; case RTB_SKY: { } break; case RTB_FORWARD: { // viewport and state
pRenderContext->SetBlendMode( RENDER_BLEND_NONE ); pRenderContext->SetZBufferMode( RENDER_ZBUFFER_ZTEST_AND_WRITE ); pRenderContext->SetCullMode( RENDER_CULLMODE_CULL_BACKFACING );
// Bind
for ( int s=0; s<NUM_SHADOW_SPLITS; ++s ) { m_forwardLightingData.m_mShadowMatrices[s] = m_pShadowMatrices[s]; pRenderContext->BindTexture( 4 + s, m_pRenderTargets[ DS_SHADOW_DEPTH0 + s ] ); pRenderContext->SetSamplerStatePS( 4 + s, RS_FILTER_MIN_MAG_MIP_POINT ); }
pRenderContext->SetConstantBufferData( m_hLightingRelated, (void*)&m_forwardLightingData, sizeof( LightingConstants_t ) ); pRenderContext->BindConstantBuffer( RENDER_PIXEL_SHADER, m_hLightingRelated, 0, 0 ); } break; } }
void CWorldRendererTest::InitRenderTargetsAndViews( const RenderViewport_t &viewport ) { for ( int i=0; i<MAX_RENDER_TARGET_TYPES; ++i ) { m_pRenderTargets[i] = CreateRenderTarget( (RenderTargetType_t)i, viewport ); }
for ( int i=0; i<MAX_VIEW_BINDING_TYPES; ++i ) { m_pViewBindings[i] = CreateRenderTargetBinding( (ViewBindingType_t)i, viewport ); }
m_bRenderTargetsInit = true; }
void CWorldRendererTest::GetDescription( char *pNameBufferOut, size_t nBufLen ) { if ( m_nVariant ) { Q_snprintf( pNameBufferOut, nBufLen, "Render the world (deferred) (Press Space to Continue)" ); } else { Q_snprintf( pNameBufferOut, nBufLen, "Render the world (forward) (Press Space to Continue)" ); } }
//-----------------------------------------------------------------------------
// Can this test be run?
//-----------------------------------------------------------------------------
bool CWorldRendererTest::CanBeRun() { return ( g_pWorldRendererMgr != NULL ) && m_bWorldLoaded; }
//-----------------------------------------------------------------------------
// check for a keypress
//-----------------------------------------------------------------------------
bool CWorldRendererTest::ProcessUserInput( const InputEvent_t &ie ) { if ( ie.m_nType == IE_AnalogValueChanged ) { switch( ie.m_nData ) { case MOUSE_XY: if ( m_nWindowCenterX > 0 && m_nWindowCenterY > 0 ) { m_nCursorDeltaX += ie.m_nData2 - m_nWindowCenterX; m_nCursorDeltaY += ie.m_nData3 - m_nWindowCenterY; } break;
case JOYSTICK_AXIS( 0, JOY_AXIS_U ): m_nCursorDeltaResetX = ie.m_nData2 / 300; m_nCursorDeltaX += m_nCursorDeltaResetX; break;
case JOYSTICK_AXIS( 0, JOY_AXIS_R ): m_nCursorDeltaResetY = -ie.m_nData2 / 300; m_nCursorDeltaY += m_nCursorDeltaResetY; break;
case JOYSTICK_AXIS( 0, JOY_AXIS_X ): if ( abs( ie.m_nData2 ) < 2 ) { m_cmd.m_nKeys &= ~FKEY_RIGHT; m_cmd.m_nKeys &= ~FKEY_LEFT; } else if ( ie.m_nData2 > 0 ) { m_cmd.m_nKeys |= FKEY_RIGHT; m_cmd.m_nKeys &= ~FKEY_LEFT; } else { m_cmd.m_nKeys &= ~FKEY_RIGHT; m_cmd.m_nKeys |= FKEY_LEFT; } break;
case JOYSTICK_AXIS( 0, JOY_AXIS_Y ): if ( abs( ie.m_nData2 ) < 2 ) { m_cmd.m_nKeys &= ~FKEY_FORWARD; m_cmd.m_nKeys &= ~FKEY_BACK; } else if ( ie.m_nData2 > 0 ) { m_cmd.m_nKeys |= FKEY_FORWARD; m_cmd.m_nKeys &= ~FKEY_BACK; } else { m_cmd.m_nKeys &= ~FKEY_FORWARD; m_cmd.m_nKeys |= FKEY_BACK; } break; } } else if ( ie.m_nType == IE_ButtonPressed || ie.m_nType == IE_ButtonReleased ) { bool bDown = (ie.m_nType == IE_ButtonPressed) ? true : false; ButtonCode_t code = (ButtonCode_t)ie.m_nData; uint nFlag = 0; switch( code ) { case KEY_W: nFlag = FKEY_FORWARD; break; case KEY_S: nFlag = FKEY_BACK; break; case KEY_A: nFlag = FKEY_LEFT; break; case KEY_D: nFlag = FKEY_RIGHT; break; case KEY_UP: nFlag = FKEY_TURNUP; break; case KEY_DOWN: nFlag = FKEY_TURNDOWN; break; case KEY_LEFT: nFlag = FKEY_TURNLEFT; break; case KEY_RIGHT: nFlag = FKEY_TURNRIGHT; break; case KEY_XBUTTON_X: case MOUSE_LEFT: nFlag = FKEY_SHOOTDECAL; break; case KEY_XBUTTON_B: case KEY_N: nFlag = FKEY_SHOOTPSYSTEM; break; case KEY_XBUTTON_Y: case KEY_M: nFlag = FKEY_SHOOTSSYSTEM; break; case KEY_O: nFlag = FKEY_LIGHTELV; break; case KEY_XBUTTON_UP: case KEY_K: nFlag = FKEY_LIGHTANG_POS; break; case KEY_XBUTTON_DOWN: case KEY_L: nFlag = FKEY_LIGHTANG_NEG; break; case KEY_XBUTTON_LEFT_SHOULDER: case KEY_LSHIFT: nFlag = FKEY_FAST; break; case KEY_HOME: nFlag = FKEY_ENABLE_VIS; break; case KEY_END: nFlag = FKEY_DISABLE_VIS; break; case KEY_RSHIFT: nFlag = FKEY_DROP_FRUSTUM; break; case KEY_P: nFlag = FKEY_TOGGLE_AERIAL; break; case KEY_V: nFlag = FKEY_TOGGLE_BOUNCE; break; case KEY_C: nFlag = FKEY_TOGGLE_DIRECT; break; case KEY_B: nFlag = FKEY_TOGGLE_LIGHTING_ONLY; break; case KEY_PAD_ENTER: nFlag = FKEY_SSAO; break; case KEY_PAD_8: nFlag = FKEY_BLUR_LIGHTING; break; case KEY_PAD_9: nFlag = FKEY_BLUR_SHADOWS; break; case MOUSE_RIGHT: nFlag = FKEY_SHOOTDECAL2; break; case MOUSE_MIDDLE: nFlag = FKEY_SHOOTWALLMONSTER; break; case KEY_X: { if ( !bDown ) { m_bViewLowTexture = !m_bViewLowTexture; if ( m_bViewLowTexture ) Msg( "Low Texture Mode: On\n" ); else Msg( "Low Texture Mode: Off\n" ); } break; } case KEY_F: { if ( !bDown ) { m_bFlashlight = !m_bFlashlight; if ( m_bFlashlight ) Msg( "Flashlight: On\n" ); else Msg( "Flashlight: Off\n" ); } break; } case KEY_G: { if ( !bDown ) { Msg( "Dropped Renderable\n" ); DropRenderable(); } break; } case KEY_0: { // Reload shaders
if ( ie.m_nType == IE_ButtonPressed ) { g_pMaterialSystem2->DynamicShaderCompile_ReloadAllShaders(); return false; } break; } case KEY_PAD_PLUS: { m_flSampleRadius += 1.0f; Msg( "SSAO Sample Radius: %f\n", m_flSampleRadius ); break; } case KEY_PAD_MINUS: { m_flSampleRadius -= 1.0f; m_flSampleRadius = MAX( 1, m_flSampleRadius ); Msg( "SSAO Sample Radius: %f\n", m_flSampleRadius ); break; } case KEY_PAD_DIVIDE: { if ( !bDown ) { m_nViewBuffer = (RenderTargetType_t)( m_nViewBuffer + 1 ); if ( m_nViewBuffer >= MAX_RENDER_TARGET_TYPES ) { m_nViewBuffer = (RenderTargetType_t)0; }
Msg( "%s\n", g_pRenderTargetName[ m_nViewBuffer ] ); } break; } case KEY_PAD_MULTIPLY: { if ( !bDown ) { m_nViewBuffer = (RenderTargetType_t)( m_nViewBuffer - 1 ); if ( m_nViewBuffer < 0 ) { m_nViewBuffer = (RenderTargetType_t)( MAX_RENDER_TARGET_TYPES - 1 ); }
Msg( "%s\n", g_pRenderTargetName[ m_nViewBuffer ] ); } break; } case KEY_TAB: { m_nReportLevel = bDown ? 1 : 3; break; } case KEY_Z: { if ( !bDown ) { Vector vCameraOrigin( 100, 24975, 250 ); QAngle vCameraAngles( 9.6, -27, 0 );
m_pFrustum->SetCameraPosition( vCameraOrigin ); m_pFrustum->SetCameraAngles( vCameraAngles );
m_pWorldRenderer->ClearOutstandingLoadRequests(); } } break; } if ( nFlag ) { if ( bDown ) { m_cmd.m_nKeys |= nFlag; } else { m_cmd.m_nKeys &= ~nFlag; } return false; } }
return BaseClass::ProcessUserInput( ie ); }
static void PerformWorkUnit( SimulateWorkUnitWorldRender_t & job ) { for( int i =0; i < job.m_nNumSystems; i++ ) { job.m_pParticles->Simulate( job.m_flTimeStep ); } }
void CWorldRendererTest::SimulateParticles( float flTimeStep ) { int nSystems = m_particleWorkUnits.Count(); for( int i = 0; i < nSystems; i++ ) { m_particleWorkUnits[i].m_flTimeStep = flTimeStep; }
ParallelProcess( m_particleWorkUnits.Base(), nSystems, PerformWorkUnit ); }
|