Coverage Report

Created: 2026-02-26 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}