source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreVisibilityOctreeSceneManager.cpp @ 726

Revision 726, 26.1 KB checked in by mattausch, 18 years ago (diff)

improved performance of TerrainSceneManager?
revisit octreescenemanager

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