materialManager.cpp
Engine/source/materials/materialManager.cpp
Public Variables
Public Functions
DefineEngineFunction(addMaterialMapping , void , (const char *texName, const char *matName) , "(string texName, string matName)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@brief Maps the given texture <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">material.\n\n</a>" "Generates <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> console warning before <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">overwriting.\n\n</a>" "<a href="/coding/class/classmaterial/">Material</a> maps are used by terrain and interiors <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> triggering " "effects when an object moves onto <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> terrain " "block or interior surface using the associated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">texture.\n\n</a>" "@ingroup Materials" )
DefineEngineFunction(dumpMaterialInstances , void , () , "@brief Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> formatted list of currently allocated material instances <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "@ingroup Materials" )
DefineEngineFunction(getMapEntry , const char * , (const char *texName) , "@hide" )
DefineEngineFunction(getMaterialInstances , void , (BaseMaterialDefinition *target, GuiTreeViewCtrl *tree) , (nullAsType< BaseMaterialDefinition * >(), nullAsType< GuiTreeViewCtrl * >()) , "@brief Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> formatted list of currently allocated material instances <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "@ingroup Materials" )
DefineEngineFunction(getMaterialMapping , const char * , (const char *texName) , "(string texName)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@brief Returns the name of the material mapped <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">texture.\n\n</a>" "If no materials are found, an empty string is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">returned.\n\n</a>" " @param texName Name of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">texture\n\n</a>" " @ingroup Materials" )
DefineEngineFunction(reInitMaterials , void , () , "@brief Flushes all procedural shaders and re-initializes all active material <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">instances.\n\n</a>" "@ingroup Materials" )
Detailed Description
Public Variables
MODULE_END
MODULE_INIT
MODULE_SHUTDOWN
Public Functions
DefineEngineFunction(addMaterialMapping , void , (const char *texName, const char *matName) , "(string texName, string matName)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@brief Maps the given texture <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the given <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">material.\n\n</a>" "Generates <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> console warning before <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">overwriting.\n\n</a>" "<a href="/coding/class/classmaterial/">Material</a> maps are used by terrain and interiors <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> triggering " "effects when an object moves onto <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> terrain " "block or interior surface using the associated <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">texture.\n\n</a>" "@ingroup Materials" )
DefineEngineFunction(dumpMaterialInstances , void , () , "@brief Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> formatted list of currently allocated material instances <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "@ingroup Materials" )
DefineEngineFunction(getMapEntry , const char * , (const char *texName) , "@hide" )
DefineEngineFunction(getMaterialInstances , void , (BaseMaterialDefinition *target, GuiTreeViewCtrl *tree) , (nullAsType< BaseMaterialDefinition * >(), nullAsType< GuiTreeViewCtrl * >()) , "@brief Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> formatted list of currently allocated material instances <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n\n</a>" "@ingroup Materials" )
DefineEngineFunction(getMaterialMapping , const char * , (const char *texName) , "(string texName)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@brief Returns the name of the material mapped <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">texture.\n\n</a>" "If no materials are found, an empty string is <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">returned.\n\n</a>" " @param texName Name of the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">texture\n\n</a>" " @ingroup Materials" )
DefineEngineFunction(reInitMaterials , void , () , "@brief Flushes all procedural shaders and re-initializes all active material <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">instances.\n\n</a>" "@ingroup Materials" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "materials/materialManager.h" 26 27#include "materials/matInstance.h" 28#include "materials/materialFeatureTypes.h" 29#include "lighting/lightManager.h" 30#include "core/util/safeDelete.h" 31#include "shaderGen/shaderGen.h" 32#include "core/module.h" 33#include "console/consoleTypes.h" 34#include "console/engineAPI.h" 35 36#include "gui/controls/guiTreeViewCtrl.h" 37 38MODULE_BEGIN( MaterialManager ) 39 40 MODULE_INIT_BEFORE( GFX ) 41 MODULE_SHUTDOWN_BEFORE( GFX ) 42 43 MODULE_INIT 44 { 45 MaterialManager::createSingleton(); 46 } 47 48 MODULE_SHUTDOWN 49 { 50 MaterialManager::deleteSingleton(); 51 } 52 53MODULE_END; 54 55 56MaterialManager::MaterialManager() 57{ 58 VECTOR_SET_ASSOCIATION( mMatInstanceList ); 59 60 mDt = 0.0f; 61 mAccumTime = 0.0f; 62 mLastTime = 0; 63 mWarningInst = NULL; 64 65 GFXDevice::getDeviceEventSignal().notify( this, &MaterialManager::_handleGFXEvent ); 66 67 // Make sure we get activation signals 68 // and that we're the last to get them. 69 LightManager::smActivateSignal.notify( this, &MaterialManager::_onLMActivate, 9999 ); 70 71 mMaterialSet = NULL; 72 73 mUsingDeferred = false; 74 75 mFlushAndReInit = false; 76 77 mDefaultAnisotropy = 1; 78 Con::addVariable( "$pref::Video::defaultAnisotropy", TypeS32, &mDefaultAnisotropy, 79 "@brief Global variable defining the default anisotropy value.\n\n" 80 "Controls the default anisotropic texture filtering level for all materials, including the terrain. " 81 "This value can be changed at runtime to see its affect without reloading.\n\n " 82 "@ingroup Materials"); 83 Con::NotifyDelegate callabck( this, &MaterialManager::_updateDefaultAnisotropy ); 84 Con::addVariableNotify( "$pref::Video::defaultAnisotropy", callabck ); 85 86 Con::NotifyDelegate callabck2( this, &MaterialManager::_onDisableMaterialFeature ); 87 Con::setVariable( "$pref::Video::disableNormalMapping", "false" ); 88 Con::addVariableNotify( "$pref::Video::disableNormalMapping", callabck2 ); 89 Con::setVariable( "$pref::Video::disableCubemapping", "false" ); 90 Con::addVariableNotify( "$pref::Video::disableCubemapping", callabck2 ); 91 Con::setVariable( "$pref::Video::disableParallaxMapping", "false" ); 92 Con::addVariableNotify( "$pref::Video::disableParallaxMapping", callabck2 ); 93} 94 95MaterialManager::~MaterialManager() 96{ 97 GFXDevice::getDeviceEventSignal().remove( this, &MaterialManager::_handleGFXEvent ); 98 LightManager::smActivateSignal.remove( this, &MaterialManager::_onLMActivate ); 99 100 SAFE_DELETE( mWarningInst ); 101 102#ifndef TORQUE_SHIPPING 103 DebugMaterialMap::Iterator itr = mMeshDebugMaterialInsts.begin(); 104 105 for ( ; itr != mMeshDebugMaterialInsts.end(); itr++ ) 106 delete itr->value; 107#endif 108} 109 110void MaterialManager::_onLMActivate( const char *lm, bool activate ) 111{ 112 if ( !activate ) 113 return; 114 115 // Since the light manager usually swaps shadergen features 116 // and changes system wide shader defines we need to completely 117 // flush and rebuild all the material instances. 118 119 mFlushAndReInit = true; 120} 121 122void MaterialManager::_updateDefaultAnisotropy() 123{ 124 // Update all the materials. 125 Vector<BaseMatInstance*>::iterator iter = mMatInstanceList.begin(); 126 for ( ; iter != mMatInstanceList.end(); iter++ ) 127 (*iter)->updateStateBlocks(); 128} 129 130Material * MaterialManager::allocateAndRegister(const String &objectName, const String &mapToName) 131{ 132 Material *newMat = new Material(); 133 134 if ( mapToName.isNotEmpty() ) 135 newMat->mMapTo = mapToName; 136 137 bool registered = newMat->registerObject(objectName ); 138 AssertFatal( registered, "Unable to register material" ); 139 140 if (registered) 141 Sim::getRootGroup()->addObject( newMat ); 142 else 143 { 144 delete newMat; 145 newMat = NULL; 146 } 147 148 return newMat; 149} 150 151Material * MaterialManager::getMaterialDefinitionByName(const String &matName) 152{ 153 // Get the material 154 Material * foundMat; 155 156 if(!Sim::findObject(matName, foundMat)) 157 { 158 Con::errorf("MaterialManager: Unable to find material '%s'", matName.c_str()); 159 return NULL; 160 } 161 162 return foundMat; 163} 164 165Material* MaterialManager::getMaterialDefinitionByMapTo(const String& mapTo) 166{ 167 // Get the material 168 Material* foundMat = nullptr; 169 170 for (SimSet::iterator itr = mMaterialSet->begin(); itr != mMaterialSet->end(); ++itr) 171 { 172 // Fetch our listed materials. 173 Material* materialDef = dynamic_cast<Material*>(*itr); 174 if (materialDef && materialDef->mMapTo.compare(mapTo, 0U, String::NoCase) == 0) 175 { 176 //We have a match, so keep it and bail the loop 177 foundMat = materialDef; 178 break; 179 } 180 } 181 182 return foundMat; 183} 184 185BaseMatInstance* MaterialManager::createMatInstance(const String &matName) 186{ 187 BaseMaterialDefinition* mat = NULL; 188 if (Sim::findObject(matName, mat)) 189 return mat->createMatInstance(); 190 191 return NULL; 192} 193 194BaseMatInstance* MaterialManager::createMatInstance( const String &matName, 195 const GFXVertexFormat *vertexFormat ) 196{ 197 return createMatInstance( matName, getDefaultFeatures(), vertexFormat ); 198} 199 200BaseMatInstance* MaterialManager::createMatInstance( const String &matName, 201 const FeatureSet& features, 202 const GFXVertexFormat *vertexFormat ) 203{ 204 BaseMatInstance* mat = createMatInstance(matName); 205 if (mat) 206 { 207 mat->init( features, vertexFormat ); 208 return mat; 209 } 210 211 return NULL; 212} 213 214BaseMatInstance * MaterialManager::createWarningMatInstance() 215{ 216 Material *warnMat = static_cast<Material*>(Sim::findObject("WarningMaterial")); 217 218 BaseMatInstance *warnMatInstance = NULL; 219 220 if( warnMat != NULL ) 221 { 222 warnMatInstance = warnMat->createMatInstance(); 223 224 GFXStateBlockDesc desc; 225 desc.setCullMode(GFXCullNone); 226 warnMatInstance->addStateBlockDesc(desc); 227 228 warnMatInstance->init( getDefaultFeatures(), 229 getGFXVertexFormat<GFXVertexPNTTB>() ); 230 } 231 232 return warnMatInstance; 233} 234 235// Gets the global warning material instance, callers should not free this copy 236BaseMatInstance * MaterialManager::getWarningMatInstance() 237{ 238 if (!mWarningInst) 239 mWarningInst = createWarningMatInstance(); 240 241 return mWarningInst; 242} 243 244#ifndef TORQUE_SHIPPING 245BaseMatInstance * MaterialManager::createMeshDebugMatInstance(const LinearColorF &meshColor) 246{ 247 String meshDebugStr = String::ToString( "Torque_MeshDebug_%d", meshColor.getRGBAPack() ); 248 249 Material *debugMat; 250 if (!Sim::findObject(meshDebugStr,debugMat)) 251 { 252 debugMat = allocateAndRegister( meshDebugStr ); 253 254 debugMat->mDiffuse[0] = meshColor; 255 debugMat->mEmissive[0] = true; 256 } 257 258 BaseMatInstance *debugMatInstance = NULL; 259 260 if( debugMat != NULL ) 261 { 262 debugMatInstance = debugMat->createMatInstance(); 263 264 GFXStateBlockDesc desc; 265 desc.setCullMode(GFXCullNone); 266 desc.fillMode = GFXFillWireframe; 267 debugMatInstance->addStateBlockDesc(desc); 268 269 // Disable fog and other stuff. 270 FeatureSet debugFeatures; 271 debugFeatures.addFeature( MFT_DiffuseColor ); 272 debugMatInstance->init( debugFeatures, getGFXVertexFormat<GFXVertexPCN>() ); 273 } 274 275 return debugMatInstance; 276} 277 278// Gets the global material instance for a given color, callers should not free this copy 279BaseMatInstance *MaterialManager::getMeshDebugMatInstance(const LinearColorF &meshColor) 280{ 281 DebugMaterialMap::Iterator itr = mMeshDebugMaterialInsts.find( meshColor.getRGBAPack() ); 282 283 BaseMatInstance *inst = NULL; 284 285 if ( itr == mMeshDebugMaterialInsts.end() ) 286 inst = createMeshDebugMatInstance( meshColor ); 287 else 288 inst = itr->value; 289 290 mMeshDebugMaterialInsts.insert( meshColor.getRGBAPack(), inst ); 291 292 return inst; 293} 294#endif 295 296void MaterialManager::mapMaterial(const String & textureName, const String & materialName) 297{ 298 if (getMapEntry(textureName).isNotEmpty()) 299 { 300 if (!textureName.equal("unmapped_mat", String::NoCase)) 301 Con::warnf(ConsoleLogEntry::General, "Warning, overwriting material for: %s", textureName.c_str()); 302 } 303 304 mMaterialMap[String::ToLower(textureName)] = materialName; 305} 306 307String MaterialManager::getMapEntry(const String & textureName) const 308{ 309 MaterialMap::ConstIterator iter = mMaterialMap.find(String::ToLower(textureName)); 310 if ( iter == mMaterialMap.end() ) 311 return String(); 312 return iter->value; 313} 314 315void MaterialManager::flushAndReInitInstances() 316{ 317 // Clear the flag if its set. 318 mFlushAndReInit = false; 319 320 // Check to see if any shader preferences have changed. 321 recalcFeaturesFromPrefs(); 322 323 // First we flush all the shader gen shaders which will 324 // invalidate all GFXShader* to them. 325 SHADERGEN->flushProceduralShaders(); 326 mFlushSignal.trigger(); 327 328 // First do a pass deleting all hooks as they can contain 329 // materials themselves. This means we have to restart the 330 // loop every time we delete any hooks... lame. 331 Vector<BaseMatInstance*>::iterator iter = mMatInstanceList.begin(); 332 while ( iter != mMatInstanceList.end() ) 333 { 334 if ( (*iter)->deleteAllHooks() != 0 ) 335 { 336 // Restart the loop. 337 iter = mMatInstanceList.begin(); 338 continue; 339 } 340 341 iter++; 342 } 343 344 // Now do a pass re-initializing materials. 345 iter = mMatInstanceList.begin(); 346 for ( ; iter != mMatInstanceList.end(); iter++ ) 347 (*iter)->reInit(); 348} 349 350// Used in the materialEditor. This flushes the material preview object so it can be reloaded easily. 351void MaterialManager::flushInstance( BaseMaterialDefinition *target ) 352{ 353 Vector<BaseMatInstance*>::iterator iter = mMatInstanceList.begin(); 354 while ( iter != mMatInstanceList.end() ) 355 { 356 if ( (*iter)->getMaterial() == target ) 357 { 358 (*iter)->deleteAllHooks(); 359 return; 360 } 361 iter++; 362 } 363} 364 365void MaterialManager::reInitInstance( BaseMaterialDefinition *target ) 366{ 367 Vector<BaseMatInstance*>::iterator iter = mMatInstanceList.begin(); 368 for ( ; iter != mMatInstanceList.end(); iter++ ) 369 { 370 if ( (*iter)->getMaterial() == target ) 371 (*iter)->reInit(); 372 } 373} 374 375void MaterialManager::updateTime() 376{ 377 U32 curTime = Sim::getCurrentTime(); 378 if(curTime > mLastTime) 379 { 380 mDt = (curTime - mLastTime) / 1000.0f; 381 mLastTime = curTime; 382 mAccumTime += mDt; 383 } 384 else 385 mDt = 0.0f; 386} 387 388SimSet * MaterialManager::getMaterialSet() 389{ 390 if(!mMaterialSet) 391 mMaterialSet = static_cast<SimSet*>( Sim::findObject( "MaterialSet" ) ); 392 393 AssertFatal( mMaterialSet, "MaterialSet not found" ); 394 return mMaterialSet; 395} 396 397void MaterialManager::dumpMaterialInstances( BaseMaterialDefinition *target ) const 398{ 399 if ( !mMatInstanceList.size() ) 400 return; 401 402 if ( target ) 403 Con::printf( "--------------------- %s MatInstances ---------------------", target->getName() ); 404 else 405 Con::printf( "--------------------- MatInstances %d ---------------------", mMatInstanceList.size() ); 406 407 for( U32 i=0; i<mMatInstanceList.size(); i++ ) 408 { 409 BaseMatInstance *inst = mMatInstanceList[i]; 410 411 if ( target && inst->getMaterial() != target ) 412 continue; 413 414 inst->dumpShaderInfo(); 415 416 Con::printf( "" ); 417 } 418 419 Con::printf( "---------------------- Dump complete ----------------------"); 420} 421 422void MaterialManager::getMaterialInstances(BaseMaterialDefinition* target, GuiTreeViewCtrl* materailInstanceTree) 423{ 424 if (!mMatInstanceList.size()) 425 return; 426 427 if (!target) 428 { 429 Con::errorf("Can't form a list without a specific MaterialDefinition"); 430 return; 431 } 432 433 if (!materailInstanceTree) 434 { 435 Con::errorf("Requires a valid GuiTreeViewCtrl object to populate data into!"); 436 return; 437 } 438 439 U32 matItem = materailInstanceTree->insertItem(0, target->getName()); 440 441 for (U32 i = 0; i < mMatInstanceList.size(); i++) 442 { 443 BaseMatInstance* inst = mMatInstanceList[i]; 444 445 if (target && inst->getMaterial() != target) 446 continue; 447 448 inst->getShaderInfo(materailInstanceTree, matItem); 449 } 450} 451 452void MaterialManager::_track( MatInstance *matInstance ) 453{ 454 mMatInstanceList.push_back( matInstance ); 455} 456 457void MaterialManager::_untrack( MatInstance *matInstance ) 458{ 459 mMatInstanceList.remove( matInstance ); 460} 461 462void MaterialManager::recalcFeaturesFromPrefs() 463{ 464 mDefaultFeatures.clear(); 465 FeatureType::addDefaultTypes( &mDefaultFeatures ); 466 467 mExclusionFeatures.setFeature( MFT_NormalMap, 468 Con::getBoolVariable( "$pref::Video::disableNormalMapping", false ) ); 469 470 mExclusionFeatures.setFeature( MFT_CubeMap, 471 Con::getBoolVariable( "$pref::Video::disableCubemapping", false ) ); 472 473 mExclusionFeatures.setFeature( MFT_Parallax, 474 Con::getBoolVariable( "$pref::Video::disableParallaxMapping", false ) ); 475} 476 477bool MaterialManager::_handleGFXEvent( GFXDevice::GFXDeviceEventType event_ ) 478{ 479 switch ( event_ ) 480 { 481 case GFXDevice::deInit: 482 recalcFeaturesFromPrefs(); 483 break; 484 485 case GFXDevice::deDestroy : 486 SAFE_DELETE( mWarningInst ); 487 break; 488 489 case GFXDevice::deStartOfFrame: 490 if ( mFlushAndReInit ) 491 flushAndReInitInstances(); 492 break; 493 494 default: 495 break; 496 } 497 498 return true; 499} 500 501DefineEngineFunction( reInitMaterials, void, (),, 502 "@brief Flushes all procedural shaders and re-initializes all active material instances.\n\n" 503 "@ingroup Materials") 504{ 505 MATMGR->flushAndReInitInstances(); 506} 507 508DefineEngineFunction( addMaterialMapping, void, (const char * texName, const char * matName), , "(string texName, string matName)\n" 509 "@brief Maps the given texture to the given material.\n\n" 510 "Generates a console warning before overwriting.\n\n" 511 "Material maps are used by terrain and interiors for triggering " 512 "effects when an object moves onto a terrain " 513 "block or interior surface using the associated texture.\n\n" 514 "@ingroup Materials") 515{ 516 MATMGR->mapMaterial(texName, matName); 517} 518 519DefineEngineFunction( getMaterialMapping, const char*, (const char * texName), , "(string texName)\n" 520 "@brief Returns the name of the material mapped to this texture.\n\n" 521 "If no materials are found, an empty string is returned.\n\n" 522 "@param texName Name of the texture\n\n" 523 "@ingroup Materials") 524{ 525 return MATMGR->getMapEntry(texName).c_str(); 526} 527 528DefineEngineFunction( dumpMaterialInstances, void, (), , 529 "@brief Dumps a formatted list of currently allocated material instances to the console.\n\n" 530 "@ingroup Materials") 531{ 532 MATMGR->dumpMaterialInstances(); 533} 534 535DefineEngineFunction(getMaterialInstances, void, (BaseMaterialDefinition* target, GuiTreeViewCtrl* tree), (nullAsType<BaseMaterialDefinition*>(), nullAsType<GuiTreeViewCtrl*>()), 536 "@brief Dumps a formatted list of currently allocated material instances to the console.\n\n" 537 "@ingroup Materials") 538{ 539 if (target == nullptr || tree == nullptr) 540 return; 541 542 MATMGR->getMaterialInstances(target, tree); 543} 544 545DefineEngineFunction( getMapEntry, const char*, (const char * texName), , 546 "@hide") 547{ 548 return MATMGR->getMapEntry( String(texName) ); 549} 550