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

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