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

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

improved performance of TerrainSceneManager?
revisit octreescenemanager

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