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 
00189 
00191         void addRenderable(Renderable* pRend);
00192 
00195         void sort(const Camera* cam);
00196 
00199         void clear(void);
00200 
00204         void setSplitPassesByLightingType(bool split)
00205         {
00206             mSplitPassesByLightingType = split;
00207         }
00208 
00212         void setSplitNoShadowPasses(bool split)
00213         {
00214             mSplitNoShadowPasses = split;
00215         }
00216 
00217 
00218     };
00219 
00220 
00230     class RenderQueueGroup
00231     {
00232     public:
00233         typedef std::map<ushort, RenderPriorityGroup*, std::less<ushort> > PriorityMap;
00234         typedef MapIterator<PriorityMap> PriorityMapIterator;
00235     protected:
00236         RenderQueue* mParent;
00237         bool mSplitPassesByLightingType;
00238         bool mSplitNoShadowPasses;
00240         PriorityMap mPriorityGroups;
00242         bool mShadowsEnabled;
00243 
00244 
00245     public:
00246         RenderQueueGroup(RenderQueue* parent, bool splitPassesByLightingType, 
00247             bool splitNoShadowPasses) 
00248             :mParent(parent), mSplitPassesByLightingType(splitPassesByLightingType),
00249             mSplitNoShadowPasses(splitNoShadowPasses), mShadowsEnabled(true) {}
00250 
00251         ~RenderQueueGroup() {
00252             // destroy contents now
00253             PriorityMap::iterator i;
00254             for (i = mPriorityGroups.begin(); i != mPriorityGroups.end(); ++i)
00255             {
00256                 delete i->second;
00257             }
00258         }
00259 
00261         PriorityMapIterator getIterator(void)
00262         {
00263             return PriorityMapIterator(mPriorityGroups.begin(), mPriorityGroups.end());
00264         }
00265 
00267         void addRenderable(Renderable* pRend, ushort priority)
00268         {
00269             // Check if priority group is there
00270             PriorityMap::iterator i = mPriorityGroups.find(priority);
00271             RenderPriorityGroup* pPriorityGrp;
00272             if (i == mPriorityGroups.end())
00273             {
00274                 // Missing, create
00275                 pPriorityGrp = new RenderPriorityGroup(this, 
00276                     mSplitPassesByLightingType, mSplitNoShadowPasses);
00277                 mPriorityGroups.insert(PriorityMap::value_type(priority, pPriorityGrp));
00278             }
00279             else
00280             {
00281                 pPriorityGrp = i->second;
00282             }
00283 
00284             // Add
00285             pPriorityGrp->addRenderable(pRend);
00286 
00287         }
00288 
00295         void clear(void)
00296         {
00297             PriorityMap::iterator i, iend;
00298             iend = mPriorityGroups.end();
00299             for (i = mPriorityGroups.begin(); i != iend; ++i)
00300             {
00301                 i->second->clear();
00302             }
00303 
00304         }
00305 
00318         void setShadowsEnabled(bool enabled) { mShadowsEnabled = enabled; }
00319 
00321         bool getShadowsEnabled(void) const { return mShadowsEnabled; }
00322 
00326         void setSplitPassesByLightingType(bool split)
00327         {
00328             mSplitPassesByLightingType = split;
00329             PriorityMap::iterator i, iend;
00330             iend = mPriorityGroups.end();
00331             for (i = mPriorityGroups.begin(); i != iend; ++i)
00332             {
00333                 i->second->setSplitPassesByLightingType(split);
00334             }
00335         }
00340         void setSplitNoShadowPasses(bool split)
00341         {
00342             mSplitNoShadowPasses = split;
00343             PriorityMap::iterator i, iend;
00344             iend = mPriorityGroups.end();
00345             for (i = mPriorityGroups.begin(); i != iend; ++i)
00346             {
00347                 i->second->setSplitNoShadowPasses(split);
00348             }
00349         }
00350 
00351     };
00352 
00353 
00354 
00355 }
00356 
00357 #endif
00358 
00359 

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