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

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

improved performance of TerrainSceneManager?
revisit octreescenemanager

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