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

Revision 202, 26.9 KB checked in by mattausch, 19 years ago (diff)

stable

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