You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
5.2 KiB
155 lines
5.2 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Responsible for drawing the scene |
|
// |
|
//===========================================================================// |
|
|
|
#include "cbase.h" |
|
#include "materialsystem/imaterialsystem.h" |
|
#include "materialsystem/imaterialvar.h" |
|
#include "materialsystem/imaterialsystemhardwareconfig.h" |
|
#include "rendertexture.h" |
|
#include "view_scene.h" |
|
#include "viewrender.h" |
|
#include "sourcevr/isourcevirtualreality.h" |
|
#include "client_virtualreality.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
//----------------------------------------------------------------------------- |
|
// Convars related to controlling rendering |
|
//----------------------------------------------------------------------------- |
|
ConVar r_updaterefracttexture( "r_updaterefracttexture", "1", FCVAR_CHEAT ); |
|
ConVar r_depthoverlay( "r_depthoverlay", "0", FCVAR_CHEAT, "Replaces opaque objects with their grayscaled depth values. r_showz_power scales the output." ); |
|
|
|
|
|
int g_viewscene_refractUpdateFrame = 0; |
|
bool g_bAllowMultipleRefractUpdatesPerScenePerFrame = false; |
|
|
|
#if defined( _X360 ) |
|
class CAllowMultipleRefractsLogic : public CAutoGameSystem |
|
{ |
|
public: |
|
void LevelInitPreEntity() |
|
{ |
|
// EP1 core room needs many refract updates per frame to avoid looking broken (ep1_citadel_03) |
|
// Same with Kleiner's lab (d1_trainstation_05) |
|
g_bAllowMultipleRefractUpdatesPerScenePerFrame = FStrEq( MapName(), "ep1_citadel_03" ) || FStrEq( MapName(), "d1_trainstation_05" ); |
|
} |
|
}; |
|
static CAllowMultipleRefractsLogic s_AllowMultipleRefractsLogic; |
|
#endif |
|
|
|
void ViewTransform( const Vector &worldSpace, Vector &viewSpace ) |
|
{ |
|
const VMatrix &viewMatrix = engine->WorldToViewMatrix(); |
|
Vector3DMultiplyPosition( viewMatrix, worldSpace, viewSpace ); |
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Transforms a world-space position into a 2D position inside a supplied frustum. |
|
//----------------------------------------------------------------------------- |
|
int FrustumTransform( const VMatrix &worldToSurface, const Vector& point, Vector& screen ) |
|
{ |
|
// UNDONE: Clean this up some, handle off-screen vertices |
|
float w; |
|
|
|
screen.x = worldToSurface[0][0] * point[0] + worldToSurface[0][1] * point[1] + worldToSurface[0][2] * point[2] + worldToSurface[0][3]; |
|
screen.y = worldToSurface[1][0] * point[0] + worldToSurface[1][1] * point[1] + worldToSurface[1][2] * point[2] + worldToSurface[1][3]; |
|
// z = worldToSurface[2][0] * point[0] + worldToSurface[2][1] * point[1] + worldToSurface[2][2] * point[2] + worldToSurface[2][3]; |
|
w = worldToSurface[3][0] * point[0] + worldToSurface[3][1] * point[1] + worldToSurface[3][2] * point[2] + worldToSurface[3][3]; |
|
|
|
// Just so we have something valid here |
|
screen.z = 0.0f; |
|
|
|
bool behind; |
|
if( w < 0.001f ) |
|
{ |
|
behind = true; |
|
screen.x *= 100000; |
|
screen.y *= 100000; |
|
} |
|
else |
|
{ |
|
behind = false; |
|
float invw = 1.0f / w; |
|
screen.x *= invw; |
|
screen.y *= invw; |
|
} |
|
|
|
return behind; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: UNDONE: Clean this up some, handle off-screen vertices |
|
// Input : *point - |
|
// *screen - |
|
// Output : int |
|
//----------------------------------------------------------------------------- |
|
int ScreenTransform( const Vector& point, Vector& screen ) |
|
{ |
|
// UNDONE: Clean this up some, handle off-screen vertices |
|
return FrustumTransform ( engine->WorldToScreenMatrix(), point, screen ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Same as ScreenTransform, but transforms to HUD space. |
|
// These are totally different things in VR mode! |
|
//----------------------------------------------------------------------------- |
|
int HudTransform( const Vector& point, Vector& screen ) |
|
{ |
|
if ( UseVR() ) |
|
{ |
|
return FrustumTransform ( g_ClientVirtualReality.GetHudProjectionFromWorld(), point, screen ); |
|
} |
|
else |
|
{ |
|
return FrustumTransform ( engine->WorldToScreenMatrix(), point, screen ); |
|
} |
|
} |
|
|
|
|
|
|
|
void UpdateFullScreenDepthTexture( void ) |
|
{ |
|
if( !g_pMaterialSystemHardwareConfig->SupportsPixelShaders_2_b() ) |
|
return; |
|
|
|
ITexture *pDepthTex = GetFullFrameDepthTexture(); |
|
CMatRenderContextPtr pRenderContext( materials ); |
|
|
|
if( IsX360() ) |
|
{ |
|
pRenderContext->CopyRenderTargetToTextureEx( pDepthTex, -1, NULL, NULL ); |
|
} |
|
else |
|
{ |
|
pRenderContext->CopyRenderTargetToTextureEx( pDepthTex, 0, NULL, NULL ); |
|
} |
|
|
|
pRenderContext->SetFullScreenDepthTextureValidityFlag( true ); |
|
|
|
if( r_depthoverlay.GetBool() ) |
|
{ |
|
IMaterial *pMaterial = materials->FindMaterial( "debug/showz", TEXTURE_GROUP_OTHER, true ); |
|
pMaterial->IncrementReferenceCount(); |
|
IMaterialVar *BaseTextureVar = pMaterial->FindVar( "$basetexture", NULL, false ); |
|
IMaterialVar *pDepthInAlpha = NULL; |
|
if( IsPC() ) |
|
{ |
|
pDepthInAlpha = pMaterial->FindVar( "$ALPHADEPTH", NULL, false ); |
|
pDepthInAlpha->SetIntValue( 1 ); |
|
} |
|
|
|
BaseTextureVar->SetTextureValue( pDepthTex ); |
|
|
|
pRenderContext->OverrideDepthEnable( true, false ); //don't write to depth, or else we'll never see translucents |
|
pRenderContext->DrawScreenSpaceQuad( pMaterial ); |
|
pRenderContext->OverrideDepthEnable( false, true ); |
|
pMaterial->DecrementReferenceCount(); |
|
} |
|
}
|
|
|