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