source: GTP/trunk/Lib/Illum/IllumModule/OgreIllumModule/src/OgreIlluminationManager.cpp @ 2185

Revision 2185, 16.9 KB checked in by szirmay, 17 years ago (diff)
Line 
1#include "OgreIlluminationManager.h"
2#include "OgreParticleSystemRenderer.h"
3#include "OgreBillboardParticleRenderer.h"
4#include "SpriteParticleRenderer.h"
5
6OgreIlluminationManager* OgreIlluminationManager::instance = NULL;
7
8Vector3 sortfrom;
9RenderingRunType sortType;
10
11class sortFromVector
12{
13public:
14   bool operator()(OgreSharedRuns* a, OgreSharedRuns* b)
15   {
16           float dist1 = (a->getRootPosition() - sortfrom).length();
17           float dist2 = (b->getRootPosition() - sortfrom).length();
18
19           return dist1 > dist2;
20   }
21};
22
23class sortFromVectorWithRunType
24{
25public:
26   bool operator()(OgreSharedRuns* a, OgreSharedRuns* b)
27   {
28           float dist1 = (a->getRootPosition(sortType) - sortfrom).length();
29           float dist2 = (b->getRootPosition(sortType) - sortfrom).length();
30
31           return dist1 > dist2;
32   }
33};
34
35
36class VisibleFinderVisitor : public QueuedRenderableVisitor
37{
38private:
39        std::vector<const Renderable*>* visibleObjects;
40public:
41   
42        VisibleFinderVisitor(std::vector<const Renderable*>* visibleObjectsVector)
43        {
44                this->visibleObjects = visibleObjectsVector;
45        }
46
47        void visit(const Renderable* r)
48        {               
49                OgreTechniqueGroup* tg = (OgreTechniqueGroup*) r->getRenderTechniqueGroup();
50               
51                if(tg != 0)
52                {
53                        tg->validateSharedRuns();
54                        visibleObjects->push_back(r);
55                }
56        }
57        bool visit(const Pass* p)       
58        {
59                return true;
60        }
61        void visit(const RenderablePass* rp)
62        {
63                Renderable* r = rp->renderable;
64
65                OgreTechniqueGroup* tg = (OgreTechniqueGroup*) r->getRenderTechniqueGroup();
66               
67                if(tg != 0)
68                {
69                        tg->validateSharedRuns();
70                        visibleObjects->push_back(r);
71                }       
72        }
73
74};
75
76OgreIlluminationManager::OgreIlluminationManager()
77{
78        visitor = new VisibleFinderVisitor(&visibleObjects);
79        maxRad = 400;
80        focusingMapSize = 32;
81        shadowMapSize = 512;
82        phaseTextureSize = 256;
83        useLISPSM = false;
84        useVSM = false;
85        blurSM = false;
86        focusingSM = true;
87        shadowMapMaterialName = "GameTools/ShadowMapDepth";
88
89        for(int i = 0; i < RUN_TYPE_COUNT; i++)
90        {
91                maxRads[(RenderingRunType)i] = (float) maxRad;
92        }
93
94        //register rendertechnique factories
95        OgreColorCubeMapRenderTechniqueFactory* colorcube = new OgreColorCubeMapRenderTechniqueFactory();
96                addRenderTechniqueFactory(colorcube);
97        OgreDistanceCubeMapRenderTechniqueFactory* distcube = new OgreDistanceCubeMapRenderTechniqueFactory();
98                addRenderTechniqueFactory(distcube);
99        OgreConvoledCubeMapRenderTechniqueFactory* convcube = new OgreConvoledCubeMapRenderTechniqueFactory();
100                addRenderTechniqueFactory(convcube);
101        OgreCausticCasterRenderTechniqueFactory* caucast = new OgreCausticCasterRenderTechniqueFactory();
102                addRenderTechniqueFactory(caucast);
103        OgreCausticRecieverRenderTechniqueFactory* caurec = new OgreCausticRecieverRenderTechniqueFactory();
104                addRenderTechniqueFactory(caurec);
105        OgreDepthShadowRecieverRenderTechniqueFactory* dsrec = new OgreDepthShadowRecieverRenderTechniqueFactory();
106                addRenderTechniqueFactory(dsrec);
107        OgreSBBRenderTechniqueFactory* sbb = new OgreSBBRenderTechniqueFactory();
108                addRenderTechniqueFactory(sbb);
109        OgreFireRenderTechniqueFactory* fire = new OgreFireRenderTechniqueFactory();
110                addRenderTechniqueFactory(fire);
111        OgreHierarchicalParticleSystemTechniqueFactory* HPSF = new OgreHierarchicalParticleSystemTechniqueFactory();
112                addRenderTechniqueFactory(HPSF);
113        OgreIllumVolumeRenderTechniqueFactory* illumVolume = new OgreIllumVolumeRenderTechniqueFactory();
114                addRenderTechniqueFactory(illumVolume);
115        OgrePathMapRenderTechniqueFactory* pathmap = new OgrePathMapRenderTechniqueFactory();
116        addRenderTechniqueFactory(pathmap);
117}
118
119OgreIlluminationManager::~OgreIlluminationManager()
120{
121       
122}
123
124OgreIlluminationManager& OgreIlluminationManager::getSingleton()
125{
126        if(instance == NULL)
127                instance= new OgreIlluminationManager();
128
129        return *instance;
130}
131
132void OgreIlluminationManager::fillVisibleList(  RenderQueue * rq )
133{
134        visibleObjects.clear();
135
136        RenderQueue::QueueGroupIterator queueIt = rq->_getQueueGroupIterator();
137   
138    while (queueIt.hasMoreElements())
139    {
140        RenderQueueGroup* pGroup = queueIt.getNext();
141               
142        RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
143
144                while (groupIt.hasMoreElements())
145                {
146                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
147                        const QueuedRenderableCollection& solids = pPriorityGrp->getSolidsBasic();
148                        const QueuedRenderableCollection& transparents = pPriorityGrp->getTransparents();
149                                                                       
150                        solids.acceptVisitor(visitor, QueuedRenderableCollection::OM_PASS_GROUP);
151                        transparents.acceptVisitor(visitor, QueuedRenderableCollection::OM_SORT_ASCENDING);             
152                }                       
153    }
154
155        rq->clear();   
156}
157
158BillboardSet* OgreIlluminationManager::findRenderableInParticleSystem(ParticleSystem* system)
159{
160        ParticleSystemRenderer* renderer = system->getRenderer();
161       
162        const String rendererType = renderer->getType();
163        if(rendererType == "billboard")
164        {
165                BillboardSet* bbSet = ((BillboardParticleRenderer*) renderer)->getBillboardSet();
166                return bbSet;
167        }
168
169        if(rendererType == "sprite")
170        {
171                BillboardSet* bbSet = ((SpriteParticleRenderer*) renderer)->getSpriteSet();
172                return bbSet;
173        }
174       
175        OGRE_EXCEPT(0, "Unsupported particle renderable type", "OgreIlluminationManager::findRenderableInParticleSystem");
176
177        return NULL;
178}
179
180void OgreIlluminationManager::initTechniques(Entity* e)
181{
182        if( e->getParentSceneNode() == 0 )//Entity not attached
183                return;
184
185        OgreSharedRuns* sharedruns = 0;
186       
187        for(unsigned int s = 0; s < e->getNumSubEntities(); s++)
188        {
189                SubEntity* sube = e->getSubEntity(s);
190
191                Material* mat = sube->getMaterial().getPointer();
192               
193                OgreRenderable* rend = 0;       
194                OgreTechniqueGroup* group = 0;
195       
196                for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
197                {
198                        Technique* tech = mat->getTechnique(t);
199
200                        for(unsigned int p = 0; p< tech->getNumPasses(); p++)
201                        {
202                                Pass* pass = tech->getPass(p);
203
204                                std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
205                                std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
206                                std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
207                               
208                                while( i != iend)
209                                {
210                                        IllumTechniqueParams* params = *i;
211                                       
212                                        if(rend == 0)
213                                        {
214                                                rend = new OgreRenderable(e, s);
215                                                group = new OgreTechniqueGroup();
216                                                sube->setRenderTechniqueGroup(group);                                                   
217                                               
218                                                if( sharedruns == 0)
219                                                {                                                                       
220                                                        sharedruns  = new OgreSharedRuns();
221                                                        addSharedRuns(sharedruns);
222                                                }
223
224                                                group->addSharedRun(sharedruns);
225                                                sharedruns->addRenderable(rend);
226                                                sharedruns->updateBounds();
227                                        }
228                                       
229                                        createTechnique(params, pass, rend, sharedruns);
230
231                                        i++;
232                                }
233                        }
234                }
235        }
236
237               
238}
239
240
241void OgreIlluminationManager::initTechniques(BillboardSet* bbs, ParticleSystem* sys)
242{
243        if( bbs->getParentSceneNode() == 0 )//billboardset not attached
244                return;
245
246        OgreSharedRuns* sharedruns = 0;
247
248        Material* mat = bbs->getMaterial().getPointer();
249       
250        OgreRenderable* rend = 0;       
251        OgreTechniqueGroup* group = 0;
252
253        for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
254        {
255                Technique* tech = mat->getTechnique(t);
256
257                for(unsigned int p = 0; p< tech->getNumPasses(); p++)
258                {
259                        Pass* pass = tech->getPass(p);
260
261                        std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
262                        std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
263                        std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
264                       
265                        while( i != iend)
266                        {
267                                IllumTechniqueParams* params = *i;
268                               
269                                if(rend == 0)
270                                {
271                                        rend = new OgreRenderable(bbs, sys);
272                                        group = new OgreTechniqueGroup();
273                                        bbs->setRenderTechniqueGroup(group);                                                   
274                                       
275                                        if( sharedruns == 0)
276                                        {                                                                       
277                                                sharedruns  = new OgreSharedRuns();
278                                                addSharedRuns(sharedruns);
279                                        }
280
281                                        group->addSharedRun(sharedruns);
282                                        sharedruns->addRenderable(rend);
283                                        sharedruns->updateBounds();
284                                }
285                               
286                                createTechnique(params, pass, rend, sharedruns);
287
288                                i++;
289                        }
290                }
291        }
292                       
293}
294
295void OgreIlluminationManager::initTechniques()
296{
297        {
298                //Entities
299                SceneManager::MovableObjectIterator it = Root::getSingleton()._getCurrentSceneManager()
300                                                                                                        ->getMovableObjectIterator("Entity");
301                while(it.hasMoreElements())
302                {
303                        MovableObject* o = it.getNext();
304                        Entity* e = (Entity*) o;
305               
306                        initTechniques(e);
307                }
308        }
309        {
310                //ParticleSystems
311                SceneManager::MovableObjectIterator it = Root::getSingleton()._getCurrentSceneManager()
312                                                                                                        ->getMovableObjectIterator("ParticleSystem");
313                while(it.hasMoreElements())
314                {
315                        MovableObject* o = it.getNext();
316                        ParticleSystem* psys = (ParticleSystem*) o;
317                       
318                        try
319                        {
320                         BillboardSet* bbset = findRenderableInParticleSystem(psys);
321                         bbset->setMaterialName(psys->getMaterialName());
322                         initTechniques(bbset, psys);
323                        }
324                        catch( ... )
325                        {
326                                //unsupported particle renderer, skip init
327                        }
328                }
329        }
330}
331
332void OgreIlluminationManager::createTechnique(IllumTechniqueParams* params, Pass* pass, OgreRenderable* rend, OgreSharedRuns* sRuns)
333{
334        std::list<RenderTechniqueFactory*>::iterator it = techniqueFactories.begin();
335        std::list<RenderTechniqueFactory*>::iterator itend = techniqueFactories.end();
336
337        OgreTechniqueGroup* group = (OgreTechniqueGroup*) rend->getRenderable()->getRenderTechniqueGroup();     
338       
339                       
340        while(it != itend)
341        {
342                RenderTechniqueFactory* factory = *it;
343               
344               
345                if(factory->isType(params->getTypeName()))
346                {
347                       
348                        RenderTechnique* newTechnique = factory->createInstance(params,
349                                                                                                                                        pass,
350                                                                                                                                        rend,
351                                                                                                                                        group );
352
353                        group->addRenderTechnique(newTechnique);
354                       
355                }
356
357                it++;
358        }
359}
360void OgreIlluminationManager::preAllUpdates()
361{
362        std::vector<UpdateListener*>::iterator it = updateListeners.begin();
363        std::vector<UpdateListener*>::iterator itend = updateListeners.end();
364
365        while(it != itend)
366        {
367                UpdateListener* l = *it;
368                l->preAllUpdates();
369                it++;
370        }
371}
372
373void OgreIlluminationManager::postAllUpdates()
374{
375        std::vector<UpdateListener*>::iterator it = updateListeners.begin();
376        std::vector<UpdateListener*>::iterator itend = updateListeners.end();
377
378        while(it != itend)
379        {
380                UpdateListener* l = *it;
381                l->postAllUpdates();
382                it++;
383        }
384}
385
386void OgreIlluminationManager::update(unsigned long frameNumber, RenderTarget* rt)
387{
388
389        RenderSystem* renderSystem = Root::getSingleton().getRenderSystem();
390        SceneManager* sceneManager = Root::getSingleton()._getCurrentSceneManager();
391       
392        for(unsigned short i = 0; i<rt->getNumViewports();i++)
393        {
394                //find visible objects from the camera
395                RenderQueue* rq = sceneManager->getRenderQueue();
396                rq->clear();
397                RenderQueue::QueueGroupIterator groupIter = rq->_getQueueGroupIterator();
398                while (groupIter.hasMoreElements())
399                {
400                        RenderQueueGroup* g = groupIter.getNext();
401                        //g->addOrganisationMode(QueuedRenderableCollection::OM_SORT_ASCENDING);
402                        g->defaultOrganisationMode();
403                }
404               
405                //sceneManager->_findVisibleObjectsOC(rt->getViewport(i)->getCamera(), rt->getViewport(i), false, false, false);
406                sceneManager->_findVisibleObjects(rt->getViewport(i)->getCamera(), false);
407               
408                fillVisibleList(rq);   
409
410//              int l = visibleObjects.size(); //debug
411               
412                joinSharedRuns();
413
414//              int ll = sharedRunRoots.size(); //debug
415
416                //update precomputings                         
417                std::vector<const Renderable*>::iterator iter = visibleObjects.begin();
418                const std::vector<const Renderable*>::iterator iend = visibleObjects.end();
419
420                preAllUpdates();
421
422                while(iter != iend)
423                {
424                        const Renderable* rend = *iter;
425                        OgreTechniqueGroup* techniqueGroup = (OgreTechniqueGroup*) rend->getRenderTechniqueGroup();
426                        if(techniqueGroup != 0)
427                        {
428                                techniqueGroup->update(frameNumber);
429                        }
430                        iter++;
431                }
432
433                postAllUpdates();
434        }
435}
436
437void OgreIlluminationManager::sharedRunSplit(SharedRuns* old, SharedRuns* new1, SharedRuns* new2)
438{
439        sharedRunRoots.remove(old);
440        sharedRunRoots.push_back(new1);
441        sharedRunRoots.push_back(new2);
442}
443
444void OgreIlluminationManager::sharedRunJoin(SharedRuns* old1, SharedRuns* old2, SharedRuns* newsr)
445{
446        sharedRunRoots.remove(old1);
447        sharedRunRoots.remove(old2);
448        sharedRunRoots.push_back(newsr);
449}
450
451void OgreIlluminationManager::joinSharedRuns()
452{
453        std::list<SharedRuns*>::iterator it1 = sharedRunRoots.begin();
454        std::list<SharedRuns*>::iterator itend = sharedRunRoots.end();
455
456        bool again = false;
457
458        while(it1 != itend)
459        {
460                std::list<SharedRuns*>::iterator it2 = sharedRunRoots.begin();         
461               
462                while(it2 != itend)
463                {
464                        if( it1 != it2 && OgreSharedRuns::canJoin(*it1, *it2))
465                        {
466                                SharedRuns* newruns = (*it1)->joinRuns(*it2);
467                                sharedRunJoin(*it1, *it2, newruns);
468                                again = true;
469                                break;
470                        }
471                        it2++;
472                }
473
474                if(again)
475                        break;         
476
477                it1++;
478        }
479        if(again)
480        joinSharedRuns();
481
482}
483
484void OgreIlluminationManager::addSharedRuns(SharedRuns* runs)
485{
486        sharedRunRoots.push_back(runs);
487}
488
489void OgreIlluminationManager::getNearestCausticCasters(Vector3 position, std::vector<OgreSharedRuns*>* nearestcasters, unsigned int maxCount)
490{
491        sortfrom = position;
492        std::vector<OgreSharedRuns*> allcasters;
493        //fill casters
494        std::list<SharedRuns*>::iterator it = sharedRunRoots.begin();
495        std::list<SharedRuns*>::iterator itend = sharedRunRoots.end();
496        while(it != itend)
497        {
498                OgreSharedRuns* sr = (OgreSharedRuns*) (*it);
499               
500                sr->findSharedRootsForType(ILLUMRUN_CAUSTIC_CUBEMAP, allcasters);
501               
502                it++;
503        }
504
505        //sort
506        std::stable_sort(allcasters.begin(), allcasters.end(), sortFromVector());
507
508        for(unsigned int i = 0; i < maxCount && i < allcasters.size(); i++)
509        {
510                nearestcasters->push_back(allcasters.at(i));
511        }
512}
513
514void OgreIlluminationManager::createGlobalRun(RenderingRunType runType)
515{
516        switch(runType)
517        {
518                case ILLUMRUN_SCENE_CAMERA_DEPTH:
519                if(globalSharedRuns.getRun(ILLUMRUN_SCENE_CAMERA_DEPTH) == 0)
520                {
521                        OgreSceneCameraDepthRenderingRun* run = new OgreSceneCameraDepthRenderingRun
522                                (&globalSharedRuns, "ILLUMMODULE_SCENE_CAMERA_DEPTH", mainViewport);
523                        globalSharedRuns.addRun(ILLUMRUN_SCENE_CAMERA_DEPTH, run);
524                }
525                case ILLUMRUN_FOCUSING_MAP:
526                if(globalSharedRuns.getRun(ILLUMRUN_FOCUSING_MAP) == 0)
527                {
528                        OgreFocusingMapRenderingRun* run  = new OgreFocusingMapRenderingRun(
529                                "LIGHT_FOCUSING_MAP",                           
530                                Matrix4::IDENTITY,
531                                focusingMapSize
532                                );
533                        globalSharedRuns.addRun(ILLUMRUN_FOCUSING_MAP, run);
534                       
535                }
536                case ILLUMRUN_PHASE_TEXTURE:
537                if(globalSharedRuns.getRun(ILLUMRUN_PHASE_TEXTURE) == 0)
538                {
539                        OgrePhaseTextureRenderingRun* run  = new OgrePhaseTextureRenderingRun(
540                                "PHASE_TEXTURE",                               
541                                phaseTextureSize,
542                                phaseTextureSize,
543                                "Phase_HenyeyGreenStein");
544                        globalSharedRuns.addRun(ILLUMRUN_PHASE_TEXTURE, run);                   
545                }
546                break;
547        }
548}
549
550void OgreIlluminationManager::savePhaseTextureToFile(String filename)
551{
552        OgrePhaseTextureRenderingRun* r = (OgrePhaseTextureRenderingRun*)
553                globalSharedRuns.getRun(ILLUMRUN_PHASE_TEXTURE)->asOgreRenderingRun();
554        Texture* t = (Texture*) TextureManager::getSingleton().getByName(r->getPhaseTextureName()).getPointer();
555       
556        t->getBuffer()->getRenderTarget()->writeContentsToFile(filename);       
557}
558
559RenderingRun* OgreIlluminationManager::getGlobalRun(RenderingRunType runType)
560{
561        if(globalSharedRuns.getRun(runType) == 0)
562                createGlobalRun(runType);
563        return globalSharedRuns.getRun(runType);
564}
565
566GlobalUseRenderTarget* OgreIlluminationManager::getGlobalTarget(GlobalTargetType type)
567{
568        std::map<GlobalTargetType, GlobalUseRenderTarget*>::iterator it = globalTargets.find(type);
569       
570        if( it != globalTargets.end())
571                return (*it).second;
572
573        return 0;
574}
575
576void OgreIlluminationManager::addGlobalTarget(GlobalTargetType type, GlobalUseRenderTarget* target)
577{
578        globalTargets[type] = target; 
579}
580
581void OgreIlluminationManager::updateGlobalRun(RenderingRunType runType, unsigned long frameNum)
582{
583        globalSharedRuns.updateRun(runType, frameNum);
584}
585
586void OgreIlluminationManager::createPerLightRun(String lightName, RenderingRunType runType)
587{
588        OgreSharedRuns* runs = 0;
589       
590        if(perLightRuns.find(lightName) == perLightRuns.end())
591        {///create sharedruns
592                OgreSharedRuns* newruns = new OgreSharedRuns();
593                perLightRuns[lightName] = newruns;
594        }
595
596        runs = perLightRuns[lightName];
597
598    switch(runType)
599        {
600                case ILLUMRUN_DEPTH_SHADOWMAP:
601                if(runs->getRun(ILLUMRUN_DEPTH_SHADOWMAP) == 0)
602                {
603                        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
604                        OgreDepthShadowMapRenderingRun* run  = new OgreDepthShadowMapRenderingRun(
605                                runs,
606                                lightName + "DEPTH_SHADOW_MAP",
607                                sm->getLight(lightName),
608                                shadowMapSize,
609                                shadowMapSize,
610                                shadowMapMaterialName //TODO
611                                );
612                        runs->addRun(ILLUMRUN_DEPTH_SHADOWMAP, run);
613                       
614                }               
615                break;
616        }       
617}
618
619RenderingRun* OgreIlluminationManager::getPerLightRun(String lightName, RenderingRunType runType)
620{
621        return perLightRuns[lightName]->getRun(runType);
622}
623
624void OgreIlluminationManager::updatePerLightRun(String lightName, RenderingRunType runType, unsigned long frameNum)
625{
626        perLightRuns[lightName]->updateRun(runType, frameNum);
627}
628
Note: See TracBrowser for help on using the repository browser.