|
77 | 77 | #ifdef MAPBASE |
78 | 78 | #include "mapbase/c_func_fake_worldportal.h" |
79 | 79 | #include "colorcorrectionmgr.h" |
| 80 | +#include "fmtstr.h" |
80 | 81 | #endif |
81 | 82 |
|
82 | 83 | // Projective textures |
@@ -126,6 +127,7 @@ static ConVar r_threaded_renderables( "r_threaded_renderables", "0" ); |
126 | 127 |
|
127 | 128 | #ifdef MAPBASE |
128 | 129 | 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" ); |
129 | 131 | #endif |
130 | 132 |
|
131 | 133 | // 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 ) |
1994 | 1996 | } |
1995 | 1997 |
|
1996 | 1998 |
|
| 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 | + |
1997 | 2112 | //----------------------------------------------------------------------------- |
1998 | 2113 | // Queues up an overlay rendering |
1999 | 2114 | //----------------------------------------------------------------------------- |
@@ -4102,7 +4217,25 @@ void CRendering3dView::DrawWorld( float waterZAdjust ) |
4102 | 4217 | return; |
4103 | 4218 | } |
4104 | 4219 |
|
| 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 |
4105 | 4237 | unsigned long engineFlags = BuildEngineDrawWorldListFlags( m_DrawFlags ); |
| 4238 | +#endif //MAPBASE |
4106 | 4239 |
|
4107 | 4240 | render->DrawWorldLists( m_pWorldRenderList, engineFlags, waterZAdjust ); |
4108 | 4241 | } |
|
0 commit comments