1 #include "pch.h"
2 #include "OgreMaterial.hpp"
3 
4 #include <OgreMaterialManager.h>
5 #include <OgreTechnique.h>
6 #include <stdexcept>
7 
8 #include "OgrePass.hpp"
9 #include "OgreMaterialSerializer.hpp"
10 #include "OgrePlatform.hpp"
11 
12 namespace sh
13 {
14 	static const std::string sDefaultTechniqueName = "SH_DefaultTechnique";
15 
OgreMaterial(const std::string & name,const std::string & resourceGroup)16 	OgreMaterial::OgreMaterial (const std::string& name, const std::string& resourceGroup)
17 		: Material()
18 	{
19 		mName = name;
20 		assert (Ogre::MaterialManager::getSingleton().getByName(name).isNull() && "Material already exists");
21 		mMaterial = Ogre::MaterialManager::getSingleton().create (name, resourceGroup);
22 		mMaterial->removeAllTechniques();
23 		mMaterial->createTechnique()->setSchemeName (sDefaultTechniqueName);
24 		mMaterial->compile();
25 	}
26 
ensureLoaded()27 	void OgreMaterial::ensureLoaded()
28 	{
29 		if (mMaterial.isNull())
30 			mMaterial = Ogre::MaterialManager::getSingleton().getByName(mName);
31 	}
32 
isUnreferenced()33 	bool OgreMaterial::isUnreferenced()
34 	{
35 		// Resource system internals hold 3 shared pointers, we hold one, so usecount of 4 means unused
36 		return (!mMaterial.isNull() && mMaterial.useCount() <= Ogre::ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS+1);
37 	}
38 
unreferenceTextures()39 	void OgreMaterial::unreferenceTextures()
40 	{
41 		mMaterial->unload();
42 	}
43 
~OgreMaterial()44 	OgreMaterial::~OgreMaterial()
45 	{
46 		if (!mMaterial.isNull())
47 			Ogre::MaterialManager::getSingleton().remove(mMaterial->getName());
48 	}
49 
createPass(const std::string & configuration,unsigned short lodIndex)50 	boost::shared_ptr<Pass> OgreMaterial::createPass (const std::string& configuration, unsigned short lodIndex)
51 	{
52 		return boost::shared_ptr<Pass> (new OgrePass (this, configuration, lodIndex));
53 	}
54 
removeAll()55 	void OgreMaterial::removeAll ()
56 	{
57 		if (mMaterial.isNull())
58 			return;
59 		mMaterial->removeAllTechniques();
60 		mMaterial->createTechnique()->setSchemeName (sDefaultTechniqueName);
61 		mMaterial->compile();
62 	}
63 
setLodLevels(const std::string & lodLevels)64 	void OgreMaterial::setLodLevels (const std::string& lodLevels)
65 	{
66 		OgreMaterialSerializer& s = OgrePlatform::getSerializer();
67 
68 		s.setMaterialProperty ("lod_values", lodLevels, mMaterial);
69 	}
70 
createConfiguration(const std::string & name,unsigned short lodIndex)71 	bool OgreMaterial::createConfiguration (const std::string& name, unsigned short lodIndex)
72 	{
73 		for (int i=0; i<mMaterial->getNumTechniques(); ++i)
74 		{
75 			if (mMaterial->getTechnique(i)->getSchemeName() == name && mMaterial->getTechnique(i)->getLodIndex() == lodIndex)
76 				return false;
77 		}
78 
79 		Ogre::Technique* t = mMaterial->createTechnique();
80 		t->setSchemeName (name);
81 		t->setLodIndex (lodIndex);
82 		if (mShadowCasterMaterial != "")
83 			t->setShadowCasterMaterial(mShadowCasterMaterial);
84 
85 		mMaterial->compile();
86 
87 		return true;
88 	}
89 
getOgreMaterial()90 	Ogre::MaterialPtr OgreMaterial::getOgreMaterial ()
91 	{
92 		return mMaterial;
93 	}
94 
getOgreTechniqueForConfiguration(const std::string & configurationName,unsigned short lodIndex)95 	Ogre::Technique* OgreMaterial::getOgreTechniqueForConfiguration (const std::string& configurationName, unsigned short lodIndex)
96 	{
97 		for (int i=0; i<mMaterial->getNumTechniques(); ++i)
98 		{
99 			if (mMaterial->getTechnique(i)->getSchemeName() == configurationName && mMaterial->getTechnique(i)->getLodIndex() == lodIndex)
100 			{
101 				return mMaterial->getTechnique(i);
102 			}
103 		}
104 
105 		// Prepare and throw error message
106 		std::stringstream message;
107 		message << "Could not find configurationName '" << configurationName
108 				<< "' and lodIndex " << lodIndex;
109 
110 		throw std::runtime_error(message.str());
111 	}
112 
setShadowCasterMaterial(const std::string & name)113 	void OgreMaterial::setShadowCasterMaterial (const std::string& name)
114 	{
115 		mShadowCasterMaterial = name;
116 		for (int i=0; i<mMaterial->getNumTechniques(); ++i)
117 		{
118 			mMaterial->getTechnique(i)->setShadowCasterMaterial(mShadowCasterMaterial);
119 		}
120 	}
121 }
122