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

Revision 120, 17.2 KB checked in by mattausch, 19 years ago (diff)
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
10
11namespace Ogre {
12
13//-----------------------------------------------------------------------
14VisibilityTerrainSceneManager::VisibilityTerrainSceneManager(
15        GtpVisibility::VisibilityManager *visManager):
16mVisibilityManager(visManager),
17mIsDepthPass(false),
18mShowVisualization(false),
19mRenderNodesForViz(false),
20mRenderNodesContentForViz(false),
21mVisualizeCulledNodes(false),
22mSkipTransparents(false),
23mDelayRenderTransparents(true),
24mUseDepthPass(false)
25{
26        mHierarchyInterface = new OctreeHierarchyInterface(this, mDestRenderSystem);
27
28        //mDisplayNodes = true;
29        //mShowBoundingBoxes = true;
30
31        // TODO: set maxdepth to reasonable value
32        mMaxDepth = 50;
33}
34//-----------------------------------------------------------------------
35void VisibilityTerrainSceneManager::InitDepthPass()
36{
37        MaterialPtr depthMat = MaterialManager::getSingleton().getByName("Visibility/DepthPass");
38
39        if (depthMat.isNull())
40    {
41                // Init
42                depthMat = MaterialManager::getSingleton().create(
43                "Visibility/DepthPass",
44                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
45        mDepthPass = depthMat->getTechnique(0)->getPass(0);
46                mDepthPass->setColourWriteEnabled(false);
47                mDepthPass->setDepthWriteEnabled(true);
48                mDepthPass->setLightingEnabled(false);
49        }
50        else
51        {
52                mDepthPass = depthMat->getTechnique(0)->getPass(0);
53        }
54}
55//-----------------------------------------------------------------------
56VisibilityTerrainSceneManager::~VisibilityTerrainSceneManager()
57{
58        if (mHierarchyInterface)
59        {
60                delete mHierarchyInterface;
61                mHierarchyInterface = NULL;
62        }
63}
64//-----------------------------------------------------------------------
65/*Pass *VisibilityTerrainSceneManager::setPass(Pass* pass)
66{
67        static bool myLastUsedVertexProgram = false;
68    static bool myLastUsedFragmentProgram = false;
69
70        // set depth fill pass only if depth write enabled
71        Pass *usedPass = pass;
72
73        if (mIsDepthPass && pass->getDepthWriteEnabled())
74        {
75                usedPass = mDepthPass;         
76        }
77
78    if (mIlluminationStage == IRS_RENDER_TO_TEXTURE)
79    {
80        // Derive a special shadow caster pass from this one
81        usedPass = deriveShadowCasterPass(usedPass);
82    }
83    else if (mIlluminationStage == IRS_RENDER_MODULATIVE_PASS)
84    {
85        usedPass = deriveShadowReceiverPass(usedPass);
86    }
87
88        bool passSurfaceAndLightParams = true;
89
90        // take original pass here
91    if (usedPass->hasVertexProgram())
92    {
93        mDestRenderSystem->bindGpuProgram(usedPass->getVertexProgram()->_getBindingDelegate());
94        // bind parameters later since they can be per-object
95        myLastUsedVertexProgram = true;
96        // does the vertex program want surface and light params passed to rendersystem?
97        passSurfaceAndLightParams = usedPass->getVertexProgram()->getPassSurfaceAndLightStates();
98    }
99    else
100    {
101        // Unbind program?
102        if (myLastUsedVertexProgram)
103        {
104            mDestRenderSystem->unbindGpuProgram(GPT_VERTEX_PROGRAM);
105            myLastUsedVertexProgram = false;
106        }
107        // Set fixed-function vertex parameters
108    }
109
110    if (passSurfaceAndLightParams)
111    {
112        // Set surface reflectance properties, only valid if lighting is enabled
113        if (usedPass->getLightingEnabled())
114        {
115            mDestRenderSystem->_setSurfaceParams(
116                usedPass->getAmbient(),
117                usedPass->getDiffuse(),
118                usedPass->getSpecular(),
119                usedPass->getSelfIllumination(),
120                usedPass->getShininess(),
121                                usedPass->getVertexColourTracking() );
122        }
123
124        // Dynamic lighting enabled?
125        mDestRenderSystem->setLightingEnabled(usedPass->getLightingEnabled());
126    }
127
128    // Using a fragment program?
129    if (usedPass->hasFragmentProgram())
130    {
131        mDestRenderSystem->bindGpuProgram(
132            usedPass->getFragmentProgram()->_getBindingDelegate());
133        // bind parameters later since they can be per-object
134        myLastUsedFragmentProgram = true;
135    }
136    else
137    {
138        // Unbind program?
139        if (myLastUsedFragmentProgram)
140        {
141            mDestRenderSystem->unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
142            myLastUsedFragmentProgram = false;
143        }
144
145        // Set fixed-function fragment settings
146
147        // Fog (assumes we want pixel fog which is the usual)
148        // New fog params can either be from scene or from material
149        FogMode newFogMode;
150        ColourValue newFogColour;
151        Real newFogStart, newFogEnd, newFogDensity;
152        if (usedPass->getFogOverride())
153        {
154            // New fog params from material
155            newFogMode = usedPass->getFogMode();
156            newFogColour = usedPass->getFogColour();
157            newFogStart = usedPass->getFogStart();
158            newFogEnd = usedPass->getFogEnd();
159            newFogDensity = usedPass->getFogDensity();
160        }
161        else
162        {
163            // New fog params from scene
164            newFogMode = mFogMode;
165            newFogColour = mFogColour;
166            newFogStart = mFogStart;
167            newFogEnd = mFogEnd;
168            newFogDensity = mFogDensity;
169        }
170        mDestRenderSystem->_setFog(newFogMode, newFogColour, newFogDensity, newFogStart, newFogEnd);
171
172        }
173
174    // The rest of the settings are the same no matter whether we use programs or not
175
176    // Set scene blending
177    mDestRenderSystem->_setSceneBlending(
178        usedPass->getSourceBlendFactor(), usedPass->getDestBlendFactor());
179
180
181    // Texture unit settings
182
183    Pass::TextureUnitStateIterator texIter =  usedPass->getTextureUnitStateIterator();
184    size_t unit = 0;
185    while(texIter.hasMoreElements())
186    {
187        TextureUnitState* pTex = texIter.getNext();
188        mDestRenderSystem->_setTextureUnitSettings(unit, *pTex);
189        ++unit;
190    }
191    // Disable remaining texture units
192    mDestRenderSystem->_disableTextureUnitsFrom(usedPass->getNumTextureUnitStates());
193
194    // Set up non-texture related material settings
195    // Depth buffer settings
196    mDestRenderSystem->_setDepthBufferFunction(usedPass->getDepthFunction());
197    mDestRenderSystem->_setDepthBufferCheckEnabled(usedPass->getDepthCheckEnabled());
198    mDestRenderSystem->_setDepthBufferWriteEnabled(usedPass->getDepthWriteEnabled());
199    mDestRenderSystem->_setDepthBias(usedPass->getDepthBias());
200        // Alpha-reject settings
201        mDestRenderSystem->_setAlphaRejectSettings(
202                usedPass->getAlphaRejectFunction(), usedPass->getAlphaRejectValue());
203    // Set colour write mode
204    // Right now we only use on/off, not per-channel
205    bool colWrite = usedPass->getColourWriteEnabled();
206    mDestRenderSystem->_setColourBufferWriteEnabled(colWrite, colWrite, colWrite, colWrite);
207    // Culling mode
208    mDestRenderSystem->_setCullingMode(usedPass->getCullingMode());
209    // Shading
210    mDestRenderSystem->setShadingType(usedPass->getShadingMode());
211
212        return usedPass;
213}*/
214//-----------------------------------------------------------------------
215void VisibilityTerrainSceneManager::ShowVisualization(Camera *cam)
216{
217        // add player camera for visualization purpose
218        try {
219                Camera *c;
220                if ((c = getCamera("PlayerCam")) != NULL)
221                {
222                        getRenderQueue()->addRenderable(c);
223                }   
224    }
225    catch(...)
226    {
227        // ignore
228    }
229        for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it)
230        {
231                getRenderQueue()->addRenderable(*it);
232        }
233        if (mRenderNodesForViz || mRenderNodesContentForViz)
234        {
235                // change node material so it is better suited for visualization
236                MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial");
237                nodeMat->setAmbient(1, 1, 0);
238                nodeMat->setLightingEnabled(true);
239                nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
240
241                for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
242                {
243                       
244                        if (mRenderNodesForViz)
245                        {
246                                getRenderQueue()->addRenderable(*it);
247                                // addbounding boxes instead of node itself
248                                //(*it)->_addBoundingBoxToQueue(getRenderQueue());
249                        }
250                        if (mRenderNodesContentForViz)
251                        {
252                                (*it)->_addToRenderQueue(cam, getRenderQueue(), false);
253                        }
254                }
255        }
256       
257}
258//-----------------------------------------------------------------------
259Pass *VisibilityTerrainSceneManager::setPass(Pass* pass)
260{
261        // setting vertex program is not efficient
262        //Pass *usedPass = ((mIsDepthPass && !pass->hasVertexProgram()) ? mDepthPass : pass);           
263        // set depth fill pass only if depth write enabled
264        Pass *usedPass = (mIsDepthPass && pass->getDepthWriteEnabled() ? mDepthPass : pass);
265       
266        if (mIsDepthPass)
267        {
268                // set vertex program of current pass
269        if (pass->hasVertexProgram())
270                {
271                        mDepthPass->setVertexProgram(pass->getVertexProgramName());
272
273                        if (mDepthPass->hasVertexProgram())
274                        {
275                                const GpuProgramPtr& prg = mDepthPass->getVertexProgram();
276                                // Load this program if not done already
277                                if (!prg->isLoaded())
278                                        prg->load();
279                                // Copy params
280                                mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters());
281                        }
282                }
283                else if (mDepthPass->hasVertexProgram())
284                {
285                        mDepthPass->setVertexProgram("");
286                }
287        }
288        /*else if (mIsItemBufferPass)
289        {
290                usedPass = mItemBufferPass;
291        }*/
292        SceneManager::setPass(usedPass);
293
294        return usedPass;
295}
296//-----------------------------------------------------------------------
297void VisibilityTerrainSceneManager::_findVisibleObjects(Camera* cam, bool onlyShadowCasters)
298{
299        //-- show visible scene nodes and octree bounding boxes from last frame
300        if (mShowVisualization)
301    {
302                ShowVisualization(cam);
303        }
304        else
305        {
306                mVisible.clear();
307            mBoxes.clear();
308               
309                // if there is no depth pass =>
310                // we interleave identification and rendering of objects
311                // in _renderVisibibleObjects
312
313                // only shadow casters will be rendered in shadow texture pass
314                mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters);
315        }
316}
317//-----------------------------------------------------------------------
318void VisibilityTerrainSceneManager::_renderVisibleObjects()
319{
320        // create material for depth pass
321        InitDepthPass();
322
323        // visualization: apply standard rendering
324        if (mShowVisualization)
325        {       
326                TerrainSceneManager::_renderVisibleObjects();
327                return;
328        }
329
330
331        //-- hierarchical culling
332        // the objects of different layers (e.g., background, scene,
333        // overlay) must be identified and rendered one after another
334
335        bool leaveTransparentsInQueue = mDelayRenderTransparents && !mUseDepthPass;
336
337        // possible two cameras (one for culling, one for rendering)
338        mHierarchyInterface->InitFrame(mOctree, mCameraInProgress,
339                                                        mCullCamera ? getCamera("CullCamera") : NULL,
340                                                        leaveTransparentsInQueue);
341
342        // call initframe to reset culling manager stats
343        mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes);
344       
345        mSkipTransparents = false;
346
347        //-- render background, in case there is one
348        clearSpecialCaseRenderQueues();
349        addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
350        addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
351        setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
352
353        SceneManager::_renderVisibleObjects();
354
355
356#ifdef GTP_VISIBILITY_MODIFIED_OGRE
357        _deleteRenderedQueueGroups(false);
358#endif
359
360        //-- render visible objects (i.e., all but overlay and skies late)
361        clearSpecialCaseRenderQueues();
362        addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE);
363        addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
364        setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
365
366        // transparents are skipped from hierarchical rendering
367        // => they need sorting, thus we render them afterwards
368        mSkipTransparents = mDelayRenderTransparents;
369
370        // set state for depth pass
371    mIsDepthPass = mUseDepthPass;
372       
373        /**
374          * the hierarchical culling algorithm
375          * for depth pass: will just find objects and update depth buffer
376          * for delayed rendering: will render all but transparents
377        **/
378       
379        mVisibilityManager->ApplyVisibilityCulling();
380
381
382        // for depth pass: add visible nodes found with the visibility culling
383        if (mUseDepthPass)
384        {
385                /*for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
386                {
387                        (*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false);
388                }*/
389                mIsDepthPass = false;
390        }
391
392        mSkipTransparents = false;
393
394        //-- now we can render all remaining queue objects
395        // for depth pass: all
396        // for delayed rendering: transparents, overlay
397        clearSpecialCaseRenderQueues();
398        SceneManager::_renderVisibleObjects();
399
400        //WriteLog(); // write out stats
401}
402//-----------------------------------------------------------------------
403void VisibilityTerrainSceneManager::_updateSceneGraph(Camera* cam)
404{
405        mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
406        mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
407
408#ifdef GTP_VISIBILITY_MODIFIED_OGRE
409    mHierarchyInterface->SetNumOctreeNodes(mNumOctreeNodes);
410#endif
411        TerrainSceneManager::_updateSceneGraph(cam);
412}
413//-----------------------------------------------------------------------
414bool VisibilityTerrainSceneManager::setOption(const String & key, const void * val)
415{
416        if (key == "UseDepthPass")
417        {
418                mUseDepthPass = (*static_cast<const bool *>(val));
419                return true;
420        }
421        if (key == "ShowVisualization")
422        {
423                mShowVisualization = (*static_cast<const bool *>(val));
424                return true;
425        }
426        if (key == "RenderNodesForViz")
427        {
428                mRenderNodesForViz = (*static_cast<const bool *>(val));
429                return true;
430        }
431        if (key == "RenderNodesContentForViz")
432        {
433                mRenderNodesContentForViz = (*static_cast<const bool *>(val));
434                return true;
435        }
436        if (key == "SkyBoxEnabled")
437        {
438                mSkyBoxEnabled = (*static_cast<const bool *>(val));
439                return true;
440        }
441        if (key == "SkyPlaneEnabled")
442        {
443                mSkyPlaneEnabled = (*static_cast<const bool *>(val));
444                return true;
445        }
446        if (key == "SkyDomeEnabled")
447        {
448                mSkyDomeEnabled = (*static_cast<const bool *>(val));
449                return true;
450        }
451        if (key == "VisualizeCulledNodes")
452        {
453                mVisualizeCulledNodes = (*static_cast<const bool *>(val));
454                return true;
455        }
456        if (key == "DelayRenderTransparents")
457        {
458                mDelayRenderTransparents = (*static_cast<const bool *>(val));
459                return true;
460        }
461        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
462                setOption(key, val) || TerrainSceneManager::setOption(key, val);
463}
464//-----------------------------------------------------------------------
465bool VisibilityTerrainSceneManager::getOption(const String & key, void *val)
466{
467        if (key == "NumHierarchyNodes")
468        {
469                * static_cast<unsigned int *>(val) = (unsigned int)mNumOctreeNodes;
470                return true;
471        }
472       
473        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
474                getOption(key, val) && TerrainSceneManager::getOption(key, val);
475}
476//-----------------------------------------------------------------------
477bool VisibilityTerrainSceneManager::getOptionValues(const String & key, StringVector &refValueList)
478{
479        return TerrainSceneManager::getOptionValues( key, refValueList);
480}
481//-----------------------------------------------------------------------
482bool VisibilityTerrainSceneManager::getOptionKeys(StringVector & refKeys)
483{
484        return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface).
485                getOptionKeys(refKeys) || TerrainSceneManager::getOptionKeys(refKeys);
486}
487//-----------------------------------------------------------------------
488void VisibilityTerrainSceneManager::setVisibilityManager(GtpVisibility::VisibilityManager *visManager)
489{
490        mVisibilityManager = visManager;
491}
492//-----------------------------------------------------------------------
493GtpVisibility::VisibilityManager *VisibilityTerrainSceneManager::getVisibilityManager( void )
494{
495        return mVisibilityManager;
496}
497//-----------------------------------------------------------------------
498void VisibilityTerrainSceneManager::WriteLog()
499{
500        std::stringstream d;
501
502        d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", "
503          << "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", "
504          << "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetUseOptimization()) << ", "
505          << "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", "
506          << "Hierarchy nodes: " << mNumOctreeNodes << ", "
507          << "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", "
508          << "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", "
509          << "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", "
510          << "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", "
511      << "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << "\n";
512
513        LogManager::getSingleton().logMessage(d.str());
514}
515//-----------------------------------------------------------------------
516void VisibilityTerrainSceneManager::renderObjects(const RenderPriorityGroup::TransparentRenderablePassList& objs,
517            bool doLightIteration, const LightList* manualLightList)
518{
519        if (!mSkipTransparents)
520        {
521                OctreeSceneManager::renderObjects(objs, doLightIteration, manualLightList);
522        }
523}
524
525} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.