source: trunk/VUT/Ogre/src/OgreVisibilityTerrainSceneManager.cpp @ 343

Revision 343, 25.5 KB checked in by mattausch, 19 years ago (diff)

added switch between NV and ARB queries in the render system and in the demos.
Fixed render queue bug: when clearing queue, we traversed through all priority groups
to clear the passmaps. This became very slow because had to traverse many elements (over 1000
for city demo). Now all we destroy the priority groups for each rendering (per hierarchy node).

Line 
1#include "OgreVisibilityTerrainSceneManager.h"
2#include "OgreVisibilityOptionsManager.h"
3#include <OgreMath.h>
4#include <OgreIteratorWrappers.h>
5#include <OgreRenderSystem.h>
6#include <OgreCamera.h>
7#include <OgreLogManager.h>
8#include <OgreStringConverter.h>
9#include <OgreEntity.h>
10#include <OgreSubEntity.h>
11
12
13namespace Ogre {
14
15//-----------------------------------------------------------------------
16VisibilityTerrainSceneManager::VisibilityTerrainSceneManager(
17                                                        GtpVisibility::VisibilityManager *visManager):
18mVisibilityManager(visManager),
19mShowVisualization(false),
20mRenderNodesForViz(false),
21mRenderNodesContentForViz(false),
22mVisualizeCulledNodes(false),
23mLeavePassesInQueue(0),
24mDelayRenderTransparents(true),
25mUseDepthPass(false),
26mIsDepthPassPhase(false),
27mUseItemBuffer(false),
28//mUseItemBuffer(true),
29mIsItemBufferPhase(false),
30mCurrentEntityId(1),
31mEnableDepthWrite(true),
32mSkipTransparents(false),
33mRenderTransparentsForItemBuffer(true),
34mExecuteVertexProgramForAllPasses(true),
35mIsHierarchicalCulling(false)
36{
37        mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem);
38       
39        //mDisplayNodes = true;
40        //mShowBoundingBoxes = true;
41        //mShowBoxes = true;
42
43        // TODO: set maxdepth to reasonable value
44        mMaxDepth = 50;
45}
46//-----------------------------------------------------------------------
47void VisibilityTerrainSceneManager::InitDepthPass()
48{
49        MaterialPtr depthMat = MaterialManager::getSingleton().getByName("Visibility/DepthPass");
50
51        if (depthMat.isNull())
52    {
53                depthMat = MaterialManager::getSingleton().create(
54                "Visibility/DepthPass",
55                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
56
57        mDepthPass = depthMat->getTechnique(0)->getPass(0);
58                mDepthPass->setColourWriteEnabled(false);
59                mDepthPass->setDepthWriteEnabled(true);
60                mDepthPass->setLightingEnabled(false);
61        }
62        else
63        {
64                mDepthPass = depthMat->getTechnique(0)->getPass(0);
65        }
66}
67//-----------------------------------------------------------------------
68VisibilityTerrainSceneManager::~VisibilityTerrainSceneManager()
69{
70        OGRE_DELETE(mHierarchyInterface);
71}
72//-----------------------------------------------------------------------
73void VisibilityTerrainSceneManager::InitItemBufferPass()
74{
75        MaterialPtr itemBufferMat = MaterialManager::getSingleton().
76                getByName("Visibility/ItemBufferPass");
77
78        if (itemBufferMat.isNull())
79    {
80                // Init
81                itemBufferMat = MaterialManager::getSingleton().create("Visibility/ItemBufferPass",
82                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
83
84                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
85                mItemBufferPass->setColourWriteEnabled(true);
86                mItemBufferPass->setDepthWriteEnabled(true);
87                mItemBufferPass->setLightingEnabled(true);
88                //mItemBufferPass->setLightingEnabled(false);
89        }
90        else
91        {
92                mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
93        }
94        //mItemBufferPass->setAmbient(1, 1, 0);
95}
96//-----------------------------------------------------------------------
97void VisibilityTerrainSceneManager::PrepareVisualization(Camera *cam)
98{
99        // add player camera for visualization purpose
100        try
101        {
102                Camera *c;
103                if ((c = getCamera("PlayerCam")) != NULL)
104                {
105                        getRenderQueue()->addRenderable(c);
106                }   
107    }
108    catch (...)
109    {
110        // ignore
111    }
112        for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it)
113        {
114                getRenderQueue()->addRenderable(*it);
115        }
116        if (mRenderNodesForViz || mRenderNodesContentForViz)
117        {
118                // HACK: change node material so it is better suited for visualization
119                MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial");
120                nodeMat->setAmbient(1, 1, 0);
121                nodeMat->setLightingEnabled(true);
122                nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
123
124                for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
125                {
126                        if (mRenderNodesForViz)
127                        {
128                                // render the leaf nodes
129                                if (((*it)->numAttachedObjects() > 0) && ((*it)->numChildren() == 0) &&
130                                         (*it)->getAttachedObject(0)->getMovableType() == "Entity")
131                                {
132                                        getRenderQueue()->addRenderable((*it));
133                                }
134
135                                // addbounding boxes instead of node itself
136                                //(*it)->_addBoundingBoxToQueue(getRenderQueue());
137                        }
138                        if (mRenderNodesContentForViz)
139                        {
140                                (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
141                        }
142                }
143        }       
144}
145//-----------------------------------------------------------------------
146Pass *VisibilityTerrainSceneManager::setPass(Pass* pass)
147{
148        // TODO: setting vertex program is not efficient
149        //Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass);
150       
151        // set depth fill pass if we currently do not make an aabb occlusion query
152        Pass *usedPass = (mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery() ?
153                                          mDepthPass : pass);
154               
155        IlluminationRenderStage savedStage = mIlluminationStage;
156       
157        // set illumination stage to NONE so no shadow material is used
158        // for depth pass or for occlusion query
159        if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery())
160        {
161                mIlluminationStage = IRS_NONE;
162        }
163       
164        // --- set vertex program of current pass in order to set correct depth
165        if (mExecuteVertexProgramForAllPasses && mIsDepthPassPhase && pass->hasVertexProgram())
166        {
167                // add vertex program of current pass to depth pass
168                mDepthPass->setVertexProgram(pass->getVertexProgramName());
169
170                if (mDepthPass->hasVertexProgram())
171                {
172                        const GpuProgramPtr& prg = mDepthPass->getVertexProgram();
173                        // Load this program if not done already
174                        if (!prg->isLoaded())
175                                prg->load();
176                        // Copy params
177                        mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters());
178                }
179        }
180        else if (mDepthPass->hasVertexProgram())
181        {
182                mDepthPass->setVertexProgram("");
183        }
184       
185
186        bool IsDepthWrite = usedPass->getDepthWriteEnabled();
187
188        // global option which enables / disables depth writes
189        if (!mEnableDepthWrite)
190        {
191                usedPass->setDepthWriteEnabled(false);
192        }
193        //else if (mIsItemBufferPass) {usedPass = mItemBufferPass;}
194       
195        Pass *result = SceneManager::setPass(usedPass);
196
197        // reset depth write
198        if (!mEnableDepthWrite)
199        {
200                usedPass->setDepthWriteEnabled(IsDepthWrite);
201        }
202
203        // reset illumination stage
204        mIlluminationStage = savedStage;
205
206        return result;
207}
208//-----------------------------------------------------------------------
209void VisibilityTerrainSceneManager::_findVisibleObjects(Camera* cam,
210                                                                                                                bool onlyShadowCasters)
211{
212        //-- show visible scene nodes and octree bounding boxes from last frame
213        if (mShowVisualization)
214    {
215                PrepareVisualization(cam);
216        }
217        else
218        {       
219                // for hierarchical culling, we interleave identification
220                // and rendering of objects in _renderVisibibleObjects
221
222                // for the shadow pass we use only standard rendering
223                // because of low occlusion
224                if (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
225                        mIlluminationStage == IRS_RENDER_TO_TEXTURE)
226                {
227                        TerrainSceneManager::_findVisibleObjects(cam, onlyShadowCasters);
228                }
229                // only shadow casters will be rendered in shadow texture pass
230                // mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters);
231        }
232       
233       
234        // -- delete lists stored for visualization
235        mVisible.clear();
236        mBoxes.clear();
237}
238//-----------------------------------------------------------------------
239void VisibilityTerrainSceneManager::_renderVisibleObjects()
240{
241
242        InitDepthPass();          // create material for depth pass
243        InitItemBufferPass(); // create material for item buffer pass
244
245        // save ambient light to reset later
246        ColourValue savedAmbient = mAmbientLight;
247
248        //-- apply standard rendering for some modes (e.g., visualization, shadow pass)
249
250        if (mShowVisualization ||
251           (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
252            mIlluminationStage == IRS_RENDER_TO_TEXTURE))
253        {       
254                IlluminationRenderStage savedStage = mIlluminationStage;
255       
256                if (mShowVisualization)
257                        // disable illumination stage to prevent rendering shadows
258                        mIlluminationStage = IRS_NONE;
259
260                // standard rendering for shadow maps because of performance
261                TerrainSceneManager::_renderVisibleObjects();
262
263                mIlluminationStage = savedStage;
264        }
265        else //-- the hierarchical culling algorithm
266        {
267                // don't render backgrounds for item buffer
268                if (mUseItemBuffer)
269                {
270                        clearSpecialCaseRenderQueues();
271                        getRenderQueue()->clear();
272                }
273
274                //-- hierarchical culling
275                // the objects of different layers (e.g., background, scene,
276                // overlay) must be identified and rendered one after another
277
278                //-- render all early skies
279                clearSpecialCaseRenderQueues();
280                addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
281                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
282                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
283
284                TerrainSceneManager::_renderVisibleObjects();
285
286#ifdef GTP_VISIBILITY_MODIFIED_OGRE
287                // delete previously rendered content
288                _deleteRenderedQueueGroups();
289#endif
290
291                //-- prepare queue for visible objects (i.e., all but overlay and skies late)
292                clearSpecialCaseRenderQueues();
293                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE);
294                addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
295       
296                // exclude this queues from hierarchical rendering
297                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
298
299                // set all necessary parameters for
300                // hierarchical visibility culling and rendering
301                InitVisibilityCulling(mCameraInProgress);
302
303                /**
304                * the hierarchical culling algorithm
305                * for depth pass: we just find objects and update depth buffer
306                * for "delayed" rendering: we render some passes afterwards
307                * e.g., transparents, because they need front-to-back sorting
308                **/
309               
310                mVisibilityManager->ApplyVisibilityCulling();
311
312                // delete remaining renderables from queue (all not in mLeavePassesInQueue)
313#ifdef GTP_VISIBILITY_MODIFIED_OGRE
314                _deleteRenderedQueueGroups(mLeavePassesInQueue);
315#endif
316
317                //-- reset parameters
318                mIsDepthPassPhase = false;
319                mIsItemBufferPhase = false;
320                mSkipTransparents = false;
321                mLeavePassesInQueue = 0;
322               
323
324                // add visible nodes found by the visibility culling algorithm
325                if (mUseDepthPass)
326                {
327                        for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
328                        {
329                                (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false);
330                        }
331                }
332               
333                //-- now we can render all remaining queue objects
334                // used for depth pass, transparents, overlay
335                clearSpecialCaseRenderQueues();
336
337                TerrainSceneManager::_renderVisibleObjects();
338        }
339               
340        // HACK: set the new render level index, important to avoid cracks
341        // in terrain caused by LOD
342        TerrainRenderable::NextRenderLevelIndex();
343       
344        // reset ambient light
345        setAmbientLight(savedAmbient);
346
347        getRenderQueue()->clear(); // finally clear render queue
348        OGRE_DELETE(mRenderQueue); // HACK: should be cleared before...
349        //WriteLog(); // write out stats
350
351}
352
353//-----------------------------------------------------------------------
354void VisibilityTerrainSceneManager::_updateSceneGraph(Camera* cam)
355{
356        mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
357        mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
358
359        TerrainSceneManager::_updateSceneGraph(cam);
360}
361//-----------------------------------------------------------------------
362bool VisibilityTerrainSceneManager::setOption(const String & key, const void * val)
363{
364        if (key == "UseDepthPass")
365        {
366                mUseDepthPass = (*static_cast<const bool *>(val));
367                return true;
368        }
369        if (key == "PrepareVisualization")
370        {
371                mShowVisualization = (*static_cast<const bool *>(val));
372                return true;
373        }
374        if (key == "RenderNodesForViz")
375        {
376                mRenderNodesForViz = (*static_cast<const bool *>(val));
377                return true;
378        }
379        if (key == "RenderNodesContentForViz")
380        {
381                mRenderNodesContentForViz = (*static_cast<const bool *>(val));
382                return true;
383        }
384        if (key == "SkyBoxEnabled")
385        {
386                mSkyBoxEnabled = (*static_cast<const bool *>(val));
387                return true;
388        }
389        if (key == "SkyPlaneEnabled")
390        {
391                mSkyPlaneEnabled = (*static_cast<const bool *>(val));
392                return true;
393        }
394        if (key == "SkyDomeEnabled")
395        {
396                mSkyDomeEnabled = (*static_cast<const bool *>(val));
397                return true;
398        }
399        if (key == "VisualizeCulledNodes")
400        {
401                mVisualizeCulledNodes = (*static_cast<const bool *>(val));
402                return true;
403        }
404        if (key == "DelayRenderTransparents")
405        {
406                mDelayRenderTransparents = (*static_cast<const bool *>(val));
407                return true;
408        }
409
410        if (key == "DepthWrite")
411        {
412                mEnableDepthWrite = (*static_cast<const bool *>(val));
413                return true;
414        }
415        if (key == "UseItemBuffer")
416        {
417                mUseItemBuffer = (*static_cast<const bool *>(val));
418                return true;
419        }
420        if (key == "ExecuteVertexProgramForAllPasses")
421        {
422                mExecuteVertexProgramForAllPasses  = (*static_cast<const bool *>(val));
423                return true;
424        }
425        if (key == "RenderTransparentsForItemBuffer")
426        {
427                mRenderTransparentsForItemBuffer  = (*static_cast<const bool *>(val));
428                return true;
429        }
430        if (key == "NodeVizScale")
431        {
432                OctreeNode::setVizScale(*static_cast<const float *>(val));
433                return true;
434        }
435
436        if (key == "UseArbQueries")
437        {
438                bool useArbQueries = (*static_cast<const bool *>(val));
439
440                if (useArbQueries)
441                {
442                        mHierarchyInterface->DeleteQueries();
443                        mDestRenderSystem->setConfigOption("ArbQueries", "Yes");
444                }
445                else
446                {
447                        mHierarchyInterface->DeleteQueries();
448                        mDestRenderSystem->setConfigOption("ArbQueries", "No");
449                }
450        }
451        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
452                setOption(key, val) || TerrainSceneManager::setOption(key, val);
453}
454//-----------------------------------------------------------------------
455bool VisibilityTerrainSceneManager::getOption(const String & key, void *val)
456{
457        if (key == "NumHierarchyNodes")
458        {
459                * static_cast<unsigned int *>(val) = (unsigned int)mNumOctants;
460                return true;
461        }
462       
463        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
464                getOption(key, val) && TerrainSceneManager::getOption(key, val);
465}
466//-----------------------------------------------------------------------
467bool VisibilityTerrainSceneManager::getOptionValues(const String & key,
468                                                                                                        StringVector &refValueList)
469{
470        return TerrainSceneManager::getOptionValues( key, refValueList);
471}
472//-----------------------------------------------------------------------
473bool VisibilityTerrainSceneManager::getOptionKeys(StringVector & refKeys)
474{
475        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
476                getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys);
477}
478//-----------------------------------------------------------------------
479void VisibilityTerrainSceneManager::setVisibilityManager(GtpVisibility::
480                                                                                                                 VisibilityManager *visManager)
481{
482        mVisibilityManager = visManager;
483}
484//-----------------------------------------------------------------------
485GtpVisibility::VisibilityManager *VisibilityTerrainSceneManager::getVisibilityManager( void )
486{
487        return mVisibilityManager;
488}
489//-----------------------------------------------------------------------
490void VisibilityTerrainSceneManager::WriteLog()
491{
492        std::stringstream d;
493
494        d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", "
495          << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", "
496          << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", "
497          << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", "
498          << "Hierarchy nodes: " << mNumOctants << ", "
499          << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", "
500          << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", "
501          << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", "
502          << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", "
503      << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << "\n";
504
505        LogManager::getSingleton().logMessage(d.str());
506}
507//-----------------------------------------------------------------------
508void VisibilityTerrainSceneManager::renderObjects(
509        const RenderPriorityGroup::TransparentRenderablePassList& objs,
510    bool doLightIteration, const LightList* manualLightList)
511{
512        // for correct rendering, transparents must be rendered after hierarchical culling
513        if (!mSkipTransparents)
514        {
515                OctreeSceneManager::renderObjects(objs, doLightIteration, manualLightList);
516        }
517}
518//-----------------------------------------------------------------------
519bool VisibilityTerrainSceneManager::validatePassForRendering(Pass* pass)
520{
521        // skip all but first pass if we are doing the depth pass
522        if ((mIsDepthPassPhase || mIsItemBufferPhase) && pass->getIndex() > 0)
523        {
524                return false;
525        }
526        return SceneManager::validatePassForRendering(pass);
527}
528//-----------------------------------------------------------------------
529void VisibilityTerrainSceneManager::renderQueueGroupObjects(RenderQueueGroup* pGroup)
530{
531        if (!mIsItemBufferPhase)
532        {
533                TerrainSceneManager::renderQueueGroupObjects(pGroup);
534                return;
535        }
536
537        //-- item buffer
538
539    // Iterate through priorities
540    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
541
542        while (groupIt.hasMoreElements())
543    {
544                RenderItemBuffer(groupIt.getNext());
545        }
546}
547//-----------------------------------------------------------------------
548void VisibilityTerrainSceneManager::RenderItemBuffer(RenderPriorityGroup* pGroup)
549{
550        // Do solids
551        RenderPriorityGroup::SolidRenderablePassMap solidObjs = pGroup->_getSolidPasses();
552
553        // ----- SOLIDS LOOP -----
554        RenderPriorityGroup::SolidRenderablePassMap::const_iterator ipass, ipassend;
555        ipassend = solidObjs.end();
556
557        for (ipass = solidObjs.begin(); ipass != ipassend; ++ipass)
558        {
559                // Fast bypass if this group is now empty
560                if (ipass->second->empty())
561                        continue;
562
563                // Render only first pass
564                if (ipass->first->getIndex() > 0)
565                        continue;
566
567                RenderPriorityGroup::RenderableList* rendList = ipass->second;
568               
569                RenderPriorityGroup::RenderableList::const_iterator irend, irendend;
570                irendend = rendList->end();
571                       
572                for (irend = rendList->begin(); irend != irendend; ++irend)
573                {
574                        std::stringstream d; d << "itembuffer, pass name: " <<
575                                ipass->first->getParent()->getParent()->getName();
576                               
577                        LogManager::getSingleton().logMessage(d.str());
578                       
579                        RenderSingleObjectForItemBuffer(*irend, ipass->first);
580                }
581        }
582
583        // -- TRANSPARENT LOOP: must be handled differently
584
585        // transparents are treated either as solids or completely discarded
586        if (mRenderTransparentsForItemBuffer)
587        {
588                RenderPriorityGroup::TransparentRenderablePassList transpObjs =
589                        pGroup->_getTransparentPasses();
590                RenderPriorityGroup::TransparentRenderablePassList::const_iterator
591                        itrans, itransend;
592
593                itransend = transpObjs.end();
594                for (itrans = transpObjs.begin(); itrans != itransend; ++itrans)
595                {
596                        // like for solids, render only first pass
597                        if (itrans->pass->getIndex() == 0)
598                        {       
599                                RenderSingleObjectForItemBuffer(itrans->renderable, itrans->pass);
600                        }
601                }
602        }
603}
604//-----------------------------------------------------------------------
605void VisibilityTerrainSceneManager::RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass)
606{
607        static LightList nullLightList;
608       
609        int col[4];
610       
611        // -- create color code out of object id
612        col[0] = (rend->getId() >> 16) & 255;
613        col[1] = (rend->getId() >> 8) & 255;
614        col[2] = rend->getId() & 255;
615//      col[3] = 255;
616
617        //mDestRenderSystem->setColour(col[0], col[1], col[2], col[3]);
618   
619        mItemBufferPass->setAmbient(ColourValue(col[0] / 255.0f,
620                                                                                    col[1] / 255.0f,
621                                                                                        col[2] / 255.0f, 1));
622
623        // set vertex program of current pass
624        if (mExecuteVertexProgramForAllPasses && pass->hasVertexProgram())
625        {
626                mItemBufferPass->setVertexProgram(pass->getVertexProgramName());
627
628                if (mItemBufferPass->hasVertexProgram())
629                {
630                        const GpuProgramPtr& prg = mItemBufferPass->getVertexProgram();
631                        // Load this program if not done already
632                        if (!prg->isLoaded())
633                                prg->load();
634                        // Copy params
635                        mItemBufferPass->setVertexProgramParameters(pass->getVertexProgramParameters());
636                }
637        }
638        else if (mItemBufferPass->hasVertexProgram())
639        {
640                mItemBufferPass->setVertexProgram("");
641        }
642
643        Pass *usedPass = setPass(mItemBufferPass);
644
645
646        // Render a single object, this will set up auto params if required
647        renderSingleObject(rend, usedPass, false, &nullLightList);
648}
649//-----------------------------------------------------------------------
650GtpVisibility::VisibilityManager *VisibilityTerrainSceneManager::GetVisibilityManager()
651{
652        return mVisibilityManager;
653}
654//-----------------------------------------------------------------------
655void VisibilityTerrainSceneManager::InitVisibilityCulling(Camera *cam)
656{
657        // reset culling manager stats
658        mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes);
659
660        // set depth pass flag before rendering
661        mIsDepthPassPhase = mUseDepthPass;
662
663        // item buffer needs full ambient lighting to use item colors as unique id
664        if (mUseItemBuffer)
665        {
666                mIsItemBufferPhase = true;
667                setAmbientLight(ColourValue(1,1,1,1));
668        }
669
670
671        // set passes which are stored in render queue
672        // for rendering AFTER hierarchical culling, i.e., passes which need
673        // a special rendering order
674        mLeavePassesInQueue = 0;
675
676        if (!mUseDepthPass && !mUseItemBuffer)
677        {
678                if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE)
679                {
680                        // TODO: remove this pass because it should be processed during hierarchical culling
681                        //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
682
683                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL;
684                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR;
685                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
686
687                        // just render ambient stuff
688                        mIlluminationStage = IRS_AMBIENT;
689                }
690       
691                if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE)
692                {
693                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
694                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
695                }
696       
697                // transparents should be rendered after hierarchical culling to
698                // provide front-to-back ordering
699                if (mDelayRenderTransparents)
700                {
701                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
702                }
703        }
704
705        // skip rendering transparents in the hierarchical culling
706        // (because they will be rendered afterwards)
707        mSkipTransparents = mUseDepthPass ||
708                (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES);
709
710        // -- initialise interface for rendering traversal of the hierarchy
711        mHierarchyInterface->SetHierarchyRoot(mOctree);
712       
713        // possible two cameras (one for culling, one for rendering)
714        mHierarchyInterface->InitTraversal(mCameraInProgress,
715                                                        mCullCamera ? getCamera("CullCamera") : NULL,
716                                                        mLeavePassesInQueue);
717               
718        //std::stringstream d; d << "leave passes in queue: " << mLeavePassesInQueue;LogManager::getSingleton().logMessage(d.str());
719}
720//-----------------------------------------------------------------------
721OctreeHierarchyInterface *VisibilityTerrainSceneManager::GetHierarchyInterface()
722{
723        return mHierarchyInterface;
724}
725//-----------------------------------------------------------------------
726void VisibilityTerrainSceneManager::endFrame()
727{
728        TerrainRenderable::ResetRenderLevelIndex();
729}
730//-----------------------------------------------------------------------
731Entity* VisibilityTerrainSceneManager::createEntity(const String& entityName,
732                                                                                                        const String& meshName)
733{
734        Entity *ent = SceneManager::createEntity(entityName, meshName);
735
736        for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
737        {
738                ent->getSubEntity(i)->setId(mCurrentEntityId);
739        }
740
741        // increase counter of entity id values
742        ++ mCurrentEntityId;
743
744        return ent;
745}
746//-----------------------------------------------------------------------
747void VisibilityTerrainSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup)
748{
749        // only render solid passes during hierarchical culling
750        if (mIsHierarchicalCulling)
751        {
752                RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
753            LightList lightList;
754
755                while (groupIt.hasMoreElements())
756                {
757                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
758
759                        // Sort the queue first
760                        pPriorityGrp->sort(mCameraInProgress);
761
762                        // Clear light list
763                        lightList.clear();
764
765                        // Render all the ambient passes first, no light iteration, no lights
766                        mIlluminationStage = IRS_AMBIENT;
767
768                        OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), false, &lightList);
769                        // Also render any objects which have receive shadows disabled
770                        OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPassesNoShadow(), true);
771                }
772        }
773        else
774        {
775                OctreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup);
776        }
777}
778//-----------------------------------------------------------------------
779void VisibilityTerrainSceneManager::renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup)
780{
781   if (mIsHierarchicalCulling)
782   {
783           // Iterate through priorities
784           RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
785
786           while (groupIt.hasMoreElements())
787           {
788                   RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
789
790                   // Sort the queue first
791                   pPriorityGrp->sort(mCameraInProgress);
792
793                   // Do (shadowable) solids
794                   OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), true);
795           }
796   }
797   else
798   {
799           SceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup);
800   }
801}
802} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.