PageRenderTime 48ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Core/Dependencies/OgreSource/OgreMain/src/OgreMaterial.cpp

https://bitbucket.org/barakianc/nvidia-physx-and-apex-in-gge
C++ | 833 lines | 639 code | 50 blank | 144 comment | 103 complexity | b41153355f4c4dd2e184a71739c901db MD5 | raw file
  1. /*
  2. -----------------------------------------------------------------------------
  3. This source file is part of OGRE
  4. (Object-oriented Graphics Rendering Engine)
  5. For the latest info, see http://www.ogre3d.org/
  6. Copyright (c) 2000-2012 Torus Knot Software Ltd
  7. Permission is hereby granted, free of charge, to any person obtaining a copy
  8. of this software and associated documentation files (the "Software"), to deal
  9. in the Software without restriction, including without limitation the rights
  10. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the Software is
  12. furnished to do so, subject to the following conditions:
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  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 FROM,
  20. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. THE SOFTWARE.
  22. -----------------------------------------------------------------------------
  23. */
  24. #include "OgreStableHeaders.h"
  25. #include "OgreMaterial.h"
  26. #include "OgreSceneManagerEnumerator.h"
  27. #include "OgreMaterialManager.h"
  28. #include "OgreIteratorWrappers.h"
  29. #include "OgreTechnique.h"
  30. #include "OgreLogManager.h"
  31. #include "OgreException.h"
  32. #include "OgreStringConverter.h"
  33. #include "OgreLodStrategy.h"
  34. #include "OgreLodStrategyManager.h"
  35. namespace Ogre {
  36. //-----------------------------------------------------------------------
  37. Material::Material(ResourceManager* creator, const String& name, ResourceHandle handle,
  38. const String& group, bool isManual, ManualResourceLoader* loader)
  39. :Resource(creator, name, handle, group, isManual, loader),
  40. mReceiveShadows(true),
  41. mTransparencyCastsShadows(false),
  42. mCompilationRequired(true)
  43. {
  44. // Override isManual, not applicable for Material (we always want to call loadImpl)
  45. if(isManual)
  46. {
  47. mIsManual = false;
  48. LogManager::getSingleton().logMessage("Material " + name +
  49. " was requested with isManual=true, but this is not applicable "
  50. "for materials; the flag has been reset to false");
  51. }
  52. // Initialise to default strategy
  53. mLodStrategy = LodStrategyManager::getSingleton().getDefaultStrategy();
  54. mLodValues.push_back(0.0f);
  55. applyDefaults();
  56. /* For consistency with StringInterface, but we don't add any parameters here
  57. That's because the Resource implementation of StringInterface is to
  58. list all the options that need to be set before loading, of which
  59. we have none as such. Full details can be set through scripts.
  60. */
  61. createParamDictionary("Material");
  62. }
  63. //-----------------------------------------------------------------------
  64. Material::~Material()
  65. {
  66. removeAllTechniques();
  67. // have to call this here reather than in Resource destructor
  68. // since calling virtual methods in base destructors causes crash
  69. unload();
  70. }
  71. //-----------------------------------------------------------------------
  72. Material& Material::operator=(const Material& rhs)
  73. {
  74. mName = rhs.mName;
  75. mGroup = rhs.mGroup;
  76. mCreator = rhs.mCreator;
  77. mIsManual = rhs.mIsManual;
  78. mLoader = rhs.mLoader;
  79. mHandle = rhs.mHandle;
  80. mSize = rhs.mSize;
  81. mReceiveShadows = rhs.mReceiveShadows;
  82. mTransparencyCastsShadows = rhs.mTransparencyCastsShadows;
  83. mLoadingState = rhs.mLoadingState;
  84. mIsBackgroundLoaded = rhs.mIsBackgroundLoaded;
  85. // Copy Techniques
  86. this->removeAllTechniques();
  87. Techniques::const_iterator i, iend;
  88. iend = rhs.mTechniques.end();
  89. for(i = rhs.mTechniques.begin(); i != iend; ++i)
  90. {
  91. Technique* t = this->createTechnique();
  92. *t = *(*i);
  93. if ((*i)->isSupported())
  94. {
  95. insertSupportedTechnique(t);
  96. }
  97. }
  98. // Also copy LOD information
  99. mUserLodValues = rhs.mUserLodValues;
  100. mLodValues = rhs.mLodValues;
  101. mLodStrategy = rhs.mLodStrategy;
  102. mCompilationRequired = rhs.mCompilationRequired;
  103. // illumination passes are not compiled right away so
  104. // mIsLoaded state should still be the same as the original material
  105. assert(isLoaded() == rhs.isLoaded());
  106. return *this;
  107. }
  108. //-----------------------------------------------------------------------
  109. void Material::prepareImpl(void)
  110. {
  111. // compile if required
  112. if (mCompilationRequired)
  113. compile();
  114. // Load all supported techniques
  115. Techniques::iterator i, iend;
  116. iend = mSupportedTechniques.end();
  117. for (i = mSupportedTechniques.begin(); i != iend; ++i)
  118. {
  119. (*i)->_prepare();
  120. }
  121. }
  122. //-----------------------------------------------------------------------
  123. void Material::unprepareImpl(void)
  124. {
  125. // Load all supported techniques
  126. Techniques::iterator i, iend;
  127. iend = mSupportedTechniques.end();
  128. for (i = mSupportedTechniques.begin(); i != iend; ++i)
  129. {
  130. (*i)->_unprepare();
  131. }
  132. }
  133. //-----------------------------------------------------------------------
  134. void Material::loadImpl(void)
  135. {
  136. // Load all supported techniques
  137. Techniques::iterator i, iend;
  138. iend = mSupportedTechniques.end();
  139. for (i = mSupportedTechniques.begin(); i != iend; ++i)
  140. {
  141. (*i)->_load();
  142. }
  143. }
  144. //-----------------------------------------------------------------------
  145. void Material::unloadImpl(void)
  146. {
  147. // Unload all supported techniques
  148. Techniques::iterator i, iend;
  149. iend = mSupportedTechniques.end();
  150. for (i = mSupportedTechniques.begin(); i != iend; ++i)
  151. {
  152. (*i)->_unload();
  153. }
  154. }
  155. //-----------------------------------------------------------------------
  156. MaterialPtr Material::clone(const String& newName, bool changeGroup,
  157. const String& newGroup) const
  158. {
  159. MaterialPtr newMat;
  160. if (changeGroup)
  161. {
  162. newMat = MaterialManager::getSingleton().create(newName, newGroup);
  163. }
  164. else
  165. {
  166. newMat = MaterialManager::getSingleton().create(newName, mGroup);
  167. }
  168. // Keep handle (see below, copy overrides everything)
  169. ResourceHandle newHandle = newMat->getHandle();
  170. // Assign values from this
  171. *newMat = *this;
  172. // Restore new group if required, will have been overridden by operator
  173. if (changeGroup)
  174. {
  175. newMat->mGroup = newGroup;
  176. }
  177. // Correct the name & handle, they get copied too
  178. newMat->mName = newName;
  179. newMat->mHandle = newHandle;
  180. return newMat;
  181. }
  182. //-----------------------------------------------------------------------
  183. void Material::copyDetailsTo(MaterialPtr& mat) const
  184. {
  185. // Keep handle (see below, copy overrides everything)
  186. ResourceHandle savedHandle = mat->mHandle;
  187. String savedName = mat->mName;
  188. String savedGroup = mat->mGroup;
  189. ManualResourceLoader* savedLoader = mat->mLoader;
  190. bool savedManual = mat->mIsManual;
  191. // Assign values from this
  192. *mat = *this;
  193. // Correct the name & handle, they get copied too
  194. mat->mName = savedName;
  195. mat->mHandle = savedHandle;
  196. mat->mGroup = savedGroup;
  197. mat->mIsManual = savedManual;
  198. mat->mLoader = savedLoader;
  199. }
  200. //-----------------------------------------------------------------------
  201. void Material::applyDefaults(void)
  202. {
  203. MaterialPtr defaults = MaterialManager::getSingleton().getDefaultSettings();
  204. if (!defaults.isNull())
  205. {
  206. // save name & handle
  207. String savedName = mName;
  208. String savedGroup = mGroup;
  209. ResourceHandle savedHandle = mHandle;
  210. ManualResourceLoader *savedLoader = mLoader;
  211. bool savedManual = mIsManual;
  212. *this = *defaults;
  213. // restore name & handle
  214. mName = savedName;
  215. mHandle = savedHandle;
  216. mGroup = savedGroup;
  217. mLoader = savedLoader;
  218. mIsManual = savedManual;
  219. }
  220. mCompilationRequired = true;
  221. }
  222. //-----------------------------------------------------------------------
  223. Technique* Material::createTechnique(void)
  224. {
  225. Technique *t = OGRE_NEW Technique(this);
  226. mTechniques.push_back(t);
  227. mCompilationRequired = true;
  228. return t;
  229. }
  230. //-----------------------------------------------------------------------
  231. Technique* Material::getTechnique(unsigned short index)
  232. {
  233. assert (index < mTechniques.size() && "Index out of bounds.");
  234. return mTechniques[index];
  235. }
  236. //-----------------------------------------------------------------------
  237. Technique* Material::getTechnique(const String& name)
  238. {
  239. Techniques::iterator i = mTechniques.begin();
  240. Techniques::iterator iend = mTechniques.end();
  241. Technique* foundTechnique = 0;
  242. // iterate through techniques to find a match
  243. while (i != iend)
  244. {
  245. if ( (*i)->getName() == name )
  246. {
  247. foundTechnique = (*i);
  248. break;
  249. }
  250. ++i;
  251. }
  252. return foundTechnique;
  253. }
  254. //-----------------------------------------------------------------------
  255. unsigned short Material::getNumTechniques(void) const
  256. {
  257. return static_cast<unsigned short>(mTechniques.size());
  258. }
  259. //-----------------------------------------------------------------------
  260. Technique* Material::getSupportedTechnique(unsigned short index)
  261. {
  262. assert (index < mSupportedTechniques.size() && "Index out of bounds.");
  263. return mSupportedTechniques[index];
  264. }
  265. //-----------------------------------------------------------------------
  266. unsigned short Material::getNumSupportedTechniques(void) const
  267. {
  268. return static_cast<unsigned short>(mSupportedTechniques.size());
  269. }
  270. //-----------------------------------------------------------------------
  271. unsigned short Material::getNumLodLevels(unsigned short schemeIndex) const
  272. {
  273. // Safety check - empty list?
  274. if (mBestTechniquesBySchemeList.empty())
  275. return 0;
  276. BestTechniquesBySchemeList::const_iterator i =
  277. mBestTechniquesBySchemeList.find(schemeIndex);
  278. if (i == mBestTechniquesBySchemeList.end())
  279. {
  280. // get the first item, will be 0 (the default) if default
  281. // scheme techniques exist, otherwise the earliest defined
  282. i = mBestTechniquesBySchemeList.begin();
  283. }
  284. return static_cast<unsigned short>(i->second->size());
  285. }
  286. //-----------------------------------------------------------------------
  287. unsigned short Material::getNumLodLevels(const String& schemeName) const
  288. {
  289. return getNumLodLevels(
  290. MaterialManager::getSingleton()._getSchemeIndex(schemeName));
  291. }
  292. //-----------------------------------------------------------------------
  293. void Material::insertSupportedTechnique(Technique* t)
  294. {
  295. mSupportedTechniques.push_back(t);
  296. // get scheme
  297. unsigned short schemeIndex = t->_getSchemeIndex();
  298. BestTechniquesBySchemeList::iterator i =
  299. mBestTechniquesBySchemeList.find(schemeIndex);
  300. LodTechniques* lodtechs = 0;
  301. if (i == mBestTechniquesBySchemeList.end())
  302. {
  303. lodtechs = OGRE_NEW_T(LodTechniques, MEMCATEGORY_RESOURCE);
  304. mBestTechniquesBySchemeList[schemeIndex] = lodtechs;
  305. }
  306. else
  307. {
  308. lodtechs = i->second;
  309. }
  310. // Insert won't replace if supported technique for this scheme/lod is
  311. // already there, which is what we want
  312. lodtechs->insert(LodTechniques::value_type(t->getLodIndex(), t));
  313. }
  314. //-----------------------------------------------------------------------------
  315. Technique* Material::getBestTechnique(unsigned short lodIndex, const Renderable* rend)
  316. {
  317. if (mSupportedTechniques.empty())
  318. {
  319. return NULL;
  320. }
  321. else
  322. {
  323. Technique* ret = 0;
  324. MaterialManager& matMgr = MaterialManager::getSingleton();
  325. // get scheme
  326. BestTechniquesBySchemeList::iterator si =
  327. mBestTechniquesBySchemeList.find(matMgr._getActiveSchemeIndex());
  328. // scheme not found?
  329. if (si == mBestTechniquesBySchemeList.end())
  330. {
  331. // listener specified alternative technique available?
  332. ret = matMgr._arbitrateMissingTechniqueForActiveScheme(this, lodIndex, rend);
  333. if (ret)
  334. return ret;
  335. // Nope, use default
  336. // get the first item, will be 0 (the default) if default
  337. // scheme techniques exist, otherwise the earliest defined
  338. si = mBestTechniquesBySchemeList.begin();
  339. }
  340. // get LOD
  341. LodTechniques::iterator li = si->second->find(lodIndex);
  342. // LOD not found?
  343. if (li == si->second->end())
  344. {
  345. // Use the next LOD level up
  346. for (LodTechniques::reverse_iterator rli = si->second->rbegin();
  347. rli != si->second->rend(); ++rli)
  348. {
  349. if (rli->second->getLodIndex() < lodIndex)
  350. {
  351. ret = rli->second;
  352. break;
  353. }
  354. }
  355. if (!ret)
  356. {
  357. // shouldn't ever hit this really, unless user defines no LOD 0
  358. // pick the first LOD we have (must be at least one to have a scheme entry)
  359. ret = si->second->begin()->second;
  360. }
  361. }
  362. else
  363. {
  364. // LOD found
  365. ret = li->second;
  366. }
  367. return ret;
  368. }
  369. }
  370. //-----------------------------------------------------------------------
  371. void Material::removeTechnique(unsigned short index)
  372. {
  373. assert (index < mTechniques.size() && "Index out of bounds.");
  374. Techniques::iterator i = mTechniques.begin() + index;
  375. OGRE_DELETE(*i);
  376. mTechniques.erase(i);
  377. mSupportedTechniques.clear();
  378. clearBestTechniqueList();
  379. mCompilationRequired = true;
  380. }
  381. //-----------------------------------------------------------------------
  382. void Material::removeAllTechniques(void)
  383. {
  384. Techniques::iterator i, iend;
  385. iend = mTechniques.end();
  386. for (i = mTechniques.begin(); i != iend; ++i)
  387. {
  388. OGRE_DELETE(*i);
  389. }
  390. mTechniques.clear();
  391. mSupportedTechniques.clear();
  392. clearBestTechniqueList();
  393. mCompilationRequired = true;
  394. }
  395. //-----------------------------------------------------------------------
  396. Material::TechniqueIterator Material::getTechniqueIterator(void)
  397. {
  398. return TechniqueIterator(mTechniques.begin(), mTechniques.end());
  399. }
  400. //-----------------------------------------------------------------------
  401. Material::TechniqueIterator Material::getSupportedTechniqueIterator(void)
  402. {
  403. return TechniqueIterator(mSupportedTechniques.begin(), mSupportedTechniques.end());
  404. }
  405. //-----------------------------------------------------------------------
  406. bool Material::isTransparent(void) const
  407. {
  408. // Check each technique
  409. Techniques::const_iterator i, iend;
  410. iend = mTechniques.end();
  411. for (i = mTechniques.begin(); i != iend; ++i)
  412. {
  413. if ( (*i)->isTransparent() )
  414. return true;
  415. }
  416. return false;
  417. }
  418. //-----------------------------------------------------------------------
  419. void Material::compile(bool autoManageTextureUnits)
  420. {
  421. // Compile each technique, then add it to the list of supported techniques
  422. mSupportedTechniques.clear();
  423. clearBestTechniqueList();
  424. mUnsupportedReasons.clear();
  425. Techniques::iterator i, iend;
  426. iend = mTechniques.end();
  427. size_t techNo = 0;
  428. for (i = mTechniques.begin(); i != iend; ++i, ++techNo)
  429. {
  430. String compileMessages = (*i)->_compile(autoManageTextureUnits);
  431. if ( (*i)->isSupported() )
  432. {
  433. insertSupportedTechnique(*i);
  434. }
  435. else
  436. {
  437. // Log informational
  438. StringUtil::StrStreamType str;
  439. str << "Material " << mName << " Technique " << techNo;
  440. if (!(*i)->getName().empty())
  441. str << "(" << (*i)->getName() << ")";
  442. str << " is not supported. " << compileMessages;
  443. LogManager::getSingleton().logMessage(str.str(), LML_TRIVIAL);
  444. mUnsupportedReasons += compileMessages;
  445. }
  446. }
  447. mCompilationRequired = false;
  448. // Did we find any?
  449. if (mSupportedTechniques.empty())
  450. {
  451. LogManager::getSingleton().stream()
  452. << "WARNING: material " << mName << " has no supportable "
  453. << "Techniques and will be blank. Explanation: \n" << mUnsupportedReasons;
  454. }
  455. }
  456. //-----------------------------------------------------------------------
  457. void Material::clearBestTechniqueList(void)
  458. {
  459. for (BestTechniquesBySchemeList::iterator i = mBestTechniquesBySchemeList.begin();
  460. i != mBestTechniquesBySchemeList.end(); ++i)
  461. {
  462. OGRE_DELETE_T(i->second, LodTechniques, MEMCATEGORY_RESOURCE);
  463. }
  464. mBestTechniquesBySchemeList.clear();
  465. }
  466. //-----------------------------------------------------------------------
  467. void Material::setPointSize(Real ps)
  468. {
  469. Techniques::iterator i, iend;
  470. iend = mTechniques.end();
  471. for (i = mTechniques.begin(); i != iend; ++i)
  472. {
  473. (*i)->setPointSize(ps);
  474. }
  475. }
  476. //-----------------------------------------------------------------------
  477. void Material::setAmbient(Real red, Real green, Real blue)
  478. {
  479. setAmbient(ColourValue(red, green, blue));
  480. }
  481. //-----------------------------------------------------------------------
  482. void Material::setAmbient(const ColourValue& ambient)
  483. {
  484. Techniques::iterator i, iend;
  485. iend = mTechniques.end();
  486. for (i = mTechniques.begin(); i != iend; ++i)
  487. {
  488. (*i)->setAmbient(ambient);
  489. }
  490. }
  491. //-----------------------------------------------------------------------
  492. void Material::setDiffuse(Real red, Real green, Real blue, Real alpha)
  493. {
  494. Techniques::iterator i, iend;
  495. iend = mTechniques.end();
  496. for (i = mTechniques.begin(); i != iend; ++i)
  497. {
  498. (*i)->setDiffuse(red, green, blue, alpha);
  499. }
  500. }
  501. //-----------------------------------------------------------------------
  502. void Material::setDiffuse(const ColourValue& diffuse)
  503. {
  504. setDiffuse(diffuse.r, diffuse.g, diffuse.b, diffuse.a);
  505. }
  506. //-----------------------------------------------------------------------
  507. void Material::setSpecular(Real red, Real green, Real blue, Real alpha)
  508. {
  509. Techniques::iterator i, iend;
  510. iend = mTechniques.end();
  511. for (i = mTechniques.begin(); i != iend; ++i)
  512. {
  513. (*i)->setSpecular(red, green, blue, alpha);
  514. }
  515. }
  516. //-----------------------------------------------------------------------
  517. void Material::setSpecular(const ColourValue& specular)
  518. {
  519. setSpecular(specular.r, specular.g, specular.b, specular.a);
  520. }
  521. //-----------------------------------------------------------------------
  522. void Material::setShininess(Real val)
  523. {
  524. Techniques::iterator i, iend;
  525. iend = mTechniques.end();
  526. for (i = mTechniques.begin(); i != iend; ++i)
  527. {
  528. (*i)->setShininess(val);
  529. }
  530. }
  531. //-----------------------------------------------------------------------
  532. void Material::setSelfIllumination(Real red, Real green, Real blue)
  533. {
  534. setSelfIllumination(ColourValue(red, green, blue));
  535. }
  536. //-----------------------------------------------------------------------
  537. void Material::setSelfIllumination(const ColourValue& selfIllum)
  538. {
  539. Techniques::iterator i, iend;
  540. iend = mTechniques.end();
  541. for (i = mTechniques.begin(); i != iend; ++i)
  542. {
  543. (*i)->setSelfIllumination(selfIllum);
  544. }
  545. }
  546. //-----------------------------------------------------------------------
  547. void Material::setDepthCheckEnabled(bool enabled)
  548. {
  549. Techniques::iterator i, iend;
  550. iend = mTechniques.end();
  551. for (i = mTechniques.begin(); i != iend; ++i)
  552. {
  553. (*i)->setDepthCheckEnabled(enabled);
  554. }
  555. }
  556. //-----------------------------------------------------------------------
  557. void Material::setDepthWriteEnabled(bool enabled)
  558. {
  559. Techniques::iterator i, iend;
  560. iend = mTechniques.end();
  561. for (i = mTechniques.begin(); i != iend; ++i)
  562. {
  563. (*i)->setDepthWriteEnabled(enabled);
  564. }
  565. }
  566. //-----------------------------------------------------------------------
  567. void Material::setDepthFunction( CompareFunction func )
  568. {
  569. Techniques::iterator i, iend;
  570. iend = mTechniques.end();
  571. for (i = mTechniques.begin(); i != iend; ++i)
  572. {
  573. (*i)->setDepthFunction(func);
  574. }
  575. }
  576. //-----------------------------------------------------------------------
  577. void Material::setColourWriteEnabled(bool enabled)
  578. {
  579. Techniques::iterator i, iend;
  580. iend = mTechniques.end();
  581. for (i = mTechniques.begin(); i != iend; ++i)
  582. {
  583. (*i)->setColourWriteEnabled(enabled);
  584. }
  585. }
  586. //-----------------------------------------------------------------------
  587. void Material::setCullingMode( CullingMode mode )
  588. {
  589. Techniques::iterator i, iend;
  590. iend = mTechniques.end();
  591. for (i = mTechniques.begin(); i != iend; ++i)
  592. {
  593. (*i)->setCullingMode(mode);
  594. }
  595. }
  596. //-----------------------------------------------------------------------
  597. void Material::setManualCullingMode( ManualCullingMode mode )
  598. {
  599. Techniques::iterator i, iend;
  600. iend = mTechniques.end();
  601. for (i = mTechniques.begin(); i != iend; ++i)
  602. {
  603. (*i)->setManualCullingMode(mode);
  604. }
  605. }
  606. //-----------------------------------------------------------------------
  607. void Material::setLightingEnabled(bool enabled)
  608. {
  609. Techniques::iterator i, iend;
  610. iend = mTechniques.end();
  611. for (i = mTechniques.begin(); i != iend; ++i)
  612. {
  613. (*i)->setLightingEnabled(enabled);
  614. }
  615. }
  616. //-----------------------------------------------------------------------
  617. void Material::setShadingMode( ShadeOptions mode )
  618. {
  619. Techniques::iterator i, iend;
  620. iend = mTechniques.end();
  621. for (i = mTechniques.begin(); i != iend; ++i)
  622. {
  623. (*i)->setShadingMode(mode);
  624. }
  625. }
  626. //-----------------------------------------------------------------------
  627. void Material::setFog(bool overrideScene, FogMode mode, const ColourValue& colour,
  628. Real expDensity, Real linearStart, Real linearEnd)
  629. {
  630. Techniques::iterator i, iend;
  631. iend = mTechniques.end();
  632. for (i = mTechniques.begin(); i != iend; ++i)
  633. {
  634. (*i)->setFog(overrideScene, mode, colour, expDensity, linearStart, linearEnd);
  635. }
  636. }
  637. //-----------------------------------------------------------------------
  638. void Material::setDepthBias(float constantBias, float slopeScaleBias)
  639. {
  640. Techniques::iterator i, iend;
  641. iend = mTechniques.end();
  642. for (i = mTechniques.begin(); i != iend; ++i)
  643. {
  644. (*i)->setDepthBias(constantBias, slopeScaleBias);
  645. }
  646. }
  647. //-----------------------------------------------------------------------
  648. void Material::setTextureFiltering(TextureFilterOptions filterType)
  649. {
  650. Techniques::iterator i, iend;
  651. iend = mTechniques.end();
  652. for (i = mTechniques.begin(); i != iend; ++i)
  653. {
  654. (*i)->setTextureFiltering(filterType);
  655. }
  656. }
  657. // --------------------------------------------------------------------
  658. void Material::setTextureAnisotropy(int maxAniso)
  659. {
  660. Techniques::iterator i, iend;
  661. iend = mTechniques.end();
  662. for (i = mTechniques.begin(); i != iend; ++i)
  663. {
  664. (*i)->setTextureAnisotropy(maxAniso);
  665. }
  666. }
  667. // --------------------------------------------------------------------
  668. void Material::setSceneBlending( const SceneBlendType sbt )
  669. {
  670. Techniques::iterator i, iend;
  671. iend = mTechniques.end();
  672. for (i = mTechniques.begin(); i != iend; ++i)
  673. {
  674. (*i)->setSceneBlending(sbt);
  675. }
  676. }
  677. // --------------------------------------------------------------------
  678. void Material::setSeparateSceneBlending( const SceneBlendType sbt, const SceneBlendType sbta )
  679. {
  680. Techniques::iterator i, iend;
  681. iend = mTechniques.end();
  682. for (i = mTechniques.begin(); i != iend; ++i)
  683. {
  684. (*i)->setSeparateSceneBlending(sbt, sbta);
  685. }
  686. }
  687. // --------------------------------------------------------------------
  688. void Material::setSceneBlending( const SceneBlendFactor sourceFactor,
  689. const SceneBlendFactor destFactor)
  690. {
  691. Techniques::iterator i, iend;
  692. iend = mTechniques.end();
  693. for (i = mTechniques.begin(); i != iend; ++i)
  694. {
  695. (*i)->setSceneBlending(sourceFactor, destFactor);
  696. }
  697. }
  698. // --------------------------------------------------------------------
  699. void Material::setSeparateSceneBlending( const SceneBlendFactor sourceFactor, const SceneBlendFactor destFactor, const SceneBlendFactor sourceFactorAlpha, const SceneBlendFactor destFactorAlpha)
  700. {
  701. Techniques::iterator i, iend;
  702. iend = mTechniques.end();
  703. for (i = mTechniques.begin(); i != iend; ++i)
  704. {
  705. (*i)->setSeparateSceneBlending(sourceFactor, destFactor, sourceFactorAlpha, destFactorAlpha);
  706. }
  707. }
  708. // --------------------------------------------------------------------
  709. void Material::_notifyNeedsRecompile(void)
  710. {
  711. mCompilationRequired = true;
  712. // Also need to unload to ensure we loaded any new items
  713. if (isLoaded()) // needed to stop this being called in 'loading' state
  714. unload();
  715. }
  716. // --------------------------------------------------------------------
  717. void Material::setLodLevels(const LodValueList& lodValues)
  718. {
  719. // Square the distances for the internal list
  720. LodValueList::const_iterator i, iend;
  721. iend = lodValues.end();
  722. // First, clear and add single zero entry
  723. mLodValues.clear();
  724. mUserLodValues.clear();
  725. mUserLodValues.push_back(0);
  726. mLodValues.push_back(mLodStrategy->getBaseValue());
  727. for (i = lodValues.begin(); i != iend; ++i)
  728. {
  729. mUserLodValues.push_back(*i);
  730. if (mLodStrategy)
  731. mLodValues.push_back(mLodStrategy->transformUserValue(*i));
  732. }
  733. }
  734. // --------------------------------------------------------------------
  735. ushort Material::getLodIndex(Real value) const
  736. {
  737. return mLodStrategy->getIndex(value, mLodValues);
  738. }
  739. // --------------------------------------------------------------------
  740. Material::LodValueIterator Material::getLodValueIterator(void) const
  741. {
  742. return LodValueIterator(mLodValues.begin(), mLodValues.end());
  743. }
  744. // --------------------------------------------------------------------
  745. Material::LodValueIterator Material::getUserLodValueIterator(void) const
  746. {
  747. return LodValueIterator(mUserLodValues.begin(), mUserLodValues.end());
  748. }
  749. //-----------------------------------------------------------------------
  750. bool Material::applyTextureAliases(const AliasTextureNamePairList& aliasList, const bool apply) const
  751. {
  752. // iterate through all techniques and apply texture aliases
  753. Techniques::const_iterator i, iend;
  754. iend = mTechniques.end();
  755. bool testResult = false;
  756. for (i = mTechniques.begin(); i != iend; ++i)
  757. {
  758. if ((*i)->applyTextureAliases(aliasList, apply))
  759. testResult = true;
  760. }
  761. return testResult;
  762. }
  763. //---------------------------------------------------------------------
  764. const LodStrategy *Material::getLodStrategy() const
  765. {
  766. return mLodStrategy;
  767. }
  768. //---------------------------------------------------------------------
  769. void Material::setLodStrategy(LodStrategy *lodStrategy)
  770. {
  771. mLodStrategy = lodStrategy;
  772. assert(mLodValues.size());
  773. mLodValues[0] = mLodStrategy->getBaseValue();
  774. // Re-transform all user lod values (starting at index 1, no need to transform base value)
  775. for (size_t i = 1; i < mUserLodValues.size(); ++i)
  776. mLodValues[i] = mLodStrategy->transformUserValue(mUserLodValues[i]);
  777. }
  778. //---------------------------------------------------------------------
  779. }