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