Beispiel #1
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input :
//-----------------------------------------------------------------------------
void CViewModelInvisProxy::OnBind( C_BaseEntity *pEnt )
{
	if ( !m_pPercentInvisible )
		return;

	if ( !pEnt )
		return;

	CTFViewModel *pVM = dynamic_cast<CTFViewModel *>( pEnt );
	if ( !pVM )
	{
		m_pPercentInvisible->SetFloatValue( 0.0f );
		return;
	}

	CTFPlayer *pPlayer = ToTFPlayer( pVM->GetOwner() );

	if ( !pPlayer )
	{
		m_pPercentInvisible->SetFloatValue( 0.0f );
		return;
	}

	float flPercentInvisible = pPlayer->GetPercentInvisible();

	// remap from 0.22 to 0.5
	// but drop to 0.0 if we're not invis at all
	float flWeaponInvis = ( flPercentInvisible < 0.01 ) ?
		0.0 :
		RemapVal( flPercentInvisible, 0.0, 1.0, tf_vm_min_invis.GetFloat(), tf_vm_max_invis.GetFloat() );

	m_pPercentInvisible->SetFloatValue( flWeaponInvis );
}
Beispiel #2
0
void CWaterLODMaterialProxy::OnBind( void *pC_BaseEntity )
{
    if( !m_pCheapWaterStartDistanceVar || !m_pCheapWaterEndDistanceVar )
    {
        return;
    }
    float start, end;
    view->GetWaterLODParams( start, end );
    m_pCheapWaterStartDistanceVar->SetFloatValue( start );
    m_pCheapWaterEndDistanceVar->SetFloatValue( end );
}
//-----------------------------------------------------------------------------
// Purpose: Updates and renders all effects
//-----------------------------------------------------------------------------
int C_HopwireExplosion::DrawModel( int flags )
{
	AddParticles();

#ifndef C17
	CMatRenderContextPtr pRenderContext( materials );
	pRenderContext->Flush();
	UpdateRefractTexture();

	IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );

	float refract = m_FXCoreAlpha.Interp( gpGlobals->curtime );
	float scale = m_FXCoreScale.Interp( gpGlobals->curtime );

	IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
	pVar->SetFloatValue( refract );

	pRenderContext->Bind( pMat, (IClientRenderable*)this );
	
	float sin1 = sinf( gpGlobals->curtime * 10 );
	float sin2 = sinf( gpGlobals->curtime );

	float scaleY = ( sin1 * sin2 ) * 32.0f;
	float scaleX = (sin2 * sin2) * 32.0f;

	// FIXME: The ball needs to sort properly at all times
	static color32 white = {255,255,255,255};
	DrawSpriteTangentSpace( GetRenderOrigin() + ( CurrentViewForward() * 128.0f ), scale+scaleX, scale+scaleY, white );
#endif

	return 1;
}
Beispiel #4
0
void CStatusEffectSkinProxy::OnBind( C_BaseEntity *pEnt )
{
	float flEffectMagnitude;

	if (pEnt->IsPlayer() && ToCFPlayer(pEnt))
	{
		C_CFPlayer* pPlayer = ToCFPlayer(pEnt);
		flEffectMagnitude = pPlayer->m_pStats->GetEffectFromBitmask(STATUSEFFECT_SLOWNESS);
	}
	else if (pEnt->IsNPC() && dynamic_cast<C_CFActor*>(pEnt))
	{
		flEffectMagnitude = dynamic_cast<C_CFActor*>(pEnt)->m_flEffectMagnitude;
	}
	else
		return;

	if (m_pDetailBlend)
	{
		float flCurrent = m_pDetailBlend->GetFloatValue();
		float flGoal = RemapValClamped(flEffectMagnitude, 0.0f, 1.0f, 0.3f, 1.0f );

		if (flEffectMagnitude < 0.01)
			flGoal = 0.0f;

		m_pDetailBlend->SetFloatValue( Approach(flGoal, flCurrent, gpGlobals->frametime/10) );
	}
}
void CAlphaMaterialProxy::OnBind( C_BaseEntity *pEnt )
{
	if (m_AlphaVar)
	{
		m_AlphaVar->SetFloatValue( pEnt->m_clrRender->a );
	}
}
Beispiel #6
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : pMaterial - 
//			source - 
//			color - 
//-----------------------------------------------------------------------------
void DrawHalo(IMaterial* pMaterial, const Vector& source, float scale, float const* color, float flHDRColorScale )
{
	static unsigned int nHDRColorScaleCache = 0;
	Vector		point, screen;
	
	if( pMaterial )
	{
		IMaterialVar *pHDRColorScaleVar = pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache );
		if( pHDRColorScaleVar )
		{
			pHDRColorScaleVar->SetFloatValue( flHDRColorScale );
		}
	}

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

	CMeshBuilder meshBuilder;
	meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 );

	// Transform source into screen space
	ScreenTransform( source, screen );

	meshBuilder.Color3fv (color);
	meshBuilder.TexCoord2f (0, 0, 1);
	VectorMA (source, -scale, CurrentViewUp(), point);
	VectorMA (point, -scale, CurrentViewRight(), point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	meshBuilder.Color3fv (color);
	meshBuilder.TexCoord2f (0, 0, 0);
	VectorMA (source, scale, CurrentViewUp(), point);
	VectorMA (point, -scale, CurrentViewRight(), point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	meshBuilder.Color3fv (color);
	meshBuilder.TexCoord2f (0, 1, 0);
	VectorMA (source, scale, CurrentViewUp(), point);
	VectorMA (point, scale, CurrentViewRight(), point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();

	meshBuilder.Color3fv (color);
	meshBuilder.TexCoord2f (0, 1, 1);
	VectorMA (source, -scale, CurrentViewUp(), point);
	VectorMA (point, scale, CurrentViewRight(), point);
	meshBuilder.Position3fv (point.Base());
	meshBuilder.AdvanceVertex();
	
	meshBuilder.End();
	pMesh->Draw();
}
void CLampBeamProxy::OnBind( C_BaseEntity *pEnt )
{
	if ( !m_pFadeValue )
		return;

	Vector vecLocal = pEnt->GetAbsOrigin() - CurrentViewOrigin();
	VectorNormalize( vecLocal );

	float fade = 1.0 - fabs( vecLocal.z );

	m_pFadeValue->SetFloatValue( fade );
}
void CzTestMaterialProxy::OnBind( void *pC_BaseEntity )
{
	C_BaseEntity *pEnt = ( C_BaseEntity * )pC_BaseEntity;
	if( !pEnt )
	{
		return;
	}

	if (m_AlphaVar)
	{
		m_AlphaVar->SetFloatValue( pEnt->m_clrRender.a );
	}

}
void CHeliBladeMaterialProxy::OnBind( C_BaseEntity *pEnt )
{
	if (!m_AlphaVar)
		return;

	C_BaseHelicopter *pHeli = dynamic_cast<C_BaseHelicopter*>( pEnt );
	if ( pHeli )
	{
		float dt = gpGlobals->curtime  - pHeli->StartupTime();
		dt /= FADE_IN_TIME;
		dt = clamp( dt, 0.0f, 1.0f );
		if ( m_bFadeOut ) 
		{
			dt = 1.0f - dt;
		}

		m_AlphaVar->SetFloatValue( dt );
	}
	else
	{
		m_AlphaVar->SetFloatValue( 1.0f );
	}
}
Beispiel #10
0
void CEngineSprite::SetFrame( float frame )
{
	if ( IsAVI() )
	{
		avi->SetFrame( m_hAVIMaterial, frame );
	}
	else
	{
		IMaterialVar* pFrameVar = m_material->FindVarFast( "$frame", &frameCache );
		if (pFrameVar)
		{
			pFrameVar->SetFloatValue( frame );
		}
		return;
	}
}
Beispiel #11
0
void C_BloodyTextureProxy::OnBind(void* pC_BaseEntity)
{
    if (!pC_BaseEntity)
        return;

    C_BaseEntity *pEntity = BindArgToEntity(pC_BaseEntity);
    C_BaseViewModel *pViewModel = dynamic_cast<C_BaseViewModel *>(pEntity);
    if (pViewModel)
    {
        C_BasePlayer *pOwner = ToBasePlayer(pViewModel->GetOwner());
        if (pOwner)
            blendFactor->SetFloatValue(pOwner->m_bShouldDrawBloodOverlay ? 1.0f : 0.0f);
    }

    if (ToolsEnabled())
        ToolFramework_RecordMaterialParams(GetMaterial());
}
Beispiel #12
0
void CPupilProxy::OnBind( C_BaseEntity *pBaseEntity )
{
	if (!pBaseEntity || !m_pAnimatedTextureVar )
		return;

	if( m_pAnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
		return;

	ITexture *pTexture = m_pAnimatedTextureVar->GetTextureValue();
	int nFrameCount = pTexture->GetNumAnimationFrames();

	// Compute the lighting at the eye position of the entity; use it to dialate the pupil
	Vector forward;
	pBaseEntity->GetVectors( &forward, NULL, NULL );

	Vector eyePt = pBaseEntity->EyePosition();
	Vector color;
	engine->ComputeLighting( eyePt, &forward, false, color );

	// Compute the intensity...
	float flIntensity = ( 0.299f * color[0] + 0.587f * color[1] + 0.114f * color[2] ) * 0.5;
	flIntensity = clamp( flIntensity, 0, 1 );
	float flLastIntensity = m_pLightingVar->GetFloatValue( );
	if ( flIntensity > flLastIntensity )
	{
		float flMaxChange = m_flPupilCloseRate.GetFloat() * gpGlobals->frametime;
		if ( flIntensity > (flMaxChange + flLastIntensity) )
		{
			flIntensity = flLastIntensity + flMaxChange;
		}
	}
	else
	{
		float flMaxChange = m_flPupilOpenRate.GetFloat() * gpGlobals->frametime;
		if ( flIntensity < (flLastIntensity - flMaxChange) )
		{
			flIntensity = flLastIntensity - flMaxChange;
		}
	}

	int nFrame = nFrameCount * flIntensity;
	nFrame = clamp( nFrame, 0, nFrameCount - 1 );

	m_pAnimatedTextureFrameNumVar->SetIntValue( nFrame );
	m_pLightingVar->SetFloatValue( flIntensity );
}
inline bool ASW_SetMaterialVarFloat( IMaterial* pMat, const char* pVarName, float flValue )
{
	Assert( pMat != NULL );
	Assert( pVarName != NULL );
	if ( pMat == NULL || pVarName == NULL )
	{
		return false;
	}

	bool bFound = false;
	IMaterialVar* pVar = pMat->FindVar( pVarName, &bFound );
	if ( bFound )
	{
		pVar->SetFloatValue( flValue );
	}

	return bFound;
}
//-----------------------------------------------------------------------------
// Does the dirty deed
//-----------------------------------------------------------------------------
void CMaterialModifyProxy::OnBindFloatLerp( C_MaterialModifyControl *pControl )
{
	if ( !pControl )
		return;

	if ( pControl->HasNewAnimationCommands() )
	{
		pControl->SetAnimationStartTime( gpGlobals->curtime );
		pControl->ClearAnimationCommands();
	}

	// Read the data from the modify entity
	materialfloatlerpcommands_t sCommands;
	pControl->GetFloatLerpCommands( &sCommands );

	m_flStartValue = sCommands.flStartValue;
	m_flEndValue = sCommands.flEndValue;
	m_flTransitionTime = sCommands.flTransitionTime;
	m_flStartTime = pControl->GetAnimationStartTime();
	bool bFound;
	m_pMaterialVar = m_pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false );

	if( bFound )
	{
		float currentValue;
		if( m_flTransitionTime > 0.0f )
		{
			currentValue = m_flStartValue + ( m_flEndValue - m_flStartValue ) * clamp( ( ( gpGlobals->curtime - m_flStartTime ) / m_flTransitionTime ), 0.0f, 1.0f );
		}
		else
		{
			currentValue = m_flEndValue;
		}

		if( debug_materialmodifycontrol_client.GetBool() && Q_stristr( m_pMaterial->GetName(), "faceandhair" ) && Q_stristr( m_pMaterialVar->GetName(), "warp" ) )
		{
			static int count = 0;
			DevMsg( 1, "CMaterialFloatLerpProxy::OnBind \"%s\" %s=%f %d\n", m_pMaterial->GetName(), m_pMaterialVar->GetName(), currentValue, count++ );
		}
		m_pMaterialVar->SetFloatValue( currentValue );
	}
}
//-----------------------------------------------------------------------------
// Set the appropriate texture...
//-----------------------------------------------------------------------------
void CObjectBuildAlphaProxy::OnBind( C_BaseEntity *pEntity )
{
	if( !m_pAlphaVar )
		return;
	
	// It needs to be a TF2 C_BaseObject to have this proxy applied
	C_BaseObject *pObject = dynamic_cast< C_BaseObject * >( pEntity );
	if ( !pObject )
		return;

	float build_amount = pObject->m_flCycle; //pObject->GetPercentageConstructed();
	float frac;

	if ( build_amount <= buildstart )
	{
		frac = 0.0f;
	}
	else if ( build_amount >= buildend )
	{
		frac = 1.0f;
	}
	else
	{
		// Avoid div by zero
		if ( buildend == buildstart )
		{
			frac = 1.0f;
		}
		else
		{
			frac = ( build_amount - buildstart ) / ( buildend - buildstart );
			frac = clamp( frac, 0.0f, 1.0f );
		}
	}

	if ( !pObject->IsBuilding() )
	{
		frac = 1.0f;
	}

	m_pAlphaVar->SetFloatValue( frac );
}
Beispiel #16
0
void CShieldVisibilityProxy::OnBind( C_BaseEntity *pEnt )
{
	if (!pEnt->GetOwnerEntity())
		return;

	if (!pEnt->GetOwnerEntity()->IsPlayer())
		return;

	C_CFPlayer* pPlayer = ToCFPlayer(pEnt->GetOwnerEntity());

	if (m_AlphaVar)
	{
		float flRefractAmount;
		if (pPlayer->m_bShieldPhysical)
			flRefractAmount = cf_barrierrefract.GetFloat();
		else
			flRefractAmount = cf_shieldrefract.GetFloat();

		m_AlphaVar->SetFloatValue( ((float)pEnt->m_clrRender->a) * flRefractAmount / 255 );
	}
}
void CLampHaloProxy::OnBind( C_BaseEntity *pEnt )
{
	if ( !m_pFadeValue )
		return;
	
	Vector vecLocal = pEnt->GetAbsOrigin() - CurrentViewOrigin();
	VectorNormalize( vecLocal );

	float fade = fabs( vecLocal.z );

	// I hate these magic numbers here, will have to revise
	// (sjb)
	if( fade < 0.25 )
	{
		fade = 0.0;
	}
	else
	{
		fade = MIN( (fade - 0.25) * 1.35, 1.0f );
	}

	m_pFadeValue->SetFloatValue( fade );
}
void CGlowObjectManager::ApplyEntityGlowEffects( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext, float flBloomScale, int x, int y, int w, int h )
{
	//=======================================================//
	// Render objects into stencil buffer					 //
	//=======================================================//
	// Set override shader to the same simple shader we use to render the glow models
	IMaterial *pMatGlowColor = materials->FindMaterial( "dev/glow_color", TEXTURE_GROUP_OTHER, true );
	g_pStudioRender->ForcedMaterialOverride( pMatGlowColor );

	ShaderStencilState_t stencilStateDisable;
	stencilStateDisable.m_bEnable = false;
	float flSavedBlend = render->GetBlend();

	// Set alpha to 0 so we don't touch any color pixels
	render->SetBlend( 0.0f );
	pRenderContext->OverrideDepthEnable( true, false );

	int iNumGlowObjects = 0;

	for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i )
	{
		if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
			continue;

		if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded || m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
		{
			if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded && m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
			{
				ShaderStencilState_t stencilState;
				stencilState.m_bEnable = true;
				stencilState.m_nReferenceValue = 1;
				stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
				stencilState.m_PassOp = STENCILOPERATION_REPLACE;
				stencilState.m_FailOp = STENCILOPERATION_KEEP;
				stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;

				stencilState.SetStencilState( pRenderContext );

				m_GlowObjectDefinitions[i].DrawModel();
			}
			else if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded )
			{
				ShaderStencilState_t stencilState;
				stencilState.m_bEnable = true;
				stencilState.m_nReferenceValue = 1;
				stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
				stencilState.m_PassOp = STENCILOPERATION_KEEP;
				stencilState.m_FailOp = STENCILOPERATION_KEEP;
				stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;

				stencilState.SetStencilState( pRenderContext );

				m_GlowObjectDefinitions[i].DrawModel();
			}
			else if ( m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
			{
				ShaderStencilState_t stencilState;
				stencilState.m_bEnable = true;
				stencilState.m_nReferenceValue = 2;
				stencilState.m_nTestMask = 0x1;
				stencilState.m_nWriteMask = 0x3;
				stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_EQUAL;
				stencilState.m_PassOp = STENCILOPERATION_INCRSAT;
				stencilState.m_FailOp = STENCILOPERATION_KEEP;
				stencilState.m_ZFailOp = STENCILOPERATION_REPLACE;

				stencilState.SetStencilState( pRenderContext );

				m_GlowObjectDefinitions[i].DrawModel();
			}
		}

		iNumGlowObjects++;
	}

	// Need to do a 2nd pass to warm stencil for objects which are rendered only when occluded
	for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i )
	{
		if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
			continue;

		if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded && !m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
		{
			ShaderStencilState_t stencilState;
			stencilState.m_bEnable = true;
			stencilState.m_nReferenceValue = 2;
			stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_ALWAYS;
			stencilState.m_PassOp = STENCILOPERATION_REPLACE;
			stencilState.m_FailOp = STENCILOPERATION_KEEP;
			stencilState.m_ZFailOp = STENCILOPERATION_KEEP;
			stencilState.SetStencilState( pRenderContext );

			m_GlowObjectDefinitions[i].DrawModel();
		}
	}

	pRenderContext->OverrideDepthEnable( false, false );
	render->SetBlend( flSavedBlend );
	stencilStateDisable.SetStencilState( pRenderContext );
	g_pStudioRender->ForcedMaterialOverride( NULL );

	// If there aren't any objects to glow, don't do all this other stuff
	// this fixes a bug where if there are glow objects in the list, but none of them are glowing,
	// the whole screen blooms.
	if ( iNumGlowObjects <= 0 )
		return;

	//=============================================
	// Render the glow colors to _rt_FullFrameFB 
	//=============================================
	{
		PIXEvent pixEvent( pRenderContext, "RenderGlowModels" );
		RenderGlowModels( pSetup, nSplitScreenSlot, pRenderContext );
	}
	
	// Get viewport
	int nSrcWidth = pSetup->width;
	int nSrcHeight = pSetup->height;
	int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
	pRenderContext->GetViewport( nViewportX, nViewportY, nViewportWidth, nViewportHeight );

	// Get material and texture pointers
	ITexture *pRtQuarterSize1 = materials->FindTexture( "_rt_SmallFB1", TEXTURE_GROUP_RENDER_TARGET );

	{
		//=======================================================================================================//
		// At this point, pRtQuarterSize0 is filled with the fully colored glow around everything as solid glowy //
		// blobs. Now we need to stencil out the original objects by only writing pixels that have no            //
		// stencil bits set in the range we care about.                                                          //
		//=======================================================================================================//
		IMaterial *pMatHaloAddToScreen = materials->FindMaterial( "dev/halo_add_to_screen", TEXTURE_GROUP_OTHER, true );

		// Do not fade the glows out at all (weight = 1.0)
		IMaterialVar *pDimVar = pMatHaloAddToScreen->FindVar( "$C0_X", NULL );
		pDimVar->SetFloatValue( 1.0f );

		// Set stencil state
		ShaderStencilState_t stencilState;
		stencilState.m_bEnable = true;
		stencilState.m_nWriteMask = 0x0; // We're not changing stencil
		stencilState.m_nTestMask = 0xFF;
		stencilState.m_nReferenceValue = 0x0;
		stencilState.m_CompareFunc = STENCILCOMPARISONFUNCTION_EQUAL;
		stencilState.m_PassOp = STENCILOPERATION_KEEP;
		stencilState.m_FailOp = STENCILOPERATION_KEEP;
		stencilState.m_ZFailOp = STENCILOPERATION_KEEP;
		stencilState.SetStencilState( pRenderContext );

		// Draw quad
		pRenderContext->DrawScreenSpaceRectangle( pMatHaloAddToScreen, 0, 0, nViewportWidth, nViewportHeight,
			0.0f, -0.5f, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1,
			pRtQuarterSize1->GetActualWidth(),
			pRtQuarterSize1->GetActualHeight() );

		stencilStateDisable.SetStencilState( pRenderContext );
	}
}
void CGlowObjectManager::ApplyEntityGlowEffects( const CViewSetup *pSetup, int nSplitScreenSlot, CMatRenderContextPtr &pRenderContext, float flBloomScale, int x, int y, int w, int h )
{
	static bool s_bFirstPass = true;

	//=======================================================//
	// Render objects into stencil buffer					 //
	//=======================================================//

	// Set override shader to the same simple shader we use to render the glow models
	IMaterial *pMatGlowColor = materials->FindMaterial( "dev/glow_color", TEXTURE_GROUP_OTHER, true );
	g_pStudioRender->ForcedMaterialOverride( pMatGlowColor );

	ShaderStencilState_t stencilStateDisable;
	stencilStateDisable.m_bEnable = false;
	float flSavedBlend = render->GetBlend();

	// Set alpha to 0 so we don't touch any color pixels
	render->SetBlend( 0.0f );
	pRenderContext->OverrideDepthEnable( true, false );

	RenderableInstance_t instance;
	instance.m_nAlpha = 255;

	int iNumGlowObjects = 0;

	for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i )
	{
		if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
			continue;

		// Full bloom rendered objects should not be stenciled out here
		if ( m_GlowObjectDefinitions[i].m_bFullBloomRender )
		{
			++ iNumGlowObjects;
			continue;
		}

		if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded || m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
		{
			if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded && m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
			{
				ShaderStencilState_t stencilState;
				stencilState.m_bEnable = true;
				stencilState.m_nReferenceValue = 1;
				stencilState.m_CompareFunc = SHADER_STENCILFUNC_ALWAYS;
				stencilState.m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE;
				stencilState.m_FailOp = SHADER_STENCILOP_KEEP;
				stencilState.m_ZFailOp = SHADER_STENCILOP_SET_TO_REFERENCE;

				pRenderContext->SetStencilState( stencilState );

				m_GlowObjectDefinitions[i].DrawModel();
			}
			else if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded )
			{
				ShaderStencilState_t stencilState;
				stencilState.m_bEnable = true;
				stencilState.m_nReferenceValue = 1;
				stencilState.m_CompareFunc = SHADER_STENCILFUNC_ALWAYS;
				stencilState.m_PassOp = SHADER_STENCILOP_KEEP;
				stencilState.m_FailOp = SHADER_STENCILOP_KEEP;
				stencilState.m_ZFailOp = SHADER_STENCILOP_SET_TO_REFERENCE;

				pRenderContext->SetStencilState( stencilState );

				m_GlowObjectDefinitions[i].DrawModel();
			}
			else if ( m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
			{
				ShaderStencilState_t stencilState;
				stencilState.m_bEnable = true;
				stencilState.m_nReferenceValue = 2;
				stencilState.m_nTestMask = 0x1;
				stencilState.m_nWriteMask = 0x3;
				stencilState.m_CompareFunc = SHADER_STENCILFUNC_EQUAL;
				stencilState.m_PassOp = SHADER_STENCILOP_INCREMENT_CLAMP;
				stencilState.m_FailOp = SHADER_STENCILOP_KEEP;
				stencilState.m_ZFailOp = SHADER_STENCILOP_SET_TO_REFERENCE;

				pRenderContext->SetStencilState( stencilState );

				m_GlowObjectDefinitions[i].DrawModel();
			}
		}

		iNumGlowObjects++;
	}

	// Need to do a 2nd pass to warm stencil for objects which are rendered only when occluded
	for ( int i = 0; i < m_GlowObjectDefinitions.Count(); ++ i )
	{
		if ( m_GlowObjectDefinitions[i].IsUnused() || !m_GlowObjectDefinitions[i].ShouldDraw( nSplitScreenSlot ) )
			continue;

		// Full bloom rendered objects should not be stenciled out here
		if ( m_GlowObjectDefinitions[i].m_bFullBloomRender )
			continue;

		if ( m_GlowObjectDefinitions[i].m_bRenderWhenOccluded && !m_GlowObjectDefinitions[i].m_bRenderWhenUnoccluded )
		{
			ShaderStencilState_t stencilState;
			stencilState.m_bEnable = true;
			stencilState.m_nReferenceValue = 2;
			stencilState.m_CompareFunc = SHADER_STENCILFUNC_ALWAYS;
			stencilState.m_PassOp = SHADER_STENCILOP_SET_TO_REFERENCE;
			stencilState.m_FailOp = SHADER_STENCILOP_KEEP;
			stencilState.m_ZFailOp = SHADER_STENCILOP_KEEP;
			pRenderContext->SetStencilState( stencilState );

			m_GlowObjectDefinitions[i].DrawModel();
		}
	}

	pRenderContext->OverrideDepthEnable( false, false );
	render->SetBlend( flSavedBlend );
	pRenderContext->SetStencilState( stencilStateDisable );
	g_pStudioRender->ForcedMaterialOverride( NULL );

	// If there aren't any objects to glow, don't do all this other stuff
	// this fixes a bug where if there are glow objects in the list, but none of them are glowing,
	// the whole screen blooms.
	if ( iNumGlowObjects <= 0 )
		return;

	//=============================================
	// Render the glow colors to _rt_FullFrameFB 
	//=============================================
	{
		PIXEvent pixEvent( pRenderContext, "RenderGlowModels" );
		RenderGlowModels( pSetup, nSplitScreenSlot, pRenderContext );
	}
	
	//===================================
	// Setup state for downsample/bloom
	//===================================

	pRenderContext->PushRenderTargetAndViewport();

	// Get viewport
	int nSrcWidth = pSetup->width;
	int nSrcHeight = pSetup->height;
	int nViewportX, nViewportY, nViewportWidth, nViewportHeight;
	pRenderContext->GetViewport( nViewportX, nViewportY, nViewportWidth, nViewportHeight );

	// Get material and texture pointers
	IMaterial *pMatDownsample = materials->FindMaterial( "dev/glow_downsample", TEXTURE_GROUP_OTHER, true);
	IMaterial *pMatBlurX = materials->FindMaterial( "dev/glow_blur_x", TEXTURE_GROUP_OTHER, true );
	IMaterial *pMatBlurY = materials->FindMaterial( "dev/glow_blur_y", TEXTURE_GROUP_OTHER, true );

	ITexture *pRtFullFrame = materials->FindTexture( FULL_FRAME_TEXTURE, TEXTURE_GROUP_RENDER_TARGET );
	ITexture *pRtQuarterSize0 = materials->FindTexture( "_rt_SmallFB0", TEXTURE_GROUP_RENDER_TARGET );
	ITexture *pRtQuarterSize1 = materials->FindTexture( "_rt_SmallFB1", TEXTURE_GROUP_RENDER_TARGET );

	//============================================
	// Downsample _rt_FullFrameFB to _rt_SmallFB0
	//============================================

	// First clear the full target to black if we're not going to touch every pixel
	if ( ( pRtQuarterSize0->GetActualWidth() != ( pSetup->width / 4 ) ) || ( pRtQuarterSize0->GetActualHeight() != ( pSetup->height / 4 ) ) )
	{
		SetRenderTargetAndViewPort( pRtQuarterSize0, pRtQuarterSize0->GetActualWidth(), pRtQuarterSize0->GetActualHeight() );
		pRenderContext->ClearColor3ub( 0, 0, 0 );
		pRenderContext->ClearBuffers( true, false, false );
	}

	// Set the viewport
	SetRenderTargetAndViewPort( pRtQuarterSize0, pSetup->width / 4, pSetup->height / 4 );

	IMaterialVar *pbloomexpvar = pMatDownsample->FindVar( "$bloomexp", null );
	if ( pbloomexpvar != NULL )
	{
		pbloomexpvar->SetFloatValue( 2.5f );
	}

	IMaterialVar *pbloomsaturationvar = pMatDownsample->FindVar( "$bloomsaturation", null );
	if ( pbloomsaturationvar != NULL )
	{
		pbloomsaturationvar->SetFloatValue( 1.0f );
	}

	// note the -2's below. Thats because we are downsampling on each axis and the shader
	// accesses pixels on both sides of the source coord
	int nFullFbWidth = nSrcWidth;
	int nFullFbHeight = nSrcHeight;

	pRenderContext->DrawScreenSpaceRectangle( pMatDownsample, 0, 0, nSrcWidth/4, nSrcHeight/4,
		0, 0, nFullFbWidth - 4, nFullFbHeight - 4,
		pRtFullFrame->GetActualWidth(), pRtFullFrame->GetActualHeight() );

	//============================//
	// Guassian blur x rt0 to rt1 //
	//============================//

	// First clear the full target to black if we're not going to touch every pixel
	if ( s_bFirstPass || ( pRtQuarterSize1->GetActualWidth() != ( pSetup->width / 4 ) ) || ( pRtQuarterSize1->GetActualHeight() != ( pSetup->height / 4 ) ) )
	{
		// On the first render, this viewport may require clearing
		s_bFirstPass = false;
		SetRenderTargetAndViewPort( pRtQuarterSize1, pRtQuarterSize1->GetActualWidth(), pRtQuarterSize1->GetActualHeight() );
		pRenderContext->ClearColor3ub( 0, 0, 0 );
		pRenderContext->ClearBuffers( true, false, false );
	}

	// Set the viewport
	SetRenderTargetAndViewPort( pRtQuarterSize1, pSetup->width / 4, pSetup->height / 4  );

	pRenderContext->DrawScreenSpaceRectangle( pMatBlurX, 0, 0, nSrcWidth/4, nSrcHeight/4,
		0, 0, nSrcWidth/4-1, nSrcHeight/4-1,
		pRtQuarterSize0->GetActualWidth(), pRtQuarterSize0->GetActualHeight() );

	//============================//
	// Gaussian blur y rt1 to rt0 //
	//============================//
	SetRenderTargetAndViewPort( pRtQuarterSize0, pSetup->width / 4, pSetup->height / 4 );
	IMaterialVar *pBloomAmountVar = pMatBlurY->FindVar( "$bloomamount", NULL );
	pBloomAmountVar->SetFloatValue( flBloomScale );
	pRenderContext->DrawScreenSpaceRectangle( pMatBlurY, 0, 0, nSrcWidth / 4, nSrcHeight / 4,
		0, 0, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1,
		pRtQuarterSize1->GetActualWidth(), pRtQuarterSize1->GetActualHeight() );

	// Pop RT
	pRenderContext->PopRenderTargetAndViewport();

	{
		//=======================================================================================================//
		// At this point, pRtQuarterSize0 is filled with the fully colored glow around everything as solid glowy //
		// blobs. Now we need to stencil out the original objects by only writing pixels that have no            //
		// stencil bits set in the range we care about.                                                          //
		//=======================================================================================================//
		IMaterial *pMatHaloAddToScreen = materials->FindMaterial( "dev/halo_add_to_screen", TEXTURE_GROUP_OTHER, true );

		// Do not fade the glows out at all (weight = 1.0)
		IMaterialVar *pDimVar = pMatHaloAddToScreen->FindVar( "$C0_X", NULL );
		pDimVar->SetFloatValue( 1.0f );

		ShaderStencilState_t stencilState;
		stencilState.m_bEnable = true;
		stencilState.m_nWriteMask = 0x0; // We're not changing stencil
		stencilState.m_nTestMask = 0x3;
		stencilState.m_nReferenceValue = 0x0;
		stencilState.m_CompareFunc = SHADER_STENCILFUNC_EQUAL;
		stencilState.m_PassOp = SHADER_STENCILOP_KEEP;
		stencilState.m_FailOp = SHADER_STENCILOP_KEEP;
		stencilState.m_ZFailOp = SHADER_STENCILOP_KEEP;
		pRenderContext->SetStencilState( stencilState );

		// Draw quad
		pRenderContext->DrawScreenSpaceRectangle( pMatHaloAddToScreen, 0, 0, nViewportWidth, nViewportHeight,
			0.0f, -0.5f, nSrcWidth / 4 - 1, nSrcHeight / 4 - 1,
			pRtQuarterSize1->GetActualWidth(),
			pRtQuarterSize1->GetActualHeight() );

		// Disable stencil
		pRenderContext->SetStencilState( stencilStateDisable );
	}

}
Beispiel #20
0
IMaterial* CStudioRender::R_StudioSetupSkinAndLighting( IMatRenderContext *pRenderContext, int index, IMaterial **ppMaterials, int materialFlags,  
	void /*IClientRenderable*/ *pClientRenderable, ColorMeshInfo_t *pColorMeshes, StudioModelLighting_t &lighting )
{
	VPROF( "R_StudioSetupSkin" );
	IMaterial *pMaterial = NULL;
	bool bCheckForConVarDrawTranslucentSubModels = false;
	if( m_pRC->m_Config.bWireframe && !m_pRC->m_pForcedMaterial )
	{
		if ( m_pRC->m_Config.bDrawZBufferedWireframe )
			pMaterial = m_pMaterialMRMWireframeZBuffer;
		else
			pMaterial = m_pMaterialMRMWireframe;
	}
	else if( m_pRC->m_Config.bShowEnvCubemapOnly )
	{
		pMaterial = m_pMaterialModelEnvCubemap;
	}
	else
	{
		if ( !m_pRC->m_pForcedMaterial && ( m_pRC->m_nForcedMaterialType != OVERRIDE_DEPTH_WRITE ) )
		{
			pMaterial = ppMaterials[index];
			if ( !pMaterial )
			{
				Assert( 0 );
				return 0;
			}
		}
		else
		{
			materialFlags = 0;
			pMaterial = m_pRC->m_pForcedMaterial;
			if (m_pRC->m_nForcedMaterialType == OVERRIDE_BUILD_SHADOWS)
			{
				// Connect the original material up to the shadow building material
				// Also bind the original material so its proxies are in the correct state
				static unsigned int translucentCache = 0;
				IMaterialVar* pOriginalMaterialVar = pMaterial->FindVarFast( "$translucent_material", &translucentCache );
				Assert( pOriginalMaterialVar );
				IMaterial *pOriginalMaterial = ppMaterials[index];
				if ( pOriginalMaterial )
				{
					// Disable any alpha modulation on the original material that was left over from when it was last rendered
					pOriginalMaterial->AlphaModulate( 1.0f );
					pRenderContext->Bind( pOriginalMaterial, pClientRenderable );
					if ( pOriginalMaterial->IsTranslucent() || pOriginalMaterial->IsAlphaTested() )
					{
						pOriginalMaterialVar->SetMaterialValue( pOriginalMaterial );
					}
					else
					{
						pOriginalMaterialVar->SetMaterialValue( NULL );
					}
				}
				else
				{
					pOriginalMaterialVar->SetMaterialValue( NULL );
				}
			}
			else if( m_pRC->m_nForcedMaterialType == OVERRIDE_DEPTH_WRITE )
			{
				// Disable any alpha modulation on the original material that was left over from when it was last rendered
				ppMaterials[index]->AlphaModulate( 1.0f );

				// Bail if the material is still considered translucent after setting the AlphaModulate to 1.0
				if ( ppMaterials[index]->IsTranslucent() )
				{
					return NULL;
				}

				static unsigned int originalTextureVarCache = 0;
				IMaterialVar *pOriginalTextureVar = ppMaterials[index]->FindVarFast( "$basetexture", &originalTextureVarCache );

				// Select proper override material
				int nAlphaTest = (int) ( ppMaterials[index]->IsAlphaTested() && pOriginalTextureVar->IsTexture() ); // alpha tested base texture
				int nNoCull = (int) ppMaterials[index]->IsTwoSided();
				pMaterial = m_pDepthWrite[nAlphaTest][nNoCull];

				// If we're alpha tested, we should set up the texture variables from the original material
				if ( nAlphaTest != 0 )
				{
					static unsigned int originalTextureFrameVarCache = 0;
					IMaterialVar *pOriginalTextureFrameVar = ppMaterials[index]->FindVarFast( "$frame", &originalTextureFrameVarCache );
					static unsigned int originalAlphaRefCache = 0;
					IMaterialVar *pOriginalAlphaRefVar = ppMaterials[index]->FindVarFast( "$AlphaTestReference", &originalAlphaRefCache );

					static unsigned int textureVarCache = 0;
					IMaterialVar *pTextureVar = pMaterial->FindVarFast( "$basetexture", &textureVarCache );
					static unsigned int textureFrameVarCache = 0;
					IMaterialVar *pTextureFrameVar = pMaterial->FindVarFast( "$frame", &textureFrameVarCache );
					static unsigned int alphaRefCache = 0;
					IMaterialVar *pAlphaRefVar = pMaterial->FindVarFast( "$AlphaTestReference", &alphaRefCache );

					if ( pOriginalTextureVar->IsTexture() ) // If $basetexture is defined
					{
						if( pTextureVar && pOriginalTextureVar )
						{
							pTextureVar->SetTextureValue( pOriginalTextureVar->GetTextureValue() );
						}

						if( pTextureFrameVar && pOriginalTextureFrameVar )
						{
							pTextureFrameVar->SetIntValue( pOriginalTextureFrameVar->GetIntValue() );
						}

						if( pAlphaRefVar && pOriginalAlphaRefVar )
						{
							pAlphaRefVar->SetFloatValue( pOriginalAlphaRefVar->GetFloatValue() );
						}
					}
				}
			}
		}

		// Set this bool to check after the bind below
		bCheckForConVarDrawTranslucentSubModels = true;

		if ( m_pRC->m_nForcedMaterialType != OVERRIDE_DEPTH_WRITE )
		{
			// Try to set the alpha based on the blend
			pMaterial->AlphaModulate( m_pRC->m_AlphaMod );

			// Try to set the color based on the colormod
			pMaterial->ColorModulate( m_pRC->m_ColorMod[0], m_pRC->m_ColorMod[1], m_pRC->m_ColorMod[2] );
		}
	}

	lighting = R_StudioComputeLighting( pMaterial, materialFlags, pColorMeshes );
	if ( lighting == LIGHTING_MOUTH )
	{
		if ( !m_pRC->m_Config.bTeeth || !R_TeethAreVisible() )
			return NULL;
		// skin it and light it, but only if we need to.
		if ( m_pRC->m_Config.m_bSupportsVertexAndPixelShaders )
		{
			R_MouthSetupVertexShader( pMaterial );
		}
	}

	pRenderContext->Bind( pMaterial, pClientRenderable );

	if ( bCheckForConVarDrawTranslucentSubModels )
	{
		bool translucent = pMaterial->IsTranslucent();

		if (( m_bDrawTranslucentSubModels && !translucent ) ||
			( !m_bDrawTranslucentSubModels && translucent ))
		{
			m_bSkippedMeshes = true;
			return NULL;
		}
	}

	return pMaterial;
}
void CASWViewRender::DoMotionBlur( const CViewSetup &view )
{	
	if ( asw_motionblur.GetInt() == 0 && g_fMarinePoisonDuration <= 0)
	{
		g_bBlurredLastTime = false;
		return;
	}

	static float fNextDrawTime = 0.0f;

	bool found;
	IMaterialVar* mv = NULL;
	IMaterial *pMatScreen = NULL;
	ITexture *pMotionBlur = NULL;
	ITexture *pOriginalTexture = NULL; 

	// Get the front buffer material
	pMatScreen = materials->FindMaterial( "swarm/effects/frontbuffer", TEXTURE_GROUP_OTHER, true );
	// Get our custom render target
	pMotionBlur = g_pASWRenderTargets->GetASWMotionBlurTexture();
	// Store the current render target
	CMatRenderContextPtr pRenderContext( materials );
	ITexture *pOriginalRenderTarget = pRenderContext->GetRenderTarget();

	// Set the camera up so we can draw the overlay
	int oldX, oldY, oldW, oldH;
	pRenderContext->GetViewport( oldX, oldY, oldW, oldH );

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

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

	// set our blur parameters, based on convars or the poison duration
	float add_alpha = asw_motionblur_addalpha.GetFloat();
	float blur_time = asw_motionblur_time.GetFloat();
	float draw_alpha = asw_motionblur_drawalpha.GetFloat();
	if (g_fMarinePoisonDuration > 0)
	{		
		if (g_fMarinePoisonDuration < 1.0f)
		{
			draw_alpha = g_fMarinePoisonDuration;
			add_alpha = 0.3f;
		}
		else
		{
			draw_alpha = 1.0f;
			float over_time = g_fMarinePoisonDuration - 1.0f;
			over_time = -MIN(4.0f, over_time);
			// map 0 to -4, to 0.3 to 0.05
			add_alpha = (over_time + 4) * 0.0625 + 0.05f;
		}
		blur_time = 0.05f;
	}
	if (!g_bBlurredLastTime)
		add_alpha = 1.0f;	// add the whole buffer if this is the first time we're blurring after a while, so we don't end up with images from ages ago

	if ( fNextDrawTime - gpGlobals->curtime > 1.0f)
	{
		fNextDrawTime = 0.0f;
	}

	if( gpGlobals->curtime >= fNextDrawTime ) 
	{
		UpdateScreenEffectTexture( 0, view.x, view.y, view.width, view.height );

		// Set the alpha to whatever our console variable is
		mv = pMatScreen->FindVar( "$alpha", &found, false );
		if (found)
		{
			if ( fNextDrawTime == 0 )
			{
				mv->SetFloatValue( 1.0f );
			}
			else
			{
				mv->SetFloatValue( add_alpha );
			}
		}

		pRenderContext->SetRenderTarget( pMotionBlur );
		pRenderContext->DrawScreenSpaceQuad( pMatScreen );

		// Set the next draw time according to the convar
		fNextDrawTime = gpGlobals->curtime + blur_time;
	}

	// Set the alpha
	mv = pMatScreen->FindVar( "$alpha", &found, false );
	if (found)
	{
		mv->SetFloatValue( draw_alpha );
	}

	// Set the texture to our buffer
	mv = pMatScreen->FindVar( "$basetexture", &found, false );
	if (found)
	{
		pOriginalTexture = mv->GetTextureValue();
		mv->SetTextureValue( pMotionBlur );
	}

	// Pretend we were never here, set everything back
	pRenderContext->SetRenderTarget( pOriginalRenderTarget );
	pRenderContext->DrawScreenSpaceQuad( pMatScreen );

	// Set our texture back to _rt_FullFrameFB
	if (found)
	{
		mv->SetTextureValue( pOriginalTexture );
	}

	pRenderContext->DepthRange( 0.0f, 1.0f );
	pRenderContext->MatrixMode( MATERIAL_PROJECTION );
	pRenderContext->PopMatrix();
	pRenderContext->MatrixMode( MATERIAL_VIEW );
	pRenderContext->PopMatrix();

	g_bBlurredLastTime = true;
}
Beispiel #22
0
int	C_StriderFX::DrawModel( int )
{
	static color32 white = {255,255,255,255};
	Vector params[STRIDERFX_PARAMETERS];
	bool hasParam[STRIDERFX_PARAMETERS];

	if ( !m_active )
		return 1;

	C_BaseEntity *ent = cl_entitylist->GetEnt( m_entityIndex );
	if ( ent )
	{
		QAngle angles;
		ent->GetAttachment( m_attachment, m_worldPosition, angles );
	}

	// This forces time to drive from the main clock instead of being integrated per-draw below
	// that way the effect moves on even when culled for visibility
	if ( m_limitHitTime > 0 && m_tMax > 0 )
	{
		float dt = m_limitHitTime - gpGlobals->curtime;
		if ( dt < 0 )
		{
			dt = 0;
		}
		// if the clock needs to move, update it.
		if ( m_tMax - dt > m_t )
		{
			m_t = m_tMax - dt;
			m_beamEndPosition = m_worldPosition;
		}
	}
	else
	{
		// don't have enough info to derive the time, integrate current frame time
		m_t += gpGlobals->frametime;
		if ( m_tMax > 0 )
		{
			m_t = clamp( m_t, 0, m_tMax );
			m_beamEndPosition = m_worldPosition;
		}
	}
	float t = m_t;

	bool hasAny = false;
	memset( hasParam, 0, sizeof(hasParam) );
	for ( int i = 0; i < STRIDERFX_PARAMETERS; i++ )
	{
		hasParam[i] = g_StriderCannonEnvelope.m_parameters[i].Interp( params[i], t );
		hasAny = hasAny || hasParam[i];
	}

	pixelvis_queryparams_t gunParams;
	gunParams.Init(m_worldPosition, 4.0f);
	float gunFractionVisible = PixelVisibility_FractionVisible( gunParams, &m_queryHandleGun );
	bool gunVisible = gunFractionVisible > 0.0f ? true : false;

	// draw the narrow beam
	if ( hasParam[STRIDERFX_NARROW_BEAM_COLOR] && hasParam[STRIDERFX_NARROW_BEAM_SIZE] )
	{
		IMaterial *pMat = materials->FindMaterial( "sprites/bluelaser1", TEXTURE_GROUP_CLIENT_EFFECTS );
		float width = NARROW_BEAM_WIDTH * params[STRIDERFX_NARROW_BEAM_SIZE].x;
		color32 color;
		float bright = params[STRIDERFX_NARROW_BEAM_COLOR].x;
		ScaleColor( color, white, bright );

		Strider_DrawLine( m_beamEndPosition, m_targetPosition, width, pMat, color );
	}

	// draw the wide beam
	if ( hasParam[STRIDERFX_WIDE_BEAM_COLOR] && hasParam[STRIDERFX_WIDE_BEAM_SIZE] )
	{
		IMaterial *pMat = materials->FindMaterial( "effects/blueblacklargebeam", TEXTURE_GROUP_CLIENT_EFFECTS );
		float width = WIDE_BEAM_WIDTH * params[STRIDERFX_WIDE_BEAM_SIZE].x;
		color32 color;
		float bright = params[STRIDERFX_WIDE_BEAM_COLOR].x;
		ScaleColor( color, white, bright );
		Vector wideBeamEnd = m_beamEndPosition;
		if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] )
		{
			float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x;
			wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt);
		}

		Strider_DrawLine( wideBeamEnd, m_targetPosition, width, pMat, color );
	}

// after glow sprite
	bool updated = false;
	CMatRenderContextPtr pRenderContext( materials );
// warpy sprite bit
	if ( hasParam[STRIDERFX_WARP_SCALE] && !hasParam[STRIDERFX_BUBBLE_SIZE] && gunVisible )
	{
		if ( !updated )
		{
			updated = true;
			pRenderContext->Flush();
			UpdateRefractTexture();
		}

		IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
		float size = WARP_SIZE;
		float refract = params[STRIDERFX_WARP_SCALE].x * WARP_REFRACT * gunFractionVisible;

		pRenderContext->Bind( pMat, (IClientRenderable*)this );
		IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
		pVar->SetFloatValue( refract );
		Strider_DrawSprite( m_worldPosition, size, white );
	}
// darkening sprite
// glowy blue flare sprite
	if ( hasParam[STRIDERFX_FLARE_COLOR] && hasParam[STRIDERFX_FLARE_SIZE] && hasParam[STRIDERFX_DARKNESS] && gunVisible )
	{
		IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
		float size = FLARE_SIZE * params[STRIDERFX_FLARE_SIZE].x;
		color32 color;
		float bright = params[STRIDERFX_FLARE_COLOR].x * gunFractionVisible;
		ScaleColor( color, white, bright );
		color.a = (int)(255 * params[STRIDERFX_DARKNESS].x);
		pRenderContext->Bind( pMat, (IClientRenderable*)this );
		Strider_DrawSprite( m_worldPosition, size, color );
	}
// bubble warpy sprite
	if ( hasParam[STRIDERFX_BUBBLE_SIZE] )
	{
		Vector wideBeamEnd = m_beamEndPosition;
		if ( hasParam[STRIDERFX_WIDE_BEAM_LENGTH] )
		{
			float amt = params[STRIDERFX_WIDE_BEAM_LENGTH].x;
			wideBeamEnd = m_beamEndPosition * amt + m_targetPosition * (1-amt);
		}
		pixelvis_queryparams_t endParams;
		endParams.Init(wideBeamEnd, 4.0f, 0.001f);
		float endFractionVisible = PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd );
		bool endVisible = endFractionVisible > 0.0f ? true : false;

		if ( endVisible )
		{
			if ( !updated )
			{
				updated = true;
				pRenderContext->Flush();
				UpdateRefractTexture();
			}
			IMaterial *pMat = materials->FindMaterial( "effects/strider_bulge_dudv", TEXTURE_GROUP_CLIENT_EFFECTS );
			float refract = endFractionVisible * WARP_BUBBLE_REFRACT * params[STRIDERFX_BUBBLE_REFRACT].x;
			float size = WARP_BUBBLE_SIZE * params[STRIDERFX_BUBBLE_SIZE].x;
			IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL );
			pVar->SetFloatValue( refract );

			pRenderContext->Bind( pMat, (IClientRenderable*)this );
			Strider_DrawSprite( wideBeamEnd, size, white );
		}
	}
	else
	{
		// call this to have the check ready on the first frame
		pixelvis_queryparams_t endParams;
		endParams.Init(m_beamEndPosition, 4.0f, 0.001f);
		PixelVisibility_FractionVisible( endParams, &m_queryHandleBeamEnd );
	}
	if ( hasParam[STRIDERFX_AFTERGLOW_COLOR] && gunVisible )
	{
		IMaterial *pMat = materials->FindMaterial( "effects/blueblackflash", TEXTURE_GROUP_CLIENT_EFFECTS );
		float size = AFTERGLOW_SIZE;// * params[STRIDERFX_FLARE_SIZE].x;
		color32 color;
		float bright = params[STRIDERFX_AFTERGLOW_COLOR].x * gunFractionVisible;
		ScaleColor( color, white, bright );

		pRenderContext->Bind( pMat, (IClientRenderable*)this );
		Strider_DrawSprite( m_worldPosition, size, color );

		dlight_t *dl = effects->CL_AllocDlight( m_entityIndex );
		dl->origin = m_worldPosition;
		dl->color.r = 40;
		dl->color.g = 60;
		dl->color.b = 255;
		dl->color.exponent = 5;
		dl->radius = bright * 128;
		dl->die = gpGlobals->curtime + 0.001;
	}

	if ( m_t >= STRIDERFX_END_ALL_TIME && !hasAny )
	{
		EffectShutdown();
	}
	return 1;
}
Beispiel #23
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : noise_divisions - 
//			*prgNoise - 
//			*spritemodel - 
//			frame - 
//			rendermode - 
//			source - 
//			delta - 
//			flags - 
//			*color - 
//			fadescale - 
//-----------------------------------------------------------------------------
void DrawSegs( int noise_divisions, float *prgNoise, const model_t* spritemodel,
				float frame, int rendermode, const Vector& source, const Vector& delta, 
				float startWidth, float endWidth, float scale, float freq, float speed, int segments,
				int flags, float* color, float fadeLength, float flHDRColorScale )
{
	int				i, noiseIndex, noiseStep;
	float			div, length, fraction, factor, vLast, vStep, brightness;
	
	Assert( fadeLength >= 0.0f );
	CEngineSprite *pSprite = Draw_SetSpriteTexture( spritemodel, frame, rendermode );
	if ( !pSprite )
		return;

	if ( segments < 2 )
		return;

	IMaterial *pMaterial = pSprite->GetMaterial( (RenderMode_t)rendermode );
	if( pMaterial )
	{
		static unsigned int nHDRColorScaleCache = 0;
		IMaterialVar *pHDRColorScaleVar = pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache );
		if( pHDRColorScaleVar )
		{
			pHDRColorScaleVar->SetFloatValue( flHDRColorScale );
		}
	}
	
	length = VectorLength( delta );
	float flMaxWidth = MAX(startWidth, endWidth) * 0.5f;
	div = 1.0 / (segments-1);

	if ( length*div < flMaxWidth * 1.414 )
	{
		// Here, we have too many segments; we could get overlap... so lets have less segments
		segments = (int)(length / (flMaxWidth * 1.414)) + 1;
		if ( segments < 2 )
		{
			segments = 2;
		}
	}

	if ( segments > noise_divisions )		// UNDONE: Allow more segments?
	{
		segments = noise_divisions;
	}

	div = 1.0 / (segments-1);
	length *= 0.01;

	// UNDONE: Expose texture length scale factor to control "fuzziness"

	if ( flags & FBEAM_NOTILE )
	{
		// Don't tile
		vStep = div;
	}
	else
	{
		// Texture length texels per space pixel
		vStep = length*div;	
	}
	
	// UNDONE: Expose this paramter as well(3.5)?  Texture scroll rate along beam
	vLast = fmod(freq*speed,1);	// Scroll speed 3.5 -- initial texture position, scrolls 3.5/sec (1.0 is entire texture)

	if ( flags & FBEAM_SINENOISE )
	{
		if ( segments < 16 )
		{
			segments = 16;
			div = 1.0 / (segments-1);
		}
		scale *= 100;
		length = segments * (1.0/10);
	}
	else
	{
		scale *= length;
	}

	// Iterator to resample noise waveform (it needs to be generated in powers of 2)
	noiseStep = (int)((float)(noise_divisions-1) * div * 65536.0f);
	noiseIndex = 0;
	
	if ( flags & FBEAM_SINENOISE )
	{
		noiseIndex = 0;
	}

	brightness = 1.0;
	if ( flags & FBEAM_SHADEIN )
	{
		brightness = 0;
	}

	// What fraction of beam should be faded
	Assert( fadeLength >= 0.0f );
	float fadeFraction = fadeLength/ delta.Length();
	
	// BUGBUG: This code generates NANs when fadeFraction is zero! REVIST!
	fadeFraction = clamp(fadeFraction,1.e-6f,1.f);

	// Choose two vectors that are perpendicular to the beam
	Vector perp1;
	ComputeBeamPerpendicular( delta, &perp1 );

	// Specify all the segments.
	CMatRenderContextPtr pRenderContext( g_pMaterialSystem );
	CBeamSegDraw segDraw;
	segDraw.Start( pRenderContext, segments, NULL );

	for ( i = 0; i < segments; i++ )
	{
		Assert( noiseIndex < (noise_divisions<<16) );
		BeamSeg_t curSeg;
		curSeg.m_flAlpha = 1;

		fraction = i * div;

		// Fade in our out beam to fadeLength

		if ( (flags & FBEAM_SHADEIN) && (flags & FBEAM_SHADEOUT) )
		{
			if (fraction < 0.5)
			{
				brightness = 2*(fraction/fadeFraction);
			}
			else
			{
				brightness = 2*(1.0 - (fraction/fadeFraction));
			}
		}
		else if ( flags & FBEAM_SHADEIN )
		{
			brightness = fraction/fadeFraction;
		}
		else if ( flags & FBEAM_SHADEOUT )
		{
			brightness = 1.0 - (fraction/fadeFraction);
		}

		// clamps
		if (brightness < 0 )		
		{
			brightness = 0;
		}
		else if (brightness > 1)		
		{
			brightness = 1;
		}

		VectorScale( *((Vector*)color), brightness, curSeg.m_vColor );

		// UNDONE: Make this a spline instead of just a line?
		VectorMA( source, fraction, delta, curSeg.m_vPos );
 
		// Distort using noise
		if ( scale != 0 )
		{
			factor = prgNoise[noiseIndex>>16] * scale;
			if ( flags & FBEAM_SINENOISE )
			{
				float	s, c;
				SinCos( fraction*M_PI*length + freq, &s, &c );
				VectorMA( curSeg.m_vPos, factor * s, CurrentViewUp(), curSeg.m_vPos );
				// Rotate the noise along the perpendicluar axis a bit to keep the bolt from looking diagonal
				VectorMA( curSeg.m_vPos, factor * c, CurrentViewRight(), curSeg.m_vPos );
			}
			else
			{
				VectorMA( curSeg.m_vPos, factor, perp1, curSeg.m_vPos );
			}
		}

		// Specify the next segment.
		if( endWidth == startWidth )
		{
			curSeg.m_flWidth = startWidth * 2;
		}
		else
		{
			curSeg.m_flWidth = ((fraction*(endWidth-startWidth))+startWidth) * 2;
		}
		
		curSeg.m_flTexCoord = vLast;
		segDraw.NextSeg( &curSeg );


		vLast += vStep;	// Advance texture scroll (v axis only)
		noiseIndex += noiseStep;
	}
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 );
		}
	}
}