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 Wed Feb 23 00:19:12 2005