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

Revision 925, 30.9 KB checked in by mattausch, 18 years ago (diff)

update for ogre 1.2
OcclusionCullingSceneManager? is the only scenemanager in the solution now

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