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

Revision 343, 12.8 KB checked in by mattausch, 19 years ago (diff)

added switch between NV and ARB queries in the render system and in the demos.
Fixed render queue bug: when clearing queue, we traversed through all priority groups
to clear the passmaps. This became very slow because had to traverse many elements (over 1000
for city demo). Now all we destroy the priority groups for each rendering (per hierarchy node).

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.