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

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