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 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 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 
00293         void clear(void)
00294         {
00295             PriorityMap::iterator i, iend;
00296             iend = mPriorityGroups.end();
00297             for (i = mPriorityGroups.begin(); i != iend; ++i)
00298             {
00299                 i->second->clear();
00300             }
00301 
00302         }
00303 
00316         void setShadowsEnabled(bool enabled) { mShadowsEnabled = enabled; }
00317 
00319         bool getShadowsEnabled(void) const { return mShadowsEnabled; }
00320 
00324         void setSplitPassesByLightingType(bool split)
00325         {
00326             mSplitPassesByLightingType = split;
00327             PriorityMap::iterator i, iend;
00328             iend = mPriorityGroups.end();
00329             for (i = mPriorityGroups.begin(); i != iend; ++i)
00330             {
00331                 i->second->setSplitPassesByLightingType(split);
00332             }
00333         }
00338         void setSplitNoShadowPasses(bool split)
00339         {
00340             mSplitNoShadowPasses = split;
00341             PriorityMap::iterator i, iend;
00342             iend = mPriorityGroups.end();
00343             for (i = mPriorityGroups.begin(); i != iend; ++i)
00344             {
00345                 i->second->setSplitNoShadowPasses(split);
00346             }
00347         }
00348 
00349     };
00350 
00351 
00352 
00353 }
00354 
00355 #endif
00356 
00357 

Copyright © 2000-2005 by The OGRE Team
Last modified Sun Apr 10 23:21:21 2005