OgreRenderQueueSortingGrouping.h
Go to the documentation of this file.
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4  (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2013 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #ifndef __RenderQueueSortingGrouping_H__
29 #define __RenderQueueSortingGrouping_H__
30 
31 // Precompiler options
32 #include "OgrePrerequisites.h"
33 #include "OgreIteratorWrappers.h"
34 #include "OgreMaterial.h"
35 #include "OgreTechnique.h"
36 #include "OgrePass.h"
37 #include "OgreRadixSort.h"
38 
39 namespace Ogre {
40 
52  {
57 
58  RenderablePass(Renderable* rend, Pass* p) :renderable(rend), pass(p) {}
59  };
60 
61 
70  {
71  public:
74 
81  virtual void visit(RenderablePass* rp) = 0;
82 
83  /* When visiting a collection grouped by pass, this is
84  called when the grouping pass changes.
85  @remarks
86  If this method is called, the RenderablePass visit
87  method will not be called for this collection. The
88  Renderable visit method will be called for each item
89  underneath the pass grouping level.
90  @return True to continue, false to skip the Renderables underneath
91  */
92  virtual bool visit(const Pass* p) = 0;
99  virtual void visit(Renderable* r) = 0;
100 
101 
102  };
103 
114  {
115  public:
125  {
127  OM_PASS_GROUP = 1,
129  OM_SORT_DESCENDING = 2,
133  OM_SORT_ASCENDING = 6
134  };
135 
136  protected:
139  {
140  bool _OgreExport operator()(const Pass* a, const Pass* b) const
141  {
142  // Sort by passHash, which is pass, then texture unit changes
143  uint32 hasha = a->getHash();
144  uint32 hashb = b->getHash();
145  if (hasha == hashb)
146  {
147  // Must differentTransparentQueueItemLessiate by pointer incase 2 passes end up with the same hash
148  return a < b;
149  }
150  else
151  {
152  return hasha < hashb;
153  }
154  }
155  };
158  {
159  const Camera* camera;
160 
162  : camera(cam)
163  {
164  }
165 
166  bool _OgreExport operator()(const RenderablePass& a, const RenderablePass& b) const
167  {
168  if (a.renderable == b.renderable)
169  {
170  // Same renderable, sort by pass hash
171  return a.pass->getHash() < b.pass->getHash();
172  }
173  else
174  {
175  // Different renderables, sort by depth
176  Real adepth = a.renderable->getSquaredViewDepth(camera);
177  Real bdepth = b.renderable->getSquaredViewDepth(camera);
178  if (Math::RealEqual(adepth, bdepth))
179  {
180  // Must return deterministic result, doesn't matter what
181  return a.pass < b.pass;
182  }
183  else
184  {
185  // Sort DESCENDING by depth (i.e. far objects first)
186  return (adepth > bdepth);
187  }
188  }
189 
190  }
191  };
192 
200 
203  {
205  {
206  return p.pass->getHash();
207  }
208  };
209 
212 
215  {
216  const Camera* camera;
217 
219  : camera(cam)
220  {
221  }
222 
223  float operator()(const RenderablePass& p) const
224  {
225  // Sort DESCENDING by depth (ie far objects first), use negative distance
226  // here because radix sorter always dealing with accessing sort
227  return static_cast<float>(- p.renderable->getSquaredViewDepth(camera));
228  }
229  };
230 
233 
236 
241 
243  void acceptVisitorGrouped(QueuedRenderableVisitor* visitor) const;
245  void acceptVisitorDescending(QueuedRenderableVisitor* visitor) const;
247  void acceptVisitorAscending(QueuedRenderableVisitor* visitor) const;
248 
249  public:
252 
254  void clear(void);
255 
261  void removePassGroup(Pass* p);
262 
269  {
270  mOrganisationMode = 0;
271  }
272 
279  {
280  mOrganisationMode |= om;
281  }
282 
284  void addRenderable(Pass* pass, Renderable* rend);
285 
289  void sort(const Camera* cam);
290 
297  void acceptVisitor(QueuedRenderableVisitor* visitor, OrganisationMode om) const;
298 
301  void merge( const QueuedRenderableCollection& rhs );
302  };
303 
324  {
325  protected:
326 
344 
346  void removePassEntry(Pass* p);
347 
349  void addSolidRenderable(Technique* pTech, Renderable* rend, bool toNoShadowMap);
351  void addSolidRenderableSplitByLightType(Technique* pTech, Renderable* rend);
353  void addUnsortedTransparentRenderable(Technique* pTech, Renderable* rend);
355  void addTransparentRenderable(Technique* pTech, Renderable* rend);
356 
357  public:
359  bool splitPassesByLightingType,
360  bool splitNoShadowPasses,
361  bool shadowCastersNotReceivers);
362 
364 
370  { return mSolidsBasic; }
374  { return mSolidsDiffuseSpecular; }
378  { return mSolidsDecal; }
382  { return mSolidsNoShadowReceive; }
385  { return mTransparentsUnsorted; }
388  { return mTransparents; }
389 
390 
397  void resetOrganisationModes(void);
398 
405  void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om);
406 
413  void defaultOrganisationMode(void);
414 
416  void addRenderable(Renderable* pRend, Technique* pTech);
417 
420  void sort(const Camera* cam);
421 
424  void clear(void);
425 
430  {
431  mSplitPassesByLightingType = split;
432  }
433 
437  void setSplitNoShadowPasses(bool split)
438  {
439  mSplitNoShadowPasses = split;
440  }
441 
446  {
447  mShadowCastersNotReceivers = ind;
448  }
449 
452  void merge( const RenderPriorityGroup* rhs );
453 
454 
455  };
456 
457 
466  {
467  public:
471  protected:
482 
483 
484  public:
486  bool splitPassesByLightingType,
487  bool splitNoShadowPasses,
488  bool shadowCastersNotReceivers)
489  : mParent(parent)
490  , mSplitPassesByLightingType(splitPassesByLightingType)
491  , mSplitNoShadowPasses(splitNoShadowPasses)
492  , mShadowCastersNotReceivers(shadowCastersNotReceivers)
493  , mShadowsEnabled(true)
494  , mOrganisationMode(0)
495  {
496  }
497 
499  // destroy contents now
500  PriorityMap::iterator i;
501  for (i = mPriorityGroups.begin(); i != mPriorityGroups.end(); ++i)
502  {
503  OGRE_DELETE i->second;
504  }
505  }
506 
509  {
510  return PriorityMapIterator(mPriorityGroups.begin(), mPriorityGroups.end());
511  }
512 
515  {
516  return ConstPriorityMapIterator(mPriorityGroups.begin(), mPriorityGroups.end());
517  }
518 
520  void addRenderable(Renderable* pRend, Technique* pTech, ushort priority)
521  {
522  // Check if priority group is there
523  PriorityMap::iterator i = mPriorityGroups.find(priority);
524  RenderPriorityGroup* pPriorityGrp;
525  if (i == mPriorityGroups.end())
526  {
527  // Missing, create
528  pPriorityGrp = OGRE_NEW RenderPriorityGroup(this,
529  mSplitPassesByLightingType,
530  mSplitNoShadowPasses,
531  mShadowCastersNotReceivers);
532  if (mOrganisationMode)
533  {
534  pPriorityGrp->resetOrganisationModes();
535  pPriorityGrp->addOrganisationMode((QueuedRenderableCollection::OrganisationMode)mOrganisationMode);
536  }
537 
538  mPriorityGroups.insert(PriorityMap::value_type(priority, pPriorityGrp));
539  }
540  else
541  {
542  pPriorityGrp = i->second;
543  }
544 
545  // Add
546  pPriorityGrp->addRenderable(pRend, pTech);
547 
548  }
549 
557  void clear(bool destroy = false)
558  {
559  PriorityMap::iterator i, iend;
560  iend = mPriorityGroups.end();
561  for (i = mPriorityGroups.begin(); i != iend; ++i)
562  {
563  if (destroy)
564  OGRE_DELETE i->second;
565  else
566  i->second->clear();
567  }
568 
569  if (destroy)
570  mPriorityGroups.clear();
571 
572  }
573 
586  void setShadowsEnabled(bool enabled) { mShadowsEnabled = enabled; }
587 
589  bool getShadowsEnabled(void) const { return mShadowsEnabled; }
590 
595  {
596  mSplitPassesByLightingType = split;
597  PriorityMap::iterator i, iend;
598  iend = mPriorityGroups.end();
599  for (i = mPriorityGroups.begin(); i != iend; ++i)
600  {
601  i->second->setSplitPassesByLightingType(split);
602  }
603  }
608  void setSplitNoShadowPasses(bool split)
609  {
610  mSplitNoShadowPasses = split;
611  PriorityMap::iterator i, iend;
612  iend = mPriorityGroups.end();
613  for (i = mPriorityGroups.begin(); i != iend; ++i)
614  {
615  i->second->setSplitNoShadowPasses(split);
616  }
617  }
622  {
623  mShadowCastersNotReceivers = ind;
624  PriorityMap::iterator i, iend;
625  iend = mPriorityGroups.end();
626  for (i = mPriorityGroups.begin(); i != iend; ++i)
627  {
628  i->second->setShadowCastersCannotBeReceivers(ind);
629  }
630  }
638  {
639  mOrganisationMode = 0;
640 
641  PriorityMap::iterator i, iend;
642  iend = mPriorityGroups.end();
643  for (i = mPriorityGroups.begin(); i != iend; ++i)
644  {
645  i->second->resetOrganisationModes();
646  }
647  }
648 
656  {
657  mOrganisationMode |= om;
658 
659  PriorityMap::iterator i, iend;
660  iend = mPriorityGroups.end();
661  for (i = mPriorityGroups.begin(); i != iend; ++i)
662  {
663  i->second->addOrganisationMode(om);
664  }
665  }
666 
674  {
675  mOrganisationMode = 0;
676 
677  PriorityMap::iterator i, iend;
678  iend = mPriorityGroups.end();
679  for (i = mPriorityGroups.begin(); i != iend; ++i)
680  {
681  i->second->defaultOrganisationMode();
682  }
683  }
684 
687  void merge( const RenderQueueGroup* rhs )
688  {
690 
691  while( it.hasMoreElements() )
692  {
693  ushort priority = it.peekNextKey();
694  RenderPriorityGroup* pSrcPriorityGrp = it.getNext();
695  RenderPriorityGroup* pDstPriorityGrp;
696 
697  // Check if priority group is there
698  PriorityMap::iterator i = mPriorityGroups.find(priority);
699  if (i == mPriorityGroups.end())
700  {
701  // Missing, create
702  pDstPriorityGrp = OGRE_NEW RenderPriorityGroup(this,
703  mSplitPassesByLightingType,
704  mSplitNoShadowPasses,
705  mShadowCastersNotReceivers);
706  if (mOrganisationMode)
707  {
708  pDstPriorityGrp->resetOrganisationModes();
709  pDstPriorityGrp->addOrganisationMode((QueuedRenderableCollection::OrganisationMode)mOrganisationMode);
710  }
711 
712  mPriorityGroups.insert(PriorityMap::value_type(priority, pDstPriorityGrp));
713  }
714  else
715  {
716  pDstPriorityGrp = i->second;
717  }
718 
719  // merge
720  pDstPriorityGrp->merge( pSrcPriorityGrp );
721  }
722  }
723  };
724 
729 }
730 
731 #endif
732 
733 
void merge(const RenderPriorityGroup *rhs)
Merge group of renderables.
void addRenderable(Renderable *pRend, Technique *pTech, ushort priority)
Add a renderable to this group, with the given priority.
Abstract class defining the interface all renderable objects must implement.
static RadixSort< RenderablePassList, RenderablePass, float > msRadixSorter2
Radix sorter for sort value 2 (distance)
Class defining a single pass of a Technique (of a Material), i.e.
Definition: OgrePass.h:80
void resetOrganisationModes(void)
Reset the organisation modes required for the solids in this group.
#define _OgreExport
Definition: OgrePlatform.h:257
void setSplitPassesByLightingType(bool split)
Sets whether or not the queue will split passes by their lighting type, ie ambient, per-light and decal.
bool hasMoreElements() const
Returns true if there are more items in the collection.
ValueType getNext()
Returns the next(=current) value element in the collection, and advances to the next.
void setSplitPassesByLightingType(bool split)
Sets whether or not the queue will split passes by their lighting type, ie ambient, per-light and decal.
std::vector< T, A > type
#define OGRE_DELETE
Concrete IteratorWrapper for nonconst access to the underlying key-value container.
Concrete IteratorWrapper for const access to the underlying key-value container.
QueuedRenderableCollection mTransparents
Transparent list.
void defaultOrganisationMode(void)
Setthe sorting / grouping mode for the solids in this group to the default.
float Real
Software floating point type.
KeyType peekNextKey(void) const
Returns the next(=current) key element in the collection, without advancing to the next...
const QueuedRenderableCollection & getSolidsNoShadowReceive(void) const
Get the collection of solids for which shadow receipt is disabled (only applicable when shadows are e...
Class to manage the scene object rendering queue.
PassGroupRenderableMap mGrouped
Grouped.
void addRenderable(Renderable *pRend, Technique *pTech)
Add a renderable to this group.
#define OGRE_NEW
QueuedRenderableCollection mSolidsNoShadowReceive
Solid pass list, used when shadows are enabled but shadow receive is turned off for these passes...
void resetOrganisationModes(void)
Reset the organisation modes required for this collection.
void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om)
Add a required sorting / grouping mode for the solids in this group.
QueuedRenderableCollection mTransparentsUnsorted
Unsorted transparent list.
bool mShadowsEnabled
Whether shadows are enabled for this queue.
void setSplitNoShadowPasses(bool split)
Sets whether or not the queue will split passes which have shadow receive turned off (in their paren...
map< Pass *, RenderableList *, PassGroupLess >::type PassGroupRenderableMap
Map of pass to renderable lists, this is a grouping by pass.
void setShadowCastersCannotBeReceivers(bool ind)
Sets whether or not objects which cast shadows should be treated as never receiving shadows...
void resetOrganisationModes(void)
Reset the organisation modes required for the solids in this group.
bool _OgreExport operator()(const Pass *a, const Pass *b) const
const QueuedRenderableCollection & getTransparents(void) const
Get the collection of transparent objects currently queued.
RenderablePass(Renderable *rend, Pass *p)
uint8 mOrganisationMode
Bitmask of the organisation modes requested.
Lowest level collection of renderables.
bool _OgreExport operator()(const RenderablePass &a, const RenderablePass &b) const
A grouping level underneath RenderQueue which groups renderables to be issued at coarsely the same t...
void setShadowsEnabled(bool enabled)
Indicate whether a given queue group will be doing any shadow setup.
ConstPriorityMapIterator getIterator(void) const
Get a const iterator for browsing through child contents.
Functor for accessing sort value 1 for radix sort (Pass)
unsigned char uint8
Definition: OgrePlatform.h:361
Collection of renderables by priority.
uint32 getHash(void) const
Gets the &#39;hash&#39; of this pass, ie a precomputed number to use for sorting.
Definition: OgrePass.h:1500
Renderable * renderable
Pointer to the Renderable details.
RenderablePassList mSortedDescending
Sorted descending (can iterate backwards to get ascending)
bool getShadowsEnabled(void) const
Are shadows enabled for this queue?
Pass * pass
Pointer to the Pass.
virtual Real getSquaredViewDepth(const Camera *cam) const =0
Returns the camera-relative squared depth of this renderable.
void merge(const RenderQueueGroup *rhs)
Merge group of renderables.
Comparator to order objects by descending camera distance.
void setSplitNoShadowPasses(bool split)
Sets whether or not passes which have shadow receive disabled should be separated.
QueuedRenderableCollection mSolidsDiffuseSpecular
Solid per-light pass list, used with additive shadows.
A viewpoint from which the scene will be rendered.
Definition: OgreCamera.h:86
void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om)
Add a required sorting / grouping mode for the solids in this group.
Class for performing a radix sort (fast comparison-less sort based on byte value) on various standard...
Definition: OgreRadixSort.h:88
map< ushort, RenderPriorityGroup *, std::less< ushort > >::type PriorityMap
MapIterator< PriorityMap > PriorityMapIterator
unsigned int uint32
Definition: OgrePlatform.h:359
void clear(bool destroy=false)
Clears this group of renderables.
QueuedRenderableCollection mSolidsBasic
Solid pass list, used when no shadows, modulative shadows, or ambient passes for additive.
uint8 mOrganisationMode
Bitmask of the organisation modes requested (for new priority groups)
Struct associating a single Pass with a single Renderable.
const QueuedRenderableCollection & getSolidsBasic(void) const
Get the collection of basic solids currently queued, this includes all solids when there are no shado...
vector< RenderablePass >::type RenderablePassList
Vector of RenderablePass objects, this is built on the assumption that vectors only ever increase in ...
const QueuedRenderableCollection & getSolidsDecal(void) const
Get the collection of solids currently queued for decal passes (only applicable in additive shadow mo...
Class representing an approach to rendering this particular Material.
Definition: OgreTechnique.h:53
const QueuedRenderableCollection & getSolidsDiffuseSpecular(void) const
Get the collection of solids currently queued per light (only applicable in additive shadow modes)...
const QueuedRenderableCollection & getTransparentsUnsorted(void) const
Get the collection of transparent objects currently queued.
Functor for descending sort value 2 for radix sort (distance)
unsigned short ushort
ConstMapIterator< PriorityMap > ConstPriorityMapIterator
void setShadowCastersCannotBeReceivers(bool ind)
Sets whether or not objects which cast shadows should be treated as never receiving shadows...
static RadixSort< RenderablePassList, RenderablePass, uint32 > msRadixSorter1
Radix sorter for accessing sort value 1 (Pass)
void addOrganisationMode(OrganisationMode om)
Add a required sorting / grouping mode to this collection when next used.
Visitor interface for items in a QueuedRenderableCollection.
RenderQueueGroup * mParent
Parent queue group.
PriorityMapIterator getIterator(void)
Get an iterator for browsing through child contents.
static bool RealEqual(Real a, Real b, Real tolerance=std::numeric_limits< Real >::epsilon())
Compare 2 reals, using tolerance for inaccuracies.
PriorityMap mPriorityGroups
Map of RenderPriorityGroup objects.
QueuedRenderableCollection mSolidsDecal
Solid decal (texture) pass list, used with additive shadows.
OrganisationMode
Organisation modes required for this collection.
Superclass for all objects that wish to use custom memory allocators when their new / delete operator...
RenderQueueGroup(RenderQueue *parent, bool splitPassesByLightingType, bool splitNoShadowPasses, bool shadowCastersNotReceivers)

Copyright © 2012 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Last modified Fri Dec 20 2013 01:24:17