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

Revision 187, 27.4 KB checked in by mattausch, 19 years ago (diff)

added animationbug fix (deleting while animation)fixed visibilityQueriesadditive shadow volumes fixed for octree
hack to fully empty queue after traversal
added demo for vienna model

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