source: trunk/VUT/Ogre/src/OgreVisibilityTerrainSceneManager.cpp @ 347

Revision 347, 26.5 KB checked in by mattausch, 19 years ago (diff)

fixed color bug
fixed terrain tile ch culling
made better terrain

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