704 lines
19 KiB
C++
704 lines
19 KiB
C++
|
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
|||
|
//
|
|||
|
// Purpose:
|
|||
|
//
|
|||
|
//=====================================================================================//
|
|||
|
|
|||
|
#include "quakedef.h"
|
|||
|
#include "gl_model_private.h"
|
|||
|
#include "console.h"
|
|||
|
#include "cdll_engine_int.h"
|
|||
|
#include "gl_cvars.h"
|
|||
|
#include "ivrenderview.h"
|
|||
|
#include "gl_matsysiface.h"
|
|||
|
#include "gl_drawlights.h"
|
|||
|
#include "gl_rsurf.h"
|
|||
|
#include "r_local.h"
|
|||
|
#include "debugoverlay.h"
|
|||
|
#include "vgui_baseui_interface.h"
|
|||
|
#include "materialsystem/imaterialsystemhardwareconfig.h"
|
|||
|
#include "demo.h"
|
|||
|
#include "istudiorender.h"
|
|||
|
#include "materialsystem/imesh.h"
|
|||
|
#include "tier0/vprof.h"
|
|||
|
#include "host.h"
|
|||
|
#include "view.h"
|
|||
|
#include "client.h"
|
|||
|
#include "sys.h"
|
|||
|
#include "cl_main.h"
|
|||
|
#include "l_studio.h"
|
|||
|
#include "IOcclusionSystem.h"
|
|||
|
#include "cl_demouipanel.h"
|
|||
|
#include "mod_vis.h"
|
|||
|
#include "ivideomode.h"
|
|||
|
#include "gl_shader.h"
|
|||
|
#include "gl_rmain.h"
|
|||
|
#include "engine/view_sharedv1.h"
|
|||
|
#include "ispatialpartitioninternal.h"
|
|||
|
#include "toolframework/itoolframework.h"
|
|||
|
#include "tier1/callqueue.h"
|
|||
|
#include "filesystem/IQueuedLoader.h"
|
|||
|
#include "r_decal.h"
|
|||
|
|
|||
|
#ifdef _PS3
|
|||
|
#include "tls_ps3.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined( INCLUDE_SCALEFORM )
|
|||
|
#include "scaleformui/scaleformui.h"
|
|||
|
#endif
|
|||
|
// memdbgon must be the last include file in a .cpp file!!!
|
|||
|
#include "tier0/memdbgon.h"
|
|||
|
|
|||
|
class IClientEntity;
|
|||
|
|
|||
|
float r_blend;
|
|||
|
float r_colormod[3] = { 1, 1, 1 };
|
|||
|
bool g_bIsBlendingOrModulating = false;
|
|||
|
|
|||
|
bool g_bIsRenderingVGuiOnly = false;
|
|||
|
|
|||
|
colorVec R_LightPoint (Vector& p);
|
|||
|
void R_DrawLightmaps( IWorldRenderList *pList, int pageId );
|
|||
|
void R_DrawIdentityBrushModel( IWorldRenderList *pRenderList, model_t *model );
|
|||
|
static ConVar r_brush_queue_mode( "r_brush_queue_mode", "0", FCVAR_CHEAT );
|
|||
|
|
|||
|
/*
|
|||
|
|
|||
|
The view is allowed to move slightly from it's true position for bobbing,
|
|||
|
but if it exceeds 8 pixels linear distance (spherical, not box), the list of
|
|||
|
entities sent from the server may not include everything in the pvs, especially
|
|||
|
when crossing a water boudnary.
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
extern ConVar r_avglightmap;
|
|||
|
|
|||
|
/*
|
|||
|
=================
|
|||
|
V_CheckGamma
|
|||
|
|
|||
|
FIXME: Define this as a change function to the ConVar's below rather than polling it
|
|||
|
every frame. Note, still need to make sure it gets called very first time through frame loop.
|
|||
|
=================
|
|||
|
*/
|
|||
|
bool V_CheckGamma( void )
|
|||
|
{
|
|||
|
if ( IsX360() )
|
|||
|
return false;
|
|||
|
|
|||
|
static int lastLightmap = -1;
|
|||
|
extern void GL_RebuildLightmaps( void );
|
|||
|
|
|||
|
// Refresh all lightmaps if r_avglightmap changes
|
|||
|
if ( r_avglightmap.GetInt() != lastLightmap )
|
|||
|
{
|
|||
|
lastLightmap = r_avglightmap.GetInt();
|
|||
|
GL_RebuildLightmaps();
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose: Initializes the view renderer
|
|||
|
// Output : void V_Init
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void V_Init( void )
|
|||
|
{
|
|||
|
BuildGammaTable( 2.2f, 2.2f, 0.0f, 2 );
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose:
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void V_Shutdown( void )
|
|||
|
{
|
|||
|
// TODO, cleanup
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose:
|
|||
|
// Input : -
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void V_RenderVGuiOnly_NoSwap()
|
|||
|
{
|
|||
|
// Need to clear the screen in this case, cause we're not drawing
|
|||
|
// the loading screen.
|
|||
|
UpdateMaterialSystemConfig();
|
|||
|
|
|||
|
CMatRenderContextPtr pRenderContext( materials );
|
|||
|
|
|||
|
pRenderContext->AntiAliasingHint( AA_HINT_MENU ); // would be better to do "Disable MLAA" here
|
|||
|
|
|||
|
pRenderContext->ClearBuffers( true, true );
|
|||
|
|
|||
|
#if defined( INCLUDE_SCALEFORM )
|
|||
|
// Render scaleform before vgui
|
|||
|
pRenderContext->AdvanceAndRenderScaleformSlot( SF_FULL_SCREEN_SLOT );
|
|||
|
#endif
|
|||
|
|
|||
|
EngineVGui()->Paint( PAINT_UIPANELS );
|
|||
|
|
|||
|
#if defined( INCLUDE_SCALEFORM )
|
|||
|
// Render cursor after vgui
|
|||
|
pRenderContext->AdvanceAndRenderScaleformCursor();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose: Renders only vgui (for loading progress) including buffer swapping and vgui simulation
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
|
|||
|
bool s_bTriggeredHostError = false;
|
|||
|
|
|||
|
void V_RenderVGuiOnly( void )
|
|||
|
{
|
|||
|
materials->BeginFrame( host_frametime );
|
|||
|
|
|||
|
CMatRenderContextPtr pRenderContext;
|
|||
|
pRenderContext.GetFrom( materials );
|
|||
|
pRenderContext->RenderScaleformSlot(SF_RESERVED_BEGINFRAME_SLOT);
|
|||
|
pRenderContext.SafeRelease();
|
|||
|
|
|||
|
EngineVGui()->Simulate();
|
|||
|
|
|||
|
g_EngineRenderer->FrameBegin();
|
|||
|
|
|||
|
toolframework->RenderFrameBegin();
|
|||
|
|
|||
|
V_RenderVGuiOnly_NoSwap();
|
|||
|
|
|||
|
toolframework->RenderFrameEnd();
|
|||
|
|
|||
|
g_EngineRenderer->FrameEnd( );
|
|||
|
|
|||
|
pRenderContext.GetFrom( materials );
|
|||
|
pRenderContext->RenderScaleformSlot(SF_RESERVED_ENDFRAME_SLOT);
|
|||
|
pRenderContext.SafeRelease();
|
|||
|
|
|||
|
materials->EndFrame();
|
|||
|
|
|||
|
Shader_SwapBuffers();
|
|||
|
|
|||
|
#ifdef _PS3
|
|||
|
if ( GetTLSGlobals()->bNormalQuitRequested )
|
|||
|
{
|
|||
|
// hack to prevent PS/3 deadlock on queued loader render mutex when quitting during loading a map
|
|||
|
uint nUnlockedQueuedRenderer = g_pQueuedLoader ? g_pQueuedLoader->UnlockProgressBarMutex() : 0;
|
|||
|
|
|||
|
if ( !s_bTriggeredHostError )
|
|||
|
{
|
|||
|
Assert( ThreadInMainThread() );
|
|||
|
s_bTriggeredHostError = true;
|
|||
|
Host_Error( "SystemQuitRequest" );
|
|||
|
}
|
|||
|
// hack to prevent PS/3 deadlock on queued loader render mutex when quitting during loading a map
|
|||
|
if( g_pQueuedLoader )
|
|||
|
{
|
|||
|
g_pQueuedLoader->LockProgressBarMutex( nUnlockedQueuedRenderer );
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose: Render the world
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
void V_RenderView( void )
|
|||
|
{
|
|||
|
VPROF( "V_RenderView" );
|
|||
|
MDLCACHE_COARSE_LOCK_(g_pMDLCache);
|
|||
|
|
|||
|
bool bCanRenderWorld = ( host_state.worldmodel != NULL ) && GetBaseLocalClient().IsActive();
|
|||
|
|
|||
|
bCanRenderWorld = bCanRenderWorld && !EngineVGui()->IsPlayingFullScreenVideo();
|
|||
|
|
|||
|
bCanRenderWorld = bCanRenderWorld && toolframework->ShouldGameRenderView();
|
|||
|
|
|||
|
if ( IsPC() && bCanRenderWorld && g_bTextMode )
|
|||
|
{
|
|||
|
// Sleep to let the other textmode clients get some cycles.
|
|||
|
Sys_Sleep( 15 );
|
|||
|
bCanRenderWorld = false;
|
|||
|
}
|
|||
|
|
|||
|
// Update stereo layer
|
|||
|
if ( !g_LostVideoMemory )
|
|||
|
{
|
|||
|
if ( materials && materials->IsStereoSupported() )
|
|||
|
{
|
|||
|
materials->NVStereoUpdate();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if ( !bCanRenderWorld )
|
|||
|
{
|
|||
|
// Because we now do a lot of downloading before spawning map, don't render anything world related
|
|||
|
// until we are an active client.
|
|||
|
V_RenderVGuiOnly_NoSwap();
|
|||
|
}
|
|||
|
else if ( !g_LostVideoMemory )
|
|||
|
{
|
|||
|
// since we know we're going to render the world, check for lightmap updates while it is easy
|
|||
|
// to tear down and rebuild
|
|||
|
R_CheckForLightingConfigChanges();
|
|||
|
R_CheckForPaintmapChanges();
|
|||
|
|
|||
|
// Pass game time to shader api
|
|||
|
{
|
|||
|
CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
|
|||
|
pRenderContext->UpdateGameTime( g_ClientGlobalVariables.curtime );
|
|||
|
}
|
|||
|
|
|||
|
// We can get into situations where some other material system app
|
|||
|
// is trying to start up; in those cases, we shouldn't render...
|
|||
|
vrect_t scr_vrect = videomode->GetClientViewRect();
|
|||
|
g_ClientDLL->View_Render( &scr_vrect );
|
|||
|
|
|||
|
// Cleanup all of the immediate cleanup decals here, after we've rendered the views.
|
|||
|
R_DecalFlushDestroyList( true );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void Linefile_Draw( void );
|
|||
|
|
|||
|
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
// Purpose: Expose rendering interface to client .dll
|
|||
|
//-----------------------------------------------------------------------------
|
|||
|
class CVRenderView : public IVRenderView, public ISpatialLeafEnumerator
|
|||
|
{
|
|||
|
public:
|
|||
|
void TouchLight( dlight_t *light )
|
|||
|
{
|
|||
|
int i;
|
|||
|
|
|||
|
i = light - cl_dlights;
|
|||
|
if (i >= 0 && i < MAX_DLIGHTS)
|
|||
|
{
|
|||
|
r_dlightchanged |= (1 << i);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void DrawBrushModel(
|
|||
|
IClientEntity *baseentity,
|
|||
|
model_t *model,
|
|||
|
const Vector& origin,
|
|||
|
const QAngle& angles,
|
|||
|
bool bUnused )
|
|||
|
{
|
|||
|
R_DrawBrushModel( baseentity, model, origin, angles, DEPTH_MODE_NORMAL, true, true );
|
|||
|
}
|
|||
|
|
|||
|
virtual void DrawBrushModelEx( IClientEntity *baseentity, model_t *model, const Vector& origin, const QAngle& angles, DrawBrushModelMode_t mode )
|
|||
|
{
|
|||
|
bool bDrawOpaque = ( mode != DBM_DRAW_TRANSLUCENT_ONLY );
|
|||
|
bool bDrawTranslucent = ( mode != DBM_DRAW_OPAQUE_ONLY );
|
|||
|
R_DrawBrushModel( baseentity, model, origin, angles, DEPTH_MODE_NORMAL, bDrawOpaque, bDrawTranslucent );
|
|||
|
}
|
|||
|
|
|||
|
virtual void DrawBrushModelArray( IMatRenderContext* pRenderContext, int nCount,
|
|||
|
const BrushArrayInstanceData_t *pInstanceData, int nModelTypeFlags )
|
|||
|
{
|
|||
|
#ifdef _DEBUG
|
|||
|
for ( int i = 0; i < nCount; ++i )
|
|||
|
{
|
|||
|
Assert( pRenderContext->IsRenderData( pInstanceData[i].m_pBrushToWorld ) );
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
ICallQueue *pCallQueue = pRenderContext->GetCallQueue();
|
|||
|
if ( !pCallQueue || r_brush_queue_mode.GetInt() == 0 )
|
|||
|
{
|
|||
|
R_DrawBrushModelArray( pRenderContext, nCount, pInstanceData, nModelTypeFlags );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
CMatRenderData< BrushArrayInstanceData_t > brushArrayData( pRenderContext );
|
|||
|
if ( !pRenderContext->IsRenderData( pInstanceData ) )
|
|||
|
{
|
|||
|
pInstanceData = brushArrayData.Lock( nCount, pInstanceData );
|
|||
|
}
|
|||
|
|
|||
|
pCallQueue->QueueCall( R_DrawBrushModelArray, nCount, pInstanceData, nModelTypeFlags );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Draw brush model shadow
|
|||
|
void DrawBrushModelShadow( IClientRenderable *pRenderable )
|
|||
|
{
|
|||
|
R_DrawBrushModelShadow( pRenderable );
|
|||
|
}
|
|||
|
|
|||
|
void DrawIdentityBrushModel( IWorldRenderList *pList, model_t *model )
|
|||
|
{
|
|||
|
R_DrawIdentityBrushModel( pList, model );
|
|||
|
}
|
|||
|
|
|||
|
void Draw3DDebugOverlays( void )
|
|||
|
{
|
|||
|
DrawSavedModelDebugOverlays();
|
|||
|
|
|||
|
if ( g_pDemoUI )
|
|||
|
{
|
|||
|
g_pDemoUI->DrawDebuggingInfo();
|
|||
|
}
|
|||
|
|
|||
|
//if ( g_pDemoUI2 )
|
|||
|
//{
|
|||
|
// g_pDemoUI2->DrawDebuggingInfo();
|
|||
|
//}
|
|||
|
|
|||
|
SpatialPartition()->DrawDebugOverlays();
|
|||
|
|
|||
|
CDebugOverlay::Draw3DOverlays();
|
|||
|
|
|||
|
// Render occlusion debugging info
|
|||
|
OcclusionSystem()->DrawDebugOverlays();
|
|||
|
}
|
|||
|
|
|||
|
FORCEINLINE void CheckBlend( void )
|
|||
|
{
|
|||
|
g_bIsBlendingOrModulating = ( r_blend != 1.0 ) ||
|
|||
|
( r_colormod[0] != 1.0 ) || ( r_colormod[1] != 1.0 ) || ( r_colormod[2] != 1.0 );
|
|||
|
|
|||
|
}
|
|||
|
void SetBlend( float blend )
|
|||
|
{
|
|||
|
r_blend = blend;
|
|||
|
CheckBlend();
|
|||
|
}
|
|||
|
|
|||
|
float GetBlend( void )
|
|||
|
{
|
|||
|
return r_blend;
|
|||
|
}
|
|||
|
|
|||
|
void SetColorModulation( float const* blend )
|
|||
|
{
|
|||
|
VectorCopy( blend, r_colormod );
|
|||
|
CheckBlend();
|
|||
|
}
|
|||
|
|
|||
|
void GetColorModulation( float* blend )
|
|||
|
{
|
|||
|
VectorCopy( r_colormod, blend );
|
|||
|
}
|
|||
|
|
|||
|
void SceneBegin( void )
|
|||
|
{
|
|||
|
g_EngineRenderer->DrawSceneBegin();
|
|||
|
}
|
|||
|
|
|||
|
void SceneEnd( void )
|
|||
|
{
|
|||
|
g_EngineRenderer->DrawSceneEnd();
|
|||
|
}
|
|||
|
|
|||
|
void GetVisibleFogVolume( const Vector& vEyePoint, const VisOverrideData_t *pVisOverrideData, VisibleFogVolumeInfo_t *pInfo )
|
|||
|
{
|
|||
|
R_GetVisibleFogVolume( vEyePoint, pVisOverrideData, pInfo );
|
|||
|
}
|
|||
|
|
|||
|
IWorldRenderList * CreateWorldList()
|
|||
|
{
|
|||
|
return g_EngineRenderer->CreateWorldList();
|
|||
|
}
|
|||
|
|
|||
|
#if defined(_PS3)
|
|||
|
IWorldRenderList * CreateWorldList_PS3( int viewID )
|
|||
|
{
|
|||
|
return g_EngineRenderer->CreateWorldList_PS3( viewID );
|
|||
|
}
|
|||
|
|
|||
|
void BuildWorldLists_PS3_Epilogue( IWorldRenderList *pList, WorldListInfo_t* pInfo, bool bShadowDepth )
|
|||
|
{
|
|||
|
g_EngineRenderer->BuildWorldLists_PS3_Epilogue( pList, pInfo, bShadowDepth );
|
|||
|
}
|
|||
|
#else
|
|||
|
void BuildWorldLists_Epilogue( IWorldRenderList *pList, WorldListInfo_t* pInfo, bool bShadowDepth )
|
|||
|
{
|
|||
|
g_EngineRenderer->BuildWorldLists_Epilogue( pList, pInfo, bShadowDepth );
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
void BuildWorldLists( IWorldRenderList *pList, WorldListInfo_t* pInfo, int iForceFViewLeaf, const VisOverrideData_t* pVisData, bool bShadowDepth, float *pReflectionWaterHeight )
|
|||
|
{
|
|||
|
g_EngineRenderer->BuildWorldLists( pList, pInfo, iForceFViewLeaf, pVisData, bShadowDepth, pReflectionWaterHeight );
|
|||
|
}
|
|||
|
|
|||
|
void DrawWorldLists( IMatRenderContext *pRenderContext, IWorldRenderList *pList, unsigned long flags, float waterZAdjust )
|
|||
|
{
|
|||
|
g_EngineRenderer->DrawWorldLists( pRenderContext, pList, flags, waterZAdjust );
|
|||
|
}
|
|||
|
|
|||
|
void GetWorldListIndicesInfo( WorldListIndicesInfo_t * pIndicesInfoOut, IWorldRenderList *pList, unsigned long nFlags )
|
|||
|
{
|
|||
|
return R_GetWorldListIndicesInfo( pIndicesInfoOut, pList, nFlags );
|
|||
|
}
|
|||
|
|
|||
|
// Optimization for top view
|
|||
|
void DrawTopView( bool enable )
|
|||
|
{
|
|||
|
R_DrawTopView( enable );
|
|||
|
}
|
|||
|
|
|||
|
void TopViewNoBackfaceCulling( bool bDisable )
|
|||
|
{
|
|||
|
R_TopViewNoBackfaceCulling( bDisable );
|
|||
|
}
|
|||
|
|
|||
|
void TopViewNoVisCheck( bool bDisable )
|
|||
|
{
|
|||
|
R_TopViewNoVisCheck( bDisable );
|
|||
|
}
|
|||
|
|
|||
|
void TopViewBounds( Vector2D const& mins, Vector2D const& maxs )
|
|||
|
{
|
|||
|
R_TopViewBounds( mins, maxs );
|
|||
|
}
|
|||
|
|
|||
|
void SetTopViewVolumeCuller( const CVolumeCuller *pVolumeCuller )
|
|||
|
{
|
|||
|
R_SetTopViewVolumeCuller( pVolumeCuller );
|
|||
|
}
|
|||
|
|
|||
|
void DrawLights( void )
|
|||
|
{
|
|||
|
DrawLightSprites();
|
|||
|
|
|||
|
#ifdef USE_CONVARS
|
|||
|
DrawLightDebuggingInfo();
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
void DrawMaskEntities( void )
|
|||
|
{
|
|||
|
// UNDONE: Don't do this with masked brush models, they should probably be in a separate list
|
|||
|
// R_DrawMaskEntities()
|
|||
|
}
|
|||
|
|
|||
|
void DrawTranslucentSurfaces( IMatRenderContext *pRenderContext, IWorldRenderList *pList, int *pSortList, int sortCount, unsigned long flags )
|
|||
|
{
|
|||
|
Shader_DrawTranslucentSurfaces( pRenderContext, pList, pSortList, sortCount, flags );
|
|||
|
}
|
|||
|
|
|||
|
bool LeafContainsTranslucentSurfaces( IWorldRenderList *pList, int sortIndex, unsigned long flags )
|
|||
|
{
|
|||
|
return Shader_LeafContainsTranslucentSurfaces( pList, sortIndex, flags );
|
|||
|
}
|
|||
|
|
|||
|
void DrawLineFile( void )
|
|||
|
{
|
|||
|
Linefile_Draw();
|
|||
|
}
|
|||
|
|
|||
|
void DrawLightmaps( IWorldRenderList *pList, int pageId )
|
|||
|
{
|
|||
|
R_DrawLightmaps( pList, pageId );
|
|||
|
}
|
|||
|
|
|||
|
void ViewSetupVis( bool novis, int numorigins, const Vector origin[] )
|
|||
|
{
|
|||
|
g_EngineRenderer->ViewSetupVis( novis, numorigins, origin );
|
|||
|
}
|
|||
|
|
|||
|
void ViewSetupVisEx( bool novis, int numorigins, const Vector origin[], unsigned int &returnFlags )
|
|||
|
{
|
|||
|
g_EngineRenderer->ViewSetupVisEx( novis, numorigins, origin, returnFlags );
|
|||
|
}
|
|||
|
|
|||
|
bool AreAnyLeavesVisible( int *leafList, int nLeaves )
|
|||
|
{
|
|||
|
return Map_AreAnyLeavesVisible( *host_state.worldbrush, leafList, nLeaves );
|
|||
|
}
|
|||
|
|
|||
|
// For backward compatibility only!!!
|
|||
|
void VguiPaint( void )
|
|||
|
{
|
|||
|
EngineVGui()->BackwardCompatibility_Paint();
|
|||
|
}
|
|||
|
|
|||
|
void VGui_Paint( int mode )
|
|||
|
{
|
|||
|
EngineVGui()->Paint( (PaintMode_t)mode );
|
|||
|
}
|
|||
|
|
|||
|
void ViewDrawFade( byte *color, IMaterial* pFadeMaterial, bool mapFullTextureToScreen )
|
|||
|
{
|
|||
|
VPROF_BUDGET( "ViewDrawFade", VPROF_BUDGETGROUP_WORLD_RENDERING );
|
|||
|
g_EngineRenderer->ViewDrawFade( color, pFadeMaterial, mapFullTextureToScreen );
|
|||
|
}
|
|||
|
|
|||
|
void OLD_SetProjectionMatrix( float fov, float zNear, float zFar )
|
|||
|
{
|
|||
|
// Here to preserve backwards compat
|
|||
|
}
|
|||
|
|
|||
|
void OLD_SetOffCenterProjectionMatrix( float fov, float zNear, float zFar, float flAspectRatio,
|
|||
|
float flBottom, float flTop, float flLeft, float flRight )
|
|||
|
{
|
|||
|
// Here to preserve backwards compat
|
|||
|
}
|
|||
|
|
|||
|
void OLD_SetProjectionMatrixOrtho( float left, float top, float right, float bottom, float zNear, float zFar )
|
|||
|
{
|
|||
|
// Here to preserve backwards compat
|
|||
|
}
|
|||
|
|
|||
|
colorVec GetLightAtPoint( Vector& pos )
|
|||
|
{
|
|||
|
return R_LightPoint( pos );
|
|||
|
}
|
|||
|
|
|||
|
int GetViewEntity( void )
|
|||
|
{
|
|||
|
return GetLocalClient().GetViewEntity();
|
|||
|
}
|
|||
|
|
|||
|
bool IsViewEntity( int entindex )
|
|||
|
{
|
|||
|
FOR_EACH_VALID_SPLITSCREEN_PLAYER( i )
|
|||
|
{
|
|||
|
if ( GetLocalClient( i ).GetViewEntity() == entindex )
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
float GetFieldOfView( void )
|
|||
|
{
|
|||
|
return g_EngineRenderer->GetFov();
|
|||
|
}
|
|||
|
|
|||
|
unsigned char **GetAreaBits( void )
|
|||
|
{
|
|||
|
return GetBaseLocalClient().GetAreaBits_BackwardCompatibility();
|
|||
|
}
|
|||
|
|
|||
|
virtual void SetAreaState(
|
|||
|
unsigned char chAreaBits[MAX_AREA_STATE_BYTES],
|
|||
|
unsigned char chAreaPortalBits[MAX_AREA_PORTAL_STATE_BYTES] )
|
|||
|
{
|
|||
|
*GetBaseLocalClient().GetAreaBits_BackwardCompatibility() = 0; // Clear the b/w compatibiltiy thing.
|
|||
|
memcpy( GetBaseLocalClient().m_chAreaBits, chAreaBits, MAX_AREA_STATE_BYTES );
|
|||
|
memcpy( GetBaseLocalClient().m_chAreaPortalBits, chAreaPortalBits, MAX_AREA_PORTAL_STATE_BYTES );
|
|||
|
GetBaseLocalClient().m_bAreaBitsValid = true;
|
|||
|
}
|
|||
|
|
|||
|
// World fog for world rendering
|
|||
|
void SetFogVolumeState( int fogVolume, bool useHeightFog )
|
|||
|
{
|
|||
|
R_SetFogVolumeState(fogVolume, useHeightFog );
|
|||
|
}
|
|||
|
|
|||
|
virtual void InstallBrushSurfaceRenderer( IBrushRenderer* pBrushRenderer )
|
|||
|
{
|
|||
|
R_InstallBrushRenderOverride( pBrushRenderer );
|
|||
|
}
|
|||
|
|
|||
|
struct BoxIntersectWaterContext_t
|
|||
|
{
|
|||
|
bool m_bFoundWaterLeaf;
|
|||
|
int m_nLeafWaterDataID;
|
|||
|
};
|
|||
|
|
|||
|
bool EnumerateLeaf( int leaf, intp context )
|
|||
|
{
|
|||
|
BoxIntersectWaterContext_t *pSearchContext = ( BoxIntersectWaterContext_t * )context;
|
|||
|
mleaf_t *pLeaf = &host_state.worldmodel->brush.pShared->leafs[leaf];
|
|||
|
if( pLeaf->leafWaterDataID == pSearchContext->m_nLeafWaterDataID )
|
|||
|
{
|
|||
|
pSearchContext->m_bFoundWaterLeaf = true;
|
|||
|
// found it . . stop enumeration
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
bool DoesBoxIntersectWaterVolume( const Vector &mins, const Vector &maxs, int leafWaterDataID )
|
|||
|
{
|
|||
|
BoxIntersectWaterContext_t context;
|
|||
|
context.m_bFoundWaterLeaf = false;
|
|||
|
context.m_nLeafWaterDataID = leafWaterDataID;
|
|||
|
g_pToolBSPTree->EnumerateLeavesInBox( mins, maxs, this, ( intp )&context );
|
|||
|
return context.m_bFoundWaterLeaf;
|
|||
|
}
|
|||
|
|
|||
|
// Push, pop views
|
|||
|
virtual void Push3DView( IMatRenderContext *pRenderContext, const CViewSetup &view, int nFlags, ITexture* pRenderTarget, Frustum frustumPlanes )
|
|||
|
{
|
|||
|
g_EngineRenderer->Push3DView( pRenderContext, view, nFlags, pRenderTarget, frustumPlanes, NULL );
|
|||
|
}
|
|||
|
|
|||
|
virtual void Push2DView( IMatRenderContext *pRenderContext, const CViewSetup &view, int nFlags, ITexture* pRenderTarget, Frustum frustumPlanes )
|
|||
|
{
|
|||
|
g_EngineRenderer->Push2DView( pRenderContext, view, nFlags, pRenderTarget, frustumPlanes );
|
|||
|
}
|
|||
|
|
|||
|
virtual void PopView( IMatRenderContext *pRenderContext, Frustum frustumPlanes )
|
|||
|
{
|
|||
|
g_EngineRenderer->PopView( pRenderContext, frustumPlanes );
|
|||
|
}
|
|||
|
|
|||
|
virtual void SetMainView( const Vector &vecOrigin, const QAngle &angles )
|
|||
|
{
|
|||
|
g_EngineRenderer->SetMainView( vecOrigin, angles );
|
|||
|
}
|
|||
|
|
|||
|
void OverrideViewFrustum( Frustum custom )
|
|||
|
{
|
|||
|
g_EngineRenderer->OverrideViewFrustum( custom );
|
|||
|
}
|
|||
|
|
|||
|
void DrawBrushModelShadowDepth(
|
|||
|
IClientEntity *baseentity,
|
|||
|
model_t *model,
|
|||
|
const Vector& origin,
|
|||
|
const QAngle& angles,
|
|||
|
ERenderDepthMode_t DepthMode )
|
|||
|
{
|
|||
|
R_DrawBrushModel( baseentity, model, origin, angles, DEPTH_MODE_SHADOW, true, true );
|
|||
|
}
|
|||
|
|
|||
|
void UpdateBrushModelLightmap( model_t *model, IClientRenderable *pRenderable )
|
|||
|
{
|
|||
|
g_EngineRenderer->UpdateBrushModelLightmap( model, pRenderable );
|
|||
|
}
|
|||
|
|
|||
|
void BeginUpdateLightmaps( void )
|
|||
|
{
|
|||
|
g_EngineRenderer->BeginUpdateLightmaps();
|
|||
|
}
|
|||
|
|
|||
|
void EndUpdateLightmaps()
|
|||
|
{
|
|||
|
g_EngineRenderer->EndUpdateLightmaps();
|
|||
|
}
|
|||
|
|
|||
|
virtual void Push3DView( IMatRenderContext *pRenderContext, const CViewSetup &view, int nFlags, ITexture* pRenderTarget, Frustum frustumPlanes, ITexture* pDepthTexture )
|
|||
|
{
|
|||
|
g_EngineRenderer->Push3DView( pRenderContext, view, nFlags, pRenderTarget, frustumPlanes, pDepthTexture );
|
|||
|
}
|
|||
|
|
|||
|
void GetMatricesForView( const CViewSetup &view, VMatrix *pWorldToView, VMatrix *pViewToProjection, VMatrix *pWorldToProjection, VMatrix *pWorldToPixels )
|
|||
|
{
|
|||
|
view.ComputeViewMatrices( pWorldToView, pViewToProjection, pWorldToProjection );
|
|||
|
ComputeWorldToScreenMatrix( pWorldToPixels, *pWorldToProjection, view );
|
|||
|
}
|
|||
|
|
|||
|
virtual bool DoesBrushModelNeedPowerOf2Framebuffer( const model_t *model )
|
|||
|
{
|
|||
|
return !!( model->flags & MODELFLAG_FRAMEBUFFER_TEXTURE );
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
static CVRenderView s_RenderView;
|
|||
|
EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CVRenderView, IVRenderView, VENGINE_RENDERVIEW_INTERFACE_VERSION, s_RenderView );
|
|||
|
|
|||
|
|
|||
|
|