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