//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CMaterialModifyProxy::OnBindSetVar( C_MaterialModifyControl *pControl ) { IMaterial *pMaterial = pControl->GetMaterial(); if( !pMaterial ) { Assert( 0 ); return; } if ( pMaterial != m_pMaterial ) { // Warning( "\t%s!=%s\n", pMaterial->GetName(), m_pMaterial->GetName() ); return; } bool bFound; IMaterialVar *pMaterialVar = pMaterial->FindVar( pControl->GetMaterialVariableName(), &bFound, false ); if ( !bFound ) return; if( Q_strcmp( pControl->GetMaterialVariableValue(), "" ) ) { // const char *pMaterialName = m_pMaterial->GetName(); // const char *pMaterialVarName = pMaterialVar->GetName(); // const char *pMaterialVarValue = pControl->GetMaterialVariableValue(); // if( debug_materialmodifycontrol_client.GetBool() // && Q_stristr( m_pMaterial->GetName(), "faceandhair" ) // && Q_stristr( pMaterialVar->GetName(), "self" ) // ) // { // static int count = 0; // DevMsg( 1, "CMaterialModifyProxy::OnBindSetVar \"%s\" %s=%s %d pControl=0x%p\n", // m_pMaterial->GetName(), pMaterialVar->GetName(), pControl->GetMaterialVariableValue(), count++, pControl ); // } pMaterialVar->SetValueAutodetectType( pControl->GetMaterialVariableValue() ); } }
//----------------------------------------------------------------------------- // Pixel and vertex shader constants.... //----------------------------------------------------------------------------- void CBaseVSShader::SetPixelShaderConstant( int pixelReg, int constantVar, int constantVar2 ) { Assert( !IsSnapshotting() ); if ((!s_ppParams) || (constantVar == -1) || (constantVar2 == -1)) return; IMaterialVar* pPixelVar = s_ppParams[constantVar]; Assert( pPixelVar ); IMaterialVar* pPixelVar2 = s_ppParams[constantVar2]; Assert( pPixelVar2 ); float val[4]; if (pPixelVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) { pPixelVar->GetVecValue( val, 3 ); } else { val[0] = val[1] = val[2] = pPixelVar->GetFloatValue(); } val[3] = pPixelVar2->GetFloatValue(); s_pShaderAPI->SetPixelShaderConstant( pixelReg, val ); }
//----------------------------------------------------------------------------- // Helpers for dealing with envmap tint //----------------------------------------------------------------------------- // set alphaVar to -1 to ignore it. void CBaseVSShader::SetEnvMapTintPixelShaderDynamicState( int pixelReg, int tintVar, int alphaVar, bool bConvertFromGammaToLinear ) { float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; if( g_pConfig->bShowSpecular && mat_fullbright.GetInt() != 2 ) { IMaterialVar* pAlphaVar = NULL; if( alphaVar >= 0 ) { pAlphaVar = s_ppParams[alphaVar]; } if( pAlphaVar ) { color[3] = pAlphaVar->GetFloatValue(); } IMaterialVar* pTintVar = s_ppParams[tintVar]; #ifdef _DEBUG pTintVar->GetVecValue( color, 3 ); float envmapTintOverride = mat_envmaptintoverride.GetFloat(); float envmapTintScaleOverride = mat_envmaptintscale.GetFloat(); if( envmapTintOverride != -1.0f ) { color[0] = color[1] = color[2] = envmapTintOverride; } if( envmapTintScaleOverride != -1.0f ) { color[0] *= envmapTintScaleOverride; color[1] *= envmapTintScaleOverride; color[2] *= envmapTintScaleOverride; } if( bConvertFromGammaToLinear ) { color[0] = color[0] > 1.0f ? color[0] : GammaToLinear( color[0] ); color[1] = color[1] > 1.0f ? color[1] : GammaToLinear( color[1] ); color[2] = color[2] > 1.0f ? color[2] : GammaToLinear( color[2] ); } #else if( bConvertFromGammaToLinear ) { pTintVar->GetLinearVecValue( color, 3 ); } else { pTintVar->GetVecValue( color, 3 ); } #endif } else { color[0] = color[1] = color[2] = color[3] = 0.0f; } s_pShaderAPI->SetPixelShaderConstant( pixelReg, color, 1 ); }
void CLessOrEqualProxy::OnBind( void *pC_BaseEntity ) { Assert( m_pSrc1 && m_pSrc2 && m_pLessVar && m_pGreaterVar && m_pResult ); IMaterialVar *pSourceVar; if (m_pSrc1->GetFloatValue() <= m_pSrc2->GetFloatValue()) { pSourceVar = m_pLessVar; } else { pSourceVar = m_pGreaterVar; } int vecSize = 0; MaterialVarType_t resultType = m_pResult->GetType(); if (resultType == MATERIAL_VAR_TYPE_VECTOR) { if (m_ResultVecComp >= 0) resultType = MATERIAL_VAR_TYPE_FLOAT; vecSize = m_pResult->VectorSize(); } else if (resultType == MATERIAL_VAR_TYPE_UNDEFINED) { resultType = pSourceVar->GetType(); if (resultType == MATERIAL_VAR_TYPE_VECTOR) { vecSize = pSourceVar->VectorSize(); } } switch( resultType ) { case MATERIAL_VAR_TYPE_VECTOR: { Vector src; pSourceVar->GetVecValue( src.Base(), vecSize ); m_pResult->SetVecValue( src.Base(), vecSize ); } break; case MATERIAL_VAR_TYPE_FLOAT: SetFloatResult( pSourceVar->GetFloatValue() ); break; case MATERIAL_VAR_TYPE_INT: m_pResult->SetFloatValue( pSourceVar->GetIntValue() ); break; } if ( ToolsEnabled() ) { ToolFramework_RecordMaterialParams( GetMaterial() ); } }
//----------------------------------------------------------------------------- // Called when the texture is bound... //----------------------------------------------------------------------------- void CZZMaterialProxy::OnBind( C_BaseEntity *pEntity ) { if( !m_pTextureVar ) { return; } if(!m_pTextureVar->IsTexture()) // Make sure it is a texture return; //ITexture *pTexture = m_pTextureVar->GetTextureValue(); m_pTexture->Download(); // Mark it so it doesn't get regenerated on task switch //m_pEnt = NULL; }
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()); }
void CBaseShader::SetFixedFunctionTextureScaledTransform( MaterialMatrixMode_t textureTransform, int transformVar, int scaleVar ) { Assert( !IsSnapshotting() ); float mat[16]; IMaterialVar* pTransformationVar = s_ppParams[transformVar]; if (pTransformationVar && (pTransformationVar->GetType() == MATERIAL_VAR_TYPE_MATRIX)) { Vector2D scale( 1, 1 ); IMaterialVar* pScaleVar = s_ppParams[scaleVar]; if (pScaleVar) { if (pScaleVar->GetType() == MATERIAL_VAR_TYPE_VECTOR) pScaleVar->GetVecValue( scale.Base(), 2 ); else if (pScaleVar->IsDefined()) scale[0] = scale[1] = pScaleVar->GetFloatValue(); } s_pShaderAPI->MatrixMode( textureTransform ); const VMatrix &transformation = pTransformationVar->GetMatrixValue(); // only do the upper 3x3 since this is a 2D matrix mat[0] = transformation[0][0] * scale[0]; mat[1] = transformation[1][0] * scale[0]; mat[2] = transformation[3][0] * scale[0]; mat[4] = transformation[0][1] * scale[1]; mat[5] = transformation[1][1] * scale[1]; mat[6] = transformation[3][1] * scale[1]; mat[8] = transformation[0][3]; mat[9] = transformation[1][3]; mat[10] = transformation[3][3]; // Better set the stuff we don't set with some sort of value! mat[3] = mat[7] = mat[11] = 0; mat[12] = mat[13] = mat[14] = 0; mat[15] = 1; s_pShaderAPI->LoadMatrix( mat ); } else { SetFixedFunctionTextureScale( textureTransform, scaleVar ); } }
//----------------------------------------------------------------------------- // 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 ); }
//----------------------------------------------------------------------------- // 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 ); } }
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 CMatrixRotateProxy::OnBind( void *pC_BaseEntity ) { VMatrix mat; Vector axis( 0, 0, 1 ); if (m_pAxisVar) { m_pAxisVar->GetVecValue( axis.Base(), 3 ); if (VectorNormalize( axis ) < 1e-3) { axis.Init( 0, 0, 1 ); } } MatrixBuildRotationAboutAxis( mat, axis, m_Angle.GetFloat() ); m_pResult->SetMatrixValue( mat ); if ( ToolsEnabled() ) { ToolFramework_RecordMaterialParams( GetMaterial() ); } }
void CTextureProxy::OnBind( void *pEntity ) { // Bail if no base variable if ( !m_pBaseTextureVar ) return; char texture[128]; if (Q_stricmp(m_szTextureType, "hometeamcrest") == 0 && GetGlobalTeam(TEAM_A)->HasCrest()) Q_snprintf(texture, sizeof(texture), "%s/%s/teamcrest", TEAMKITS_PATH, GetGlobalTeam(TEAM_A)->GetFolderName()); else if (Q_stricmp(m_szTextureType, "awayteamcrest") == 0 && GetGlobalTeam(TEAM_B)->HasCrest()) Q_snprintf(texture, sizeof(texture), "%s/%s/teamcrest", TEAMKITS_PATH, GetGlobalTeam(TEAM_B)->GetFolderName()); else Q_snprintf(texture, sizeof(texture), "%s", m_pDefaultTexture->GetName()); m_pNewTexture = materials->FindTexture(texture, NULL, true); m_pBaseTextureVar->SetTextureValue(m_pNewTexture); GetMaterial()->RecomputeStateSnapshots(); }
bool CZZMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) { // ZZ return false; // hack! Need to make sure that the TGA loader has a valid filesystem before trying // to load the camo pattern. m_pMaterial = pMaterial; // get pointers to material vars. bool found; m_pTextureVar = pMaterial->FindVar( "$baseTexture", &found ); if( !found ) { m_pTextureVar = NULL; return false; } m_pTexture = m_pTextureVar->GetTextureValue(); if (m_pTexture) m_pTexture->SetTextureRegenerator( &m_TextureRegen ); return true; }
bool CTextureProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues ) { #ifdef ALLPROXIESFAIL return false; #endif // Check for $basetexture variable m_pBaseTextureVar = pMaterial->FindVar( "$basetexture", NULL ); if ( !m_pBaseTextureVar ) return false; // Set default texture and make sure its not an error texture m_pDefaultTexture = m_pBaseTextureVar->GetTextureValue(); if ( IsErrorTexture( m_pDefaultTexture ) ) return false; Q_strncpy(m_szTextureType, pKeyValues->GetString("type"), sizeof(m_szTextureType)); return true; }
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 CCamoMaterialProxy::LoadCamoPattern( void ) { #if 0 // hack - need to figure out a name to attach that isn't too long. m_pCamoPatternImage = ( unsigned char * )datacache->FindByName( &m_camoImageDataCache, "camopattern" ); if( m_pCamoPatternImage ) { // is already in the cache. return m_pCamoPatternImage; } #endif enum ImageFormat indexImageFormat; int indexImageSize; #ifndef _XBOX float dummyGamma; if( !TGALoader::GetInfo( m_pCamoPatternTextureVar->GetStringValue(), &m_CamoPatternWidth, &m_CamoPatternHeight, &indexImageFormat, &dummyGamma ) ) { //Warning( "Can't get tga info for hl2/materials/models/combine_elite/camo7paletted.tga for camo material\n" ); m_pCamoTextureVar = NULL; return; } #else // xboxissue - no tga support, why implemented this way Assert( 0 ); m_pCamoTextureVar = NULL; return; #endif if( indexImageFormat != IMAGE_FORMAT_I8 ) { // Warning( "Camo material texture hl2/materials/models/combine_elite/camo7paletted.tga must be 8-bit greyscale\n" ); m_pCamoTextureVar = NULL; return; } indexImageSize = ImageLoader::GetMemRequired( m_CamoPatternWidth, m_CamoPatternHeight, 1, indexImageFormat, false ); #if 0 m_pCamoPatternImage = ( unsigned char * ) datacache->Alloc( &m_camoImageDataCache, indexImageSize, "camopattern" ); #endif m_pCamoPatternImage = ( unsigned char * )new unsigned char[indexImageSize]; if( !m_pCamoPatternImage ) { m_pCamoTextureVar = NULL; return; } #ifndef _XBOX if( !TGALoader::Load( m_pCamoPatternImage, m_pCamoPatternTextureVar->GetStringValue(), m_CamoPatternWidth, m_CamoPatternHeight, IMAGE_FORMAT_I8, dummyGamma, false ) ) { // Warning( "camo texture hl2/materials/models/combine_elite/camo7paletted.tga must be grey-scale" ); m_pCamoTextureVar = NULL; return; } #else // xboxissue - no tga support, why is the camo done this way? Assert( 0 ); #endif bool colorUsed[256]; int colorRemap[256]; // count the number of colors used in the image. int i; for( i = 0; i < 256; i++ ) { colorUsed[i] = false; } for( i = 0; i < indexImageSize; i++ ) { colorUsed[m_pCamoPatternImage[i]] = true; } m_CamoPatternNumColors = 0; for( i = 0; i < 256; i++ ) { if( colorUsed[i] ) { colorRemap[i] = m_CamoPatternNumColors; m_CamoPatternNumColors++; } } // remap the color to the beginning of the palette. for( i = 0; i < indexImageSize; i++ ) { m_pCamoPatternImage[i] = colorRemap[m_pCamoPatternImage[i]]; // hack // m_pCamoPatternImage[i] = 0; } }
bool CEngineSprite::Init( const char *pName ) { m_hAVIMaterial = AVIMATERIAL_INVALID; m_hBIKMaterial = BIKMATERIAL_INVALID; m_width = m_height = m_numFrames = 1; const char *pExt = Q_GetFileExtension( pName ); bool bIsAVI = pExt && !Q_stricmp( pExt, "avi" ); #if !defined( _X360 ) || defined( BINK_ENABLED_FOR_X360 ) bool bIsBIK = pExt && !Q_stricmp( pExt, "bik" ); #endif if ( bIsAVI && IsPC() ) { m_hAVIMaterial = avi->CreateAVIMaterial( pName, pName, "GAME" ); if ( m_hAVIMaterial == AVIMATERIAL_INVALID ) return false; IMaterial *pMaterial = avi->GetMaterial( m_hAVIMaterial ); avi->GetFrameSize( m_hAVIMaterial, &m_width, &m_height ); m_numFrames = avi->GetFrameCount( m_hAVIMaterial ); for ( int i = 0; i < kRenderModeCount; ++i ) { m_material[i] = pMaterial; pMaterial->IncrementReferenceCount(); } } #if !defined( _X360 ) || defined( BINK_ENABLED_FOR_X360 ) else if ( bIsBIK ) { m_hBIKMaterial = bik->CreateMaterial( pName, pName, "GAME" ); if ( m_hBIKMaterial == BIKMATERIAL_INVALID ) return false; IMaterial *pMaterial = bik->GetMaterial( m_hBIKMaterial ); bik->GetFrameSize( m_hBIKMaterial, &m_width, &m_height ); m_numFrames = bik->GetFrameCount( m_hBIKMaterial ); for ( int i = 0; i < kRenderModeCount; ++i ) { m_material[i] = pMaterial; pMaterial->IncrementReferenceCount(); } } #endif 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) ); for ( int i = 0; i < kRenderModeCount; ++i ) { m_material[i] = NULL; } 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 ) { continue; } // strip possible materials/ Q_snprintf( pMaterialPath, sizeof(pMaterialPath), "%s_rendermode_%d", pMaterialName + ( bIsUNC ? 0 : 10 ), 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; }
IMaterial *CPlayerLogoProxy::GetMaterial() { return m_pBaseTextureVar->GetOwningMaterial(); }
void CPlayerLogoProxy::OnBind( void *pC_BaseEntity ) { // Decal's are bound with the player index as the passed in paramter int playerindex = (int)pC_BaseEntity; if ( playerindex <= 0 ) return; if ( playerindex > gpGlobals->maxClients ) return; if ( !m_pBaseTextureVar ) return; // Find player player_info_t info; engine->GetPlayerInfo( playerindex, &info ); if ( !info.customFiles[0] ) return; // So we don't trash this too hard ITexture *texture = NULL; PlayerLogo logo; logo.crc = (unsigned int)info.customFiles[0]; logo.texture = NULL; int lookup = m_Logos.Find( logo ); if ( lookup == m_Logos.InvalidIndex() ) { char crcfilename[ 512 ]; char logohex[ 16 ]; Q_binarytohex( (byte *)&info.customFiles[0], sizeof( info.customFiles[0] ), logohex, sizeof( logohex ) ); Q_snprintf( crcfilename, sizeof( crcfilename ), "temp/%s", logohex ); texture = materials->FindTexture( crcfilename, TEXTURE_GROUP_DECAL, false ); if ( texture ) { // Make sure it doesn't get flushed texture->IncrementReferenceCount(); logo.texture = texture; } m_Logos.Insert( logo ); } else { texture = m_Logos[ lookup ].texture; } if ( texture ) { m_pBaseTextureVar->SetTextureValue( texture ); } else if ( m_pDefaultTexture ) { m_pBaseTextureVar->SetTextureValue( m_pDefaultTexture ); } if ( ToolsEnabled() ) { ToolFramework_RecordMaterialParams( GetMaterial() ); } }
//----------------------------------------------------------------------------- // Purpose: Render the effect //----------------------------------------------------------------------------- void CStunEffect::Render( int x, int y, int w, int h ) { // Make sure we're ready to play this effect if ( m_flFinishTime < gpGlobals->curtime ) return; IMaterial *pMaterial = materials->FindMaterial( "effects/stun", TEXTURE_GROUP_CLIENT_EFFECTS, true ); if ( pMaterial == NULL ) return; bool bResetBaseFrame = m_bUpdated; // Set ourselves to the proper rendermode materials->MatrixMode( MATERIAL_VIEW ); materials->PushMatrix(); materials->LoadIdentity(); materials->MatrixMode( MATERIAL_PROJECTION ); materials->PushMatrix(); materials->LoadIdentity(); // Get our current view if ( m_pStunTexture == NULL ) { m_pStunTexture = GetPowerOfTwoFrameBufferTexture(); } // Draw the texture if we're using it if ( m_pStunTexture != NULL ) { bool foundVar; IMaterialVar* pBaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false ); if ( bResetBaseFrame ) { // Save off this pass Rect_t srcRect; srcRect.x = x; srcRect.y = y; srcRect.width = w; srcRect.height = h; pBaseTextureVar->SetTextureValue( m_pStunTexture ); materials->CopyRenderTargetToTextureEx( m_pStunTexture, 0, &srcRect, NULL ); materials->SetFrameBufferCopyTexture( m_pStunTexture ); m_bUpdated = false; } byte overlaycolor[4] = { 255, 255, 255, 0 }; float flEffectPerc = ( m_flFinishTime - gpGlobals->curtime ) / m_flDuration; overlaycolor[3] = (byte) (150.0f * flEffectPerc); render->ViewDrawFade( overlaycolor, pMaterial ); float viewOffs = ( flEffectPerc * 32.0f ) * cos( gpGlobals->curtime * 10.0f * cos( gpGlobals->curtime * 2.0f ) ); float vX = x + viewOffs; float vY = y; // just do one pass for dxlevel < 80. if (g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 80) { materials->DrawScreenSpaceRectangle( pMaterial, vX, vY, w, h, 0, 0, m_pStunTexture->GetActualWidth()-1, m_pStunTexture->GetActualHeight()-1, m_pStunTexture->GetActualWidth(), m_pStunTexture->GetActualHeight() ); render->ViewDrawFade( overlaycolor, pMaterial ); materials->DrawScreenSpaceRectangle( pMaterial, x, y, w, h, 0, 0, m_pStunTexture->GetActualWidth()-1, m_pStunTexture->GetActualHeight()-1, m_pStunTexture->GetActualWidth(), m_pStunTexture->GetActualHeight() ); } // Save off this pass Rect_t srcRect; srcRect.x = x; srcRect.y = y; srcRect.width = w; srcRect.height = h; pBaseTextureVar->SetTextureValue( m_pStunTexture ); materials->CopyRenderTargetToTextureEx( m_pStunTexture, 0, &srcRect, NULL ); } // Restore our state materials->MatrixMode( MATERIAL_VIEW ); materials->PopMatrix(); materials->MatrixMode( MATERIAL_PROJECTION ); materials->PopMatrix(); }
//----------------------------------------------------------------------------- // Purpose: Render the effect //----------------------------------------------------------------------------- void CEP1IntroEffect::Render( int x, int y, int w, int h ) { if ( ( m_flFinishTime == 0 ) || ( IsEnabled() == false ) ) return; IMaterial *pMaterial = materials->FindMaterial( "effects/introblur", TEXTURE_GROUP_CLIENT_EFFECTS, true ); if ( pMaterial == NULL ) return; // Set ourselves to the proper rendermode materials->MatrixMode( MATERIAL_VIEW ); materials->PushMatrix(); materials->LoadIdentity(); materials->MatrixMode( MATERIAL_PROJECTION ); materials->PushMatrix(); materials->LoadIdentity(); // Get our current view if ( m_pStunTexture == NULL ) { m_pStunTexture = GetWaterRefractionTexture(); } // Draw the texture if we're using it if ( m_pStunTexture != NULL ) { bool foundVar; IMaterialVar* pBaseTextureVar = pMaterial->FindVar( "$basetexture", &foundVar, false ); if ( m_bUpdateView ) { // Save off this pass Rect_t srcRect; srcRect.x = x; srcRect.y = y; srcRect.width = w; srcRect.height = h; pBaseTextureVar->SetTextureValue( m_pStunTexture ); materials->CopyRenderTargetToTextureEx( m_pStunTexture, 0, &srcRect, NULL ); materials->SetFrameBufferCopyTexture( m_pStunTexture ); m_bUpdateView = false; } byte overlaycolor[4] = { 255, 255, 255, 0 }; // Get our fade value depending on our fade duration overlaycolor[3] = GetFadeAlpha(); // Disable overself if we're done fading out if ( m_bFadeOut && overlaycolor[3] == 0 ) { // Takes effect next frame (we don't want to hose our matrix stacks here) g_pScreenSpaceEffects->DisableScreenSpaceEffect( "episodic_intro" ); m_bUpdateView = true; } // Calculate some wavey noise to jitter the view by float vX = 2.0f * -fabs( cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 6.0 ) ); float vY = 2.0f * cosf( gpGlobals->curtime ) * cosf( gpGlobals->curtime * 5.0 ); // Scale percentage float flScalePerc = 0.02f + ( 0.01f * cosf( gpGlobals->curtime * 2.0f ) * cosf( gpGlobals->curtime * 0.5f ) ); // Scaled offsets for the UVs (as texels) float flUOffset = ( m_pStunTexture->GetActualWidth() - 1 ) * flScalePerc * 0.5f; float flVOffset = ( m_pStunTexture->GetActualHeight() - 1 ) * flScalePerc * 0.5f; // New UVs with scaling offsets float flU1 = flUOffset; float flU2 = ( m_pStunTexture->GetActualWidth() - 1 ) - flUOffset; float flV1 = flVOffset; float flV2 = ( m_pStunTexture->GetActualHeight() - 1 ) - flVOffset; // Draw the "zoomed" overlay materials->DrawScreenSpaceRectangle( pMaterial, vX, vY, w, h, flU1, flV1, flU2, flV2, m_pStunTexture->GetActualWidth(), m_pStunTexture->GetActualHeight() ); render->ViewDrawFade( overlaycolor, pMaterial ); // Save off this pass Rect_t srcRect; srcRect.x = x; srcRect.y = y; srcRect.width = w; srcRect.height = h; pBaseTextureVar->SetTextureValue( m_pStunTexture ); materials->CopyRenderTargetToTextureEx( m_pStunTexture, 0, &srcRect, NULL ); } // Restore our state materials->MatrixMode( MATERIAL_VIEW ); materials->PopMatrix(); materials->MatrixMode( MATERIAL_PROJECTION ); materials->PopMatrix(); }
bool CEngineSprite::Init( const char *pName ) { m_hAVIMaterial = AVIMATERIAL_INVALID; m_hBIKMaterial = BIKMATERIAL_INVALID; m_width = m_height = m_numFrames = 1; const char *pExt = Q_GetFileExtension( pName ); bool bIsAVI = pExt && !Q_stricmp( pExt, "avi" ); bool bIsBIK = pExt && !Q_stricmp( pExt, "bik" ); if ( bIsAVI ) { m_hAVIMaterial = avi->CreateAVIMaterial( pName, pName, "GAME" ); if ( m_hAVIMaterial == AVIMATERIAL_INVALID ) return false; m_material = avi->GetMaterial( m_hAVIMaterial ); avi->GetFrameSize( m_hAVIMaterial, &m_width, &m_height ); m_numFrames = avi->GetFrameCount( m_hAVIMaterial ); } else if ( bIsBIK ) { m_hBIKMaterial = bik->CreateMaterial( pName, pName, "GAME" ); if (m_hBIKMaterial == BIKMATERIAL_INVALID ) return false; m_material = bik->GetMaterial( m_hBIKMaterial ); bik->GetFrameSize( m_hBIKMaterial, &m_width, &m_height ); m_numFrames = bik->GetFrameCount( m_hBIKMaterial ); } else { m_material = materials->FindMaterial( pName, TEXTURE_GROUP_CLIENT_EFFECTS ); m_width = m_material->GetMappingWidth(); m_height = m_material->GetMappingHeight(); m_numFrames = (!bIsAVI) ? m_material->GetNumAnimationFrames() : avi->GetFrameCount( m_hAVIMaterial ); } if ( !m_material ) return false; m_material->IncrementReferenceCount(); IMaterialVar *orientationVar = m_material->FindVarFast( "$spriteorientation", &spriteOrientationCache ); m_orientation = orientationVar ? orientationVar->GetIntValue() : C_SpriteRenderer::SPR_VP_PARALLEL_UPRIGHT; IMaterialVar *originVar = m_material->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; }
IMaterial *CTextureScrollMaterialProxy::GetMaterial() { return m_pTextureScrollVar->GetOwningMaterial(); }
void DrawSpriteModel( IClientEntity *baseentity, CEngineSprite *psprite, const Vector &origin, float fscale, float frame, int rendermode, int r, int g, int b, int a, const Vector& forward, const Vector& right, const Vector& up, float flHDRColorScale ) { float scale; IMaterial *material; // don't even bother culling, because it's just a single // polygon without a surface cache if ( fscale > 0 ) scale = fscale; else scale = 1.0f; if ( rendermode == kRenderNormal ) { render->SetBlend( 1.0f ); } material = psprite->GetMaterial( (RenderMode_t)rendermode, frame ); if ( !material ) return; CMatRenderContextPtr pRenderContext( materials ); if ( ShouldDrawInWireFrameMode() || r_drawsprites.GetInt() == 2 ) { IMaterial *pMaterial = materials->FindMaterial( "debug/debugspritewireframe", TEXTURE_GROUP_OTHER ); pRenderContext->Bind( pMaterial, NULL ); } else { pRenderContext->Bind( material, (IClientRenderable*)baseentity ); } unsigned char color[4]; color[0] = r; color[1] = g; color[2] = b; color[3] = a; IMaterialVar *pHDRColorScaleVar = material->FindVarFast( "$HDRCOLORSCALE", &s_nHDRColorScaleCache ); if( pHDRColorScaleVar ) { pHDRColorScaleVar->SetVecValue( flHDRColorScale, flHDRColorScale, flHDRColorScale ); } Vector point; IMesh* pMesh = pRenderContext->GetDynamicMesh(); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vec_a; Vector vec_b; Vector vec_c; Vector vec_d; // isolate common terms VectorMA( origin, psprite->GetDown() * scale, up, vec_a ); VectorScale( right, psprite->GetLeft() * scale, vec_b ); VectorMA( origin, psprite->GetUp() * scale, up, vec_c ); VectorScale( right, psprite->GetRight() * scale, vec_d ); float flMinU, flMinV, flMaxU, flMaxV; psprite->GetTexCoordRange( &flMinU, &flMinV, &flMaxU, &flMaxV ); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMinU, flMaxV ); VectorAdd( vec_a, vec_b, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMinU, flMinV ); VectorAdd( vec_c, vec_b, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMaxU, flMinV ); VectorAdd( vec_c, vec_d, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.Color4ubv( color ); meshBuilder.TexCoord2f( 0, flMaxU, flMaxV ); VectorAdd( vec_a, vec_d, point ); meshBuilder.Position3fv( point.Base() ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); }
int C_NEOPlayer::DrawModel( int flags ) { C_NEOPlayer* localPlayer = C_NEOPlayer::GetLocalNEOPlayer(); int result = -1; if ( localPlayer ) { if ( GetTeamNumber() == localPlayer->GetTeamNumber() ) m_bUnknown = true; if ( m_iOldVision != 3 ) { if ( m_bUnknown2 ) { m_bUnknown2 = false; dlight_t* light = effects->CL_AllocDlight( LIGHT_INDEX_TE_DYNAMIC + index ); light->origin = GetAbsOrigin(); light->radius = 96.f; light->decay = 192.f; light->color.r = 64; light->color.g = 64; light->color.b = 255; light->color.exponent = 10; light->die = gpGlobals->curtime + 0.1f; return 0; } if ( !g_pMaterialSystemHardwareConfig->SupportsPixelShaders_2_0() ) return 0; UpdateRefractTexture(); IMaterial* thermopticMaterial = GetThermopticMaterial(); UpdateThermopticMaterial( thermopticMaterial, m_flUnknown ); modelrender->ForcedMaterialOverride( thermopticMaterial ); result = BaseClass::InternalDrawModel( flags ); modelrender->ForcedMaterialOverride( nullptr ); } else { if ( !g_pMaterialSystemHardwareConfig->SupportsPixelShaders_2_0() ) return BaseClass::DrawModel( flags ); IMaterial* matThermal = g_pMaterialSystem->FindMaterial( "dev/thermal", TEXTURE_GROUP_OTHER ); if ( IsErrorMaterial( matThermal ) ) { DevMsg( SPEW_MESSAGE, "F**k me...\n" ); // Their message, not mine kek BaseClass::DrawModel( flags ); } bool found = false; IMaterialVar* matVar = matThermal->FindVar( "$eyevec", &found ); if ( found ) { Vector forward; GetVectors( &forward, nullptr, nullptr ); matVar->SetVecValue( forward.x, forward.y, forward.z, 3.f ); } modelrender->ForcedMaterialOverride( matThermal ); result = BaseClass::InternalDrawModel( flags ); modelrender->ForcedMaterialOverride( nullptr ); } if ( m_iThermoptic == 1 ) { if ( !g_pMaterialSystemHardwareConfig->SupportsPixelShaders_2_0() ) return BaseClass::DrawModel( flags ); IMaterial* matMotion = g_pMaterialSystem->FindMaterial( "dev/motion", TEXTURE_GROUP_OTHER ); if ( IsErrorMaterial( matMotion ) ) { DevMsg( SPEW_MESSAGE, "F**k me...\n" ); BaseClass::DrawModel( flags ); } float velocity = localPlayer->GetLocalVelocity().Length() / 75.f; if ( velocity > 4.f ) velocity = 4.f; bool found = false; IMaterialVar* matVar = matMotion->FindVar( "$eyevec", &found ); if ( found ) { Vector forward; GetVectors( &forward, nullptr, nullptr ); matVar->SetVecValue( forward.x, forward.y, forward.z, velocity ); } modelrender->ForcedMaterialOverride( matMotion ); result = BaseClass::InternalDrawModel( flags ); modelrender->ForcedMaterialOverride( nullptr ); } if ( m_iVision == 3 ) // Thermal vision { if ( !g_pMaterialSystemHardwareConfig->SupportsPixelShaders_2_0() ) return BaseClass::DrawModel( flags ); IMaterial* matThermal = g_pMaterialSystem->FindMaterial( "dev/vm_thermal", "Other textures" ); if ( IsErrorMaterial( matThermal ) ) { DevMsg( SPEW_MESSAGE, "F**k me...\n" ); BaseClass::DrawModel( flags ); } bool found = false; IMaterialVar* matVar = matThermal->FindVar( "$eyevec", &found ); if ( found ) { Vector forward; GetVectors( &forward, nullptr, nullptr ); matVar->SetVecValue( forward.x, forward.y, forward.z, 3.f ); } modelrender->ForcedMaterialOverride( matThermal ); result = BaseClass::InternalDrawModel( flags ); modelrender->ForcedMaterialOverride( nullptr ); } if ( m_bUnknown2 ) m_bUnknown2 = false; if ( result >= 0 ) return result; } return BaseClass::DrawModel( flags ); }
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; }
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: // 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 ); } } }