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