OGRE  1.9.0
OgreRenderQueueSortingGrouping.h
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2014 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26-----------------------------------------------------------------------------
27*/
28#ifndef __RenderQueueSortingGrouping_H__
29#define __RenderQueueSortingGrouping_H__
30
31// Precompiler options
32#include "OgrePrerequisites.h"
34#include "OgreMaterial.h"
35#include "OgreTechnique.h"
36#include "OgrePass.h"
37#include "OgreRadixSort.h"
38
39namespace 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 {
160
162 : camera(cam)
163 {
164 }
165
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 {
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
248
249 public:
252
254 void clear(void);
255
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
298
302 };
303
324 {
325 protected:
326
344
347
349 void addSolidRenderable(Technique* pTech, Renderable* rend, bool toNoShadowMap);
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
398
406
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();
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
#define _OgreExport
Superclass for all objects that wish to use custom memory allocators when their new / delete operator...
A viewpoint from which the scene will be rendered.
Definition OgreCamera.h:87
Concrete IteratorWrapper for const access to the underlying key-value container.
bool hasMoreElements() const
Returns true if there are more items in the collection.
KeyType peekNextKey(void) const
Returns the next(=current) key element in the collection, without advancing to the next.
ValueType getNext()
Returns the next(=current) value element in the collection, and advances to the next.
Concrete IteratorWrapper for nonconst access to the underlying key-value container.
Class defining a single pass of a Technique (of a Material), i.e.
Definition OgrePass.h:81
uint32 getHash(void) const
Gets the 'hash' of this pass, ie a precomputed number to use for sorting.
Definition OgrePass.h:1500
Lowest level collection of renderables.
void addOrganisationMode(OrganisationMode om)
Add a required sorting / grouping mode to this collection when next used.
void acceptVisitorDescending(QueuedRenderableVisitor *visitor) const
Internal visitor implementation.
void acceptVisitorAscending(QueuedRenderableVisitor *visitor) const
Internal visitor implementation.
static RadixSort< RenderablePassList, RenderablePass, uint32 > msRadixSorter1
Radix sorter for accessing sort value 1 (Pass)
void acceptVisitorGrouped(QueuedRenderableVisitor *visitor) const
Internal visitor implementation.
void merge(const QueuedRenderableCollection &rhs)
Merge renderable collection.
vector< RenderablePass >::type RenderablePassList
Vector of RenderablePass objects, this is built on the assumption that vectors only ever increase in ...
void addRenderable(Pass *pass, Renderable *rend)
Add a renderable to the collection using a given pass.
OrganisationMode
Organisation modes required for this collection.
RenderablePassList mSortedDescending
Sorted descending (can iterate backwards to get ascending)
void removePassGroup(Pass *p)
Remove the group entry (if any) for a given Pass.
static RadixSort< RenderablePassList, RenderablePass, float > msRadixSorter2
Radix sorter for sort value 2 (distance)
map< Pass *, RenderableList *, PassGroupLess >::type PassGroupRenderableMap
Map of pass to renderable lists, this is a grouping by pass.
void clear(void)
Empty the collection.
uint8 mOrganisationMode
Bitmask of the organisation modes requested.
void acceptVisitor(QueuedRenderableVisitor *visitor, OrganisationMode om) const
Accept a visitor over the collection contents.
void sort(const Camera *cam)
Perform any sorting that is required on this collection.
void resetOrganisationModes(void)
Reset the organisation modes required for this collection.
Visitor interface for items in a QueuedRenderableCollection.
virtual void visit(Renderable *r)=0
Visit method called once per Renderable on a grouped collection.
virtual void visit(RenderablePass *rp)=0
Called when visiting a RenderablePass, i.e.
virtual bool visit(const Pass *p)=0
Class for performing a radix sort (fast comparison-less sort based on byte value) on various standard...
Collection of renderables by priority.
void setSplitPassesByLightingType(bool split)
Sets whether or not the queue will split passes by their lighting type, ie ambient,...
void addSolidRenderable(Technique *pTech, Renderable *rend, bool toNoShadowMap)
Internal method for adding a solid renderable.
void sort(const Camera *cam)
Sorts the objects which have been added to the queue; transparent objects by their depth in relation ...
const QueuedRenderableCollection & getSolidsNoShadowReceive(void) const
Get the collection of solids for which shadow receipt is disabled (only applicable when shadows are e...
const QueuedRenderableCollection & getSolidsDiffuseSpecular(void) const
Get the collection of solids currently queued per light (only applicable in additive shadow modes).
const QueuedRenderableCollection & getSolidsBasic(void) const
Get the collection of basic solids currently queued, this includes all solids when there are no shado...
QueuedRenderableCollection mSolidsDiffuseSpecular
Solid per-light pass list, used with additive shadows.
QueuedRenderableCollection mTransparentsUnsorted
Unsorted transparent list.
RenderPriorityGroup(RenderQueueGroup *parent, bool splitPassesByLightingType, bool splitNoShadowPasses, bool shadowCastersNotReceivers)
const QueuedRenderableCollection & getTransparentsUnsorted(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.
void addUnsortedTransparentRenderable(Technique *pTech, Renderable *rend)
Internal method for adding an unsorted transparent renderable.
const QueuedRenderableCollection & getTransparents(void) const
Get the collection of transparent objects currently queued.
void addTransparentRenderable(Technique *pTech, Renderable *rend)
Internal method for adding a transparent renderable.
void defaultOrganisationMode(void)
Set the sorting / grouping mode for the solids in this group to the default.
void addRenderable(Renderable *pRend, Technique *pTech)
Add a renderable to this group.
QueuedRenderableCollection mSolidsBasic
Solid pass list, used when no shadows, modulative shadows, or ambient passes for additive.
const QueuedRenderableCollection & getSolidsDecal(void) const
Get the collection of solids currently queued for decal passes (only applicable in additive shadow mo...
QueuedRenderableCollection mTransparents
Transparent list.
void setShadowCastersCannotBeReceivers(bool ind)
Sets whether or not objects which cast shadows should be treated as never receiving shadows.
void clear(void)
Clears this group of renderables.
void addSolidRenderableSplitByLightType(Technique *pTech, Renderable *rend)
Internal method for adding a solid renderable.
QueuedRenderableCollection mSolidsNoShadowReceive
Solid pass list, used when shadows are enabled but shadow receive is turned off for these passes.
void merge(const RenderPriorityGroup *rhs)
Merge group of renderables.
void removePassEntry(Pass *p)
remove a pass entry from all collections
void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om)
Add a required sorting / grouping mode for the solids in this group.
QueuedRenderableCollection mSolidsDecal
Solid decal (texture) pass list, used with additive shadows.
RenderQueueGroup * mParent
Parent queue group.
void resetOrganisationModes(void)
Reset the organisation modes required for the solids in this group.
A grouping level underneath RenderQueue which groups renderables to be issued at coarsely the same ti...
void addRenderable(Renderable *pRend, Technique *pTech, ushort priority)
Add a renderable to this group, with the given priority.
void defaultOrganisationMode(void)
Setthe sorting / grouping mode for the solids in this group to the default.
void setShadowsEnabled(bool enabled)
Indicate whether a given queue group will be doing any shadow setup.
void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om)
Add a required sorting / grouping mode for the solids in this group.
ConstMapIterator< PriorityMap > ConstPriorityMapIterator
MapIterator< PriorityMap > PriorityMapIterator
void merge(const RenderQueueGroup *rhs)
Merge group of renderables.
void resetOrganisationModes(void)
Reset the organisation modes required for the solids in this group.
ConstPriorityMapIterator getIterator(void) const
Get a const iterator for browsing through child contents.
map< ushort, RenderPriorityGroup *, std::less< ushort > >::type PriorityMap
void setShadowCastersCannotBeReceivers(bool ind)
Sets whether or not objects which cast shadows should be treated as never receiving shadows.
bool mShadowsEnabled
Whether shadows are enabled for this queue.
PriorityMap mPriorityGroups
Map of RenderPriorityGroup objects.
PriorityMapIterator getIterator(void)
Get an iterator for browsing through child contents.
uint8 mOrganisationMode
Bitmask of the organisation modes requested (for new priority groups)
void setSplitNoShadowPasses(bool split)
Sets whether or not the queue will split passes which have shadow receive turned off (in their parent...
RenderQueueGroup(RenderQueue *parent, bool splitPassesByLightingType, bool splitNoShadowPasses, bool shadowCastersNotReceivers)
void setSplitPassesByLightingType(bool split)
Sets whether or not the queue will split passes by their lighting type, ie ambient,...
bool getShadowsEnabled(void) const
Are shadows enabled for this queue?
void clear(bool destroy=false)
Clears this group of renderables.
Class to manage the scene object rendering queue.
Abstract class defining the interface all renderable objects must implement.
virtual Real getSquaredViewDepth(const Camera *cam) const =0
Returns the camera-relative squared depth of this renderable.
Class representing an approach to rendering this particular Material.
#define OGRE_NEW
#define OGRE_DELETE
unsigned char uint8
float Real
Software floating point type.
unsigned int uint32
unsigned short ushort
Comparator to order objects by descending camera distance.
bool _OgreExport operator()(const RenderablePass &a, const RenderablePass &b) const
bool _OgreExport operator()(const Pass *a, const Pass *b) const
Functor for descending sort value 2 for radix sort (distance)
Functor for accessing sort value 1 for radix sort (Pass)
Struct associating a single Pass with a single Renderable.
Renderable * renderable
Pointer to the Renderable details.
RenderablePass(Renderable *rend, Pass *p)
Pass * pass
Pointer to the Pass.
std::map< K, V, P, A > type
std::vector< T, A > type