source: trunk/VUT/Ogre/src/OgreVisibilityOctreeSceneManager.cpp @ 259

Revision 259, 25.8 KB checked in by mattausch, 19 years ago (diff)

refined measurements

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