void ImposterCaptureMaterialHook::init( BaseMatInstance *inMat ) { // We cannot capture impostors on custom materials // as we don't know how to get just diffuse and just // normals rendering. if ( dynamic_cast<CustomMaterial*>( inMat->getMaterial() ) ) return; // Tweak the feature data to include just what we need. FeatureSet features; features.addFeature( MFT_VertTransform ); features.addFeature( MFT_DiffuseMap ); features.addFeature( MFT_OverlayMap ); features.addFeature( MFT_DetailMap ); features.addFeature( MFT_DiffuseColor ); features.addFeature( MFT_AlphaTest ); features.addFeature( MFT_IsTranslucent ); const String &matName = inMat->getMaterial()->getName(); mDiffuseMatInst = MATMGR->createMatInstance( matName ); mDiffuseMatInst->getFeaturesDelegate().bind( &ImposterCaptureMaterialHook::_overrideFeatures ); mDiffuseMatInst->init( features, inMat->getVertexFormat() ); features.addFeature( MFT_IsDXTnm ); features.addFeature( MFT_NormalMap ); features.addFeature( MFT_NormalsOut ); mNormalsMatInst = MATMGR->createMatInstance( matName ); mNormalsMatInst->getFeaturesDelegate().bind( &ImposterCaptureMaterialHook::_overrideFeatures ); mNormalsMatInst->init( features, inMat->getVertexFormat() ); }
BaseMatInstance* InstancingMaterialHook::getInstancingMat( BaseMatInstance *matInst ) { PROFILE_SCOPE( InstancingMaterialHook_GetInstancingMat ); if ( matInst == NULL ) return NULL; InstancingMaterialHook *hook = matInst->getHook<InstancingMaterialHook>(); if ( hook == NULL ) { hook = new InstancingMaterialHook(); matInst->addHook( hook ); BaseMatInstance *instMat = matInst->getMaterial()->createMatInstance(); FeatureSet features( matInst->getRequestedFeatures() ); features.addFeature( MFT_UseInstancing ); if ( !instMat->init( features, matInst->getVertexFormat() ) ) SAFE_DELETE( instMat ); hook->mMatInst = instMat; } return hook->mMatInst; }
BaseMatInstance * MaterialManager::createMeshDebugMatInstance(const ColorF &meshColor) { String meshDebugStr = String::ToString( "Torque_MeshDebug_%d", meshColor.getRGBAPack() ); Material *debugMat; if (!Sim::findObject(meshDebugStr,debugMat)) { debugMat = allocateAndRegister( meshDebugStr ); debugMat->mDiffuse[0] = meshColor; debugMat->mEmissive[0] = true; } BaseMatInstance *debugMatInstance = NULL; if( debugMat != NULL ) { debugMatInstance = debugMat->createMatInstance(); GFXStateBlockDesc desc; desc.setCullMode(GFXCullNone); desc.fillMode = GFXFillWireframe; debugMatInstance->addStateBlockDesc(desc); // Disable fog and other stuff. FeatureSet debugFeatures; debugFeatures.addFeature( MFT_DiffuseColor ); debugMatInstance->init( debugFeatures, getGFXVertexFormat<GFXVertexPCN>() ); } return debugMatInstance; }
BaseMatInstance* MaterialManager::createMatInstance( const String &matName, const FeatureSet& features, const GFXVertexFormat *vertexFormat ) { BaseMatInstance* mat = createMatInstance(matName); if (mat) { mat->init( features, vertexFormat ); return mat; } return NULL; }
void MaterialList::initMatInstances( const FeatureSet &features, const GFXVertexFormat *vertexFormat ) { for( U32 i=0; i < mMatInstList.size(); i++ ) { BaseMatInstance *matInst = mMatInstList[i]; if ( !matInst ) continue; if ( !matInst->init( features, vertexFormat ) ) { Con::errorf( "MaterialList::initMatInstances - failed to initialize material instance for '%s'", matInst->getMaterial()->getName() ); // Fall back to warning material. SAFE_DELETE( matInst ); matInst = MATMGR->createMatInstance( "WarningMaterial" ); matInst->init( MATMGR->getDefaultFeatures(), vertexFormat ); mMatInstList[ i ] = matInst; } } }
BaseMatInstance* TerrainCellMaterial::getShadowMat() { // Find our material which has some settings // defined on it in script. Material *mat = MATMGR->getMaterialDefinitionByName( "AL_DefaultShadowMaterial" ); // Create the material instance adding the feature which // handles rendering terrain cut outs. FeatureSet features = MATMGR->getDefaultFeatures(); BaseMatInstance *matInst = mat->createMatInstance(); if ( !matInst->init( features, getGFXVertexFormat<TerrVertex>() ) ) { delete matInst; matInst = NULL; } return matInst; }
bool WaterObject::initMaterial( S32 idx ) { // We must return false for any case which it is NOT safe for the caller // to use the indexed material. if ( idx < 0 || idx > NumMatTypes ) return false; BaseMatInstance *mat = mMatInstances[idx]; WaterMatParams &matParams = mMatParamHandles[idx]; // Is it already initialized? if ( mat && mat->isValid() ) return true; // Do we need to allocate anything? if ( mSurfMatName[idx].isNotEmpty() ) { if ( mat ) SAFE_DELETE( mat ); CustomMaterial *custMat; if ( Sim::findObject( mSurfMatName[idx], custMat ) && custMat->mShaderData ) mat = custMat->createMatInstance(); else mat = MATMGR->createMatInstance( mSurfMatName[idx] ); const GFXVertexFormat *flags = getGFXVertexFormat<GFXVertexPC>(); if ( mat && mat->init( MATMGR->getDefaultFeatures(), flags ) ) { mMatInstances[idx] = mat; matParams.init( mat ); return true; } SAFE_DELETE( mat ); } return false; }
BaseMatInstance * MaterialManager::createWarningMatInstance() { Material *warnMat = static_cast<Material*>(Sim::findObject("WarningMaterial")); BaseMatInstance *warnMatInstance = NULL; if( warnMat != NULL ) { warnMatInstance = warnMat->createMatInstance(); GFXStateBlockDesc desc; desc.setCullMode(GFXCullNone); warnMatInstance->addStateBlockDesc(desc); warnMatInstance->init( getDefaultFeatures(), getGFXVertexFormat<GFXVertexPNTTB>() ); } return warnMatInstance; }
void ShadowMaterialHook::init( BaseMatInstance *inMat ) { if( !inMat->isValid() ) return; // Tweak the feature data to include just what we need. FeatureSet features; features.addFeature( MFT_VertTransform ); features.addFeature( MFT_DiffuseMap ); features.addFeature( MFT_TexAnim ); features.addFeature( MFT_AlphaTest ); features.addFeature( MFT_Visibility ); // Actually we want to include features from the inMat // if they operate on the preTransform verts so things // like wind/deformation effects will also affect the shadow. const FeatureSet &inFeatures = inMat->getFeatures(); for ( U32 i = 0; i < inFeatures.getCount(); i++ ) { const FeatureType& ft = inFeatures.getAt(i); if ( ft.getGroup() == MFG_PreTransform ) features.addFeature( ft ); } // Do instancing in shadows if we can. if ( inFeatures.hasFeature( MFT_UseInstancing ) ) features.addFeature( MFT_UseInstancing ); Material *shadowMat = (Material*)inMat->getMaterial(); if ( dynamic_cast<CustomMaterial*>( shadowMat ) ) { // This is a custom material... who knows what it really does, but // if it wasn't already filtered out of the shadow render then just // give it some default depth out material. shadowMat = MATMGR->getMaterialDefinitionByName( "AL_DefaultShadowMaterial" ); } // By default we want to disable some states // that the material might enable for us. GFXStateBlockDesc forced; forced.setBlend( false ); forced.setAlphaTest( false ); // We should force on zwrite as the prepass // will disable it by default. forced.setZReadWrite( true, true ); // TODO: Should we render backfaces for // shadows or does the ESM take care of // all our acne issues? //forced.setCullMode( GFXCullCW ); // Vector, and spotlights use the same shadow material. BaseMatInstance *newMat = new ShadowMatInstance( shadowMat ); newMat->setUserObject( inMat->getUserObject() ); newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures ); newMat->addStateBlockDesc( forced ); if( !newMat->init( features, inMat->getVertexFormat() ) ) { SAFE_DELETE( newMat ); newMat = MATMGR->createWarningMatInstance(); } mShadowMat[ShadowType_Spot] = newMat; newMat = new ShadowMatInstance( shadowMat ); newMat->setUserObject( inMat->getUserObject() ); newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures ); forced.setCullMode( GFXCullCW ); newMat->addStateBlockDesc( forced ); forced.cullDefined = false; newMat->addShaderMacro( "CUBE_SHADOW_MAP", "" ); newMat->init( features, inMat->getVertexFormat() ); mShadowMat[ShadowType_CubeMap] = newMat; // A dual paraboloid shadow rendered in a single draw call. features.addFeature( MFT_ParaboloidVertTransform ); features.addFeature( MFT_IsSinglePassParaboloid ); features.removeFeature( MFT_VertTransform ); newMat = new ShadowMatInstance( shadowMat ); newMat->setUserObject( inMat->getUserObject() ); GFXStateBlockDesc noCull( forced ); noCull.setCullMode( GFXCullNone ); newMat->addStateBlockDesc( noCull ); newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures ); newMat->init( features, inMat->getVertexFormat() ); mShadowMat[ShadowType_DualParaboloidSinglePass] = newMat; // Regular dual paraboloid shadow. features.addFeature( MFT_ParaboloidVertTransform ); features.removeFeature( MFT_IsSinglePassParaboloid ); features.removeFeature( MFT_VertTransform ); newMat = new ShadowMatInstance( shadowMat ); newMat->setUserObject( inMat->getUserObject() ); newMat->addStateBlockDesc( forced ); newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures ); newMat->init( features, inMat->getVertexFormat() ); mShadowMat[ShadowType_DualParaboloid] = newMat; /* // A single paraboloid shadow. newMat = new ShadowMatInstance( startMatInstance ); GFXStateBlockDesc noCull; noCull.setCullMode( GFXCullNone ); newMat->addStateBlockDesc( noCull ); newMat->getFeaturesDelegate().bind( &ShadowMaterialHook::_overrideFeatures ); newMat->init( features, globalFeatures, inMat->getVertexFormat() ); mShadowMat[ShadowType_DualParaboloidSinglePass] = newMat; */ }