source: trunk/VUT/work/ogre_changes/OgreMain/src/OgreRenderQueueSortingGrouping.cpp @ 139

Revision 139, 13.2 KB checked in by mattausch, 19 years ago (diff)

fixed bug with tight octree boxes
added more flexible renderqueue (can delete per flag)
reordered functions in visibility terrain scene manager

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::clearSolids(void)
281    {
282        /*SolidRenderablePassMap::iterator i, iend;
283        // Delete queue groups which are using passes which are to be
284        // deleted, we won't need these any more and they clutter up
285        // the list and can cause problems with future clones
286        const Pass::PassSet& graveyardList = Pass::getPassGraveyard();
287        Pass::PassSet::const_iterator gi, giend;
288        giend = graveyardList.end();
289        for (gi = graveyardList.begin(); gi != giend; ++gi)
290        {
291            removeSolidPassEntry(*gi);
292        }
293
294        // Now remove any dirty passes, these will have their hashes recalculated
295        // by the parent queue after all groups have been processed
296        // If we don't do this, the std::map will become inconsistent for new insterts
297        const Pass::PassSet& dirtyList = Pass::getDirtyHashList();
298        Pass::PassSet::const_iterator di, diend;
299        diend = dirtyList.end();
300        for (di = dirtyList.begin(); di != diend; ++di)
301        {
302            removeSolidPassEntry(*di);
303        }*/
304        // NB we do NOT clear the graveyard or the dirty list here, because
305        // it needs to be acted on for all groups, the parent queue takes
306        // care of this afterwards
307
308        // We do not clear the unchanged solid pass maps, only the contents of each list
309        // This is because we assume passes are reused a lot and it saves resorting
310        clearSolidPassMap(mSolidPasses);
311        clearSolidPassMap(mSolidPassesDecal);
312        clearSolidPassMap(mSolidPassesDiffuseSpecular);
313        clearSolidPassMap(mSolidPassesNoShadow);
314    }
315        //-----------------------------------------------------------------------
316    void RenderPriorityGroup::clear(const int leavePassesInQueue)
317    {
318                SolidRenderablePassMap::iterator i, iend;
319       
320                // -- standard method if no passes are left in queue
321                if (leavePassesInQueue == 0)
322                {
323                        clear();
324                        return;
325                }
326
327        // We do not clear the unchanged solid pass maps, only the contents of each list
328        // This is because we assume passes are reused a lot and it saves resorting
329                if (!(leavePassesInQueue & SOLID_PASSES))
330                        clearSolidPassMap(mSolidPasses);
331                if (!(leavePassesInQueue & SOLID_PASSES_DECAL))
332                        clearSolidPassMap(mSolidPassesDecal);
333                if (!(leavePassesInQueue & SOLID_PASSES_DIFFUSE_SPECULAR))
334                        clearSolidPassMap(mSolidPassesDiffuseSpecular);
335                if (!(leavePassesInQueue & SOLID_PASSES_NOSHADOW))
336                        clearSolidPassMap(mSolidPassesNoShadow);
337
338        if (!(leavePassesInQueue & TRANSPARENT_PASSES))
339                        mTransparentPasses.clear();
340    }
341#endif // GTP_VISIBILITY_MODIFIED_OGRE         
342//-----------------------------------------------------------------------
343
344}
345
Note: See TracBrowser for help on using the repository browser.