Skip to content

Instantly share code, notes, and snippets.

@alanedwardes
Created June 11, 2013 21:59
Show Gist options
  • Save alanedwardes/5761109 to your computer and use it in GitHub Desktop.
Save alanedwardes/5761109 to your computer and use it in GitHub Desktop.
A passthru material system for the source engine. Doesn't work very well.
#include "cbase.h"
#include "estranged_materialsystem.h"
#include "materialsystem\itexture.h"
#include "materialsystem/imaterialvar.h"
static void AppendShaderParams(const char* shader, IMaterial *pMat, KeyValues *newParams)
{
int nParams = pMat->ShaderParamCount();
IMaterialVar **pParams = pMat->GetShaderParams();
char str[ 512 ];
for ( int i = 0; i < nParams; ++i )
{
IMaterialVar *pVar = pParams[ i ];
const char *pVarName = pVar->GetName();
if (!stricmp("$flags", pVarName) ||
!stricmp("$flags_defined", pVarName) ||
!stricmp("$flags2", pVarName) ||
!stricmp("$flags_defined2", pVarName) )
continue;
MaterialVarType_t vartype = pVar->GetType();
switch ( vartype )
{
case MATERIAL_VAR_TYPE_FLOAT:
newParams->SetFloat( pVarName, pVar->GetFloatValue() );
break;
case MATERIAL_VAR_TYPE_INT:
newParams->SetInt( pVarName, pVar->GetIntValue() );
break;
case MATERIAL_VAR_TYPE_STRING:
newParams->SetString( pVarName, pVar->GetStringValue() );
break;
case MATERIAL_VAR_TYPE_FOURCC:
Assert( 0 ); // JDTODO
break;
case MATERIAL_VAR_TYPE_VECTOR:
{
const float *pVal = pVar->GetVecValue();
int dim = pVar->VectorSize();
switch ( dim )
{
case 1:
V_snprintf( str, sizeof( str ), "[%f]", pVal[ 0 ] );
break;
case 2:
V_snprintf( str, sizeof( str ), "[%f %f]", pVal[ 0 ], pVal[ 1 ] );
break;
case 3:
V_snprintf( str, sizeof( str ), "[%f %f %f]", pVal[ 0 ], pVal[ 1 ], pVal[ 2 ] );
break;
case 4:
V_snprintf( str, sizeof( str ), "[%f %f %f %f]", pVal[ 0 ], pVal[ 1 ], pVal[ 2 ], pVal[ 3 ] );
break;
default:
Assert( 0 );
*str = 0;
}
newParams->SetString( pVarName, str );
}
break;
case MATERIAL_VAR_TYPE_MATRIX:
{
const VMatrix &matrix = pVar->GetMatrixValue();
const float *pVal = matrix.Base();
V_snprintf( str, sizeof( str ),
"[%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f]",
pVal[ 0 ], pVal[ 1 ], pVal[ 2 ], pVal[ 3 ],
pVal[ 4 ], pVal[ 5 ], pVal[ 6 ], pVal[ 7 ],
pVal[ 8 ], pVal[ 9 ], pVal[ 10 ], pVal[ 11 ],
pVal[ 12 ], pVal[ 13 ], pVal[ 14 ], pVal[ 15 ] );
newParams->SetString( pVarName, str );
}
break;
case MATERIAL_VAR_TYPE_TEXTURE:
newParams->SetString( pVarName, pVar->GetTextureValue()->GetName() );
break;
case MATERIAL_VAR_TYPE_MATERIAL:
newParams->SetString( pVarName, pVar->GetMaterialValue()->GetName() );
break;
}
}
const bool bAlphaBlending = pMat->IsTranslucent() || pMat->GetMaterialVarFlag( MATERIAL_VAR_TRANSLUCENT );
const bool bAlphaTesting = pMat->IsAlphaTested() || pMat->GetMaterialVarFlag( MATERIAL_VAR_ALPHATEST );
const bool bSelfillum = pMat->GetMaterialVarFlag( MATERIAL_VAR_SELFILLUM );
const bool bDecal = shader != NULL && Q_stristr( shader,"decal" ) || pMat->GetMaterialVarFlag( MATERIAL_VAR_DECAL );
const bool bNormalMapAlphaEnvmapMask = pMat->GetMaterialVarFlag( MATERIAL_VAR_NORMALMAPALPHAENVMAPMASK );
if ( bDecal )
{
newParams->SetInt( "$decal", 1 );
}
if ( bAlphaTesting )
{
newParams->SetInt( "$alphatest", 1 );
}
else if ( bAlphaBlending )
{
newParams->SetInt( "$translucent", 1 );
}
if ( pMat->IsTwoSided() )
{
newParams->SetInt( "$nocull", 1 );
}
if ( bSelfillum )
{
newParams->SetInt( "$selfillum", 1 );
}
if ( bNormalMapAlphaEnvmapMask )
{
newParams->SetInt( "$normalmapalphaenvmapmask", 1 );
}
pMat->SetShaderAndParams(newParams);
pMat->RefreshPreservingMaterialVars();
}
static void ShaderReplace( const char *szShadername, IMaterial *pMat )
{
KeyValues *msg = new KeyValues(szShadername);
AppendShaderParams(szShadername, pMat, msg);
msg->deleteThis();
}
static void ShaderFixup(const char *szShadername, IMaterial *pMat)
{
if (!Q_stricmp(szShadername, "vertexlitgeneric"))
{
IMaterialVar *pBumpmap = pMat->FindVar("$bumpmap", NULL);
if (!pBumpmap->IsDefined())
{
KeyValues *newParams = new KeyValues(szShadername);
newParams->SetString("$bumpmap", "dud_normal");
IMaterialVar *var;
var = pMat->FindVar("$envmapmask", NULL);
if (var->IsDefined()) var->SetUndefined();
var = pMat->FindVar("$envmap", NULL);
if (var->IsDefined()) var->SetUndefined();
AppendShaderParams(szShadername, pMat, newParams);
newParams->deleteThis();
}
}
}
static const char *pszShaderReplaceDict[][2] = {
//"vertexlitgeneric", "sdk_vertexlitgeneric",
"lightmappedgeneric", "sdk_lightmappedgeneric",
//"dummy", "sdk_dummy",
};
static const int iNumShaderReplaceDict = ARRAYSIZE( pszShaderReplaceDict );
static const char *pszShaderFixupDict[] = {
"vertexlitgeneric",
};
static const int iNumShaderFixupDict = ARRAYSIZE( pszShaderReplaceDict );
static ConVar ae_modifymaterialsystem("ae_modifymaterialsystem", "1", FCVAR_CHEAT);
IMaterial *CEstrangedMaterialSystem::FindMaterial( char const* pMaterialName, const char *pTextureGroupName, bool complain, const char *pComplainPrefix )
{
IMaterial *pMat = m_pBaseMaterialsPassThru->FindMaterial(pMaterialName, pTextureGroupName, complain);
if (!ae_modifymaterialsystem.GetBool())
{
return pMat;
}
if (pMat->HasProxy())
{
return pMat;
}
if (pMat->GetNumAnimationFrames() > 1)
{
return pMat;
}
if (pMat != NULL)
{
if (!pMat->ShaderParamCount())
{
return pMat;
}
const char *pszShaderName = pMat->GetShaderName();
if (pszShaderName && *pszShaderName)
{
for (int i = 0; i < iNumShaderReplaceDict; i++)
{
if (!Q_stricmp(pszShaderName, pszShaderReplaceDict[i][0]))
{
ShaderReplace(pszShaderReplaceDict[i][1], pMat);
break;
}
}
for (int i = 0; i < iNumShaderFixupDict; i++)
{
if (!Q_stricmp(pszShaderName, pszShaderFixupDict[i]))
{
ShaderFixup(pszShaderFixupDict[i], pMat);
break;
}
}
}
}
return pMat;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment