OGRE  1.9
Object-Oriented Graphics Rendering Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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-2014 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 
const QueuedRenderableCollection & getSolidsNoShadowReceive(void) const
Get the collection of solids for which shadow receipt is disabled (only applicable when shadows are e...
QueuedRenderableCollection mSolidsNoShadowReceive
Solid pass list, used when shadows are enabled but shadow receive is turned off for these passes...
Functor for accessing sort value 1 for radix sort (Pass)
unsigned char uint8
Definition: OgrePlatform.h:346
A viewpoint from which the scene will be rendered.
Definition: OgreCamera.h:86
void merge(const RenderQueueGroup *rhs)
Merge group of renderables.
void setSplitNoShadowPasses(bool split)
Sets whether or not the queue will split passes which have shadow receive turned off (in their parent...
float Real
Software floating point type.
QueuedRenderableCollection mSolidsDecal
Solid decal (texture) pass list, used with additive shadows.
unsigned int uint32
Definition: OgrePlatform.h:344
RenderablePassList mSortedDescending
Sorted descending (can iterate backwards to get ascending)
#define _OgreExport
Definition: OgrePlatform.h:260
Struct associating a single Pass with a single Renderable.
std::vector< T, A > type
Class for performing a radix sort (fast comparison-less sort based on byte value) on various standard...
Definition: OgreRadixSort.h:88
RenderQueueGroup(RenderQueue *parent, bool splitPassesByLightingType, bool splitNoShadowPasses, bool shadowCastersNotReceivers)
Comparator to order objects by descending camera distance.
A grouping level underneath RenderQueue which groups renderables to be issued at coarsely the same ti...
void resetOrganisationModes(void)
Reset the organisation modes required for the solids in this group.
void addOrganisationMode(OrganisationMode om)
Add a required sorting / grouping mode to this collection when next used.
Collection of renderables by priority.
static RadixSort< RenderablePassList, RenderablePass, uint32 > msRadixSorter1
Radix sorter for accessing sort value 1 (Pass)
map< Pass *, RenderableList *, PassGroupLess >::type PassGroupRenderableMap
Map of pass to renderable lists, this is a grouping by pass.
ConstMapIterator< PriorityMap > ConstPriorityMapIterator
const QueuedRenderableCollection & getTransparentsUnsorted(void) const
Get the collection of transparent objects currently queued.
void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om)
Add a required sorting / grouping mode for the solids in this group.
OrganisationMode
Organisation modes required for this collection.
Class representing an approach to rendering this particular Material.
Definition: OgreTechnique.h:53
QueuedRenderableCollection mTransparents
Transparent list.
void resetOrganisationModes(void)
Reset the organisation modes required for the solids in this group.
RenderQueueGroup * mParent
Parent queue group.
void resetOrganisationModes(void)
Reset the organisation modes required for this collection.
Class defining a single pass of a Technique (of a Material), i.e.
Definition: OgrePass.h:80
static bool RealEqual(Real a, Real b, Real tolerance=std::numeric_limits< Real >::epsilon())
Compare 2 reals, using tolerance for inaccuracies.
Abstract class defining the interface all renderable objects must implement.
void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om)
Add a required sorting / grouping mode for the solids in this group.
Concrete IteratorWrapper for nonconst access to the underlying key-value container.
bool hasMoreElements() const
Returns true if there are more items in the collection.
void setShadowsEnabled(bool enabled)
Indicate whether a given queue group will be doing any shadow setup.
bool getShadowsEnabled(void) const
Are shadows enabled for this queue?
Lowest level collection of renderables.
void defaultOrganisationMode(void)
Setthe sorting / grouping mode for the solids in this group to the default.
const QueuedRenderableCollection & getSolidsBasic(void) const
Get the collection of basic solids currently queued, this includes all solids when there are no shado...
Functor for descending sort value 2 for radix sort (distance)
const QueuedRenderableCollection & getSolidsDiffuseSpecular(void) const
Get the collection of solids currently queued per light (only applicable in additive shadow modes)...
uint8 mOrganisationMode
Bitmask of the organisation modes requested (for new priority groups)
vector< RenderablePass >::type RenderablePassList
Vector of RenderablePass objects, this is built on the assumption that vectors only ever increase in ...
RenderablePass(Renderable *rend, Pass *p)
bool mShadowsEnabled
Whether shadows are enabled for this queue.
void addRenderable(Renderable *pRend, Technique *pTech, ushort priority)
Add a renderable to this group, with the given priority.
void setShadowCastersCannotBeReceivers(bool ind)
Sets whether or not objects which cast shadows should be treated as never receiving shadows...
KeyType peekNextKey(void) const
Returns the next(=current) key element in the collection, without advancing to the next...
Superclass for all objects that wish to use custom memory allocators when their new / delete operator...
uint8 mOrganisationMode
Bitmask of the organisation modes requested.
QueuedRenderableCollection mSolidsBasic
Solid pass list, used when no shadows, modulative shadows, or ambient passes for additive.
PassGroupRenderableMap mGrouped
Grouped.
#define OGRE_DELETE
Visitor interface for items in a QueuedRenderableCollection.
ConstPriorityMapIterator getIterator(void) const
Get a const iterator for browsing through child contents.
uint32 getHash(void) const
Gets the 'hash' of this pass, ie a precomputed number to use for sorting.
Definition: OgrePass.h:1500
unsigned short ushort
void clear(bool destroy=false)
Clears this group of renderables.
void setShadowCastersCannotBeReceivers(bool ind)
Sets whether or not objects which cast shadows should be treated as never receiving shadows...
static RadixSort< RenderablePassList, RenderablePass, float > msRadixSorter2
Radix sorter for sort value 2 (distance)
QueuedRenderableCollection mTransparentsUnsorted
Unsorted transparent list.
void setSplitPassesByLightingType(bool split)
Sets whether or not the queue will split passes by their lighting type, ie ambient, per-light and decal.
void addRenderable(Renderable *pRend, Technique *pTech)
Add a renderable to this group.
void setSplitPassesByLightingType(bool split)
Sets whether or not the queue will split passes by their lighting type, ie ambient, per-light and decal.
PriorityMap mPriorityGroups
Map of RenderPriorityGroup objects.
#define OGRE_NEW
void merge(const RenderPriorityGroup *rhs)
Merge group of renderables.
Class to manage the scene object rendering queue.
Concrete IteratorWrapper for const access to the underlying key-value container.
const QueuedRenderableCollection & getTransparents(void) const
Get the collection of transparent objects currently queued.
void setSplitNoShadowPasses(bool split)
Sets whether or not passes which have shadow receive disabled should be separated.
MapIterator< PriorityMap > PriorityMapIterator
ValueType getNext()
Returns the next(=current) value element in the collection, and advances to the next.
Pass * pass
Pointer to the Pass.
QueuedRenderableCollection mSolidsDiffuseSpecular
Solid per-light pass list, used with additive shadows.
virtual Real getSquaredViewDepth(const Camera *cam) const =0
Returns the camera-relative squared depth of this renderable.
bool _OgreExport operator()(const Pass *a, const Pass *b) const
bool _OgreExport operator()(const RenderablePass &a, const RenderablePass &b) const
map< ushort, RenderPriorityGroup *, std::less< ushort > >::type PriorityMap
PriorityMapIterator getIterator(void)
Get an iterator for browsing through child contents.
const QueuedRenderableCollection & getSolidsDecal(void) const
Get the collection of solids currently queued for decal passes (only applicable in additive shadow mo...
Renderable * renderable
Pointer to the Renderable details.