1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
//========= 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();
}
}
|