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

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

improved performance of TerrainSceneManager?
revisit octreescenemanager

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