/src/ogre/OgreMain/src/OgreMaterialManager.cpp
Line | Count | Source |
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 | | |
7 | | Copyright (c) 2000-2014 Torus Knot Software Ltd |
8 | | |
9 | | Permission is hereby granted, free of charge, to any person obtaining a copy |
10 | | of this software and associated documentation files (the "Software"), to deal |
11 | | in the Software without restriction, including without limitation the rights |
12 | | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
13 | | copies of the Software, and to permit persons to whom the Software is |
14 | | furnished to do so, subject to the following conditions: |
15 | | |
16 | | The above copyright notice and this permission notice shall be included in |
17 | | all copies or substantial portions of the Software. |
18 | | |
19 | | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
20 | | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
21 | | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
22 | | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
23 | | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
24 | | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
25 | | THE SOFTWARE. |
26 | | ----------------------------------------------------------------------------- |
27 | | */ |
28 | | #include "OgreStableHeaders.h" |
29 | | #include "OgreLodStrategyManager.h" |
30 | | |
31 | | |
32 | | namespace Ogre { |
33 | | const String MSN_DEFAULT = "Default"; |
34 | | const String MSN_SHADERGEN = "ShaderGeneratorDefaultScheme"; |
35 | | const String MSN_SHADOWCASTER = "ShadowCaster"; |
36 | | |
37 | | //----------------------------------------------------------------------- |
38 | | template<> MaterialManager* Singleton<MaterialManager>::msSingleton = 0; |
39 | | MaterialManager* MaterialManager::getSingletonPtr(void) |
40 | 0 | { |
41 | 0 | return msSingleton; |
42 | 0 | } |
43 | | MaterialManager& MaterialManager::getSingleton(void) |
44 | 0 | { |
45 | 0 | assert( msSingleton ); return ( *msSingleton ); |
46 | 0 | } |
47 | | String MaterialManager::DEFAULT_SCHEME_NAME = MSN_DEFAULT; |
48 | | //----------------------------------------------------------------------- |
49 | | MaterialManager::MaterialManager() |
50 | 1 | { |
51 | | // Loading order |
52 | 1 | mLoadOrder = 100.0f; |
53 | | // Scripting is supported by this manager |
54 | | |
55 | | // Resource type |
56 | 1 | mResourceType = "Material"; |
57 | | |
58 | | // Register with resource group manager |
59 | 1 | ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this); |
60 | | |
61 | | // Default scheme |
62 | 1 | mActiveSchemeIndex = 0; |
63 | 1 | mActiveSchemeName = MSN_DEFAULT; |
64 | 1 | mSchemes[mActiveSchemeName] = 0; |
65 | | |
66 | 1 | } |
67 | | //----------------------------------------------------------------------- |
68 | | MaterialManager::~MaterialManager() |
69 | 1 | { |
70 | 1 | mDefaultSettings.reset(); |
71 | | |
72 | 1 | Pass::processPendingPassUpdates(); // make sure pass graveyard is cleaned |
73 | | |
74 | | // Resources cleared by superclass |
75 | | // Unregister with resource group manager |
76 | 1 | ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType); |
77 | 1 | ResourceGroupManager::getSingleton()._unregisterScriptLoader(this); |
78 | 1 | } |
79 | | //----------------------------------------------------------------------- |
80 | | Resource* MaterialManager::createImpl(const String& name, ResourceHandle handle, |
81 | | const String& group, bool isManual, ManualResourceLoader* loader, |
82 | | const NameValuePairList* params) |
83 | 0 | { |
84 | 0 | return OGRE_NEW Material(this, name, handle, group, isManual, loader); |
85 | 0 | } |
86 | | //----------------------------------------------------------------------- |
87 | | MaterialPtr MaterialManager::create (const String& name, const String& group, |
88 | | bool isManual, ManualResourceLoader* loader, |
89 | | const NameValuePairList* createParams) |
90 | 0 | { |
91 | 0 | return static_pointer_cast<Material>(createResource(name,group,isManual,loader,createParams)); |
92 | 0 | } |
93 | | //----------------------------------------------------------------------- |
94 | | MaterialPtr MaterialManager::getByName(const String& name, const String& groupName) const |
95 | 0 | { |
96 | 0 | return static_pointer_cast<Material>(getResourceByName(name, groupName)); |
97 | 0 | } |
98 | | |
99 | 0 | MaterialPtr MaterialManager::getDefaultMaterial(bool useLighting) { |
100 | 0 | MaterialPtr ret = getByName(useLighting ? "BaseWhite" : "BaseWhiteNoLighting", |
101 | 0 | ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); |
102 | |
|
103 | 0 | OgreAssert(ret, |
104 | 0 | "Can't find default material Did you forget to call MaterialManager::initialise()?"); |
105 | | |
106 | 0 | return ret; |
107 | 0 | } |
108 | | |
109 | | //----------------------------------------------------------------------- |
110 | | void MaterialManager::initialise(void) |
111 | 0 | { |
112 | | // Set up default material - don't use name constructor as we want to avoid applying defaults |
113 | 0 | mDefaultSettings = create("DefaultSettings", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); |
114 | | // Add a single technique and pass, non-programmable |
115 | 0 | mDefaultSettings->createTechnique()->createPass(); |
116 | | |
117 | | // Set the default LOD strategy |
118 | 0 | mDefaultSettings->setLodStrategy(LodStrategyManager::getSingleton().getDefaultStrategy()); |
119 | | |
120 | | // Set up a lit base white material |
121 | 0 | create("BaseWhite", ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); |
122 | | // Set up an unlit base white material |
123 | 0 | MaterialPtr baseWhiteNoLighting = create("BaseWhiteNoLighting", |
124 | 0 | ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME); |
125 | 0 | baseWhiteNoLighting->setLightingEnabled(false); |
126 | |
|
127 | 0 | } |
128 | | //----------------------------------------------------------------------- |
129 | | void MaterialManager::setDefaultTextureFiltering(TextureFilterOptions fo) |
130 | 0 | { |
131 | 0 | TextureManager::getSingleton().getDefaultSampler()->setFiltering(fo); |
132 | 0 | } |
133 | | //----------------------------------------------------------------------- |
134 | | void MaterialManager::setDefaultAnisotropy(unsigned int maxAniso) |
135 | 0 | { |
136 | 0 | TextureManager::getSingleton().getDefaultSampler()->setAnisotropy(maxAniso); |
137 | 0 | } |
138 | | //----------------------------------------------------------------------- |
139 | | unsigned int MaterialManager::getDefaultAnisotropy() const |
140 | 0 | { |
141 | 0 | return TextureManager::getSingleton().getDefaultSampler()->getAnisotropy(); |
142 | 0 | } |
143 | | //----------------------------------------------------------------------- |
144 | | void MaterialManager::setDefaultTextureFiltering(FilterType ftype, FilterOptions opts) |
145 | 0 | { |
146 | 0 | TextureManager::getSingleton().getDefaultSampler()->setFiltering(ftype, opts); |
147 | 0 | } |
148 | | //----------------------------------------------------------------------- |
149 | | void MaterialManager::setDefaultTextureFiltering(FilterOptions minFilter, |
150 | | FilterOptions magFilter, FilterOptions mipFilter) |
151 | 0 | { |
152 | 0 | TextureManager::getSingleton().getDefaultSampler()->setFiltering(minFilter, magFilter, mipFilter); |
153 | 0 | } |
154 | | //----------------------------------------------------------------------- |
155 | | FilterOptions MaterialManager::getDefaultTextureFiltering(FilterType ftype) const |
156 | 0 | { |
157 | 0 | return TextureManager::getSingleton().getDefaultSampler()->getFiltering(ftype); |
158 | 0 | } |
159 | | //----------------------------------------------------------------------- |
160 | | unsigned short MaterialManager::_getSchemeIndex(const String& schemeName) |
161 | 0 | { |
162 | 0 | unsigned short ret = 0; |
163 | 0 | SchemeMap::iterator i = mSchemes.find(schemeName); |
164 | 0 | if (i != mSchemes.end()) |
165 | 0 | { |
166 | 0 | ret = i->second; |
167 | 0 | } |
168 | 0 | else |
169 | 0 | { |
170 | | // Create new |
171 | 0 | ret = static_cast<unsigned short>(mSchemes.size()); |
172 | 0 | mSchemes[schemeName] = ret; |
173 | 0 | } |
174 | 0 | return ret; |
175 | |
|
176 | 0 | } |
177 | | //----------------------------------------------------------------------- |
178 | | const String& MaterialManager::_getSchemeName(unsigned short index) |
179 | 0 | { |
180 | 0 | for (auto & scheme : mSchemes) |
181 | 0 | { |
182 | 0 | if (scheme.second == index) |
183 | 0 | return scheme.first; |
184 | 0 | } |
185 | 0 | return MSN_DEFAULT; |
186 | 0 | } |
187 | | //----------------------------------------------------------------------- |
188 | | void MaterialManager::setActiveScheme(const String& schemeName) |
189 | 0 | { |
190 | 0 | if (mActiveSchemeName != schemeName) |
191 | 0 | { |
192 | | // Allow the creation of new scheme indexes on demand |
193 | | // even if they're not specified in any Technique |
194 | 0 | mActiveSchemeIndex = _getSchemeIndex(schemeName); |
195 | 0 | mActiveSchemeName = schemeName; |
196 | 0 | } |
197 | 0 | } |
198 | | //----------------------------------------------------------------------- |
199 | | void MaterialManager::addListener(Listener* l, const Ogre::String& schemeName) |
200 | 0 | { |
201 | 0 | mListenerMap[schemeName].push_back(l); |
202 | 0 | } |
203 | | //--------------------------------------------------------------------- |
204 | | void MaterialManager::removeListener(Listener* l, const Ogre::String& schemeName) |
205 | 0 | { |
206 | 0 | mListenerMap[schemeName].remove(l); |
207 | 0 | } |
208 | | //--------------------------------------------------------------------- |
209 | | Technique* MaterialManager::_arbitrateMissingTechniqueForActiveScheme( |
210 | | Material* mat, unsigned short lodIndex, const Renderable* rend) |
211 | 0 | { |
212 | | //First, check the scheme specific listeners |
213 | 0 | ListenerMap::iterator it = mListenerMap.find(mActiveSchemeName); |
214 | 0 | if (it != mListenerMap.end()) |
215 | 0 | { |
216 | 0 | ListenerList& listenerList = it->second; |
217 | 0 | for (auto & i : listenerList) |
218 | 0 | { |
219 | 0 | Technique* t = i->handleSchemeNotFound(mActiveSchemeIndex, mActiveSchemeName, mat, lodIndex, rend); |
220 | 0 | if (t) |
221 | 0 | return t; |
222 | 0 | } |
223 | 0 | } |
224 | | |
225 | | //If no success, check generic listeners |
226 | 0 | it = mListenerMap.find(BLANKSTRING); |
227 | 0 | if (it != mListenerMap.end()) |
228 | 0 | { |
229 | 0 | ListenerList& listenerList = it->second; |
230 | 0 | for (auto & i : listenerList) |
231 | 0 | { |
232 | 0 | Technique* t = i->handleSchemeNotFound(mActiveSchemeIndex, mActiveSchemeName, mat, lodIndex, rend); |
233 | 0 | if (t) |
234 | 0 | return t; |
235 | 0 | } |
236 | 0 | } |
237 | | |
238 | | |
239 | 0 | return 0; |
240 | |
|
241 | 0 | } |
242 | | |
243 | | void MaterialManager::_notifyAfterIlluminationPassesCreated(Technique* tech) |
244 | 0 | { |
245 | | // First, check the scheme specific listeners |
246 | 0 | ListenerMap::iterator it = mListenerMap.find(mActiveSchemeName); |
247 | 0 | if(it != mListenerMap.end()) |
248 | 0 | { |
249 | 0 | ListenerList& listenerList = it->second; |
250 | 0 | for(auto & i : listenerList) |
251 | 0 | { |
252 | 0 | bool handled = i->afterIlluminationPassesCreated(tech); |
253 | 0 | if(handled) |
254 | 0 | return; |
255 | 0 | } |
256 | 0 | } |
257 | | |
258 | | //If no success, check generic listeners |
259 | 0 | it = mListenerMap.find(BLANKSTRING); |
260 | 0 | if(it != mListenerMap.end()) |
261 | 0 | { |
262 | 0 | ListenerList& listenerList = it->second; |
263 | 0 | for(auto & i : listenerList) |
264 | 0 | { |
265 | 0 | bool handled = i->afterIlluminationPassesCreated(tech); |
266 | 0 | if(handled) |
267 | 0 | return; |
268 | 0 | } |
269 | 0 | } |
270 | 0 | } |
271 | | |
272 | | void MaterialManager::_notifyBeforeIlluminationPassesCleared(Technique* tech) |
273 | 0 | { |
274 | | // First, check the scheme specific listeners |
275 | 0 | ListenerMap::iterator it = mListenerMap.find(mActiveSchemeName); |
276 | 0 | if(it != mListenerMap.end()) |
277 | 0 | { |
278 | 0 | ListenerList& listenerList = it->second; |
279 | 0 | for(auto & i : listenerList) |
280 | 0 | { |
281 | 0 | bool handled = i->beforeIlluminationPassesCleared(tech); |
282 | 0 | if(handled) |
283 | 0 | return; |
284 | 0 | } |
285 | 0 | } |
286 | | |
287 | | //If no success, check generic listeners |
288 | 0 | it = mListenerMap.find(BLANKSTRING); |
289 | 0 | if(it != mListenerMap.end()) |
290 | 0 | { |
291 | 0 | ListenerList& listenerList = it->second; |
292 | 0 | for(auto & i : listenerList) |
293 | 0 | { |
294 | 0 | bool handled = i->beforeIlluminationPassesCleared(tech); |
295 | 0 | if(handled) |
296 | 0 | return; |
297 | 0 | } |
298 | 0 | } |
299 | 0 | } |
300 | | |
301 | | } |