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

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