# 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
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Feb 12 12:59:51 2006