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

Revision 868, 30.3 KB checked in by mattausch, 18 years ago (diff)

fitting objects to bb, debug

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