diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /sp/src/game/client/spritemodel.cpp | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/game/client/spritemodel.cpp')
| -rw-r--r-- | sp/src/game/client/spritemodel.cpp | 1082 |
1 files changed, 541 insertions, 541 deletions
diff --git a/sp/src/game/client/spritemodel.cpp b/sp/src/game/client/spritemodel.cpp index ee548bf0..018e918f 100644 --- a/sp/src/game/client/spritemodel.cpp +++ b/sp/src/game/client/spritemodel.cpp @@ -1,542 +1,542 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose:
-//
-// $NoKeywords: $
-//===========================================================================//
-#include "cbase.h"
-#include "enginesprite.h"
-#include "hud.h"
-#include "materialsystem/imesh.h"
-#include "materialsystem/imaterial.h"
-#include "materialsystem/imaterialvar.h"
-#include "c_sprite.h"
-#include "tier1/callqueue.h"
-#include "tier1/KeyValues.h"
-#include "tier2/tier2.h"
-#include "filesystem.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-// Sprites are clipped to this rectangle (x,y,width,height) if ScissorTest is enabled
-static int scissor_x = 0;
-static int scissor_y = 0;
-static int scissor_width = 0;
-static int scissor_height = 0;
-static bool giScissorTest = false;
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Set the scissor
-// the coordinate system for gl is upsidedown (inverted-y) as compared to software, so the
-// specified clipping rect must be flipped
-// Input : x -
-// y -
-// width -
-// height -
-//-----------------------------------------------------------------------------
-void EnableScissorTest( int x, int y, int width, int height )
-{
- x = clamp( x, 0, ScreenWidth() );
- y = clamp( y, 0, ScreenHeight() );
- width = clamp( width, 0, ScreenWidth() - x );
- height = clamp( height, 0, ScreenHeight() - y );
-
- scissor_x = x;
- scissor_width = width;
- scissor_y = y;
- scissor_height = height;
-
- giScissorTest = true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void DisableScissorTest( void )
-{
- scissor_x = 0;
- scissor_width = 0;
- scissor_y = 0;
- scissor_height = 0;
-
- giScissorTest = false;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Verify that this is a valid, properly ordered rectangle.
-// Input : *prc -
-// Output : int
-//-----------------------------------------------------------------------------
-static int ValidateWRect(const wrect_t *prc)
-{
-
- if (!prc)
- return false;
-
- if ((prc->left >= prc->right) || (prc->top >= prc->bottom))
- {
- //!!!UNDONE Dev only warning msg
- return false;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: classic interview question
-// Input : *prc1 -
-// *prc2 -
-// *prc -
-// Output : int
-//-----------------------------------------------------------------------------
-static int IntersectWRect(const wrect_t *prc1, const wrect_t *prc2, wrect_t *prc)
-{
- wrect_t rc;
-
- if (!prc)
- prc = &rc;
-
- prc->left = MAX(prc1->left, prc2->left);
- prc->right = MIN(prc1->right, prc2->right);
-
- if (prc->left < prc->right)
- {
- prc->top = MAX(prc1->top, prc2->top);
- prc->bottom = MIN(prc1->bottom, prc2->bottom);
-
- if (prc->top < prc->bottom)
- return 1;
-
- }
-
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : x -
-// y -
-// width -
-// height -
-// u0 -
-// v0 -
-// u1 -
-// v1 -
-// Output : static bool
-//-----------------------------------------------------------------------------
-static bool Scissor( int& x, int& y, int& width, int& height, float& u0, float& v0, float& u1, float& v1 )
-{
- // clip sub rect to sprite
- if ((width == 0) || (height == 0))
- return false;
-
- if ((x + width <= scissor_x) || (x >= scissor_x + scissor_width) ||
- (y + height <= scissor_y) || (y >= scissor_y + scissor_height))
- return false;
-
- float dudx = (u1-u0) / width;
- float dvdy = (v1-v0) / height;
- if (x < scissor_x)
- {
- u0 += (scissor_x - x) * dudx;
- width -= scissor_x - x;
- x = scissor_x;
- }
-
- if (x + width > scissor_x + scissor_width)
- {
- u1 -= (x + width - (scissor_x + scissor_width)) * dudx;
- width = scissor_x + scissor_width - x;
- }
-
- if (y < scissor_y)
- {
- v0 += (scissor_y - y) * dvdy;
- height -= scissor_y - y;
- y = scissor_y;
- }
-
- if (y + height > scissor_y + scissor_height)
- {
- v1 -= (y + height - (scissor_y + scissor_height)) * dvdy;
- height = scissor_y + scissor_height - y;
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pSprite -
-// frame -
-// *pfLeft -
-// *pfRight -
-// *pfTop -
-// *pfBottom -
-// *pw -
-// *ph -
-// *prcSubRect -
-// Output : static void
-//-----------------------------------------------------------------------------
-static void AdjustSubRect(CEngineSprite *pSprite, int frame, float *pfLeft, float *pfRight, float *pfTop,
- float *pfBottom, int *pw, int *ph, const wrect_t *prcSubRect)
-{
- wrect_t rc;
- float f;
-
- if (!ValidateWRect(prcSubRect))
- return;
-
- // clip sub rect to sprite
-
- rc.top = rc.left = 0;
- rc.right = *pw;
- rc.bottom = *ph;
-
- if (!IntersectWRect(prcSubRect, &rc, &rc))
- return;
-
- *pw = rc.right - rc.left;
- *ph = rc.bottom - rc.top;
-
- f = 1.0 / (float)pSprite->GetWidth();;
- *pfLeft = ((float)rc.left + 0.5) * f;
- *pfRight = ((float)rc.right - 0.5) * f;
-
- f = 1.0 / (float)pSprite->GetHeight();
- *pfTop = ((float)rc.top + 0.5) * f;
- *pfBottom = ((float)rc.bottom - 0.5) * f;
-
- return;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-static unsigned int spriteOriginCache = 0;
-static unsigned int spriteOrientationCache = 0;
-bool CEngineSprite::Init( const char *pName )
-{
- m_VideoMaterial = NULL;
- for ( int i = 0; i < kRenderModeCount; ++i )
- {
- m_material[ i ] = NULL;
- }
-
- m_width = m_height = m_numFrames = 1;
-
- Assert( g_pVideo != NULL );
-
- if ( g_pVideo != NULL && g_pVideo->LocateVideoSystemForPlayingFile( pName ) != VideoSystem::NONE )
- {
- m_VideoMaterial = g_pVideo->CreateVideoMaterial( pName, pName, "GAME", VideoPlaybackFlags::DEFAULT_MATERIAL_OPTIONS, VideoSystem::DETERMINE_FROM_FILE_EXTENSION, false );
-
- if ( m_VideoMaterial == NULL )
- return false;
-
- IMaterial *pMaterial = m_VideoMaterial->GetMaterial();
- m_VideoMaterial->GetVideoImageSize( &m_width, &m_height );
- m_numFrames = m_VideoMaterial->GetFrameCount();
- for ( int i = 0; i < kRenderModeCount; ++i )
- {
- m_material[i] = pMaterial;
- pMaterial->IncrementReferenceCount();
- }
- }
- else
- {
- char pTemp[MAX_PATH];
- char pMaterialName[MAX_PATH];
- char pMaterialPath[MAX_PATH];
- Q_StripExtension( pName, pTemp, sizeof(pTemp) );
- Q_strlower( pTemp );
- Q_FixSlashes( pTemp, '/' );
-
- // Check to see if this is a UNC-specified material name
- bool bIsUNC = pTemp[0] == '/' && pTemp[1] == '/' && pTemp[2] != '/';
- if ( !bIsUNC )
- {
- Q_strncpy( pMaterialName, "materials/", sizeof(pMaterialName) );
- Q_strncat( pMaterialName, pTemp, sizeof(pMaterialName), COPY_ALL_CHARACTERS );
- }
- else
- {
- Q_strncpy( pMaterialName, pTemp, sizeof(pMaterialName) );
- }
- Q_strncpy( pMaterialPath, pMaterialName, sizeof(pMaterialPath) );
- Q_SetExtension( pMaterialPath, ".vmt", sizeof(pMaterialPath) );
-
- KeyValues *kv = new KeyValues( "vmt" );
- if ( !kv->LoadFromFile( g_pFullFileSystem, pMaterialPath, "GAME" ) )
- {
- Warning( "Unable to load sprite material %s!\n", pMaterialPath );
- return false;
- }
-
- for ( int i = 0; i < kRenderModeCount; ++i )
- {
- if ( i == kRenderNone || i == kRenderEnvironmental )
- {
- m_material[i] = NULL;
- continue;
- }
-
- Q_snprintf( pMaterialPath, sizeof(pMaterialPath), "%s_rendermode_%d", pMaterialName, i );
- KeyValues *pMaterialKV = kv->MakeCopy();
- pMaterialKV->SetInt( "$spriteRenderMode", i );
- m_material[i] = g_pMaterialSystem->FindProceduralMaterial( pMaterialPath, TEXTURE_GROUP_CLIENT_EFFECTS, pMaterialKV );
- m_material[ i ]->IncrementReferenceCount();
- }
-
- kv->deleteThis();
-
- m_width = m_material[0]->GetMappingWidth();
- m_height = m_material[0]->GetMappingHeight();
- m_numFrames = m_material[0]->GetNumAnimationFrames();
- }
-
- for ( int i = 0; i < kRenderModeCount; ++i )
- {
- if ( i == kRenderNone || i == kRenderEnvironmental )
- continue;
-
- if ( !m_material[i] )
- return false;
- }
-
- IMaterialVar *orientationVar = m_material[0]->FindVarFast( "$spriteorientation", &spriteOrientationCache );
- m_orientation = orientationVar ? orientationVar->GetIntValue() : C_SpriteRenderer::SPR_VP_PARALLEL_UPRIGHT;
-
- IMaterialVar *originVar = m_material[0]->FindVarFast( "$spriteorigin", &spriteOriginCache );
- Vector origin, originVarValue;
- if( !originVar || ( originVar->GetType() != MATERIAL_VAR_TYPE_VECTOR ) )
- {
- origin[0] = -m_width * 0.5f;
- origin[1] = m_height * 0.5f;
- }
- else
- {
- originVar->GetVecValue( &originVarValue[0], 3 );
- origin[0] = -m_width * originVarValue[0];
- origin[1] = m_height * originVarValue[1];
- }
-
- up = origin[1];
- down = origin[1] - m_height;
- left = origin[0];
- right = m_width + origin[0];
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEngineSprite::Shutdown( void )
-{
- if ( g_pVideo != NULL && m_VideoMaterial != NULL )
- {
- g_pVideo->DestroyVideoMaterial( m_VideoMaterial );
- m_VideoMaterial = NULL;
- }
-
- UnloadMaterial();
-}
-
-
-
-//-----------------------------------------------------------------------------
-// Is the sprite a video sprite?
-//-----------------------------------------------------------------------------
-bool CEngineSprite::IsVideo()
-{
- return ( m_VideoMaterial != NULL );
-}
-
-//-----------------------------------------------------------------------------
-// Returns the texture coordinate range used to draw the sprite
-//-----------------------------------------------------------------------------
-void CEngineSprite::GetTexCoordRange( float *pMinU, float *pMinV, float *pMaxU, float *pMaxV )
-{
- *pMaxU = 1.0f;
- *pMaxV = 1.0f;
- if ( IsVideo() )
- {
- m_VideoMaterial->GetVideoTexCoordRange( pMaxU, pMaxV );
- }
-
- float flOOWidth = ( m_width != 0 ) ? 1.0f / m_width : 1.0f;
- float flOOHeight = ( m_height!= 0 ) ? 1.0f / m_height : 1.0f;
-
- *pMinU = 0.5f * flOOWidth;
- *pMinV = 0.5f * flOOHeight;
- *pMaxU = (*pMaxU) - (*pMinU);
- *pMaxV = (*pMaxV) - (*pMinV);
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEngineSprite::SetColor( float r, float g, float b )
-{
- Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) );
- Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) );
- m_hudSpriteColor[0] = r;
- m_hudSpriteColor[1] = g;
- m_hudSpriteColor[2] = b;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEngineSprite::GetHUDSpriteColor( float* color )
-{
- VectorCopy( m_hudSpriteColor, color );
-}
-
-
-//-----------------------------------------------------------------------------
-// Returns the material
-//-----------------------------------------------------------------------------
-static unsigned int frameCache = 0;
-IMaterial *CEngineSprite::GetMaterial( RenderMode_t nRenderMode, int nFrame )
-{
- if ( nRenderMode == kRenderNone || nRenderMode == kRenderEnvironmental )
- return NULL;
-
- if ( IsVideo() )
- {
- m_VideoMaterial->SetFrame( nFrame );
- }
-
-
- IMaterial *pMaterial = m_material[nRenderMode];
- IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache );
- if ( pFrameVar )
- {
- pFrameVar->SetIntValue( nFrame );
- }
-
- return pMaterial;
-}
-
-void CEngineSprite::SetFrame( RenderMode_t nRenderMode, int nFrame )
-{
- if ( IsVideo() )
- {
- m_VideoMaterial->SetFrame( nFrame );
- return;
- }
-
-
- IMaterial *pMaterial = m_material[nRenderMode];
- if ( !pMaterial )
- return;
-
- IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache );
- if ( pFrameVar )
- {
- pFrameVar->SetIntValue( nFrame );
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Output : int
-//-----------------------------------------------------------------------------
-int CEngineSprite::GetOrientation( void )
-{
- return m_orientation;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEngineSprite::UnloadMaterial( void )
-{
- for ( int i = 0; i < kRenderModeCount; ++i )
- {
- if( m_material[i] )
- {
- m_material[i]->DecrementReferenceCount();
- m_material[i] = NULL;
- }
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CEngineSprite::DrawFrame( RenderMode_t nRenderMode, int frame, int x, int y, const wrect_t *prcSubRect )
-{
- DrawFrameOfSize( nRenderMode, frame, x, y, GetWidth(), GetHeight(), prcSubRect );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : frame -
-// x -
-// y -
-// *prcSubRect -
-//-----------------------------------------------------------------------------
-void CEngineSprite::DrawFrameOfSize( RenderMode_t nRenderMode, int frame, int x, int y, int iWidth, int iHeight, const wrect_t *prcSubRect )
-{
- // FIXME: If we ever call this with AVIs, need to have it call GetTexCoordRange and make that work
- Assert( !IsVideo() );
- float fLeft = 0;
- float fRight = 1;
- float fTop = 0;
- float fBottom = 1;
-
- if ( prcSubRect )
- {
- AdjustSubRect( this, frame, &fLeft, &fRight, &fTop, &fBottom, &iWidth, &iHeight, prcSubRect );
- }
-
- if ( giScissorTest && !Scissor( x, y, iWidth, iHeight, fLeft, fTop, fRight, fBottom ) )
- return;
-
- SetFrame( nRenderMode, frame );
-
- CMatRenderContextPtr pRenderContext( materials );
- IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, GetMaterial( nRenderMode ) );
-
- CMeshBuilder meshBuilder;
- meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );
-
- float color[3];
- GetHUDSpriteColor( color );
-
- meshBuilder.Color3fv( color );
- meshBuilder.TexCoord2f( 0, fLeft, fTop );
- meshBuilder.Position3f( x, y, 0.0f );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color3fv( color );
- meshBuilder.TexCoord2f( 0, fRight, fTop );
- meshBuilder.Position3f( x + iWidth, y, 0.0f );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color3fv( color );
- meshBuilder.TexCoord2f( 0, fRight, fBottom );
- meshBuilder.Position3f( x + iWidth, y + iHeight, 0.0f );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.Color3fv( color );
- meshBuilder.TexCoord2f( 0, fLeft, fBottom );
- meshBuilder.Position3f( x, y + iHeight, 0.0f );
- meshBuilder.AdvanceVertex();
-
- meshBuilder.End();
- pMesh->Draw();
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//===========================================================================// +#include "cbase.h" +#include "enginesprite.h" +#include "hud.h" +#include "materialsystem/imesh.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imaterialvar.h" +#include "c_sprite.h" +#include "tier1/callqueue.h" +#include "tier1/KeyValues.h" +#include "tier2/tier2.h" +#include "filesystem.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +// Sprites are clipped to this rectangle (x,y,width,height) if ScissorTest is enabled +static int scissor_x = 0; +static int scissor_y = 0; +static int scissor_width = 0; +static int scissor_height = 0; +static bool giScissorTest = false; + +//----------------------------------------------------------------------------- +// Purpose: +// Set the scissor +// the coordinate system for gl is upsidedown (inverted-y) as compared to software, so the +// specified clipping rect must be flipped +// Input : x - +// y - +// width - +// height - +//----------------------------------------------------------------------------- +void EnableScissorTest( int x, int y, int width, int height ) +{ + x = clamp( x, 0, ScreenWidth() ); + y = clamp( y, 0, ScreenHeight() ); + width = clamp( width, 0, ScreenWidth() - x ); + height = clamp( height, 0, ScreenHeight() - y ); + + scissor_x = x; + scissor_width = width; + scissor_y = y; + scissor_height = height; + + giScissorTest = true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void DisableScissorTest( void ) +{ + scissor_x = 0; + scissor_width = 0; + scissor_y = 0; + scissor_height = 0; + + giScissorTest = false; +} + +//----------------------------------------------------------------------------- +// Purpose: Verify that this is a valid, properly ordered rectangle. +// Input : *prc - +// Output : int +//----------------------------------------------------------------------------- +static int ValidateWRect(const wrect_t *prc) +{ + + if (!prc) + return false; + + if ((prc->left >= prc->right) || (prc->top >= prc->bottom)) + { + //!!!UNDONE Dev only warning msg + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: classic interview question +// Input : *prc1 - +// *prc2 - +// *prc - +// Output : int +//----------------------------------------------------------------------------- +static int IntersectWRect(const wrect_t *prc1, const wrect_t *prc2, wrect_t *prc) +{ + wrect_t rc; + + if (!prc) + prc = &rc; + + prc->left = MAX(prc1->left, prc2->left); + prc->right = MIN(prc1->right, prc2->right); + + if (prc->left < prc->right) + { + prc->top = MAX(prc1->top, prc2->top); + prc->bottom = MIN(prc1->bottom, prc2->bottom); + + if (prc->top < prc->bottom) + return 1; + + } + + return 0; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : x - +// y - +// width - +// height - +// u0 - +// v0 - +// u1 - +// v1 - +// Output : static bool +//----------------------------------------------------------------------------- +static bool Scissor( int& x, int& y, int& width, int& height, float& u0, float& v0, float& u1, float& v1 ) +{ + // clip sub rect to sprite + if ((width == 0) || (height == 0)) + return false; + + if ((x + width <= scissor_x) || (x >= scissor_x + scissor_width) || + (y + height <= scissor_y) || (y >= scissor_y + scissor_height)) + return false; + + float dudx = (u1-u0) / width; + float dvdy = (v1-v0) / height; + if (x < scissor_x) + { + u0 += (scissor_x - x) * dudx; + width -= scissor_x - x; + x = scissor_x; + } + + if (x + width > scissor_x + scissor_width) + { + u1 -= (x + width - (scissor_x + scissor_width)) * dudx; + width = scissor_x + scissor_width - x; + } + + if (y < scissor_y) + { + v0 += (scissor_y - y) * dvdy; + height -= scissor_y - y; + y = scissor_y; + } + + if (y + height > scissor_y + scissor_height) + { + v1 -= (y + height - (scissor_y + scissor_height)) * dvdy; + height = scissor_y + scissor_height - y; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +// Input : *pSprite - +// frame - +// *pfLeft - +// *pfRight - +// *pfTop - +// *pfBottom - +// *pw - +// *ph - +// *prcSubRect - +// Output : static void +//----------------------------------------------------------------------------- +static void AdjustSubRect(CEngineSprite *pSprite, int frame, float *pfLeft, float *pfRight, float *pfTop, + float *pfBottom, int *pw, int *ph, const wrect_t *prcSubRect) +{ + wrect_t rc; + float f; + + if (!ValidateWRect(prcSubRect)) + return; + + // clip sub rect to sprite + + rc.top = rc.left = 0; + rc.right = *pw; + rc.bottom = *ph; + + if (!IntersectWRect(prcSubRect, &rc, &rc)) + return; + + *pw = rc.right - rc.left; + *ph = rc.bottom - rc.top; + + f = 1.0 / (float)pSprite->GetWidth();; + *pfLeft = ((float)rc.left + 0.5) * f; + *pfRight = ((float)rc.right - 0.5) * f; + + f = 1.0 / (float)pSprite->GetHeight(); + *pfTop = ((float)rc.top + 0.5) * f; + *pfBottom = ((float)rc.bottom - 0.5) * f; + + return; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +static unsigned int spriteOriginCache = 0; +static unsigned int spriteOrientationCache = 0; +bool CEngineSprite::Init( const char *pName ) +{ + m_VideoMaterial = NULL; + for ( int i = 0; i < kRenderModeCount; ++i ) + { + m_material[ i ] = NULL; + } + + m_width = m_height = m_numFrames = 1; + + Assert( g_pVideo != NULL ); + + if ( g_pVideo != NULL && g_pVideo->LocateVideoSystemForPlayingFile( pName ) != VideoSystem::NONE ) + { + m_VideoMaterial = g_pVideo->CreateVideoMaterial( pName, pName, "GAME", VideoPlaybackFlags::DEFAULT_MATERIAL_OPTIONS, VideoSystem::DETERMINE_FROM_FILE_EXTENSION, false ); + + if ( m_VideoMaterial == NULL ) + return false; + + IMaterial *pMaterial = m_VideoMaterial->GetMaterial(); + m_VideoMaterial->GetVideoImageSize( &m_width, &m_height ); + m_numFrames = m_VideoMaterial->GetFrameCount(); + for ( int i = 0; i < kRenderModeCount; ++i ) + { + m_material[i] = pMaterial; + pMaterial->IncrementReferenceCount(); + } + } + else + { + char pTemp[MAX_PATH]; + char pMaterialName[MAX_PATH]; + char pMaterialPath[MAX_PATH]; + Q_StripExtension( pName, pTemp, sizeof(pTemp) ); + Q_strlower( pTemp ); + Q_FixSlashes( pTemp, '/' ); + + // Check to see if this is a UNC-specified material name + bool bIsUNC = pTemp[0] == '/' && pTemp[1] == '/' && pTemp[2] != '/'; + if ( !bIsUNC ) + { + Q_strncpy( pMaterialName, "materials/", sizeof(pMaterialName) ); + Q_strncat( pMaterialName, pTemp, sizeof(pMaterialName), COPY_ALL_CHARACTERS ); + } + else + { + Q_strncpy( pMaterialName, pTemp, sizeof(pMaterialName) ); + } + Q_strncpy( pMaterialPath, pMaterialName, sizeof(pMaterialPath) ); + Q_SetExtension( pMaterialPath, ".vmt", sizeof(pMaterialPath) ); + + KeyValues *kv = new KeyValues( "vmt" ); + if ( !kv->LoadFromFile( g_pFullFileSystem, pMaterialPath, "GAME" ) ) + { + Warning( "Unable to load sprite material %s!\n", pMaterialPath ); + return false; + } + + for ( int i = 0; i < kRenderModeCount; ++i ) + { + if ( i == kRenderNone || i == kRenderEnvironmental ) + { + m_material[i] = NULL; + continue; + } + + Q_snprintf( pMaterialPath, sizeof(pMaterialPath), "%s_rendermode_%d", pMaterialName, i ); + KeyValues *pMaterialKV = kv->MakeCopy(); + pMaterialKV->SetInt( "$spriteRenderMode", i ); + m_material[i] = g_pMaterialSystem->FindProceduralMaterial( pMaterialPath, TEXTURE_GROUP_CLIENT_EFFECTS, pMaterialKV ); + m_material[ i ]->IncrementReferenceCount(); + } + + kv->deleteThis(); + + m_width = m_material[0]->GetMappingWidth(); + m_height = m_material[0]->GetMappingHeight(); + m_numFrames = m_material[0]->GetNumAnimationFrames(); + } + + for ( int i = 0; i < kRenderModeCount; ++i ) + { + if ( i == kRenderNone || i == kRenderEnvironmental ) + continue; + + if ( !m_material[i] ) + return false; + } + + IMaterialVar *orientationVar = m_material[0]->FindVarFast( "$spriteorientation", &spriteOrientationCache ); + m_orientation = orientationVar ? orientationVar->GetIntValue() : C_SpriteRenderer::SPR_VP_PARALLEL_UPRIGHT; + + IMaterialVar *originVar = m_material[0]->FindVarFast( "$spriteorigin", &spriteOriginCache ); + Vector origin, originVarValue; + if( !originVar || ( originVar->GetType() != MATERIAL_VAR_TYPE_VECTOR ) ) + { + origin[0] = -m_width * 0.5f; + origin[1] = m_height * 0.5f; + } + else + { + originVar->GetVecValue( &originVarValue[0], 3 ); + origin[0] = -m_width * originVarValue[0]; + origin[1] = m_height * originVarValue[1]; + } + + up = origin[1]; + down = origin[1] - m_height; + left = origin[0]; + right = m_width + origin[0]; + + return true; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEngineSprite::Shutdown( void ) +{ + if ( g_pVideo != NULL && m_VideoMaterial != NULL ) + { + g_pVideo->DestroyVideoMaterial( m_VideoMaterial ); + m_VideoMaterial = NULL; + } + + UnloadMaterial(); +} + + + +//----------------------------------------------------------------------------- +// Is the sprite a video sprite? +//----------------------------------------------------------------------------- +bool CEngineSprite::IsVideo() +{ + return ( m_VideoMaterial != NULL ); +} + +//----------------------------------------------------------------------------- +// Returns the texture coordinate range used to draw the sprite +//----------------------------------------------------------------------------- +void CEngineSprite::GetTexCoordRange( float *pMinU, float *pMinV, float *pMaxU, float *pMaxV ) +{ + *pMaxU = 1.0f; + *pMaxV = 1.0f; + if ( IsVideo() ) + { + m_VideoMaterial->GetVideoTexCoordRange( pMaxU, pMaxV ); + } + + float flOOWidth = ( m_width != 0 ) ? 1.0f / m_width : 1.0f; + float flOOHeight = ( m_height!= 0 ) ? 1.0f / m_height : 1.0f; + + *pMinU = 0.5f * flOOWidth; + *pMinV = 0.5f * flOOHeight; + *pMaxU = (*pMaxU) - (*pMinU); + *pMaxV = (*pMaxV) - (*pMinV); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEngineSprite::SetColor( float r, float g, float b ) +{ + Assert( (r >= 0.0) && (g >= 0.0) && (b >= 0.0) ); + Assert( (r <= 1.0) && (g <= 1.0) && (b <= 1.0) ); + m_hudSpriteColor[0] = r; + m_hudSpriteColor[1] = g; + m_hudSpriteColor[2] = b; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEngineSprite::GetHUDSpriteColor( float* color ) +{ + VectorCopy( m_hudSpriteColor, color ); +} + + +//----------------------------------------------------------------------------- +// Returns the material +//----------------------------------------------------------------------------- +static unsigned int frameCache = 0; +IMaterial *CEngineSprite::GetMaterial( RenderMode_t nRenderMode, int nFrame ) +{ + if ( nRenderMode == kRenderNone || nRenderMode == kRenderEnvironmental ) + return NULL; + + if ( IsVideo() ) + { + m_VideoMaterial->SetFrame( nFrame ); + } + + + IMaterial *pMaterial = m_material[nRenderMode]; + IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); + if ( pFrameVar ) + { + pFrameVar->SetIntValue( nFrame ); + } + + return pMaterial; +} + +void CEngineSprite::SetFrame( RenderMode_t nRenderMode, int nFrame ) +{ + if ( IsVideo() ) + { + m_VideoMaterial->SetFrame( nFrame ); + return; + } + + + IMaterial *pMaterial = m_material[nRenderMode]; + if ( !pMaterial ) + return; + + IMaterialVar* pFrameVar = pMaterial->FindVarFast( "$frame", &frameCache ); + if ( pFrameVar ) + { + pFrameVar->SetIntValue( nFrame ); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Output : int +//----------------------------------------------------------------------------- +int CEngineSprite::GetOrientation( void ) +{ + return m_orientation; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEngineSprite::UnloadMaterial( void ) +{ + for ( int i = 0; i < kRenderModeCount; ++i ) + { + if( m_material[i] ) + { + m_material[i]->DecrementReferenceCount(); + m_material[i] = NULL; + } + } +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CEngineSprite::DrawFrame( RenderMode_t nRenderMode, int frame, int x, int y, const wrect_t *prcSubRect ) +{ + DrawFrameOfSize( nRenderMode, frame, x, y, GetWidth(), GetHeight(), prcSubRect ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : frame - +// x - +// y - +// *prcSubRect - +//----------------------------------------------------------------------------- +void CEngineSprite::DrawFrameOfSize( RenderMode_t nRenderMode, int frame, int x, int y, int iWidth, int iHeight, const wrect_t *prcSubRect ) +{ + // FIXME: If we ever call this with AVIs, need to have it call GetTexCoordRange and make that work + Assert( !IsVideo() ); + float fLeft = 0; + float fRight = 1; + float fTop = 0; + float fBottom = 1; + + if ( prcSubRect ) + { + AdjustSubRect( this, frame, &fLeft, &fRight, &fTop, &fBottom, &iWidth, &iHeight, prcSubRect ); + } + + if ( giScissorTest && !Scissor( x, y, iWidth, iHeight, fLeft, fTop, fRight, fBottom ) ) + return; + + SetFrame( nRenderMode, frame ); + + CMatRenderContextPtr pRenderContext( materials ); + IMesh* pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, GetMaterial( nRenderMode ) ); + + CMeshBuilder meshBuilder; + meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); + + float color[3]; + GetHUDSpriteColor( color ); + + meshBuilder.Color3fv( color ); + meshBuilder.TexCoord2f( 0, fLeft, fTop ); + meshBuilder.Position3f( x, y, 0.0f ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color3fv( color ); + meshBuilder.TexCoord2f( 0, fRight, fTop ); + meshBuilder.Position3f( x + iWidth, y, 0.0f ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color3fv( color ); + meshBuilder.TexCoord2f( 0, fRight, fBottom ); + meshBuilder.Position3f( x + iWidth, y + iHeight, 0.0f ); + meshBuilder.AdvanceVertex(); + + meshBuilder.Color3fv( color ); + meshBuilder.TexCoord2f( 0, fLeft, fBottom ); + meshBuilder.Position3f( x, y + iHeight, 0.0f ); + meshBuilder.AdvanceVertex(); + + meshBuilder.End(); + pMesh->Draw(); }
\ No newline at end of file |