Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound 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 © 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 #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 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             _OgreExport bool 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 
00089             _OgreExport bool operator()(const RenderablePass& a, const RenderablePass& b) const
00090             {
00091                 if (a.renderable == b.renderable)
00092                 {
00093                     // Same renderable, sort by pass hash
00094                     return a.pass->getHash() < b.pass->getHash();
00095                 }
00096                 else
00097                 {
00098                     // Different renderables, sort by depth
00099                     Real adepth = a.renderable->getSquaredViewDepth(camera);
00100                     Real bdepth = b.renderable->getSquaredViewDepth(camera);
00101                     if (adepth == bdepth)
00102                     {
00103                         // Must return deterministic result, doesn't matter what
00104                         return a.pass < b.pass;
00105                     }
00106                     else
00107                     {
00108                         // Sort DESCENDING by depth (ie far objects first)
00109                         return (adepth > bdepth);
00110                     }
00111                 }
00112 
00113             }
00114         };
00115     public:
00119         typedef std::vector<RenderablePass> TransparentRenderablePassList;
00120         typedef std::vector<Renderable*> RenderableList;
00123         typedef std::map<Pass*, RenderableList*, SolidQueueItemLess> SolidRenderablePassMap;
00124     protected:
00126         RenderQueueGroup* mParent;
00127         bool mSplitPassesByLightingType;
00128         bool mSplitNoShadowPasses;
00130         SolidRenderablePassMap mSolidPasses;
00132         SolidRenderablePassMap mSolidPassesDiffuseSpecular;
00134         SolidRenderablePassMap mSolidPassesDecal;
00136         SolidRenderablePassMap mSolidPassesNoShadow;
00137 
00139         TransparentRenderablePassList mTransparentPasses;
00140 
00142         void destroySolidPassMap(SolidRenderablePassMap& passmap);
00143 
00145         void removeSolidPassEntry(Pass* p);
00146 
00148         void clearSolidPassMap(SolidRenderablePassMap& passmap);
00150         void addSolidRenderable(Technique* pTech, Renderable* rend, bool toNoShadowMap);
00152         void addSolidRenderableSplitByLightType(Technique* pTech, Renderable* rend);
00154         void addTransparentRenderable(Technique* pTech, Renderable* rend);
00155 
00156     public:
00157         RenderPriorityGroup(RenderQueueGroup* parent, 
00158             bool splitPassesByLightingType, bool splitNoShadowPasses) 
00159             :mParent(parent), mSplitPassesByLightingType(splitPassesByLightingType),
00160             mSplitNoShadowPasses(splitNoShadowPasses) { }
00161 
00162         ~RenderPriorityGroup() {
00163             // destroy all the pass map entries
00164             destroySolidPassMap(mSolidPasses);
00165             destroySolidPassMap(mSolidPassesDecal);
00166             destroySolidPassMap(mSolidPassesDiffuseSpecular);
00167             destroySolidPassMap(mSolidPassesNoShadow);
00168             mTransparentPasses.clear();
00169 
00170         }
00171 
00173         const SolidRenderablePassMap& _getSolidPasses(void) const
00174         { return mSolidPasses; }
00176         const SolidRenderablePassMap& _getSolidPassesDiffuseSpecular(void) const
00177         { return mSolidPassesDiffuseSpecular; }
00179         const SolidRenderablePassMap& _getSolidPassesDecal(void) const
00180         { return mSolidPassesDecal; }
00182         const SolidRenderablePassMap& _getSolidPassesNoShadow(void) const
00183         { return mSolidPassesNoShadow; }
00185         const TransparentRenderablePassList& _getTransparentPasses(void) const
00186         { return mTransparentPasses; }
00187 
00188 
00190         void addRenderable(Renderable* pRend);
00191 
00194         void sort(const Camera* cam);
00195 
00198         void clear(void);
00199 
00203         void setSplitPassesByLightingType(bool split)
00204         {
00205             mSplitPassesByLightingType = split;
00206         }
00207 
00211         void setSplitNoShadowPasses(bool split)
00212         {
00213             mSplitNoShadowPasses = split;
00214         }
00215 
00216 
00217     };
00218 
00219 
00229     class RenderQueueGroup
00230     {
00231     public:
00232         typedef std::map<ushort, RenderPriorityGroup*, std::less<ushort> > PriorityMap;
00233         typedef MapIterator<PriorityMap> PriorityMapIterator;
00234     protected:
00235         RenderQueue* mParent;
00236         bool mSplitPassesByLightingType;
00237         bool mSplitNoShadowPasses;
00239         PriorityMap mPriorityGroups;
00241         bool mShadowsEnabled;
00242 
00243 
00244     public:
00245         RenderQueueGroup(RenderQueue* parent, bool splitPassesByLightingType, 
00246             bool splitNoShadowPasses) 
00247             :mParent(parent), mSplitPassesByLightingType(splitPassesByLightingType),
00248             mSplitNoShadowPasses(splitNoShadowPasses), mShadowsEnabled(true) {}
00249 
00250         ~RenderQueueGroup() {
00251             // destroy contents now
00252             PriorityMap::iterator i;
00253             for (i = mPriorityGroups.begin(); i != mPriorityGroups.end(); ++i)
00254             {
00255                 delete i->second;
00256             }
00257         }
00258 
00260         PriorityMapIterator getIterator(void)
00261         {
00262             return PriorityMapIterator(mPriorityGroups.begin(), mPriorityGroups.end());
00263         }
00264 
00266         void addRenderable(Renderable* pRend, ushort priority)
00267         {
00268             // Check if priority group is there
00269             PriorityMap::iterator i = mPriorityGroups.find(priority);
00270             RenderPriorityGroup* pPriorityGrp;
00271             if (i == mPriorityGroups.end())
00272             {
00273                 // Missing, create
00274                 pPriorityGrp = new RenderPriorityGroup(this, 
00275                     mSplitPassesByLightingType, mSplitNoShadowPasses);
00276                 mPriorityGroups.insert(PriorityMap::value_type(priority, pPriorityGrp));
00277             }
00278             else
00279             {
00280                 pPriorityGrp = i->second;
00281             }
00282 
00283             // Add
00284             pPriorityGrp->addRenderable(pRend);
00285 
00286         }
00287 
00294         void clear(void)
00295         {
00296             PriorityMap::iterator i, iend;
00297             iend = mPriorityGroups.end();
00298             for (i = mPriorityGroups.begin(); i != iend; ++i)
00299             {
00300                 i->second->clear();
00301             }
00302 
00303         }
00304 
00317         void setShadowsEnabled(bool enabled) { mShadowsEnabled = enabled; }
00318 
00320         bool getShadowsEnabled(void) const { return mShadowsEnabled; }
00321 
00325         void setSplitPassesByLightingType(bool split)
00326         {
00327             mSplitPassesByLightingType = split;
00328             PriorityMap::iterator i, iend;
00329             iend = mPriorityGroups.end();
00330             for (i = mPriorityGroups.begin(); i != iend; ++i)
00331             {
00332                 i->second->setSplitPassesByLightingType(split);
00333             }
00334         }
00339         void setSplitNoShadowPasses(bool split)
00340         {
00341             mSplitNoShadowPasses = split;
00342             PriorityMap::iterator i, iend;
00343             iend = mPriorityGroups.end();
00344             for (i = mPriorityGroups.begin(); i != iend; ++i)
00345             {
00346                 i->second->setSplitNoShadowPasses(split);
00347             }
00348         }
00349 
00350     };
00351 
00352 
00353 
00354 }
00355 
00356 #endif
00357 
00358 

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