void DrawCross(CMeshBuilder& meshBuilder, const Vector& vecOrigin, const Vector& vecRight, const Vector& vecDirection, const float& flAlpha)
{
	float flWidth = 2.5f;
	float flLength = 250;

	meshBuilder.Color4f( 1, 1, 1, flAlpha );
	meshBuilder.TexCoord2f( 0,0, 0 );
	meshBuilder.Position3fv( (vecOrigin + (vecRight * flWidth) - (vecDirection * flLength)).Base() );
	meshBuilder.AdvanceVertex();

	meshBuilder.Color4f( 1, 1, 1, flAlpha );
	meshBuilder.TexCoord2f( 0,1, 0 );
	meshBuilder.Position3fv( (vecOrigin - (vecRight * flWidth) - (vecDirection * flLength)).Base() );
	meshBuilder.AdvanceVertex();

	meshBuilder.Color4f( 1, 1, 1, flAlpha );
	meshBuilder.TexCoord2f( 0,1, 1 );
	meshBuilder.Position3fv( (vecOrigin - (vecRight * flWidth)).Base() );
	meshBuilder.AdvanceVertex();

	meshBuilder.Color4f( 1, 1, 1, flAlpha );
	meshBuilder.TexCoord2f( 0,0, 1 );
	meshBuilder.Position3fv( (vecOrigin + (vecRight * flWidth)).Base() );
	meshBuilder.AdvanceVertex();
}
void DrawSmokeFogOverlay()
{
	if(g_SmokeFogOverlayAlpha == 0 || !g_pSmokeFogMaterial || !materials)
		return;

	// Hard-coded for now..
	g_SmokeFogOverlayColor.Init( 0.3, 0.3, 0.3 );
	
	CMatRenderContextPtr pRenderContext( materials );

	pRenderContext->MatrixMode( MATERIAL_PROJECTION );
	pRenderContext->LoadIdentity();
	pRenderContext->Ortho( 0, 0, 1, 1, -99999, 99999 );

	pRenderContext->MatrixMode( MATERIAL_VIEW );
	pRenderContext->LoadIdentity();

	pRenderContext->MatrixMode( MATERIAL_MODEL );
	pRenderContext->LoadIdentity();

	IMesh* pMesh = pRenderContext->GetDynamicMesh( false, NULL, NULL, g_pSmokeFogMaterial );
	CMeshBuilder meshBuilder;

	static float dist = 10;

	Vector vColor = g_SmokeFogOverlayColor;
	vColor.x = MIN(MAX(vColor.x, 0), 1);
	vColor.y = MIN(MAX(vColor.y, 0), 1);
	vColor.z = MIN(MAX(vColor.z, 0), 1);
	float alpha = MIN(MAX(g_SmokeFogOverlayAlpha, 0), 1);

	meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

	meshBuilder.Position3f( 0, 0, dist );
	meshBuilder.Color4f( vColor.x, vColor.y, vColor.z, alpha );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3f( 0, 1, dist );
	meshBuilder.Color4f( vColor.x, vColor.y, vColor.z, alpha );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3f( 1, 1, dist );
	meshBuilder.Color4f( vColor.x, vColor.y, vColor.z, alpha );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.AdvanceVertex();

	meshBuilder.Position3f( 1, 0, dist );
	meshBuilder.Color4f( vColor.x, vColor.y, vColor.z, alpha );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.AdvanceVertex();

	meshBuilder.End();
	pMesh->Draw();
}
Exemplo n.º 3
0
void R_DrawPortals()
{
	// Draw the portals.
	if( !r_DrawPortals.GetInt() )
		return;

	IMaterial *pMaterial = materialSystemInterface->FindMaterial( "debug\\debugportals", NULL );
	IMesh *pMesh = materialSystemInterface->GetDynamicMesh( true, NULL, NULL, pMaterial );

	brushdata_t *pBrush = &host_state.worldmodel->brush;
	for( int i=0; i < pBrush->m_nAreaPortals; i++ )
	{
		dareaportal_t *pAreaPortal = &pBrush->m_pAreaPortals[i];

		if( !R_IsAreaVisible( pAreaPortal->otherarea ) )
			continue;

		CMeshBuilder builder;
		builder.Begin( pMesh, MATERIAL_LINES, pAreaPortal->m_nClipPortalVerts );

		for( int j=0; j < pAreaPortal->m_nClipPortalVerts; j++ )
		{
			unsigned short iVert;

			iVert = pAreaPortal->m_FirstClipPortalVert + j;
			builder.Position3f( VectorExpand( pBrush->m_pClipPortalVerts[iVert] ) );
			builder.Color4f( 0, 0, 0, 1 );
			builder.AdvanceVertex();

			iVert = pAreaPortal->m_FirstClipPortalVert + (j+1) % pAreaPortal->m_nClipPortalVerts;
			builder.Position3f( VectorExpand( pBrush->m_pClipPortalVerts[iVert] ) );
			builder.Color4f( 0, 0, 0, 1 );
			builder.AdvanceVertex();
		}

		builder.End( false, true );
	}

	// Draw the clip rectangles.
	for( i=0; i < g_PortalRects.Size(); i++ )
	{
		CPortalRect *pRect = &g_PortalRects[i];
		R_DrawScreenRect( pRect->left, pRect->top, pRect->right, pRect->bottom );
	}
	g_PortalRects.Purge();
}
Exemplo n.º 4
0
void CGlowOverlay::Draw( bool bCacheFullSceneState )
{
	extern ConVar	r_drawsprites;
	if( !r_drawsprites.GetBool() )
		return;
	
	// Get the vector to the sun.
	Vector vToGlow;
	
	if( m_bDirectional )
		vToGlow = m_vDirection;
	else
		vToGlow = m_vPos - CurrentViewOrigin();

	VectorNormalize( vToGlow );

	float flDot = vToGlow.Dot( CurrentViewForward() );

	UpdateGlowObstruction( vToGlow, bCacheFullSceneState );
	if( m_flGlowObstructionScale == 0 )
		return;
	
	bool bWireframe = ShouldDrawInWireFrameMode() || (r_drawsprites.GetInt() == 2);
	
	CMatRenderContextPtr pRenderContext( materials );

	for( int iSprite=0; iSprite < m_nSprites; iSprite++ )
	{
		CGlowSprite *pSprite = &m_Sprites[iSprite];
 
		// Figure out the color and size to draw it.
		float flHorzSize, flVertSize;
		Vector vColor;
		CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor );
	
		// If we're alpha'd out, then don't bother
		if ( vColor.LengthSqr() < 0.00001f )
			continue;
		
		// Setup the basis to draw the sprite.
		Vector vBasePt, vUp, vRight;
		CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight );

		//Get our diagonal radius
		float radius = (vRight+vUp).Length();
		if ( R_CullSphere( view->GetFrustum(), 5, &vBasePt, radius ) )
			continue;

		// Get our material (deferred default load)
		if ( m_Sprites[iSprite].m_pMaterial == NULL )
		{
			m_Sprites[iSprite].m_pMaterial = materials->FindMaterial( "sprites/light_glow02_add_noz", TEXTURE_GROUP_CLIENT_EFFECTS );
		}

		Assert( m_Sprites[iSprite].m_pMaterial );
		static unsigned int		nHDRColorScaleCache = 0;
		IMaterialVar *pHDRColorScaleVar = m_Sprites[iSprite].m_pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache );
		if( pHDRColorScaleVar )
		{
			pHDRColorScaleVar->SetFloatValue( m_flHDRColorScale );
		}

		// Draw the sprite.
		IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, m_Sprites[iSprite].m_pMaterial );

		CMeshBuilder builder;
		builder.Begin( pMesh, MATERIAL_QUADS, 1 );
		
		Vector vPt;
		
		vPt = vBasePt - vRight + vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 0, 1 );
		builder.AdvanceVertex();
		
		vPt = vBasePt + vRight + vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 1, 1 );
		builder.AdvanceVertex();
		
		vPt = vBasePt + vRight - vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 1, 0 );
		builder.AdvanceVertex();
		
		vPt = vBasePt - vRight - vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 0, 0 );
		builder.AdvanceVertex();
		
		builder.End( false, true );

		if( bWireframe )
		{
			IMaterial *pWireframeMaterial = materials->FindMaterial( "debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER );
			pRenderContext->Bind( pWireframeMaterial );
			
			// Draw the sprite.
			IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pWireframeMaterial );
			
			CMeshBuilder builder;
			builder.Begin( pMesh, MATERIAL_QUADS, 1 );
			
			Vector vPt;
			
			vPt = vBasePt - vRight + vUp;
			builder.Position3fv( vPt.Base() );
			builder.Color3f( 1.0f, 0.0f, 0.0f );
			builder.AdvanceVertex();
			
			vPt = vBasePt + vRight + vUp;
			builder.Position3fv( vPt.Base() );
			builder.Color3f( 1.0f, 0.0f, 0.0f );
			builder.AdvanceVertex();
			
			vPt = vBasePt + vRight - vUp;
			builder.Position3fv( vPt.Base() );
			builder.Color3f( 1.0f, 0.0f, 0.0f );
			builder.AdvanceVertex();
			
			vPt = vBasePt - vRight - vUp;
			builder.Position3fv( vPt.Base() );
			builder.Color3f( 1.0f, 0.0f, 0.0f );
			builder.AdvanceVertex();
			
			builder.End( false, true );
		}
	}
}
Exemplo n.º 5
0
//-----------------------------------------------------------------------------
// Debugging aid to display title safe areas.
// Title Safe critical insets are SD:32x24 or HD:64x48
//-----------------------------------------------------------------------------
static void OverlayTitleSafe()
{
	IMaterial		*pMaterial;

	pMaterial = materials->FindMaterial( "vgui/white", TEXTURE_GROUP_OTHER, true );

	int backBufferWidth, backBufferHeight;
	materials->GetBackBufferDimensions( backBufferWidth, backBufferHeight );

	CMatRenderContextPtr pRenderContext( materials );

	pRenderContext->Bind( pMaterial );
	IMesh* pMesh = pRenderContext->GetDynamicMesh( true );

	CMeshBuilder meshBuilder;

	// Required Title safe is TCR documented at inner 90% (RED)
	int insetX = 0.05f * backBufferWidth;
	int insetY = 0.05f * backBufferHeight;
	meshBuilder.Begin( pMesh, MATERIAL_LINE_LOOP, 4 );
	meshBuilder.Position3f( insetX, insetY, 0.0f );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4f( 1, 0, 0, 1 );
	meshBuilder.AdvanceVertex();
	meshBuilder.Position3f( backBufferWidth-insetX, insetY, 0.0f );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4f( 1, 0, 0, 1 );
	meshBuilder.AdvanceVertex();
	meshBuilder.Position3f( backBufferWidth-insetX, backBufferHeight-insetY, 0.0f );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4f( 1, 0, 0, 1 );
	meshBuilder.AdvanceVertex();
	meshBuilder.Position3f( insetX, backBufferHeight-insetY, 0.0f );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4f( 1, 0, 0, 1 );
	meshBuilder.AdvanceVertex();
	meshBuilder.End();
	pMesh->Draw();

	// Suggested Title Safe is TCR documented at inner 85% (YELLOW)
	insetX = 0.075f * backBufferWidth;
	insetY = 0.075f * backBufferHeight;
	meshBuilder.Begin( pMesh, MATERIAL_LINE_LOOP, 4 );
	meshBuilder.Position3f( insetX, insetY, 0.0f );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4f( 1, 1, 0, 1 );
	meshBuilder.AdvanceVertex();
	meshBuilder.Position3f( backBufferWidth-insetX, insetY, 0.0f );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4f( 1, 1, 0, 1 );
	meshBuilder.AdvanceVertex();
	meshBuilder.Position3f( backBufferWidth-insetX, backBufferHeight-insetY, 0.0f );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4f( 1, 1, 0, 1 );
	meshBuilder.AdvanceVertex();
	meshBuilder.Position3f( insetX, backBufferHeight-insetY, 0.0f );
	meshBuilder.TexCoord2f( 0, 0.0f, 0.0f );
	meshBuilder.Color4f( 1, 1, 0, 1 );
	meshBuilder.AdvanceVertex();
	meshBuilder.End();
	pMesh->Draw();
}
Exemplo n.º 6
0
//-----------------------------------------------------------------------------
// Purpose: Update and draw the frame
//-----------------------------------------------------------------------------
void VideoPanel::Paint( void )
{
	BaseClass::Paint();

	// No video to play, so do nothing
	if ( m_BIKHandle == BIKHANDLE_INVALID || m_bPlaying == false )
	{
		return;
	}

	// Update our frame
	if ( bik->Update( m_BIKHandle ) == false )
	{
		if ( m_bRepeat )
		{
			Play();
		}
		else
		{
			OnClose();
		}
	}

	// Sit in the "center"
	int xpos, ypos;
	GetPanelPos( xpos, ypos );

	// Black out the background (we could omit drawing under the video surface, but this is straight-forward)
	if ( m_bBlackBackground )
	{
		vgui::surface()->DrawSetColor(  0, 0, 0, 255 );
		vgui::surface()->DrawFilledRect( 0, 0, GetWide(), GetTall() );
	}

	// Draw the polys to draw this out
	CMatRenderContextPtr pRenderContext( materials );
	
	pRenderContext->MatrixMode( MATERIAL_VIEW );
	pRenderContext->PushMatrix();
	pRenderContext->LoadIdentity();

	pRenderContext->MatrixMode( MATERIAL_PROJECTION );
	pRenderContext->PushMatrix();
	pRenderContext->LoadIdentity();

	pRenderContext->Bind( m_pMaterial, NULL );

	CMeshBuilder meshBuilder;
	IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
	meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

	float flLeftX = xpos;
	float flRightX = xpos + (m_nPlaybackWidth-1);

	float flTopY = ypos;
	float flBottomY = ypos + (m_nPlaybackHeight-1);

	// Map our UVs to cut out just the portion of the video we're interested in
	float flLeftU = 0.0f;
	float flTopV = 0.0f;

	// We need to subtract off a pixel to make sure we don't bleed
	float flRightU = m_flU - ( 1.0f / (float) m_nPlaybackWidth );
	float flBottomV = m_flV - ( 1.0f / (float) m_nPlaybackHeight );

	// Get the current viewport size
	int vx, vy, vw, vh;
	pRenderContext->GetViewport( vx, vy, vw, vh );

	// map from screen pixel coords to -1..1
	flRightX = FLerp( -1, 1, 0, vw, flRightX );
	flLeftX = FLerp( -1, 1, 0, vw, flLeftX );
	flTopY = FLerp( 1, -1, 0, vh ,flTopY );
	flBottomY = FLerp( 1, -1, 0, vh, flBottomY );

	float alpha = ((float)GetFgColor()[3]/255.0f);

	for ( int corner=0; corner<4; corner++ )
	{
		bool bLeft = (corner==0) || (corner==3);
		meshBuilder.Position3f( (bLeft) ? flLeftX : flRightX, (corner & 2) ? flBottomY : flTopY, 0.0f );
		meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f );
		meshBuilder.TexCoord2f( 0, (bLeft) ? flLeftU : flRightU, (corner & 2) ? flBottomV : flTopV );
		meshBuilder.TangentS3f( 0.0f, 1.0f, 0.0f );
		meshBuilder.TangentT3f( 1.0f, 0.0f, 0.0f );
		meshBuilder.Color4f( 1.0f, 1.0f, 1.0f, alpha );
		meshBuilder.AdvanceVertex();
	}
	
	meshBuilder.End();
	pMesh->Draw();

	pRenderContext->MatrixMode( MATERIAL_VIEW );
	pRenderContext->PopMatrix();

	pRenderContext->MatrixMode( MATERIAL_PROJECTION );
	pRenderContext->PopMatrix();
}
//-----------------------------------------------------------------------------
// Purpose: Update and draw the frame
//-----------------------------------------------------------------------------
void VideoPlayerPanel::Paint( void )
{
	BaseClass::Paint();

	// Get our dimensions
	int xpos = 0;
	int ypos = 0;
	vgui::ipanel()->GetAbsPos( GetVPanel(), xpos, ypos );
//	GetPanelPos( xpos, ypos );
	int width = GetWide();
	int height = GetTall();

	
	// Are we playing the video?  Do we even have a video?
	if ( !m_VideoLoaded || !m_VideoPlaying )
	{
		vgui::surface()->DrawSetColor(  0, 0, 0, 255 );
		vgui::surface()->DrawFilledRect( 0, 0, width, height );
		return;		
	}
	
	if ( m_VideoMaterial == NULL )
		return;

	if ( m_VideoMaterial->Update() == false )
	{
		StopVideo();
		return;
	}

	// Black out the letterbox ares if we have them
	if ( m_letterBox != 0 )
	{
		vgui::surface()->DrawSetColor(  0, 0, 0, 255 );
		
		if ( m_letterBox == 1 )		// bars on top, bottom
		{
			int excess = ( height - m_nPlaybackHeight );
			int top = excess /2;
			int bot = excess - top;
		
			vgui::surface()->DrawFilledRect( 0, 0, width, top );
			vgui::surface()->DrawFilledRect( 0, height - bot, width, height );
		}
		
		if ( m_letterBox == 2 )		// bars on left, right
		{
			int excess = ( width - m_nPlaybackWidth );
			int left = excess /2;
			int right = excess - left;
		
			vgui::surface()->DrawFilledRect( 0, 0, left, height );
			vgui::surface()->DrawFilledRect( width-right, 0, width, height );
		}
	}

	// Draw the polys to draw this out
	CMatRenderContextPtr pRenderContext( materials );
	
	pRenderContext->MatrixMode( MATERIAL_VIEW );
	pRenderContext->PushMatrix();
	pRenderContext->LoadIdentity();

	pRenderContext->MatrixMode( MATERIAL_PROJECTION );
	pRenderContext->PushMatrix();
	pRenderContext->LoadIdentity();

	pRenderContext->Bind( m_pMaterial, NULL );

	CMeshBuilder meshBuilder;
	IMesh* pMesh = pRenderContext->GetDynamicMesh( true );
	meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

	float flLeftX = xpos;
	float flRightX = xpos + ( m_nPlaybackWidth-1 );

	float flTopY = ypos;
	float flBottomY = ypos + ( m_nPlaybackHeight-1 );

	// Map our UVs to cut out just the portion of the video we're interested in
	float flLeftU = 0.0f;
	float flTopV = 0.0f;

	// We need to subtract off a pixel to make sure we don't bleed
	float flRightU = m_flU - ( 1.0f / (float) m_nPlaybackWidth );
	float flBottomV = m_flV - ( 1.0f / (float) m_nPlaybackHeight );

	// Get the current viewport size
	int vx, vy, vw, vh;
	pRenderContext->GetViewport( vx, vy, vw, vh );

	// map from screen pixel coords to -1..1
	flRightX = FLerp( -1, 1, 0, vw, flRightX );
	flLeftX = FLerp( -1, 1, 0, vw, flLeftX );
	flTopY = FLerp( 1, -1, 0, vh ,flTopY );
	flBottomY = FLerp( 1, -1, 0, vh, flBottomY );

	float alpha = ((float)GetFgColor()[3]/255.0f);

	for ( int corner=0; corner<4; corner++ )
	{
		bool bLeft = (corner==0) || (corner==3);
		meshBuilder.Position3f( (bLeft) ? flLeftX : flRightX, (corner & 2) ? flBottomY : flTopY, 0.0f );
		meshBuilder.Normal3f( 0.0f, 0.0f, 1.0f );
		meshBuilder.TexCoord2f( 0, (bLeft) ? flLeftU : flRightU, (corner & 2) ? flBottomV : flTopV );
		meshBuilder.TangentS3f( 0.0f, 1.0f, 0.0f );
		meshBuilder.TangentT3f( 1.0f, 0.0f, 0.0f );
		meshBuilder.Color4f( 1.0f, 1.0f, 1.0f, alpha );
		meshBuilder.AdvanceVertex();
	}
	
	meshBuilder.End();
	pMesh->Draw();

	pRenderContext->MatrixMode( MATERIAL_VIEW );
	pRenderContext->PopMatrix();

	pRenderContext->MatrixMode( MATERIAL_PROJECTION );
	pRenderContext->PopMatrix();
	
}
Exemplo n.º 8
0
//-----------------------------------------------------------------------------
// Purpose: Special draw for the warped overlay
//-----------------------------------------------------------------------------
void CWarpOverlay::Draw( bool bCacheFullSceneState )
{
	// Get the vector to the sun.
	Vector vToGlow;
	
	if( m_bDirectional )
		vToGlow = m_vDirection;
	else
		vToGlow = m_vPos - CurrentViewOrigin();

	VectorNormalize( vToGlow );

	float flDot = vToGlow.Dot( CurrentViewForward() );

	if( flDot <= g_flOverlayRange )
		return;

	UpdateGlowObstruction( vToGlow, bCacheFullSceneState );
	if( m_flGlowObstructionScale == 0 )
		return;
	
	CMatRenderContextPtr pRenderContext( materials );
	
	//FIXME: Allow multiple?
	for( int iSprite=0; iSprite < m_nSprites; iSprite++ )
	{
		CGlowSprite *pSprite = &m_Sprites[iSprite];

		// Figure out the color and size to draw it.
		float flHorzSize, flVertSize;
		Vector vColor;
		CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor );
	
		// Setup the basis to draw the sprite.
		Vector vBasePt, vUp, vRight;
		CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight );

		// Draw the sprite.
		IMaterial *pMaterial = materials->FindMaterial( "sun/overlay", TEXTURE_GROUP_CLIENT_EFFECTS );
		IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pMaterial );

		CMeshBuilder builder;
		builder.Begin( pMesh, MATERIAL_QUADS, 1 );
		
		Vector vPt;

		vPt = vBasePt - vRight + vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 0, 1 );
		builder.AdvanceVertex();

		vPt = vBasePt + vRight + vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 1, 1 );
		builder.AdvanceVertex();

		vPt = vBasePt + vRight - vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 1, 0 );
		builder.AdvanceVertex();

		vPt = vBasePt - vRight - vUp;
		builder.Position3fv( vPt.Base() );
		builder.Color4f( VectorExpand(vColor), 1 );
		builder.TexCoord2f( 0, 0, 0 );
		builder.AdvanceVertex();
		
		builder.End( false, true );
	}
}
	int CBaseGrenadeProjectile::DrawModel( int flags )
	{
		// During the first half-second of our life, don't draw ourselves if he's
		// still playing his throw animation.
		// (better yet, we could draw ourselves in his hand).
		if ( GetThrower() != C_BasePlayer::GetLocalPlayer() )
		{
			if ( gpGlobals->curtime - m_flSpawnTime < 0.5 )
			{
//Tony; FIXME!
//				C_SDKPlayer *pPlayer = dynamic_cast<C_SDKPlayer*>( GetThrower() );
//				if ( pPlayer && pPlayer->m_PlayerAnimState->IsThrowingGrenade() )
//				{
//					return 0;
//				}
			}
		}

		if (!g_hGrenadeArrow.IsValid())
			g_hGrenadeArrow.Init( "particle/grenadearrow.vmt", TEXTURE_GROUP_OTHER );

		int iReturn = BaseClass::DrawModel(flags);

		C_SDKPlayer* pLocalPlayer = C_SDKPlayer::GetLocalSDKPlayer();
		if (!pLocalPlayer)
			return iReturn;

		if (pLocalPlayer == GetThrower())
			return iReturn;

		float flAppearDistance = 500;
		float flAppearDistanceSqr = flAppearDistance*flAppearDistance;

		if ((pLocalPlayer->GetAbsOrigin() - GetAbsOrigin()).LengthSqr() < flAppearDistanceSqr)
			m_flArrowGoalSize = 20;
		else
			m_flArrowGoalSize = 0;

		float flTime = C_SDKPlayer::GetLocalSDKPlayer()->GetCurrentTime() + m_flArrowSpinOffset;
		float flFrameTime = gpGlobals->frametime * C_SDKPlayer::GetLocalSDKPlayer()->GetSlowMoMultiplier();

		m_flArrowCurSize = Approach(m_flArrowGoalSize, m_flArrowCurSize, flFrameTime*100);

		if (m_flArrowCurSize == 0)
			return iReturn;

		Vector vecViewForward, vecViewRight, vecViewUp;
		pLocalPlayer->EyeVectors(&vecViewForward, &vecViewRight, &vecViewUp);

		float flSin = sin(flTime*4);
		float flCos = cos(flTime*4);

		Vector vecOrigin = GetAbsOrigin();
		Vector vecRight = vecViewRight * flSin + vecViewUp * flCos;
		Vector vecUp = vecViewRight * -flCos + vecViewUp * flSin;

		float flSize = m_flArrowCurSize;

		CMeshBuilder meshBuilder;
		CMatRenderContextPtr pRenderContext( materials );
		IMesh* pMesh = pRenderContext->GetDynamicMesh();

		pRenderContext->Bind( g_hGrenadeArrow );
		meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

		meshBuilder.Color4f( 1, 1, 1, 1 );
		meshBuilder.TexCoord2f( 0,0, 0 );
		meshBuilder.Position3fv( (vecOrigin + (vecRight * -flSize) + (vecUp * flSize)).Base() );
		meshBuilder.AdvanceVertex();

		meshBuilder.Color4f( 1, 1, 1, 1 );
		meshBuilder.TexCoord2f( 0,1, 0 );
		meshBuilder.Position3fv( (vecOrigin + (vecRight * flSize) + (vecUp * flSize)).Base() );
		meshBuilder.AdvanceVertex();

		meshBuilder.Color4f( 1, 1, 1, 1 );
		meshBuilder.TexCoord2f( 0,1, 1 );
		meshBuilder.Position3fv( (vecOrigin + (vecRight * flSize) + (vecUp * -flSize)).Base() );
		meshBuilder.AdvanceVertex();

		meshBuilder.Color4f( 1, 1, 1, 1 );
		meshBuilder.TexCoord2f( 0,0, 1 );
		meshBuilder.Position3fv( (vecOrigin + (vecRight * -flSize) + (vecUp * -flSize)).Base() );
		meshBuilder.AdvanceVertex();

		meshBuilder.End(false, true);

		return iReturn;
	}