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

Revision 865, 28.8 KB checked in by mattausch, 18 years ago (diff)

fixed uint bug

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