diff options
Diffstat (limited to 'app/legion/rendermanager.cpp')
| -rw-r--r-- | app/legion/rendermanager.cpp | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/app/legion/rendermanager.cpp b/app/legion/rendermanager.cpp new file mode 100644 index 0000000..5d2e2a4 --- /dev/null +++ b/app/legion/rendermanager.cpp @@ -0,0 +1,255 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: The main manager of the rendering +// +// $Revision: $ +// $NoKeywords: $ +//===========================================================================// + +#include "rendermanager.h" +#include "legion.h" +#include "uimanager.h" +#include "worldmanager.h" +#include "materialsystem/imaterialsystem.h" +#include "tier2/tier2.h" + + +//----------------------------------------------------------------------------- +// Camera property +//----------------------------------------------------------------------------- +DEFINE_FIXEDSIZE_ALLOCATOR( CCameraProperty, 1, CMemoryPool::GROW_SLOW ); + + +CCameraProperty::CCameraProperty() +{ + m_Origin.Init(); + m_Angles.Init(); + m_Velocity.Init(); + m_AngVelocity.Init(); +} + +void CCameraProperty::GetForward( Vector *pForward ) +{ + AngleVectors( m_Angles, pForward ); +} + + +//----------------------------------------------------------------------------- +// Singleton accessor +//----------------------------------------------------------------------------- +static CRenderManager s_RenderManager; +extern CRenderManager *g_pRenderManager = &s_RenderManager; + + +//----------------------------------------------------------------------------- +// Game initialization +//----------------------------------------------------------------------------- +bool CRenderManager::Init() +{ + m_bRenderWorldFullscreen = true; + return true; +} + +void CRenderManager::Shutdown() +{ +} + + +//----------------------------------------------------------------------------- +// Level initialization +//----------------------------------------------------------------------------- +LevelRetVal_t CRenderManager::LevelInit( bool bFirstCall ) +{ + return FINISHED; +} + +LevelRetVal_t CRenderManager::LevelShutdown( bool bFirstCall ) +{ + return FINISHED; +} + + +//----------------------------------------------------------------------------- +// Property allocation +//----------------------------------------------------------------------------- +CCameraProperty *CRenderManager::CreateCameraProperty() +{ + return new CCameraProperty; +} + +void CRenderManager::DestroyCameraProperty( CCameraProperty *pProperty ) +{ + delete pProperty; +} + + +//----------------------------------------------------------------------------- +// Sets the rectangle to draw into +//----------------------------------------------------------------------------- +void CRenderManager::RenderWorldFullscreen() +{ + m_bRenderWorldFullscreen = true; +} + +void CRenderManager::RenderWorldInRect( int x, int y, int nWidth, int nHeight ) +{ + m_bRenderWorldFullscreen = false; + m_nRenderX = x; + m_nRenderY = y; + m_nRenderWidth = nWidth; + m_nRenderHeight = nHeight; +} + + +//----------------------------------------------------------------------------- +// Done completely client-side, want total smoothness, so simulate at render interval +//----------------------------------------------------------------------------- +void CRenderManager::UpdateLocalPlayerCamera() +{ + float dt = IGameManager::DeltaTime(); + CCameraProperty *pCamera = g_pWorldManager->GetLocalPlayer()->m_pCameraProperty; + VectorMA( pCamera->m_Origin, dt, pCamera->m_Velocity, pCamera->m_Origin ); + VectorMA( pCamera->m_Angles, dt, pCamera->m_AngVelocity, pCamera->m_Angles ); +} + + +//----------------------------------------------------------------------------- +// Per-frame update +//----------------------------------------------------------------------------- +void CRenderManager::Update( ) +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + if ( GetLevelState() == NOT_IN_LEVEL ) + { + g_pMaterialSystem->BeginFrame( 0 ); + pRenderContext->ClearColor4ub( 76, 88, 68, 255 ); + pRenderContext->ClearBuffers( true, true ); + g_pUIManager->DrawUI(); + g_pMaterialSystem->EndFrame(); + g_pMaterialSystem->SwapBuffers(); + return; + } + + UpdateLocalPlayerCamera(); + + g_pMaterialSystem->BeginFrame( 0 ); + pRenderContext->ClearColor4ub( 0, 0, 0, 255 ); + pRenderContext->ClearBuffers( true, true ); + RenderWorld(); + g_pUIManager->DrawUI(); + g_pMaterialSystem->EndFrame(); + g_pMaterialSystem->SwapBuffers(); +} + + +//----------------------------------------------------------------------------- +// Sets up the camera +//----------------------------------------------------------------------------- +void CRenderManager::SetupCameraRenderState( ) +{ + CCameraProperty *pCamera = g_pWorldManager->GetLocalPlayer()->m_pCameraProperty; + + matrix3x4_t cameraToWorld; + AngleMatrix( pCamera->m_Angles, pCamera->m_Origin, cameraToWorld ); + + matrix3x4_t matRotate; + matrix3x4_t matRotateZ; + MatrixBuildRotationAboutAxis( Vector(0,0,1), -90, matRotateZ ); + MatrixMultiply( cameraToWorld, matRotateZ, matRotate ); + + matrix3x4_t matRotateX; + MatrixBuildRotationAboutAxis( Vector(1,0,0), 90, matRotateX ); + MatrixMultiply( matRotate, matRotateX, matRotate ); + + matrix3x4_t view; + MatrixInvert( matRotate, view ); + + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->LoadMatrix( view ); +} + + +//----------------------------------------------------------------------------- +// Set up a projection matrix for a 90 degree fov +//----------------------------------------------------------------------------- + +// FIXME: Better control over Z range +#define ZNEAR 0.1f +#define ZFAR 10000.0f + +void CRenderManager::SetupProjectionMatrix( int nWidth, int nHeight, float flFOV ) +{ + VMatrix proj; + float flZNear = ZNEAR; + float flZFar = ZFAR; + float flApsectRatio = (nHeight != 0.0f) ? (float)nWidth / (float)nHeight : 100.0f; + + float halfWidth = tan( flFOV * M_PI / 360.0 ); + float halfHeight = halfWidth / flApsectRatio; + + memset( proj.Base(), 0, sizeof( proj ) ); + proj[0][0] = 1.0f / halfWidth; + proj[1][1] = 1.0f / halfHeight; + proj[2][2] = flZFar / ( flZNear - flZFar ); + proj[3][2] = -1.0f; + proj[2][3] = flZNear * flZFar / ( flZNear - flZFar ); + + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->LoadMatrix( proj ); +} + + +//----------------------------------------------------------------------------- +// Set up a orthographic projection matrix +//----------------------------------------------------------------------------- +void CRenderManager::SetupOrthoMatrix( int nWidth, int nHeight ) +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->LoadIdentity(); + pRenderContext->Ortho( 0, 0, nWidth, nHeight, -1.0f, 1.0f ); +} + + +//----------------------------------------------------------------------------- +// Renders the world +//----------------------------------------------------------------------------- +void CRenderManager::RenderWorld() +{ + CMatRenderContextPtr pRenderContext( g_pMaterialSystem ); + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PushMatrix(); + + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PushMatrix(); + + pRenderContext->MatrixMode( MATERIAL_MODEL ); + pRenderContext->PushMatrix(); + pRenderContext->LoadIdentity(); + + if ( m_bRenderWorldFullscreen ) + { + m_nRenderX = m_nRenderY = 0; + pRenderContext->GetRenderTargetDimensions( m_nRenderWidth, m_nRenderHeight ); + } + + pRenderContext->DepthRange( 0, 1 ); + pRenderContext->Viewport( m_nRenderX, m_nRenderY, m_nRenderWidth, m_nRenderHeight ); + + SetupProjectionMatrix( m_nRenderWidth, m_nRenderHeight, 90 ); + + SetupCameraRenderState(); + + g_pWorldManager->DrawWorld(); + + pRenderContext->MatrixMode( MATERIAL_PROJECTION ); + pRenderContext->PopMatrix(); + + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->PopMatrix(); + + pRenderContext->MatrixMode( MATERIAL_MODEL ); + pRenderContext->PopMatrix(); +}
\ No newline at end of file |