source: OGRE/trunk/src/OgreVisibilityOctreeSceneManager.cpp @ 343

Revision 343, 26.2 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 "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       
240                //InitVisibilityCulling(mCameraInProgress);
241                //mVisibilityManager->ApplyVisibilityCulling();
242
243                if(1){
244        InitDepthPass();          // create material for depth pass
245        InitItemBufferPass(); // create material for item buffer pass
246
247        // save ambient light to reset later
248        ColourValue savedAmbient = mAmbientLight;
249
250        //-- apply standard rendering for some modes (e.g., visualization, shadow pass)
251
252        if (mShowVisualization ||
253           (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE &&
254            mIlluminationStage == IRS_RENDER_TO_TEXTURE))
255        {
256                IlluminationRenderStage savedStage = mIlluminationStage;
257       
258                if (mShowVisualization)
259                {
260                        // disable illumination stage to prevent rendering shadows
261                        mIlluminationStage = IRS_NONE;
262                }
263
264                // standard rendering for shadow maps because of performance
265                OctreeSceneManager::_renderVisibleObjects();
266
267                mIlluminationStage = savedStage;
268        }
269        else //-- the hierarchical culling algorithm
270        {       
271                // don't render backgrounds for item buffer
272                if (mUseItemBuffer)
273                {
274                        clearSpecialCaseRenderQueues();
275                        getRenderQueue()->clear();
276                }       
277
278                //-- hierarchical culling
279                // the objects of different layers (e.g., background, scene,
280                // overlay) must be identified and rendered one after another
281
282                //-- render all early skies
283                clearSpecialCaseRenderQueues();
284                addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
285                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
286                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
287
288                OctreeSceneManager::_renderVisibleObjects();
289
290
291#ifdef GTP_VISIBILITY_MODIFIED_OGRE
292                // delete previously rendered content
293                _deleteRenderedQueueGroups();
294#endif
295
296                //-- prepare queue for visible objects (i.e., all but overlay and skies late)
297                clearSpecialCaseRenderQueues();
298                addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE);
299                addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
300                setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
301       
302
303                // set all necessary parameters for
304                // hierarchical visibility culling and rendering
305                InitVisibilityCulling(mCameraInProgress);
306       
307                /**
308                * the hierarchical culling algorithm
309                * for depth pass: we just find objects and update depth buffer
310                * for "delayed" rendering: we render some passes afterwards
311                * e.g., transparents, because they need front-to-back sorting
312                **/
313       
314                mVisibilityManager->ApplyVisibilityCulling();
315       
316                // delete remaining renderables from queue (all not in mLeavePassesInQueue)
317#ifdef GTP_VISIBILITY_MODIFIED_OGRE
318                _deleteRenderedQueueGroups(mLeavePassesInQueue);
319#endif
320
321                //-- reset parameters
322                mIsDepthPassPhase = false;
323                mIsItemBufferPhase = false;
324                mSkipTransparents = false;
325                mIsHierarchicalCulling = false;
326
327                mLeavePassesInQueue = 0;
328
329                // add visible nodes found by the visibility culling algorithm
330                if (mUseDepthPass)
331                {
332                        for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
333                        {
334                                (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false);
335                        }
336                }
337       
338                //-- we render all remaining queue objects
339                // used for depth pass, transparents, overlay
340                clearSpecialCaseRenderQueues();
341                OctreeSceneManager::_renderVisibleObjects();
342       
343        }   // hierarchical culling
344
345        // reset ambient light
346        setAmbientLight(savedAmbient);
347}       
348        getRenderQueue()->clear(); // finally clear render queue
349        OGRE_DELETE(mRenderQueue); // HACK: should be cleared before...
350        //WriteLog(); // write out stats
351
352}
353
354//-----------------------------------------------------------------------
355void VisibilityOctreeSceneManager::_updateSceneGraph(Camera* cam)
356{
357        mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
358        mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
359
360        OctreeSceneManager::_updateSceneGraph(cam);
361}
362//-----------------------------------------------------------------------
363bool VisibilityOctreeSceneManager::setOption(const String & key, const void * val)
364{
365        if (key == "UseDepthPass")
366        {
367                mUseDepthPass = (*static_cast<const bool *>(val));
368                return true;
369        }
370        if (key == "PrepareVisualization")
371        {
372                mShowVisualization = (*static_cast<const bool *>(val));
373                return true;
374        }
375        if (key == "RenderNodesForViz")
376        {
377                mRenderNodesForViz = (*static_cast<const bool *>(val));
378                return true;
379        }
380        if (key == "RenderNodesContentForViz")
381        {
382                mRenderNodesContentForViz = (*static_cast<const bool *>(val));
383                return true;
384        }
385        if (key == "SkyBoxEnabled")
386        {
387                mSkyBoxEnabled = (*static_cast<const bool *>(val));
388                return true;
389        }
390        if (key == "SkyPlaneEnabled")
391        {
392                mSkyPlaneEnabled = (*static_cast<const bool *>(val));
393                return true;
394        }
395        if (key == "SkyDomeEnabled")
396        {
397                mSkyDomeEnabled = (*static_cast<const bool *>(val));
398                return true;
399        }
400        if (key == "VisualizeCulledNodes")
401        {
402                mVisualizeCulledNodes = (*static_cast<const bool *>(val));
403                return true;
404        }
405        if (key == "DelayRenderTransparents")
406        {
407                mDelayRenderTransparents = (*static_cast<const bool *>(val));
408                return true;
409        }
410
411        if (key == "DepthWrite")
412        {
413                mEnableDepthWrite = (*static_cast<const bool *>(val));
414                return true;
415        }
416        if (key == "UseItemBuffer")
417        {
418                mUseItemBuffer = (*static_cast<const bool *>(val));
419                return true;
420        }
421        if (key == "ExecuteVertexProgramForAllPasses")
422        {
423                mExecuteVertexProgramForAllPasses  = (*static_cast<const bool *>(val));
424                return true;
425        }
426        if (key == "RenderTransparentsForItemBuffer")
427        {
428                mRenderTransparentsForItemBuffer  = (*static_cast<const bool *>(val));
429                return true;
430        }
431        if (key == "NodeVizScale")
432        {
433                OctreeNode::setVizScale(*static_cast<const float *>(val));
434                return true;
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
452        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
453                setOption(key, val) || OctreeSceneManager::setOption(key, val);
454}
455//-----------------------------------------------------------------------
456bool VisibilityOctreeSceneManager::getOption(const String & key, void *val)
457{
458        if (key == "NumHierarchyNodes")
459        {
460                * static_cast<unsigned int *>(val) = (unsigned int)mNumOctants;
461                return true;
462        }
463
464        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
465                getOption(key, val) && OctreeSceneManager::getOption(key, val);
466}
467//-----------------------------------------------------------------------
468bool VisibilityOctreeSceneManager::getOptionValues(const String & key, StringVector  &refValueList)
469{
470        return OctreeSceneManager::getOptionValues( key, refValueList );
471}
472//-----------------------------------------------------------------------
473bool VisibilityOctreeSceneManager::getOptionKeys(StringVector & refKeys)
474{
475        return  VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
476                getOptionKeys (refKeys) || OctreeSceneManager::getOptionKeys(refKeys);
477}
478//-----------------------------------------------------------------------
479void VisibilityOctreeSceneManager::setVisibilityManager(GtpVisibility::VisibilityManager *visManager)
480{
481    mVisibilityManager = visManager;
482}
483//-----------------------------------------------------------------------
484GtpVisibility::VisibilityManager *VisibilityOctreeSceneManager::getVisibilityManager()
485{
486        return mVisibilityManager;
487}
488//-----------------------------------------------------------------------
489void VisibilityOctreeSceneManager::WriteLog()
490{
491        std::stringstream d;
492
493        d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", "
494          << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", "
495          << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", "
496          << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << "\n"
497          << "Hierarchy nodes: " << mNumOctants << ", "
498          << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", "
499          << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", "
500          << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", "
501          << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", "
502      << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << "\n";
503          /*<< "avg. FPS: " << mCurrentViewport->getTarget()->getAverageFPS() << ", "
504          << "best FPS: " << mCurrentViewport->getTarget()->getBestFPS() << ", "
505          << "worst FPS: " << mCurrentViewport->getTarget()->getWorstFPS() << ", "
506          << "best frame time: " <<     mCurrentViewport->getTarget()->getBestFrameTime() << ", "
507          << "worst frame time: " << mCurrentViewport->getTarget()->getWorstFrameTime() << "\n";*/
508
509        LogManager::getSingleton().logMessage(d.str());
510}
511//-----------------------------------------------------------------------
512void VisibilityOctreeSceneManager::renderObjects(
513        const RenderPriorityGroup::TransparentRenderablePassList& objs,
514            bool doLightIteration, const LightList* manualLightList)
515{
516        // for correct rendering, transparents must be rendered after hierarchical culling
517        if (!mSkipTransparents)
518        {
519                OctreeSceneManager::renderObjects(objs, doLightIteration, manualLightList);
520        }
521}
522//-----------------------------------------------------------------------
523bool VisibilityOctreeSceneManager::validatePassForRendering(Pass* pass)
524{
525        // skip all but first pass if we are doing the depth pass
526        if ((mIsDepthPassPhase || mIsItemBufferPhase) && pass->getIndex() > 0)
527        {
528                return false;
529        }
530        return SceneManager::validatePassForRendering(pass);
531}
532//-----------------------------------------------------------------------
533void VisibilityOctreeSceneManager::renderQueueGroupObjects(RenderQueueGroup* pGroup)
534{
535        if (!mIsItemBufferPhase)
536        {
537                OctreeSceneManager::renderQueueGroupObjects(pGroup);
538                return;
539        }
540
541        //-- renders item buffer
542
543    // Iterate through priorities
544    RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
545
546        while (groupIt.hasMoreElements())
547    {
548                RenderItemBuffer(groupIt.getNext());
549        }
550}
551//-----------------------------------------------------------------------
552void VisibilityOctreeSceneManager::RenderItemBuffer(RenderPriorityGroup* pGroup)
553{
554        // Do solids
555        RenderPriorityGroup::SolidRenderablePassMap solidObjs = pGroup->_getSolidPasses();
556
557        // ----- SOLIDS LOOP -----
558        RenderPriorityGroup::SolidRenderablePassMap::const_iterator ipass, ipassend;
559        ipassend = solidObjs.end();
560
561        for (ipass = solidObjs.begin(); ipass != ipassend; ++ipass)
562        {
563                // Fast bypass if this group is now empty
564                if (ipass->second->empty())
565                        continue;
566
567                // Render only first pass
568                if (ipass->first->getIndex() > 0)
569                        continue;
570
571                RenderPriorityGroup::RenderableList* rendList = ipass->second;
572               
573                RenderPriorityGroup::RenderableList::const_iterator irend, irendend;
574                irendend = rendList->end();
575                       
576                for (irend = rendList->begin(); irend != irendend; ++irend)
577                {
578                        std::stringstream d; d << "itembuffer, pass name: " <<
579                                ipass->first->getParent()->getParent()->getName();
580                               
581                        LogManager::getSingleton().logMessage(d.str());
582                       
583                        RenderSingleObjectForItemBuffer(*irend, ipass->first);
584                }
585        }
586
587        //-- TRANSPARENT LOOP: must be handled differently
588
589        // transparents are treated either as solids or completely discarded
590        if (mRenderTransparentsForItemBuffer)
591        {
592                RenderPriorityGroup::TransparentRenderablePassList transpObjs =
593                        pGroup->_getTransparentPasses();
594                RenderPriorityGroup::TransparentRenderablePassList::const_iterator
595                        itrans, itransend;
596
597                itransend = transpObjs.end();
598                for (itrans = transpObjs.begin(); itrans != itransend; ++itrans)
599                {
600                        // like for solids, render only first pass
601                        if (itrans->pass->getIndex() == 0)
602                        {       
603                                RenderSingleObjectForItemBuffer(itrans->renderable, itrans->pass);
604                        }
605                }
606        }
607}
608//-----------------------------------------------------------------------
609void VisibilityOctreeSceneManager::RenderSingleObjectForItemBuffer(Renderable *rend, Pass *pass)
610{
611        static LightList nullLightList;
612       
613        int col[4];
614       
615        // -- create color code out of object id
616        col[0] = (rend->getId() >> 16) & 255;
617        col[1] = (rend->getId() >> 8) & 255;
618        col[2] = rend->getId() & 255;
619//      col[3] = 255;
620
621        //mDestRenderSystem->setColour(col[0], col[1], col[2], col[3]);
622   
623        mItemBufferPass->setAmbient(ColourValue(col[0] / 255.0f,
624                                                                                    col[1] / 255.0f,
625                                                                                        col[2] / 255.0f, 1));
626
627        // set vertex program of current pass
628        if (mExecuteVertexProgramForAllPasses && pass->hasVertexProgram())
629        {
630                mItemBufferPass->setVertexProgram(pass->getVertexProgramName());
631
632                if (mItemBufferPass->hasVertexProgram())
633                {
634                        const GpuProgramPtr& prg = mItemBufferPass->getVertexProgram();
635                        // Load this program if not done already
636                        if (!prg->isLoaded())
637                                prg->load();
638                        // Copy params
639                        mItemBufferPass->setVertexProgramParameters(pass->getVertexProgramParameters());
640                }
641        }
642        else if (mItemBufferPass->hasVertexProgram())
643        {
644                mItemBufferPass->setVertexProgram("");
645        }
646
647        Pass *usedPass = setPass(mItemBufferPass);
648
649
650        // Render a single object, this will set up auto params if required
651        renderSingleObject(rend, usedPass, false, &nullLightList);
652}
653//-----------------------------------------------------------------------
654GtpVisibility::VisibilityManager *VisibilityOctreeSceneManager::GetVisibilityManager()
655{
656        return mVisibilityManager;
657}
658//-----------------------------------------------------------------------
659void VisibilityOctreeSceneManager::InitVisibilityCulling(Camera *cam)
660{
661        // reset culling manager stats
662        mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes);
663
664        // set depth pass flag before rendering
665        mIsDepthPassPhase = mUseDepthPass;
666
667        mIsHierarchicalCulling = true; // during hierarchical culling
668
669        // item buffer needs full ambient lighting to use item colors as unique id
670        if (mUseItemBuffer)
671        {
672                mIsItemBufferPhase = true;
673                setAmbientLight(ColourValue(1,1,1,1));
674        }
675
676
677        // set passes which are stored in render queue
678        // for rendering AFTER hierarchical culling, i.e., passes which need
679        // a special rendering order
680       
681        mLeavePassesInQueue = 0;
682
683        if (!mUseDepthPass && !mUseItemBuffer)
684        {
685                if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE)
686                {
687                        // TODO: remove this pass because it should be processed during hierarchical culling
688                        //mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
689
690                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL;
691                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR;
692                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
693
694                        // just render ambient passes
695                        mIlluminationStage = IRS_AMBIENT;
696                        getRenderQueue()->setSplitPassesByLightingType(true);
697                }
698       
699                if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE)
700                {
701                        mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
702                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
703                }
704       
705                // transparents should be rendered after hierarchical culling to
706                // provide front-to-back ordering
707                if (mDelayRenderTransparents)
708                {
709                        mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
710                }
711        }
712
713        // skip rendering transparents in the hierarchical culling
714        // (because they will be rendered afterwards)
715        mSkipTransparents = mUseDepthPass ||
716                (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES);
717
718        // -- initialise interface for rendering traversal of the hierarchy
719        mHierarchyInterface->SetHierarchyRoot(mOctree);
720       
721        // possible two cameras (one for culling, one for rendering)
722        mHierarchyInterface->InitTraversal(mCameraInProgress,
723                                                        mCullCamera ? getCamera("CullCamera") : NULL,
724                                                        mLeavePassesInQueue);
725               
726        //std::stringstream d; d << "leave passes in queue: " << mLeavePassesInQueue;LogManager::getSingleton().logMessage(d.str());
727}
728//-----------------------------------------------------------------------
729OctreeHierarchyInterface *VisibilityOctreeSceneManager::GetHierarchyInterface()
730{
731        return mHierarchyInterface;
732}
733//-----------------------------------------------------------------------
734void VisibilityOctreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup)
735{
736        // only render solid passes during hierarchical culling
737        if (mIsHierarchicalCulling)
738        {
739                RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
740            LightList lightList;
741
742                while (groupIt.hasMoreElements())
743                {
744                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
745
746                        // Sort the queue first
747                        pPriorityGrp->sort(mCameraInProgress);
748
749                        // Clear light list
750                        lightList.clear();
751
752                        // Render all the ambient passes first, no light iteration, no lights
753                        mIlluminationStage = IRS_AMBIENT;
754
755                        OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), false, &lightList);
756                        // Also render any objects which have receive shadows disabled
757                        OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPassesNoShadow(), true);
758               
759                        /*std::stringstream d;
760                        d << " solid size: " << (int)pPriorityGrp->_getSolidPasses().size()
761                                << " solid no shadow size: " << (int)pPriorityGrp->_getSolidPassesNoShadow().size()
762                                << "difspec size: " << (int)pPriorityGrp->_getSolidPassesDiffuseSpecular().size()
763                                << " decal size: " << (int)pPriorityGrp->_getSolidPassesDecal().size();
764                        LogManager::getSingleton().logMessage(d.str());*/
765                }
766        }
767        else // render the rest of the passes
768        {
769                OctreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup);
770        }
771}
772//-----------------------------------------------------------------------
773void VisibilityOctreeSceneManager::renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup)
774{
775   if (mIsHierarchicalCulling)
776   {
777           // Iterate through priorities
778           RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
779
780           while (groupIt.hasMoreElements())
781           {
782                   RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
783
784                   // Sort the queue first
785                   pPriorityGrp->sort(mCameraInProgress);
786
787                   // Do (shadowable) solids
788                   OctreeSceneManager::renderObjects(pPriorityGrp->_getSolidPasses(), true);
789           }
790   }
791   else
792   {
793           SceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup);
794   }
795}
796//-------------------------------------------------------------------------
797void VisibilityOctreeSceneManager::loadVisibilityConfig(const String& filename)
798{
799        /// Set up the options
800        ConfigFile config;
801        String val;
802
803        config.load(filename);
804
805        val = config.getSetting("Algorithm");
806
807    if (!val.empty())
808        {
809                 VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).setOption("Algorithm", val.c_str());
810        }
811
812        val = config.getSetting("UseDepthPass");
813
814        if (!val.empty())
815        {
816                 setOption("UseDepthPass", val.c_str());
817        }
818}
819}  // namespace Ogre
Note: See TracBrowser for help on using the repository browser.