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-2005 The OGRE Team
|
---|
8 | Also see acknowledgements in Readme.html
|
---|
9 |
|
---|
10 | This program is free software; you can redistribute it and/or modify it under
|
---|
11 | the terms of the GNU Lesser General Public License as published by the Free Software
|
---|
12 | Foundation; either version 2 of the License, or (at your option) any later
|
---|
13 | version.
|
---|
14 |
|
---|
15 | This program is distributed in the hope that it will be useful, but WITHOUT
|
---|
16 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
---|
17 | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
|
---|
18 |
|
---|
19 | You should have received a copy of the GNU Lesser General Public License along with
|
---|
20 | this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
---|
21 | Place - Suite 330, Boston, MA 02111-1307, USA, or go to
|
---|
22 | http://www.gnu.org/copyleft/lesser.txt.
|
---|
23 | -----------------------------------------------------------------------------
|
---|
24 | */
|
---|
25 | #ifndef __RenderQueueSortingGrouping_H__
|
---|
26 | #define __RenderQueueSortingGrouping_H__
|
---|
27 |
|
---|
28 | // Precompiler options
|
---|
29 | #include "OgrePrerequisites.h"
|
---|
30 | #include "OgreIteratorWrappers.h"
|
---|
31 | #include "OgreMaterial.h"
|
---|
32 | #include "OgreTechnique.h"
|
---|
33 | #include "OgrePass.h"
|
---|
34 | #include "OgreRadixSort.h"
|
---|
35 |
|
---|
36 | namespace Ogre {
|
---|
37 |
|
---|
38 | /** Struct associating a single Pass with a single Renderable.
|
---|
39 | This is used to for objects sorted by depth and thus not
|
---|
40 | grouped by pass.
|
---|
41 | */
|
---|
42 | struct RenderablePass
|
---|
43 | {
|
---|
44 | /// Pointer to the Renderable details
|
---|
45 | Renderable* renderable;
|
---|
46 | /// Pointer to the Pass
|
---|
47 | Pass* pass;
|
---|
48 |
|
---|
49 | RenderablePass(Renderable* rend, Pass* p) :renderable(rend), pass(p) {}
|
---|
50 | };
|
---|
51 |
|
---|
52 |
|
---|
53 | /** Visitor interface for items in a QueuedRenderableCollection.
|
---|
54 | @remarks
|
---|
55 | Those wishing to iterate over the items in a
|
---|
56 | QueuedRenderableCollection should implement this visitor pattern,
|
---|
57 | since internal organisation of the collection depends on the
|
---|
58 | sorting method in use.
|
---|
59 | */
|
---|
60 | class _OgreExport QueuedRenderableVisitor
|
---|
61 | {
|
---|
62 | public:
|
---|
63 | QueuedRenderableVisitor() {}
|
---|
64 | virtual ~QueuedRenderableVisitor() {}
|
---|
65 |
|
---|
66 | /** Called when visiting a RenderablePass, ie items in a
|
---|
67 | sorted collection where items are not grouped by pass.
|
---|
68 | @remarks
|
---|
69 | If this is called, neither of the other 2 visit methods
|
---|
70 | will be called.
|
---|
71 | */
|
---|
72 | virtual void visit(const RenderablePass* rp) = 0;
|
---|
73 |
|
---|
74 | /* When visiting a collection grouped by pass, this is
|
---|
75 | called when the grouping pass changes.
|
---|
76 | @remarks
|
---|
77 | If this method is called, the RenderablePass visit
|
---|
78 | method will not be called for this collection. The
|
---|
79 | Renderable visit method will be called for each item
|
---|
80 | underneath the pass grouping level.
|
---|
81 | @returns True to continue, false to skip the Renderables underneath
|
---|
82 | */
|
---|
83 | virtual bool visit(const Pass* p) = 0;
|
---|
84 | /** Visit method called once per Renderable on a grouped
|
---|
85 | collection.
|
---|
86 | @remarks
|
---|
87 | If this method is called, the RenderablePass visit
|
---|
88 | method will not be called for this collection.
|
---|
89 | */
|
---|
90 | virtual void visit(const Renderable* r) = 0;
|
---|
91 |
|
---|
92 |
|
---|
93 | };
|
---|
94 |
|
---|
95 | /** Lowest level collection of renderables.
|
---|
96 | @remarks
|
---|
97 | To iterate over items in this collection, you must call
|
---|
98 | the accept method and supply a QueuedRenderableVisitor.
|
---|
99 | The order of the iteration, and whether that iteration is
|
---|
100 | over a RenderablePass list or a 2-level grouped list which
|
---|
101 | causes a visit call at the Pass level, and a call for each
|
---|
102 | Renderable underneath.
|
---|
103 | */
|
---|
104 | class _OgreExport QueuedRenderableCollection
|
---|
105 | {
|
---|
106 | public:
|
---|
107 | /** Organisation modes required for this collection.
|
---|
108 | @remarks
|
---|
109 | This affects the internal placement of the items added to this collection;
|
---|
110 | if only one type of sorting / grouping is to be required, then renderables
|
---|
111 | can be stored only once, whilst if multiple types are going to be needed
|
---|
112 | then internally there will be multiple organisations. Changing the organisation
|
---|
113 | needs to be done when the collection is empty.
|
---|
114 | */
|
---|
115 | enum OrganisationMode
|
---|
116 | {
|
---|
117 | /// Group by pass
|
---|
118 | OM_PASS_GROUP = 1,
|
---|
119 | /// Sort descending camera distance
|
---|
120 | OM_SORT_DESCENDING = 2,
|
---|
121 | /** Sort ascending camera distance
|
---|
122 | Note value overlaps with descending since both use same sort
|
---|
123 | */
|
---|
124 | OM_SORT_ASCENDING = 6
|
---|
125 | };
|
---|
126 |
|
---|
127 | protected:
|
---|
128 | /// Comparator to order pass groups
|
---|
129 | struct PassGroupLess
|
---|
130 | {
|
---|
131 | bool _OgreExport operator()(const Pass* a, const Pass* b) const
|
---|
132 | {
|
---|
133 | // Sort by passHash, which is pass, then texture unit changes
|
---|
134 | uint32 hasha = a->getHash();
|
---|
135 | uint32 hashb = b->getHash();
|
---|
136 | if (hasha == hashb)
|
---|
137 | {
|
---|
138 | // Must differentTransparentQueueItemLessiate by pointer incase 2 passes end up with the same hash
|
---|
139 | return a < b;
|
---|
140 | }
|
---|
141 | else
|
---|
142 | {
|
---|
143 | return hasha < hashb;
|
---|
144 | }
|
---|
145 | }
|
---|
146 | };
|
---|
147 | /// Comparator to order objects by descending camera distance
|
---|
148 | struct DepthSortDescendingLess
|
---|
149 | {
|
---|
150 | const Camera* camera;
|
---|
151 |
|
---|
152 | DepthSortDescendingLess(const Camera* cam)
|
---|
153 | : camera(cam)
|
---|
154 | {
|
---|
155 | }
|
---|
156 |
|
---|
157 | bool _OgreExport operator()(const RenderablePass& a, const RenderablePass& b) const
|
---|
158 | {
|
---|
159 | if (a.renderable == b.renderable)
|
---|
160 | {
|
---|
161 | // Same renderable, sort by pass hash
|
---|
162 | return a.pass->getHash() < b.pass->getHash();
|
---|
163 | }
|
---|
164 | else
|
---|
165 | {
|
---|
166 | // Different renderables, sort by depth
|
---|
167 | Real adepth = a.renderable->getSquaredViewDepth(camera);
|
---|
168 | Real bdepth = b.renderable->getSquaredViewDepth(camera);
|
---|
169 | if (adepth == bdepth)
|
---|
170 | {
|
---|
171 | // Must return deterministic result, doesn't matter what
|
---|
172 | return a.pass < b.pass;
|
---|
173 | }
|
---|
174 | else
|
---|
175 | {
|
---|
176 | // Sort DESCENDING by depth (ie far objects first)
|
---|
177 | return (adepth > bdepth);
|
---|
178 | }
|
---|
179 | }
|
---|
180 |
|
---|
181 | }
|
---|
182 | };
|
---|
183 |
|
---|
184 | /** Vector of RenderablePass objects, this is built on the assumption that
|
---|
185 | vectors only ever increase in size, so even if we do clear() the memory stays
|
---|
186 | allocated, ie fast */
|
---|
187 | typedef std::vector<RenderablePass> RenderablePassList;
|
---|
188 | typedef std::vector<Renderable*> RenderableList;
|
---|
189 | /** Map of pass to renderable lists, this is a grouping by pass. */
|
---|
190 | typedef std::map<Pass*, RenderableList*, PassGroupLess> PassGroupRenderableMap;
|
---|
191 |
|
---|
192 | /// Functor for accessing sort value 1 for radix sort (Pass)
|
---|
193 | struct RadixSortFunctorPass
|
---|
194 | {
|
---|
195 | uint32 operator()(const RenderablePass& p) const
|
---|
196 | {
|
---|
197 | return p.pass->getHash();
|
---|
198 | }
|
---|
199 | };
|
---|
200 |
|
---|
201 | /// Radix sorter for accessing sort value 1 (Pass)
|
---|
202 | static RadixSort<RenderablePassList, RenderablePass, uint32> msRadixSorter1;
|
---|
203 |
|
---|
204 | /// Functor for descending sort value 2 for radix sort (distance)
|
---|
205 | struct RadixSortFunctorDistance
|
---|
206 | {
|
---|
207 | const Camera* camera;
|
---|
208 |
|
---|
209 | RadixSortFunctorDistance(const Camera* cam)
|
---|
210 | : camera(cam)
|
---|
211 | {
|
---|
212 | }
|
---|
213 |
|
---|
214 | float operator()(const RenderablePass& p) const
|
---|
215 | {
|
---|
216 | // Sort DESCENDING by depth (ie far objects first), use negative distance
|
---|
217 | // here because radix sorter always dealing with accessing sort
|
---|
218 | return static_cast<float>(- p.renderable->getSquaredViewDepth(camera));
|
---|
219 | }
|
---|
220 | };
|
---|
221 |
|
---|
222 | /// Radix sorter for sort value 2 (distance)
|
---|
223 | static RadixSort<RenderablePassList, RenderablePass, float> msRadixSorter2;
|
---|
224 |
|
---|
225 | /// Bitmask of the organisation modes requested
|
---|
226 | uint8 mOrganisationMode;
|
---|
227 |
|
---|
228 | /// Grouped
|
---|
229 | PassGroupRenderableMap mGrouped;
|
---|
230 | /// Sorted descending (can iterate backwards to get ascending)
|
---|
231 | RenderablePassList mSortedDescending;
|
---|
232 |
|
---|
233 | /// Internal visitor implementation
|
---|
234 | void acceptVisitorGrouped(QueuedRenderableVisitor* visitor) const;
|
---|
235 | /// Internal visitor implementation
|
---|
236 | void acceptVisitorDescending(QueuedRenderableVisitor* visitor) const;
|
---|
237 | /// Internal visitor implementation
|
---|
238 | void acceptVisitorAscending(QueuedRenderableVisitor* visitor) const;
|
---|
239 |
|
---|
240 | public:
|
---|
241 | QueuedRenderableCollection();
|
---|
242 | ~QueuedRenderableCollection();
|
---|
243 |
|
---|
244 | /// Empty the collection
|
---|
245 | void clear(void);
|
---|
246 |
|
---|
247 | /** Remove the group entry (if any) for a given Pass.
|
---|
248 | @remarks
|
---|
249 | To be used when a pass is destroyed, such that any
|
---|
250 | grouping level for it becomes useless.
|
---|
251 | */
|
---|
252 | void removePassGroup(Pass* p);
|
---|
253 |
|
---|
254 | /** Reset the organisation modes required for this collection.
|
---|
255 | @remarks
|
---|
256 | You can only do this when the collection is empty.
|
---|
257 | @see OrganisationMode
|
---|
258 | */
|
---|
259 | void resetOrganisationModes(void)
|
---|
260 | {
|
---|
261 | mOrganisationMode = 0;
|
---|
262 | }
|
---|
263 |
|
---|
264 | /** Add a required sorting / grouping mode to this collection when next used.
|
---|
265 | @remarks
|
---|
266 | You can only do this when the collection is empty.
|
---|
267 | @see OrganisationMode
|
---|
268 | */
|
---|
269 | void addOrganisationMode(OrganisationMode om)
|
---|
270 | {
|
---|
271 | mOrganisationMode |= om;
|
---|
272 | }
|
---|
273 |
|
---|
274 | /// Add a renderable to the collection using a given pass
|
---|
275 | void addRenderable(Pass* pass, Renderable* rend);
|
---|
276 |
|
---|
277 | /** Perform any sorting that is required on this collection.
|
---|
278 | @param cam The camera
|
---|
279 | */
|
---|
280 | void sort(const Camera* cam);
|
---|
281 |
|
---|
282 | /** Accept a visitor over the collection contents.
|
---|
283 | @param visitor Visitor class which should be called back
|
---|
284 | @param om The organisation mode which you want to iterate over.
|
---|
285 | Note that this must have been included in an addOrganisationMode
|
---|
286 | call before any renderables were added.
|
---|
287 | */
|
---|
288 | void acceptVisitor(QueuedRenderableVisitor* visitor, OrganisationMode om) const;
|
---|
289 |
|
---|
290 | };
|
---|
291 |
|
---|
292 | /** Collection of renderables by priority.
|
---|
293 | @remarks
|
---|
294 | This class simply groups renderables for rendering. All the
|
---|
295 | renderables contained in this class are destined for the same
|
---|
296 | RenderQueueGroup (coarse groupings like those between the main
|
---|
297 | scene and overlays) and have the same priority (fine groupings
|
---|
298 | for detailed overlap control).
|
---|
299 | @par
|
---|
300 | This class can order solid renderables by a number of criteria;
|
---|
301 | it can optimise them into groups based on pass to reduce render
|
---|
302 | state changes, or can sort them by ascending or descending view
|
---|
303 | depth. Transparent objects are always ordered by descending depth.
|
---|
304 | @par
|
---|
305 | To iterate over items in the collections held by this object
|
---|
306 | you should retrieve the collection in use (e.g. solids, solids with
|
---|
307 | no shadows, transparents) and use the accept() method, providing
|
---|
308 | a class implementing QueuedRenderableVisitor.
|
---|
309 |
|
---|
310 | */
|
---|
311 | class _OgreExport RenderPriorityGroup
|
---|
312 | {
|
---|
313 | protected:
|
---|
314 |
|
---|
315 | /// Parent queue group
|
---|
316 | RenderQueueGroup* mParent;
|
---|
317 | bool mSplitPassesByLightingType;
|
---|
318 | bool mSplitNoShadowPasses;
|
---|
319 | bool mShadowCastersNotReceivers;
|
---|
320 | /// Solid pass list, used when no shadows, modulative shadows, or ambient passes for additive
|
---|
321 | QueuedRenderableCollection mSolidsBasic;
|
---|
322 | /// Solid per-light pass list, used with additive shadows
|
---|
323 | QueuedRenderableCollection mSolidsDiffuseSpecular;
|
---|
324 | /// Solid decal (texture) pass list, used with additive shadows
|
---|
325 | QueuedRenderableCollection mSolidsDecal;
|
---|
326 | /// Solid pass list, used when shadows are enabled but shadow receive is turned off for these passes
|
---|
327 | QueuedRenderableCollection mSolidsNoShadowReceive;
|
---|
328 | /// Transparent list
|
---|
329 | QueuedRenderableCollection mTransparents;
|
---|
330 |
|
---|
331 | /// remove a pass entry from all collections
|
---|
332 | void removePassEntry(Pass* p);
|
---|
333 |
|
---|
334 | /// Internal method for adding a solid renderable
|
---|
335 | void addSolidRenderable(Technique* pTech, Renderable* rend, bool toNoShadowMap);
|
---|
336 | /// Internal method for adding a solid renderable
|
---|
337 | void addSolidRenderableSplitByLightType(Technique* pTech, Renderable* rend);
|
---|
338 | /// Internal method for adding a transparent renderable
|
---|
339 | void addTransparentRenderable(Technique* pTech, Renderable* rend);
|
---|
340 |
|
---|
341 | public:
|
---|
342 | RenderPriorityGroup(RenderQueueGroup* parent,
|
---|
343 | bool splitPassesByLightingType,
|
---|
344 | bool splitNoShadowPasses,
|
---|
345 | bool shadowCastersNotReceivers);
|
---|
346 |
|
---|
347 | ~RenderPriorityGroup() { }
|
---|
348 |
|
---|
349 | /** Get the collection of basic solids currently queued, this includes
|
---|
350 | all solids when there are no shadows, or all solids which have shadow
|
---|
351 | receiving enabled when using modulative shadows, or all ambient passes
|
---|
352 | of solids which have shadow receive enabled for additive shadows. */
|
---|
353 | const QueuedRenderableCollection& getSolidsBasic(void) const
|
---|
354 | { return mSolidsBasic; }
|
---|
355 | /** Get the collection of solids currently queued per light (only applicable in
|
---|
356 | additive shadow modes). */
|
---|
357 | const QueuedRenderableCollection& getSolidsDiffuseSpecular(void) const
|
---|
358 | { return mSolidsDiffuseSpecular; }
|
---|
359 | /** Get the collection of solids currently queued for decal passes (only
|
---|
360 | applicable in additive shadow modes). */
|
---|
361 | const QueuedRenderableCollection& getSolidsDecal(void) const
|
---|
362 | { return mSolidsDecal; }
|
---|
363 | /** Get the collection of solids for which shadow receipt is disabled (only
|
---|
364 | applicable when shadows are enabled). */
|
---|
365 | const QueuedRenderableCollection& getSolidsNoShadowReceive(void) const
|
---|
366 | { return mSolidsNoShadowReceive; }
|
---|
367 | /** Get the collection of transparent objects currently queued */
|
---|
368 | const QueuedRenderableCollection& getTransparents(void) const
|
---|
369 | { return mTransparents; }
|
---|
370 |
|
---|
371 |
|
---|
372 | /** Reset the organisation modes required for the solids in this group.
|
---|
373 | @remarks
|
---|
374 | You can only do this when the group is empty, ie after clearing the
|
---|
375 | queue.
|
---|
376 | @see QueuedRenderableCollection::OrganisationMode
|
---|
377 | */
|
---|
378 | void resetOrganisationModes(void);
|
---|
379 |
|
---|
380 | /** Add a required sorting / grouping mode for the solids in this group.
|
---|
381 | @remarks
|
---|
382 | You can only do this when the group is empty, ie after clearing the
|
---|
383 | queue.
|
---|
384 | @see QueuedRenderableCollection::OrganisationMode
|
---|
385 | */
|
---|
386 | void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om);
|
---|
387 |
|
---|
388 | /** Set the sorting / grouping mode for the solids in this group to the default.
|
---|
389 | @remarks
|
---|
390 | You can only do this when the group is empty, ie after clearing the
|
---|
391 | queue.
|
---|
392 | @see QueuedRenderableCollection::OrganisationMode
|
---|
393 | */
|
---|
394 | void defaultOrganisationMode(void);
|
---|
395 |
|
---|
396 | /** Add a renderable to this group. */
|
---|
397 | void addRenderable(Renderable* pRend, Technique* pTech);
|
---|
398 |
|
---|
399 | /** Sorts the objects which have been added to the queue; transparent objects by their
|
---|
400 | depth in relation to the passed in Camera. */
|
---|
401 | void sort(const Camera* cam);
|
---|
402 |
|
---|
403 | /** Clears this group of renderables.
|
---|
404 | */
|
---|
405 | void clear(void);
|
---|
406 |
|
---|
407 | /** Sets whether or not the queue will split passes by their lighting type,
|
---|
408 | ie ambient, per-light and decal.
|
---|
409 | */
|
---|
410 | void setSplitPassesByLightingType(bool split)
|
---|
411 | {
|
---|
412 | mSplitPassesByLightingType = split;
|
---|
413 | }
|
---|
414 |
|
---|
415 | /** Sets whether or not passes which have shadow receive disabled should
|
---|
416 | be separated.
|
---|
417 | */
|
---|
418 | void setSplitNoShadowPasses(bool split)
|
---|
419 | {
|
---|
420 | mSplitNoShadowPasses = split;
|
---|
421 | }
|
---|
422 |
|
---|
423 | /** Sets whether or not objects which cast shadows should be treated as
|
---|
424 | never receiving shadows.
|
---|
425 | */
|
---|
426 | void setShadowCastersCannotBeReceivers(bool ind)
|
---|
427 | {
|
---|
428 | mShadowCastersNotReceivers = ind;
|
---|
429 | }
|
---|
430 |
|
---|
431 |
|
---|
432 |
|
---|
433 | };
|
---|
434 |
|
---|
435 |
|
---|
436 | /** A grouping level underneath RenderQueue which groups renderables
|
---|
437 | to be issued at coarsely the same time to the renderer.
|
---|
438 | @remarks
|
---|
439 | Each instance of this class itself hold RenderPriorityGroup instances,
|
---|
440 | which are the groupings of renderables by priority for fine control
|
---|
441 | of ordering (not required for most instances).
|
---|
442 | */
|
---|
443 | class _OgreExport RenderQueueGroup
|
---|
444 | {
|
---|
445 | public:
|
---|
446 | typedef std::map<ushort, RenderPriorityGroup*, std::less<ushort> > PriorityMap;
|
---|
447 | typedef MapIterator<PriorityMap> PriorityMapIterator;
|
---|
448 | protected:
|
---|
449 | RenderQueue* mParent;
|
---|
450 | bool mSplitPassesByLightingType;
|
---|
451 | bool mSplitNoShadowPasses;
|
---|
452 | bool mShadowCastersNotReceivers;
|
---|
453 | /// Map of RenderPriorityGroup objects
|
---|
454 | PriorityMap mPriorityGroups;
|
---|
455 | /// Whether shadows are enabled for this queue
|
---|
456 | bool mShadowsEnabled;
|
---|
457 |
|
---|
458 |
|
---|
459 | public:
|
---|
460 | RenderQueueGroup(RenderQueue* parent,
|
---|
461 | bool splitPassesByLightingType,
|
---|
462 | bool splitNoShadowPasses,
|
---|
463 | bool shadowCastersNotReceivers)
|
---|
464 | : mParent(parent)
|
---|
465 | , mSplitPassesByLightingType(splitPassesByLightingType)
|
---|
466 | , mSplitNoShadowPasses(splitNoShadowPasses)
|
---|
467 | , mShadowCastersNotReceivers(shadowCastersNotReceivers)
|
---|
468 | , mShadowsEnabled(true)
|
---|
469 | {
|
---|
470 | }
|
---|
471 |
|
---|
472 | ~RenderQueueGroup() {
|
---|
473 | // destroy contents now
|
---|
474 | PriorityMap::iterator i;
|
---|
475 | for (i = mPriorityGroups.begin(); i != mPriorityGroups.end(); ++i)
|
---|
476 | {
|
---|
477 | delete i->second;
|
---|
478 | }
|
---|
479 | }
|
---|
480 |
|
---|
481 | /** Get an iterator for browsing through child contents. */
|
---|
482 | PriorityMapIterator getIterator(void)
|
---|
483 | {
|
---|
484 | return PriorityMapIterator(mPriorityGroups.begin(), mPriorityGroups.end());
|
---|
485 | }
|
---|
486 |
|
---|
487 | /** Add a renderable to this group, with the given priority. */
|
---|
488 | void addRenderable(Renderable* pRend, Technique* pTech, ushort priority)
|
---|
489 | {
|
---|
490 | // Check if priority group is there
|
---|
491 | PriorityMap::iterator i = mPriorityGroups.find(priority);
|
---|
492 | RenderPriorityGroup* pPriorityGrp;
|
---|
493 | if (i == mPriorityGroups.end())
|
---|
494 | {
|
---|
495 | // Missing, create
|
---|
496 | pPriorityGrp = new RenderPriorityGroup(this,
|
---|
497 | mSplitPassesByLightingType,
|
---|
498 | mSplitNoShadowPasses,
|
---|
499 | mShadowCastersNotReceivers);
|
---|
500 | mPriorityGroups.insert(PriorityMap::value_type(priority, pPriorityGrp));
|
---|
501 | }
|
---|
502 | else
|
---|
503 | {
|
---|
504 | pPriorityGrp = i->second;
|
---|
505 | }
|
---|
506 |
|
---|
507 | // Add
|
---|
508 | pPriorityGrp->addRenderable(pRend, pTech);
|
---|
509 |
|
---|
510 | }
|
---|
511 |
|
---|
512 | /** Clears this group of renderables.
|
---|
513 | @param destroy
|
---|
514 | If false, doesn't delete any priority groups, just empties them. Saves on
|
---|
515 | memory deallocations since the chances are rougly the same kinds of
|
---|
516 | renderables are going to be sent to the queue again next time. If
|
---|
517 | true, completely destroys.
|
---|
518 | */
|
---|
519 | void clear(bool destroy = false)
|
---|
520 | {
|
---|
521 | PriorityMap::iterator i, iend;
|
---|
522 | iend = mPriorityGroups.end();
|
---|
523 | for (i = mPriorityGroups.begin(); i != iend; ++i)
|
---|
524 | {
|
---|
525 | if (destroy)
|
---|
526 | delete i->second;
|
---|
527 | else
|
---|
528 | i->second->clear();
|
---|
529 | }
|
---|
530 |
|
---|
531 | if (destroy)
|
---|
532 | mPriorityGroups.clear();
|
---|
533 |
|
---|
534 | }
|
---|
535 |
|
---|
536 | /** Indicate whether a given queue group will be doing any
|
---|
537 | shadow setup.
|
---|
538 | @remarks
|
---|
539 | This method allows you to inform the queue about a queue group, and to
|
---|
540 | indicate whether this group will require shadow processing of any sort.
|
---|
541 | In order to preserve rendering order, OGRE has to treat queue groups
|
---|
542 | as very separate elements of the scene, and this can result in it
|
---|
543 | having to duplicate shadow setup for each group. Therefore, if you
|
---|
544 | know that a group which you are using will never need shadows, you
|
---|
545 | should preregister the group using this method in order to improve
|
---|
546 | the performance.
|
---|
547 | */
|
---|
548 | void setShadowsEnabled(bool enabled) { mShadowsEnabled = enabled; }
|
---|
549 |
|
---|
550 | /** Are shadows enabled for this queue? */
|
---|
551 | bool getShadowsEnabled(void) const { return mShadowsEnabled; }
|
---|
552 |
|
---|
553 | /** Sets whether or not the queue will split passes by their lighting type,
|
---|
554 | ie ambient, per-light and decal.
|
---|
555 | */
|
---|
556 | void setSplitPassesByLightingType(bool split)
|
---|
557 | {
|
---|
558 | mSplitPassesByLightingType = split;
|
---|
559 | PriorityMap::iterator i, iend;
|
---|
560 | iend = mPriorityGroups.end();
|
---|
561 | for (i = mPriorityGroups.begin(); i != iend; ++i)
|
---|
562 | {
|
---|
563 | i->second->setSplitPassesByLightingType(split);
|
---|
564 | }
|
---|
565 | }
|
---|
566 | /** Sets whether or not the queue will split passes which have shadow receive
|
---|
567 | turned off (in their parent material), which is needed when certain shadow
|
---|
568 | techniques are used.
|
---|
569 | */
|
---|
570 | void setSplitNoShadowPasses(bool split)
|
---|
571 | {
|
---|
572 | mSplitNoShadowPasses = split;
|
---|
573 | PriorityMap::iterator i, iend;
|
---|
574 | iend = mPriorityGroups.end();
|
---|
575 | for (i = mPriorityGroups.begin(); i != iend; ++i)
|
---|
576 | {
|
---|
577 | i->second->setSplitNoShadowPasses(split);
|
---|
578 | }
|
---|
579 | }
|
---|
580 | /** Sets whether or not objects which cast shadows should be treated as
|
---|
581 | never receiving shadows.
|
---|
582 | */
|
---|
583 | void setShadowCastersCannotBeReceivers(bool ind)
|
---|
584 | {
|
---|
585 | mShadowCastersNotReceivers = ind;
|
---|
586 | PriorityMap::iterator i, iend;
|
---|
587 | iend = mPriorityGroups.end();
|
---|
588 | for (i = mPriorityGroups.begin(); i != iend; ++i)
|
---|
589 | {
|
---|
590 | i->second->setShadowCastersCannotBeReceivers(ind);
|
---|
591 | }
|
---|
592 | }
|
---|
593 | /** Reset the organisation modes required for the solids in this group.
|
---|
594 | @remarks
|
---|
595 | You can only do this when the group is empty, ie after clearing the
|
---|
596 | queue.
|
---|
597 | @see QueuedRenderableCollection::OrganisationMode
|
---|
598 | */
|
---|
599 | void resetOrganisationModes(void)
|
---|
600 | {
|
---|
601 | PriorityMap::iterator i, iend;
|
---|
602 | iend = mPriorityGroups.end();
|
---|
603 | for (i = mPriorityGroups.begin(); i != iend; ++i)
|
---|
604 | {
|
---|
605 | i->second->resetOrganisationModes();
|
---|
606 | }
|
---|
607 | }
|
---|
608 |
|
---|
609 | /** Add a required sorting / grouping mode for the solids in this group.
|
---|
610 | @remarks
|
---|
611 | You can only do this when the group is empty, ie after clearing the
|
---|
612 | queue.
|
---|
613 | @see QueuedRenderableCollection::OrganisationMode
|
---|
614 | */
|
---|
615 | void addOrganisationMode(QueuedRenderableCollection::OrganisationMode om)
|
---|
616 | {
|
---|
617 | PriorityMap::iterator i, iend;
|
---|
618 | iend = mPriorityGroups.end();
|
---|
619 | for (i = mPriorityGroups.begin(); i != iend; ++i)
|
---|
620 | {
|
---|
621 | i->second->addOrganisationMode(om);
|
---|
622 | }
|
---|
623 | }
|
---|
624 |
|
---|
625 | /** Setthe sorting / grouping mode for the solids in this group to the default.
|
---|
626 | @remarks
|
---|
627 | You can only do this when the group is empty, ie after clearing the
|
---|
628 | queue.
|
---|
629 | @see QueuedRenderableCollection::OrganisationMode
|
---|
630 | */
|
---|
631 | void defaultOrganisationMode(void)
|
---|
632 | {
|
---|
633 | PriorityMap::iterator i, iend;
|
---|
634 | iend = mPriorityGroups.end();
|
---|
635 | for (i = mPriorityGroups.begin(); i != iend; ++i)
|
---|
636 | {
|
---|
637 | i->second->defaultOrganisationMode();
|
---|
638 | }
|
---|
639 | }
|
---|
640 |
|
---|
641 | };
|
---|
642 |
|
---|
643 |
|
---|
644 |
|
---|
645 | }
|
---|
646 |
|
---|
647 | #endif
|
---|
648 |
|
---|
649 |
|
---|