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

OgreRenderQueueSortingGrouping.h

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 (c) 2000-2005 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 #ifndef __RenderQueueSortingGrouping_H__
00026 #define __RenderQueueSortingGrouping_H__
00027 
00028 // Precompiler options
00029 #include "OgrePrerequisites.h"
00030 #include "OgreIteratorWrappers.h"
00031 #include "OgreMaterial.h"
00032 #include "OgreTechnique.h"
00033 #include "OgrePass.h"
00034 #include "OgreMaterialManager.h"
00035 
00036 namespace Ogre {
00037 
00050     class _OgrePrivate RenderPriorityGroup
00051     {
00055         struct RenderablePass
00056         {
00058             Renderable* renderable;
00060             Pass* pass;
00061 
00062             RenderablePass(Renderable* rend, Pass* p) :renderable(rend), pass(p) {}
00063         };
00064 
00066         struct SolidQueueItemLess
00067         {
00068             bool _OgreExport operator()(const Pass* a, const Pass* b) const
00069             {
00070                 // Sort by passHash, which is pass, then texture unit changes
00071                 unsigned long hasha = a->getHash();
00072                 unsigned long hashb = b->getHash();
00073                 if (hasha == hashb)
00074                 {
00075                     // Must differentiate by pointer incase 2 passes end up with the same hash
00076                     return a < b;
00077                 }
00078                 else
00079                 {
00080                     return hasha < hashb;
00081                 }
00082             }
00083         };
00085         struct TransparentQueueItemLess
00086         {
00087             const Camera* camera;
00088             bool _OgreExport operator()(const RenderablePass& a, const RenderablePass& b) const
00089             {
00090                 if (a.renderable == b.renderable)
00091                 {
00092                     // Same renderable, sort by pass hash
00093                     return a.pass->getHash() < b.pass->getHash();
00094                 }
00095                 else
00096                 {
00097                     // Different renderables, sort by depth
00098                     Real adepth = a.renderable->getSquaredViewDepth(camera);
00099                     Real bdepth = b.renderable->getSquaredViewDepth(camera);
00100                     if (adepth == bdepth)
00101                     {
00102                         // Must return deterministic result, doesn't matter what
00103                         return a.pass < b.pass;
00104                     }
00105                     else
00106                     {
00107                         // Sort DESCENDING by depth (ie far objects first)
00108                         return (adepth > bdepth);
00109                     }
00110                 }
00111 
00112             }
00113         };
00114     public:
00118         typedef std::vector<RenderablePass> TransparentRenderablePassList;
00119         typedef std::vector<Renderable*> RenderableList;
00122         typedef std::map<Pass*, RenderableList*, SolidQueueItemLess> SolidRenderablePassMap;
00123     protected:
00125         RenderQueueGroup* mParent;
00126         bool mSplitPassesByLightingType;
00127         bool mSplitNoShadowPasses;
00129         SolidRenderablePassMap mSolidPasses;
00131         SolidRenderablePassMap mSolidPassesDiffuseSpecular;
00133         SolidRenderablePassMap mSolidPassesDecal;
00135         SolidRenderablePassMap mSolidPassesNoShadow;
00136 
00138         TransparentRenderablePassList mTransparentPasses;
00139 
00141         void destroySolidPassMap(SolidRenderablePassMap& passmap);
00142 
00144         void removeSolidPassEntry(Pass* p);
00145 
00147         void clearSolidPassMap(SolidRenderablePassMap& passmap);
00149         void addSolidRenderable(Technique* pTech, Renderable* rend, bool toNoShadowMap);
00151         void addSolidRenderableSplitByLightType(Technique* pTech, Renderable* rend);
00153         void addTransparentRenderable(Technique* pTech, Renderable* rend);
00154 
00155     public:
00156         RenderPriorityGroup(RenderQueueGroup* parent, 
00157             bool splitPassesByLightingType, bool splitNoShadowPasses) 
00158             :mParent(parent), mSplitPassesByLightingType(splitPassesByLightingType),
00159             mSplitNoShadowPasses(splitNoShadowPasses) { }
00160 
00161         ~RenderPriorityGroup() {
00162             // destroy all the pass map entries
00163             destroySolidPassMap(mSolidPasses);
00164             destroySolidPassMap(mSolidPassesDecal);
00165             destroySolidPassMap(mSolidPassesDiffuseSpecular);
00166             destroySolidPassMap(mSolidPassesNoShadow);
00167             mTransparentPasses.clear();
00168 
00169         }
00170 
00172         const SolidRenderablePassMap& _getSolidPasses(void) const
00173         { return mSolidPasses; }
00175         const SolidRenderablePassMap& _getSolidPassesDiffuseSpecular(void) const
00176         { return mSolidPassesDiffuseSpecular; }
00178         const SolidRenderablePassMap& _getSolidPassesDecal(void) const
00179         { return mSolidPassesDecal; }
00181         const SolidRenderablePassMap& _getSolidPassesNoShadow(void) const
00182         { return mSolidPassesNoShadow; }
00184         const TransparentRenderablePassList& _getTransparentPasses(void) const
00185         { return mTransparentPasses; }
00186 
00187 
00189         void addRenderable(Renderable* pRend);
00190 
00193         void sort(const Camera* cam);
00194 
00197         void clear(void);
00198 
00202         void setSplitPassesByLightingType(bool split)
00203         {
00204             mSplitPassesByLightingType = split;
00205         }
00206 
00210         void setSplitNoShadowPasses(bool split)
00211         {
00212             mSplitNoShadowPasses = split;
00213         }
00214 
00215 
00216     };
00217 
00218 
00228     class _OgrePrivate RenderQueueGroup
00229     {
00230     public:
00231         typedef std::map<ushort, RenderPriorityGroup*, std::less<ushort> > PriorityMap;
00232         typedef MapIterator<PriorityMap> PriorityMapIterator;
00233     protected:
00234         RenderQueue* mParent;
00235         bool mSplitPassesByLightingType;
00236         bool mSplitNoShadowPasses;
00238         PriorityMap mPriorityGroups;
00240         bool mShadowsEnabled;
00241 
00242 
00243     public:
00244         RenderQueueGroup(RenderQueue* parent, bool splitPassesByLightingType, 
00245             bool splitNoShadowPasses) 
00246             :mParent(parent), mSplitPassesByLightingType(splitPassesByLightingType),
00247             mSplitNoShadowPasses(splitNoShadowPasses), mShadowsEnabled(true) {}
00248 
00249         ~RenderQueueGroup() {
00250             // destroy contents now
00251             PriorityMap::iterator i;
00252             for (i = mPriorityGroups.begin(); i != mPriorityGroups.end(); ++i)
00253             {
00254                 delete i->second;
00255             }
00256         }
00257 
00259         PriorityMapIterator getIterator(void)
00260         {
00261             return PriorityMapIterator(mPriorityGroups.begin(), mPriorityGroups.end());
00262         }
00263 
00265         void addRenderable(Renderable* pRend, ushort priority)
00266         {
00267             // Check if priority group is there
00268             PriorityMap::iterator i = mPriorityGroups.find(priority);
00269             RenderPriorityGroup* pPriorityGrp;
00270             if (i == mPriorityGroups.end())
00271             {
00272                 // Missing, create
00273                 pPriorityGrp = new RenderPriorityGroup(this, 
00274                     mSplitPassesByLightingType, mSplitNoShadowPasses);
00275                 mPriorityGroups.insert(PriorityMap::value_type(priority, pPriorityGrp));
00276             }
00277             else
00278             {
00279                 pPriorityGrp = i->second;
00280             }
00281 
00282             // Add
00283             pPriorityGrp->addRenderable(pRend);
00284 
00285         }
00286 
00294         void clear(bool destroy = false)
00295         {
00296             PriorityMap::iterator i, iend;
00297             iend = mPriorityGroups.end();
00298             for (i = mPriorityGroups.begin(); i != iend; ++i)
00299             {
00300                 if (destroy)
00301                     delete i->second;
00302                 else
00303                     i->second->clear();
00304             }
00305 
00306             if (destroy)
00307                 mPriorityGroups.clear();
00308 
00309         }
00310 
00323         void setShadowsEnabled(bool enabled) { mShadowsEnabled = enabled; }
00324 
00326         bool getShadowsEnabled(void) const { return mShadowsEnabled; }
00327 
00331         void setSplitPassesByLightingType(bool split)
00332         {
00333             mSplitPassesByLightingType = split;
00334             PriorityMap::iterator i, iend;
00335             iend = mPriorityGroups.end();
00336             for (i = mPriorityGroups.begin(); i != iend; ++i)
00337             {
00338                 i->second->setSplitPassesByLightingType(split);
00339             }
00340         }
00345         void setSplitNoShadowPasses(bool split)
00346         {
00347             mSplitNoShadowPasses = split;
00348             PriorityMap::iterator i, iend;
00349             iend = mPriorityGroups.end();
00350             for (i = mPriorityGroups.begin(); i != iend; ++i)
00351             {
00352                 i->second->setSplitNoShadowPasses(split);
00353             }
00354         }
00355 
00356     };
00357 
00358 
00359 
00360 }
00361 
00362 #endif
00363 
00364 

Copyright © 2000-2005 by The OGRE Team
Last modified Sun Sep 25 17:35:59 2005