Skip to content

Commit 4e5cd8a

Browse files
committed
Add custom 2D SkyBox renderer to game client
1 parent 6cc2937 commit 4e5cd8a

5 files changed

Lines changed: 199 additions & 1 deletion

File tree

sp/src/game/client/iviewrender.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ abstract_class IViewRender
145145
virtual void FreezeFrame( float flFreezeTime ) = 0;
146146

147147
virtual IReplayScreenshotSystem *GetReplayScreenshotSystem() = 0;
148+
149+
#ifdef MAPBASE
150+
virtual bool BSetupSkyBox( const char *pszSkyName ) = 0;
151+
virtual void DrawSkyBox( const CViewSetup &View, bool bNoHeightClip ) = 0;
152+
#endif //MAPBASE
148153
};
149154

150155
extern IViewRender *view;

sp/src/game/client/view.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@
5959
#include "c_prop_portal.h" //portal surface rendering functions
6060
#endif
6161

62+
#ifdef MAPBASE
63+
#include "movevars_shared.h"
64+
#endif //MAPBASE
6265

6366
// memdbgon must be the last include file in a .cpp file!!!
6467
#include "tier0/memdbgon.h"
@@ -344,6 +347,11 @@ void CViewRender::LevelInit( void )
344347
}
345348
m_flFreezeFrameUntil = 0;
346349

350+
#ifdef MAPBASE
351+
// Ensure the sky is properly loaded
352+
BSetupSkyBox( sv_skyname.GetString() );
353+
#endif //MAPBASE
354+
347355
// Clear our overlay materials
348356
m_ScreenOverlayMaterial.Init( NULL );
349357

sp/src/game/client/viewrender.cpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
#ifdef MAPBASE
7878
#include "mapbase/c_func_fake_worldportal.h"
7979
#include "colorcorrectionmgr.h"
80+
#include "fmtstr.h"
8081
#endif
8182

8283
// Projective textures
@@ -126,6 +127,7 @@ static ConVar r_threaded_renderables( "r_threaded_renderables", "0" );
126127

127128
#ifdef MAPBASE
128129
static ConVar r_skybox_use_complex_views( "r_skybox_use_complex_views", "0", FCVAR_CHEAT, "Enable complex views in skyboxes, like reflective glass" );
130+
static ConVar r_skybox_use_new_renderer( "r_skybox_use_new_renderer", "1", FCVAR_NONE, "Use game client's 2D SkyBox renderer" );
129131
#endif
130132

131133
// FIXME: This is not static because we needed to turn it off for TF2 playtests
@@ -1994,6 +1996,119 @@ void CViewRender::CleanupMain3DView( const CViewSetup &view )
19941996
}
19951997

19961998

1999+
#ifdef MAPBASE
2000+
//-----------------------------------------------------------------------------
2001+
// Builds and draws the 2D SkyBox faces
2002+
//-----------------------------------------------------------------------------
2003+
CViewRender::skyface_t CViewRender::s_rgSkyFaces[ k_ESkyFaceCount ] =
2004+
{
2005+
{ "LF", {-1.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }, { 0.f, 0.f, 1.f } },
2006+
{ "RT", { 1.f, 0.f, 0.f }, { 0.f,-1.f, 0.f }, { 0.f, 0.f, 1.f } },
2007+
{ "FT", { 0.f,-1.f, 0.f }, {-1.f, 0.f, 0.f }, { 0.f, 0.f, 1.f } },
2008+
{ "BK", { 0.f, 1.f, 0.f }, { 1.f, 0.f, 0.f }, { 0.f, 0.f, 1.f } },
2009+
{ "UP", { 0.f, 0.f, 1.f }, { 0.f,-1.f, 0.f }, {-1.f, 0.f, 0.f } },
2010+
{ "DN", { 0.f, 0.f,-1.f }, { 0.f,-1.f, 0.f }, { 1.f, 0.f, 0.f } },
2011+
};
2012+
2013+
bool CViewRender::BSetupSkyBox( const char *pszSkyName )
2014+
{
2015+
bool bRetVal = true;
2016+
for ( int iFace = k_ESkyFaceFirst; iFace <= k_ESkyFaceLast; iFace++ )
2017+
{
2018+
auto &sf = s_rgSkyFaces[ iFace ];
2019+
2020+
sf.pMaterial.Init( CFmtStr( "SkyBox/%s%s", pszSkyName, sf.pszPostfix ), TEXTURE_GROUP_SKYBOX );
2021+
sf.nSamplingResolution = 256;
2022+
2023+
if ( IsErrorMaterial( sf.pMaterial ) )
2024+
{
2025+
bRetVal = false; // Mark as failed, but try to get rest of the faces..
2026+
continue;
2027+
}
2028+
2029+
// Get at the texture and it's mapping dimensions, since IMaterial::GetMappingWidth/Height is busted here
2030+
bool bFound;
2031+
IMaterialVar *pBaseTextureVar = sf.pMaterial->FindVar( "$BaseTexture", &bFound, false );
2032+
if ( bFound )
2033+
{
2034+
ITexture *pTexture = NULL;
2035+
switch ( pBaseTextureVar->GetType() )
2036+
{
2037+
case MATERIAL_VAR_TYPE_STRING:
2038+
pTexture = g_pMaterialSystem->FindTexture( pBaseTextureVar->GetStringValue(), TEXTURE_GROUP_SKYBOX, false );
2039+
break;
2040+
case MATERIAL_VAR_TYPE_TEXTURE:
2041+
pTexture = pBaseTextureVar->GetTextureValue();
2042+
break;
2043+
default:
2044+
Assert( NULL );
2045+
}
2046+
if ( pTexture )
2047+
{
2048+
sf.nSamplingResolution = Min( pTexture->GetMappingWidth(), pTexture->GetMappingHeight() );
2049+
}
2050+
}
2051+
}
2052+
return bRetVal;
2053+
}
2054+
2055+
void CViewRender::DrawSkyBox( const CViewSetup &View, bool bNoHeightClip )
2056+
{
2057+
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
2058+
2059+
MaterialHeightClipMode_t ePrevClipMode = pRenderContext->GetHeightClipMode();
2060+
if ( bNoHeightClip )
2061+
{
2062+
pRenderContext->SetHeightClipMode( MATERIAL_HEIGHTCLIPMODE_DISABLE );
2063+
}
2064+
2065+
float flDist = View.zFar / 2.f;
2066+
2067+
// Draw a quad for each face of the sky around the camera
2068+
for ( int iFace = k_ESkyFaceFirst; iFace <= k_ESkyFaceLast; iFace++ )
2069+
{
2070+
auto &sf = s_rgSkyFaces[ iFace ];
2071+
2072+
Vector vecCenter = flDist * sf.vecNormal + View.origin;
2073+
Vector vecRight = flDist * sf.vecRight;
2074+
Vector vecUp = flDist * sf.vecUp;
2075+
2076+
float flMinUV = .5f / ( float )sf.nSamplingResolution;
2077+
float flMaxUV = 1.f - flMinUV;
2078+
2079+
IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, sf.pMaterial );
2080+
2081+
CMeshBuilder MeshBuilder;
2082+
MeshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
2083+
2084+
MeshBuilder.Position3fv( ( vecCenter - vecRight + vecUp ).Base() );
2085+
MeshBuilder.TexCoord2f( 0, flMinUV, flMinUV );
2086+
MeshBuilder.AdvanceVertexF< VTX_HAVEPOS, 1 >();
2087+
2088+
MeshBuilder.Position3fv( ( vecCenter + vecRight + vecUp ).Base() );
2089+
MeshBuilder.TexCoord2f( 0, flMaxUV, flMinUV );
2090+
MeshBuilder.AdvanceVertexF< VTX_HAVEPOS, 1 >();
2091+
2092+
MeshBuilder.Position3fv( ( vecCenter + vecRight - vecUp ).Base() );
2093+
MeshBuilder.TexCoord2f( 0, flMaxUV, flMaxUV );
2094+
MeshBuilder.AdvanceVertexF< VTX_HAVEPOS, 1 >();
2095+
2096+
MeshBuilder.Position3fv( ( vecCenter - vecRight - vecUp ).Base() );
2097+
MeshBuilder.TexCoord2f( 0, flMinUV, flMaxUV );
2098+
MeshBuilder.AdvanceVertexF< VTX_HAVEPOS, 1 >();
2099+
2100+
MeshBuilder.End();
2101+
pMesh->Draw();
2102+
}
2103+
2104+
if ( bNoHeightClip )
2105+
{
2106+
pRenderContext->SetHeightClipMode( ePrevClipMode );
2107+
}
2108+
}
2109+
#endif //MAPBASE
2110+
2111+
19972112
//-----------------------------------------------------------------------------
19982113
// Queues up an overlay rendering
19992114
//-----------------------------------------------------------------------------
@@ -4102,7 +4217,25 @@ void CRendering3dView::DrawWorld( float waterZAdjust )
41024217
return;
41034218
}
41044219

4220+
#ifdef MAPBASE
4221+
unsigned long engineFlags;
4222+
if ( r_skybox_use_new_renderer.GetBool() )
4223+
{
4224+
if ( m_DrawFlags & DF_DRAWSKYBOX )
4225+
{
4226+
// Hook up our own 2D sky draw routine
4227+
m_pMainView->DrawSkyBox( ( *this ), !( m_DrawFlags & DF_CLIP_SKYBOX ) );
4228+
}
4229+
4230+
engineFlags = BuildEngineDrawWorldListFlags( m_DrawFlags & ~DF_DRAWSKYBOX );
4231+
}
4232+
else
4233+
{
4234+
engineFlags = BuildEngineDrawWorldListFlags( m_DrawFlags );
4235+
}
4236+
#else
41054237
unsigned long engineFlags = BuildEngineDrawWorldListFlags( m_DrawFlags );
4238+
#endif //MAPBASE
41064239

41074240
render->DrawWorldLists( m_pWorldRenderList, engineFlags, waterZAdjust );
41084241
}

sp/src/game/client/viewrender.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,12 @@ class CViewRender : public IViewRender,
438438
{
439439
m_UnderWaterOverlayMaterial.Init( pMaterial );
440440
}
441+
442+
#ifdef MAPBASE
443+
virtual bool BSetupSkyBox( const char *pszSkyName );
444+
virtual void DrawSkyBox( const CViewSetup &View, bool bNoHeightClip );
445+
#endif //MAPBASE
446+
441447
private:
442448
int m_BuildWorldListsNumber;
443449

@@ -559,6 +565,33 @@ class CViewRender : public IViewRender,
559565
#if defined( REPLAY_ENABLED )
560566
CReplayScreenshotTaker *m_pReplayScreenshotTaker;
561567
#endif
568+
569+
#ifdef MAPBASE
570+
enum ESkyFace
571+
{
572+
k_ESkyFaceLeft = 0,
573+
k_ESkyFaceRight,
574+
k_ESkyFaceFront,
575+
k_ESkyFaceBack,
576+
k_ESkyFaceUp,
577+
k_ESkyFaceDown,
578+
579+
k_ESkyFaceCount,
580+
581+
k_ESkyFaceFirst = k_ESkyFaceLeft,
582+
k_ESkyFaceLast = k_ESkyFaceDown
583+
};
584+
585+
struct skyface_t
586+
{
587+
const char *pszPostfix; // Postfix of the texture filename
588+
const Vector vecNormal, vecRight, vecUp; // Face direction and local tangent axes for building quads
589+
CMaterialReference pMaterial; // Material associated with this face
590+
int nSamplingResolution; // Used for UV clamping, smallest of texture width/height
591+
};
592+
593+
static skyface_t s_rgSkyFaces[ k_ESkyFaceCount ];
594+
#endif //MAPBASE
562595
};
563596

564597
#endif // VIEWRENDER_H

sp/src/game/shared/movevars_shared.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
#include "cbase.h"
99
#include "movevars_shared.h"
1010

11+
#if defined( CLIENT_DLL ) && defined( MAPBASE )
12+
#include "iviewrender.h"
13+
#endif // CLIENT_DLL && MAPBASE
14+
1115
#if defined( TF_CLIENT_DLL ) || defined( TF_DLL )
1216
#include "tf_gamerules.h"
1317
#endif
@@ -102,7 +106,22 @@ ConVar sv_backspeed ( "sv_backspeed", "0.6", FCVAR_ARCHIVE | FCVAR_REPLICATED |
102106
ConVar sv_waterdist ( "sv_waterdist","12", FCVAR_REPLICATED | FCVAR_DEVELOPMENTONLY, "Vertical view fixup when eyes are near water plane." );
103107
#endif // CSTRIKE_DLL
104108

105-
ConVar sv_skyname ( "sv_skyname", "sky_urb01", FCVAR_ARCHIVE | FCVAR_REPLICATED, "Current name of the skybox texture" );
109+
#if defined( CLIENT_DLL ) && defined( MAPBASE )
110+
static void OnSkyNameChanged( IConVar *pCVar, const char *pszOldValue, float flOldValue )
111+
{
112+
// Tell the view renderer that we have swapped skies
113+
if ( !view->BSetupSkyBox( sv_skyname.GetString() ) )
114+
{
115+
Warning( "Some/all faces of the \"%s\" SkyBox are missing or corrupted.\n", sv_skyname.GetString() );
116+
}
117+
}
118+
#endif // CLIENT_DLL && MAPBASE
119+
120+
ConVar sv_skyname ( "sv_skyname", "sky_urb01", FCVAR_ARCHIVE | FCVAR_REPLICATED, "Current name of the skybox texture"
121+
#if defined( CLIENT_DLL ) && defined( MAPBASE )
122+
, OnSkyNameChanged
123+
#endif // CLIENT_DLL && MAPBASE
124+
);
106125

107126
// Vehicle convars
108127
ConVar r_VehicleViewDampen( "r_VehicleViewDampen", "1", FCVAR_CHEAT | FCVAR_NOTIFY | FCVAR_REPLICATED );

0 commit comments

Comments
 (0)