Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreRenderQueueSortingGrouping.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004 (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2004 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreStableHeaders.h"
00026 #include "OgreRenderQueueSortingGrouping.h"
00027 
00028 namespace Ogre {
00029 
00030     //-----------------------------------------------------------------------
00031     void RenderPriorityGroup::destroySolidPassMap(SolidRenderablePassMap& passmap)
00032     {
00033         // destroy all the pass map entries
00034         SolidRenderablePassMap::iterator i, iend;
00035         iend = passmap.end();
00036         for (i = passmap.begin(); i != iend; ++i)
00037         {
00038             // Free the list associated with this pass
00039             delete i->second;
00040         }
00041         passmap.clear();
00042     }
00043     //-----------------------------------------------------------------------
00044     void RenderPriorityGroup::removeSolidPassEntry(Pass* p)
00045     {
00046         SolidRenderablePassMap::iterator i;
00047 
00048         i = mSolidPasses.find(p);
00049         if (i != mSolidPasses.end())
00050         {
00051             // free memory
00052             delete i->second;
00053             // erase from map
00054             mSolidPasses.erase(i);
00055         }
00056 
00057         i = mSolidPassesDiffuseSpecular.find(p);
00058         if (i != mSolidPassesDiffuseSpecular.end())
00059         {
00060             // free memory
00061             delete i->second;
00062             // erase from map
00063             mSolidPassesDiffuseSpecular.erase(i);
00064         }
00065         i = mSolidPassesDecal.find(p);
00066         if (i != mSolidPassesDecal.end())
00067         {
00068             // free memory
00069             delete i->second;
00070             // erase from map
00071             mSolidPassesDecal.erase(i);
00072         }
00073         i = mSolidPassesNoShadow.find(p);
00074         if (i != mSolidPassesNoShadow.end())
00075         {
00076             // free memory
00077             delete i->second;
00078             // erase from map
00079             mSolidPassesNoShadow.erase(i);
00080         }
00081 
00082     }
00083     //-----------------------------------------------------------------------
00084     void RenderPriorityGroup::clearSolidPassMap(SolidRenderablePassMap& passmap)
00085     {
00086         SolidRenderablePassMap::iterator i, iend;
00087         iend = passmap.end();
00088         for (i = passmap.begin(); i != iend; ++i)
00089         {
00090             // Clear the list associated with this pass, but leave the pass entry
00091             i->second->clear();
00092         }
00093     }
00094     //-----------------------------------------------------------------------
00095     void RenderPriorityGroup::addRenderable(Renderable* rend)
00096     {
00097         // Check material & technique supplied (the former since the default implementation
00098         // of getTechnique is based on it for backwards compatibility
00099         Technique* pTech;
00100         if(!rend->getMaterial() || !rend->getTechnique())
00101         {
00102             // Use default base white
00103             pTech = static_cast<Material*>(
00104                 MaterialManager::getSingleton().getByName("BaseWhite"))->getTechnique(0);
00105         }
00106         else
00107         {
00108             // Get technique
00109             pTech = rend->getTechnique();
00110         }
00111 
00112         // Transparent?
00113         if (pTech->isTransparent())
00114         {
00115             addTransparentRenderable(pTech, rend);
00116         }
00117         else
00118         {
00119             if (mSplitNoShadowPasses && !pTech->getParent()->getReceiveShadows())
00120             {
00121                 // Add solid renderable and add passes to no-shadow group
00122                 addSolidRenderable(pTech, rend, true);
00123             }
00124             else
00125             {
00126                 if (mSplitPassesByLightingType)
00127                 {
00128                     addSolidRenderableSplitByLightType(pTech, rend);
00129                 }
00130                 else
00131                 {
00132                     addSolidRenderable(pTech, rend, false);
00133                 }
00134             }
00135         }
00136 
00137     }
00138     //-----------------------------------------------------------------------
00139     void RenderPriorityGroup::addSolidRenderable(Technique* pTech, 
00140         Renderable* rend, bool addToNoShadow)
00141     {
00142         Technique::PassIterator pi = pTech->getPassIterator();
00143 
00144         SolidRenderablePassMap* passMap;
00145         if (addToNoShadow)
00146         {
00147             passMap = &mSolidPassesNoShadow;
00148         }
00149         else
00150         {
00151             passMap = &mSolidPasses;
00152         }
00153 
00154 
00155         while (pi.hasMoreElements())
00156         {
00157             // Insert into solid list
00158             Pass* p = pi.getNext();
00159             SolidRenderablePassMap::iterator i = passMap->find(p);
00160             if (i == passMap->end())
00161             {
00162                 std::pair<SolidRenderablePassMap::iterator, bool> retPair;
00163                 // Create new pass entry, build a new list
00164                 // Note that this pass and list are never destroyed until the engine
00165                 // shuts down, although the lists will be cleared
00166                 retPair = passMap->insert(
00167                     SolidRenderablePassMap::value_type(p, new RenderableList() ) );
00168                 assert(retPair.second && "Error inserting new pass entry into SolidRenderablePassMap");
00169                 i = retPair.first;
00170             }
00171             // Insert renderable
00172             i->second->push_back(rend);
00173 
00174         }
00175     }
00176     //-----------------------------------------------------------------------
00177     void RenderPriorityGroup::addSolidRenderableSplitByLightType(Technique* pTech, Renderable* rend)
00178     {
00179         // Divide the passes into the 3 categories
00180         Technique::IlluminationPassIterator pi = 
00181             pTech->getIlluminationPassIterator();
00182 
00183         while (pi.hasMoreElements())
00184         {
00185             // Insert into solid list
00186             IlluminationPass* p = pi.getNext();
00187             SolidRenderablePassMap* passMap;
00188             switch(p->stage)
00189             {
00190             case IS_AMBIENT:
00191                 passMap = &mSolidPasses;
00192                 break;
00193             case IS_PER_LIGHT:
00194                 passMap = &mSolidPassesDiffuseSpecular;
00195                 break;
00196             case IS_DECAL:
00197                 passMap = &mSolidPassesDecal;
00198                 break;
00199             };
00200 
00201             SolidRenderablePassMap::iterator i = passMap->find(p->pass);
00202             if (i == passMap->end())
00203             {
00204                 std::pair<SolidRenderablePassMap::iterator, bool> retPair;
00205                 // Create new pass entry, build a new list
00206                 // Note that this pass and list are never destroyed until the engine
00207                 // shuts down, although the lists will be cleared
00208                 retPair = passMap->insert(
00209                     SolidRenderablePassMap::value_type(p->pass, new RenderableList() ) );
00210                 assert(retPair.second && "Error inserting new pass entry into SolidRenderablePassMap");
00211                 i = retPair.first;
00212             }
00213             // Insert renderable
00214             i->second->push_back(rend);
00215         }
00216     }
00217     //-----------------------------------------------------------------------
00218     void RenderPriorityGroup::addTransparentRenderable(Technique* pTech, Renderable* rend)
00219     {
00220         Technique::PassIterator pi = pTech->getPassIterator();
00221 
00222         while (pi.hasMoreElements())
00223         {
00224             // Insert into transparent list
00225             mTransparentPasses.push_back(RenderablePass(rend, pi.getNext()));
00226         }
00227     }
00228     //-----------------------------------------------------------------------
00229     void RenderPriorityGroup::sort(const Camera* cam)
00230     {
00231         TransparentQueueItemLess transFunctor;
00232         transFunctor.camera = cam;
00233 
00234         std::stable_sort(mTransparentPasses.begin(), mTransparentPasses.end(), 
00235             transFunctor);
00236     }
00237     //-----------------------------------------------------------------------
00238     void RenderPriorityGroup::clear(void)
00239     {
00240         SolidRenderablePassMap::iterator i, iend;
00241         // Delete queue groups which are using passes which are to be
00242         // deleted, we won't need these any more and they clutter up 
00243         // the list and can cause problems with future clones
00244         const Pass::PassSet& graveyardList = Pass::getPassGraveyard();
00245         Pass::PassSet::const_iterator gi, giend;
00246         giend = graveyardList.end();
00247         for (gi = graveyardList.begin(); gi != giend; ++gi)
00248         {
00249             removeSolidPassEntry(*gi);
00250         }
00251 
00252         // Now remove any dirty passes, these will have their hashes recalculated
00253         // by the parent queue after all groups have been processed
00254         // If we don't do this, the std::map will become inconsistent for new insterts
00255         const Pass::PassSet& dirtyList = Pass::getDirtyHashList();
00256         Pass::PassSet::const_iterator di, diend;
00257         diend = dirtyList.end();
00258         for (di = dirtyList.begin(); di != diend; ++di)
00259         {
00260             removeSolidPassEntry(*di);
00261         }
00262         // NB we do NOT clear the graveyard or the dirty list here, because 
00263         // it needs to be acted on for all groups, the parent queue takes 
00264         // care of this afterwards
00265 
00266         // We do not clear the unchanged solid pass maps, only the contents of each list
00267         // This is because we assume passes are reused a lot and it saves resorting
00268         clearSolidPassMap(mSolidPasses);
00269         clearSolidPassMap(mSolidPassesDecal);
00270         clearSolidPassMap(mSolidPassesDiffuseSpecular);
00271         clearSolidPassMap(mSolidPassesNoShadow);
00272 
00273         // Always empty the transparents list
00274         mTransparentPasses.clear();
00275 
00276     }
00277     //-----------------------------------------------------------------------
00278 
00279 
00280 
00281 
00282 
00283 }
00284 

Copyright © 2002-2003 by The OGRE Team
Last modified Fri May 14 23:22:39 2004