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 and depth settings mean depth sorting is required?
00113         if (pTech->isTransparent() && 
00114             !(pTech->isDepthWriteEnabled() && pTech->isDepthCheckEnabled()) )
00115         {
00116             addTransparentRenderable(pTech, rend);
00117         }
00118         else
00119         {
00120             if (mSplitNoShadowPasses && !pTech->getParent()->getReceiveShadows())
00121             {
00122                 // Add solid renderable and add passes to no-shadow group
00123                 addSolidRenderable(pTech, rend, true);
00124             }
00125             else
00126             {
00127                 if (mSplitPassesByLightingType)
00128                 {
00129                     addSolidRenderableSplitByLightType(pTech, rend);
00130                 }
00131                 else
00132                 {
00133                     addSolidRenderable(pTech, rend, false);
00134                 }
00135             }
00136         }
00137 
00138     }
00139     //-----------------------------------------------------------------------
00140     void RenderPriorityGroup::addSolidRenderable(Technique* pTech, 
00141         Renderable* rend, bool addToNoShadow)
00142     {
00143         Technique::PassIterator pi = pTech->getPassIterator();
00144 
00145         SolidRenderablePassMap* passMap;
00146         if (addToNoShadow)
00147         {
00148             passMap = &mSolidPassesNoShadow;
00149         }
00150         else
00151         {
00152             passMap = &mSolidPasses;
00153         }
00154 
00155 
00156         while (pi.hasMoreElements())
00157         {
00158             // Insert into solid list
00159             Pass* p = pi.getNext();
00160             SolidRenderablePassMap::iterator i = passMap->find(p);
00161             if (i == passMap->end())
00162             {
00163                 std::pair<SolidRenderablePassMap::iterator, bool> retPair;
00164                 // Create new pass entry, build a new list
00165                 // Note that this pass and list are never destroyed until the engine
00166                 // shuts down, although the lists will be cleared
00167                 retPair = passMap->insert(
00168                     SolidRenderablePassMap::value_type(p, new RenderableList() ) );
00169                 assert(retPair.second && "Error inserting new pass entry into SolidRenderablePassMap");
00170                 i = retPair.first;
00171             }
00172             // Insert renderable
00173             i->second->push_back(rend);
00174 
00175         }
00176     }
00177     //-----------------------------------------------------------------------
00178     void RenderPriorityGroup::addSolidRenderableSplitByLightType(Technique* pTech, Renderable* rend)
00179     {
00180         // Divide the passes into the 3 categories
00181         Technique::IlluminationPassIterator pi = 
00182             pTech->getIlluminationPassIterator();
00183 
00184         while (pi.hasMoreElements())
00185         {
00186             // Insert into solid list
00187             IlluminationPass* p = pi.getNext();
00188             SolidRenderablePassMap* passMap;
00189             switch(p->stage)
00190             {
00191             case IS_AMBIENT:
00192                 passMap = &mSolidPasses;
00193                 break;
00194             case IS_PER_LIGHT:
00195                 passMap = &mSolidPassesDiffuseSpecular;
00196                 break;
00197             case IS_DECAL:
00198                 passMap = &mSolidPassesDecal;
00199                 break;
00200             };
00201 
00202             SolidRenderablePassMap::iterator i = passMap->find(p->pass);
00203             if (i == passMap->end())
00204             {
00205                 std::pair<SolidRenderablePassMap::iterator, bool> retPair;
00206                 // Create new pass entry, build a new list
00207                 // Note that this pass and list are never destroyed until the engine
00208                 // shuts down, although the lists will be cleared
00209                 retPair = passMap->insert(
00210                     SolidRenderablePassMap::value_type(p->pass, new RenderableList() ) );
00211                 assert(retPair.second && "Error inserting new pass entry into SolidRenderablePassMap");
00212                 i = retPair.first;
00213             }
00214             // Insert renderable
00215             i->second->push_back(rend);
00216         }
00217     }
00218     //-----------------------------------------------------------------------
00219     void RenderPriorityGroup::addTransparentRenderable(Technique* pTech, Renderable* rend)
00220     {
00221         Technique::PassIterator pi = pTech->getPassIterator();
00222 
00223         while (pi.hasMoreElements())
00224         {
00225             // Insert into transparent list
00226             mTransparentPasses.push_back(RenderablePass(rend, pi.getNext()));
00227         }
00228     }
00229     //-----------------------------------------------------------------------
00230     void RenderPriorityGroup::sort(const Camera* cam)
00231     {
00232         TransparentQueueItemLess transFunctor;
00233         transFunctor.camera = cam;
00234 
00235         std::stable_sort(mTransparentPasses.begin(), mTransparentPasses.end(), 
00236             transFunctor);
00237     }
00238     //-----------------------------------------------------------------------
00239     void RenderPriorityGroup::clear(void)
00240     {
00241         SolidRenderablePassMap::iterator i, iend;
00242         // Delete queue groups which are using passes which are to be
00243         // deleted, we won't need these any more and they clutter up 
00244         // the list and can cause problems with future clones
00245         const Pass::PassSet& graveyardList = Pass::getPassGraveyard();
00246         Pass::PassSet::const_iterator gi, giend;
00247         giend = graveyardList.end();
00248         for (gi = graveyardList.begin(); gi != giend; ++gi)
00249         {
00250             removeSolidPassEntry(*gi);
00251         }
00252 
00253         // Now remove any dirty passes, these will have their hashes recalculated
00254         // by the parent queue after all groups have been processed
00255         // If we don't do this, the std::map will become inconsistent for new insterts
00256         const Pass::PassSet& dirtyList = Pass::getDirtyHashList();
00257         Pass::PassSet::const_iterator di, diend;
00258         diend = dirtyList.end();
00259         for (di = dirtyList.begin(); di != diend; ++di)
00260         {
00261             removeSolidPassEntry(*di);
00262         }
00263         // NB we do NOT clear the graveyard or the dirty list here, because 
00264         // it needs to be acted on for all groups, the parent queue takes 
00265         // care of this afterwards
00266 
00267         // We do not clear the unchanged solid pass maps, only the contents of each list
00268         // This is because we assume passes are reused a lot and it saves resorting
00269         clearSolidPassMap(mSolidPasses);
00270         clearSolidPassMap(mSolidPassesDecal);
00271         clearSolidPassMap(mSolidPassesDiffuseSpecular);
00272         clearSolidPassMap(mSolidPassesNoShadow);
00273 
00274         // Always empty the transparents list
00275         mTransparentPasses.clear();
00276 
00277     }
00278     //-----------------------------------------------------------------------
00279 
00280 
00281 
00282 
00283 
00284 }
00285 

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:42 2004