source: OGRE/trunk/ogrenew/OgreMain/src/OgreRenderQueueSortingGrouping.cpp @ 657

Revision 657, 12.8 KB checked in by mattausch, 18 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26#include "OgreRenderQueueSortingGrouping.h"
27
28namespace Ogre {
29
30    //-----------------------------------------------------------------------
31    void RenderPriorityGroup::destroySolidPassMap(SolidRenderablePassMap& passmap)
32    {
33        // destroy all the pass map entries
34        SolidRenderablePassMap::iterator i, iend;
35        iend = passmap.end();
36        for (i = passmap.begin(); i != iend; ++i)
37        {
38            // Free the list associated with this pass
39            delete i->second;
40        }
41        passmap.clear();
42    }
43    //-----------------------------------------------------------------------
44    void RenderPriorityGroup::removeSolidPassEntry(Pass* p)
45    {
46        SolidRenderablePassMap::iterator i;
47
48        i = mSolidPasses.find(p);
49        if (i != mSolidPasses.end())
50        {
51            // free memory
52            delete i->second;
53            // erase from map
54            mSolidPasses.erase(i);
55        }
56
57        i = mSolidPassesDiffuseSpecular.find(p);
58        if (i != mSolidPassesDiffuseSpecular.end())
59        {
60            // free memory
61            delete i->second;
62            // erase from map
63            mSolidPassesDiffuseSpecular.erase(i);
64        }
65        i = mSolidPassesDecal.find(p);
66        if (i != mSolidPassesDecal.end())
67        {
68            // free memory
69            delete i->second;
70            // erase from map
71            mSolidPassesDecal.erase(i);
72        }
73        i = mSolidPassesNoShadow.find(p);
74        if (i != mSolidPassesNoShadow.end())
75        {
76            // free memory
77            delete i->second;
78            // erase from map
79            mSolidPassesNoShadow.erase(i);
80        }
81
82    }
83    //-----------------------------------------------------------------------
84    void RenderPriorityGroup::clearSolidPassMap(SolidRenderablePassMap& passmap)
85    {
86        SolidRenderablePassMap::iterator i, iend;
87        iend = passmap.end();
88        for (i = passmap.begin(); i != iend; ++i)
89        {
90            // Clear the list associated with this pass, but leave the pass entry
91            i->second->clear();
92        }
93    }
94    //-----------------------------------------------------------------------
95    void RenderPriorityGroup::addRenderable(Renderable* rend)
96    {
97        // Check material & technique supplied (the former since the default implementation
98        // of getTechnique is based on it for backwards compatibility
99        Technique* pTech;
100        if(rend->getMaterial().isNull() || !rend->getTechnique())
101        {
102            // Use default base white
103                        MaterialPtr baseWhite = MaterialManager::getSingleton().getByName("BaseWhite");
104            pTech = baseWhite->getTechnique(0);
105        }
106        else
107        {
108            // Get technique
109            pTech = rend->getTechnique();
110        }
111
112        // Transparent and depth settings mean depth sorting is required?
113        if (pTech->isTransparent() &&
114            !(pTech->isDepthWriteEnabled() && pTech->isDepthCheckEnabled()) )
115        {
116            addTransparentRenderable(pTech, rend);
117        }
118        else
119        {
120            if (mSplitNoShadowPasses && !pTech->getParent()->getReceiveShadows())
121            {
122                // Add solid renderable and add passes to no-shadow group
123                addSolidRenderable(pTech, rend, true);
124            }
125            else
126            {
127                if (mSplitPassesByLightingType)
128                {
129                    addSolidRenderableSplitByLightType(pTech, rend);
130                }
131                else
132                {
133                    addSolidRenderable(pTech, rend, false);
134                }
135            }
136        }
137
138    }
139    //-----------------------------------------------------------------------
140    void RenderPriorityGroup::addSolidRenderable(Technique* pTech,
141        Renderable* rend, bool addToNoShadow)
142    {
143        Technique::PassIterator pi = pTech->getPassIterator();
144
145        SolidRenderablePassMap* passMap;
146        if (addToNoShadow)
147        {
148            passMap = &mSolidPassesNoShadow;
149        }
150        else
151        {
152            passMap = &mSolidPasses;
153        }
154
155
156        while (pi.hasMoreElements())
157        {
158            // Insert into solid list
159            Pass* p = pi.getNext();
160            SolidRenderablePassMap::iterator i = passMap->find(p);
161            if (i == passMap->end())
162            {
163                std::pair<SolidRenderablePassMap::iterator, bool> retPair;
164                // Create new pass entry, build a new list
165                // Note that this pass and list are never destroyed until the engine
166                // shuts down, although the lists will be cleared
167                retPair = passMap->insert(
168                    SolidRenderablePassMap::value_type(p, new RenderableList() ) );
169                assert(retPair.second && "Error inserting new pass entry into SolidRenderablePassMap");
170                i = retPair.first;
171            }
172            // Insert renderable
173            i->second->push_back(rend);
174
175        }
176    }
177    //-----------------------------------------------------------------------
178    void RenderPriorityGroup::addSolidRenderableSplitByLightType(Technique* pTech, Renderable* rend)
179    {
180        // Divide the passes into the 3 categories
181        Technique::IlluminationPassIterator pi =
182            pTech->getIlluminationPassIterator();
183
184        while (pi.hasMoreElements())
185        {
186            // Insert into solid list
187            IlluminationPass* p = pi.getNext();
188            SolidRenderablePassMap* passMap;
189            switch(p->stage)
190            {
191            case IS_AMBIENT:
192                passMap = &mSolidPasses;
193                break;
194            case IS_PER_LIGHT:
195                passMap = &mSolidPassesDiffuseSpecular;
196                break;
197            case IS_DECAL:
198                passMap = &mSolidPassesDecal;
199                break;
200            };
201
202            SolidRenderablePassMap::iterator i = passMap->find(p->pass);
203            if (i == passMap->end())
204            {
205                std::pair<SolidRenderablePassMap::iterator, bool> retPair;
206                // Create new pass entry, build a new list
207                // Note that this pass and list are never destroyed until the engine
208                // shuts down, although the lists will be cleared
209                retPair = passMap->insert(
210                    SolidRenderablePassMap::value_type(p->pass, new RenderableList() ) );
211                assert(retPair.second && "Error inserting new pass entry into SolidRenderablePassMap");
212                i = retPair.first;
213            }
214            // Insert renderable
215            i->second->push_back(rend);
216        }
217    }
218    //-----------------------------------------------------------------------
219    void RenderPriorityGroup::addTransparentRenderable(Technique* pTech, Renderable* rend)
220    {
221        Technique::PassIterator pi = pTech->getPassIterator();
222
223        while (pi.hasMoreElements())
224        {
225            // Insert into transparent list
226            mTransparentPasses.push_back(RenderablePass(rend, pi.getNext()));
227        }
228    }
229    //-----------------------------------------------------------------------
230    void RenderPriorityGroup::sort(const Camera* cam)
231    {
232        TransparentQueueItemLess transFunctor;
233        transFunctor.camera = cam;
234
235        std::stable_sort(mTransparentPasses.begin(), mTransparentPasses.end(),
236            transFunctor);
237    }
238    //-----------------------------------------------------------------------
239    void RenderPriorityGroup::clear(void)
240    {
241        SolidRenderablePassMap::iterator i, iend;
242        // Delete queue groups which are using passes which are to be
243        // deleted, we won't need these any more and they clutter up
244        // the list and can cause problems with future clones
245        const Pass::PassSet& graveyardList = Pass::getPassGraveyard();
246        Pass::PassSet::const_iterator gi, giend;
247        giend = graveyardList.end();
248        for (gi = graveyardList.begin(); gi != giend; ++gi)
249        {
250            removeSolidPassEntry(*gi);
251        }
252
253        // Now remove any dirty passes, these will have their hashes recalculated
254        // by the parent queue after all groups have been processed
255        // If we don't do this, the std::map will become inconsistent for new insterts
256        const Pass::PassSet& dirtyList = Pass::getDirtyHashList();
257        Pass::PassSet::const_iterator di, diend;
258        diend = dirtyList.end();
259        for (di = dirtyList.begin(); di != diend; ++di)
260        {
261            removeSolidPassEntry(*di);
262        }
263        // NB we do NOT clear the graveyard or the dirty list here, because
264        // it needs to be acted on for all groups, the parent queue takes
265        // care of this afterwards
266
267        // We do not clear the unchanged solid pass maps, only the contents of each list
268        // This is because we assume passes are reused a lot and it saves resorting
269        clearSolidPassMap(mSolidPasses);
270        clearSolidPassMap(mSolidPassesDecal);
271        clearSolidPassMap(mSolidPassesDiffuseSpecular);
272        clearSolidPassMap(mSolidPassesNoShadow);
273
274        // Always empty the transparents list
275        mTransparentPasses.clear();
276
277    }
278#ifdef GTP_VISIBILITY_MODIFIED_OGRE     
279    //-----------------------------------------------------------------------
280    void RenderPriorityGroup::clear(const int leavePassesInQueue)
281    {
282                //-- standard method if no passes are left in queue
283                if (leavePassesInQueue == 0)
284                {
285                        clear();
286                        return;
287                }
288
289        // We do not clear the unchanged solid pass maps, only the contents of each list
290        // This is because we assume passes are reused a lot and it saves resorting
291                if (!(leavePassesInQueue & SOLID_PASSES))
292                        destroySolidPassMap(mSolidPasses);
293                if (!(leavePassesInQueue & SOLID_PASSES_DECAL))
294                        destroySolidPassMap(mSolidPassesDecal);
295                if (!(leavePassesInQueue & SOLID_PASSES_DIFFUSE_SPECULAR))
296                        destroySolidPassMap(mSolidPassesDiffuseSpecular);
297                if (!(leavePassesInQueue & SOLID_PASSES_NOSHADOW))
298                        destroySolidPassMap(mSolidPassesNoShadow);
299
300        if (!(leavePassesInQueue & TRANSPARENT_PASSES))
301                        mTransparentPasses.clear();
302    }
303        //-----------------------------------------------------------------------
304    void RenderPriorityGroup::destroyPassMaps(const int leavePassesInQueue)
305    {
306                /*   
307        const Pass::PassSet& graveyardList = Pass::getPassGraveyard();
308        Pass::PassSet::const_iterator gi, giend;
309        giend = graveyardList.end();
310        for (gi = graveyardList.begin(); gi != giend; ++gi)
311        {
312            removeSolidPassEntry(*gi);
313        }
314
315        const Pass::PassSet& dirtyList = Pass::getDirtyHashList();
316        Pass::PassSet::const_iterator di, diend;
317        diend = dirtyList.end();
318        for (di = dirtyList.begin(); di != diend; ++di)
319        {
320            removeSolidPassEntry(*di);
321                }
322                */
323
324        // We do not clear the unchanged solid pass maps, only the contents of each list
325        // This is because we assume passes are reused a lot and it saves resorting
326                if (!(leavePassesInQueue & SOLID_PASSES))
327                        destroySolidPassMap(mSolidPasses);
328                if (!(leavePassesInQueue & SOLID_PASSES_DECAL))
329                        destroySolidPassMap(mSolidPassesDecal);
330                if (!(leavePassesInQueue & SOLID_PASSES_DIFFUSE_SPECULAR))
331                        destroySolidPassMap(mSolidPassesDiffuseSpecular);
332                if (!(leavePassesInQueue & SOLID_PASSES_NOSHADOW))
333                        destroySolidPassMap(mSolidPassesNoShadow);
334    }
335#endif // GTP_VISIBILITY_MODIFIED_OGRE         
336//-----------------------------------------------------------------------
337
338}
339
Note: See TracBrowser for help on using the repository browser.