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

Revision 2166, 16.7 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 
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
434void OgreIlluminationManager::sharedRunSplit(SharedRuns* old, SharedRuns* new1, SharedRuns* new2)
435{
436        sharedRunRoots.remove(old);
437        sharedRunRoots.push_back(new1);
438        sharedRunRoots.push_back(new2);
439}
440
441void OgreIlluminationManager::sharedRunJoin(SharedRuns* old1, SharedRuns* old2, SharedRuns* newsr)
442{
443        sharedRunRoots.remove(old1);
444        sharedRunRoots.remove(old2);
445        sharedRunRoots.push_back(newsr);
446}
447
448void OgreIlluminationManager::joinSharedRuns()
449{
450        std::list<SharedRuns*>::iterator it1 = sharedRunRoots.begin();
451        std::list<SharedRuns*>::iterator itend = sharedRunRoots.end();
452
453        bool again = false;
454
455        while(it1 != itend)
456        {
457                std::list<SharedRuns*>::iterator it2 = sharedRunRoots.begin();         
458               
459                while(it2 != itend)
460                {
461                        if( it1 != it2 && OgreSharedRuns::canJoin(*it1, *it2))
462                        {
463                                SharedRuns* newruns = (*it1)->joinRuns(*it2);
464                                sharedRunJoin(*it1, *it2, newruns);
465                                again = true;
466                                break;
467                        }
468                        it2++;
469                }
470
471                if(again)
472                        break;         
473
474                it1++;
475        }
476        if(again)
477        joinSharedRuns();
478
479}
480
481void OgreIlluminationManager::addSharedRuns(SharedRuns* runs)
482{
483        sharedRunRoots.push_back(runs);
484}
485
486void OgreIlluminationManager::getNearestCausticCasters(Vector3 position, std::vector<OgreSharedRuns*>* nearestcasters, unsigned int maxCount)
487{
488        sortfrom = position;
489        std::vector<OgreSharedRuns*> allcasters;
490        //fill casters
491        std::list<SharedRuns*>::iterator it = sharedRunRoots.begin();
492        std::list<SharedRuns*>::iterator itend = sharedRunRoots.end();
493        while(it != itend)
494        {
495                OgreSharedRuns* sr = (OgreSharedRuns*) (*it);
496               
497                sr->findSharedRootsForType(ILLUMRUN_CAUSTIC_CUBEMAP, allcasters);
498               
499                it++;
500        }
501
502        //sort
503        std::stable_sort(allcasters.begin(), allcasters.end(), sortFromVector());
504
505        for(unsigned int i = 0; i < maxCount && i < allcasters.size(); i++)
506        {
507                nearestcasters->push_back(allcasters.at(i));
508        }
509}
510
511void OgreIlluminationManager::createGlobalRun(RenderingRunType runType)
512{
513        switch(runType)
514        {
515                case ILLUMRUN_SCENE_CAMERA_DEPTH:
516                if(globalSharedRuns.getRun(ILLUMRUN_SCENE_CAMERA_DEPTH) == 0)
517                {
518                        OgreSceneCameraDepthRenderingRun* run = new OgreSceneCameraDepthRenderingRun
519                                (&globalSharedRuns, "ILLUMMODULE_SCENE_CAMERA_DEPTH", mainViewport);
520                        globalSharedRuns.addRun(ILLUMRUN_SCENE_CAMERA_DEPTH, run);
521                }
522                case ILLUMRUN_FOCUSING_MAP:
523                if(globalSharedRuns.getRun(ILLUMRUN_FOCUSING_MAP) == 0)
524                {
525                        OgreFocusingMapRenderingRun* run  = new OgreFocusingMapRenderingRun(
526                                "LIGHT_FOCUSING_MAP",                           
527                                Matrix4::IDENTITY,
528                                focusingMapSize
529                                );
530                        globalSharedRuns.addRun(ILLUMRUN_FOCUSING_MAP, run);
531                       
532                }
533                case ILLUMRUN_PHASE_TEXTURE:
534                if(globalSharedRuns.getRun(ILLUMRUN_PHASE_TEXTURE) == 0)
535                {
536                        OgrePhaseTextureRenderingRun* run  = new OgrePhaseTextureRenderingRun(
537                                "PHASE_TEXTURE",                               
538                                phaseTextureSize,
539                                phaseTextureSize,
540                                "Phase_HenyeyGreenStein");
541                        globalSharedRuns.addRun(ILLUMRUN_PHASE_TEXTURE, run);                   
542                }
543                break;
544        }
545}
546
547void OgreIlluminationManager::savePhaseTextureToFile(String filename)
548{
549        OgrePhaseTextureRenderingRun* r = (OgrePhaseTextureRenderingRun*)
550                globalSharedRuns.getRun(ILLUMRUN_PHASE_TEXTURE)->asOgreRenderingRun();
551        Texture* t = (Texture*) TextureManager::getSingleton().getByName(r->getPhaseTextureName()).getPointer();
552       
553        t->getBuffer()->getRenderTarget()->writeContentsToFile(filename);       
554}
555
556RenderingRun* OgreIlluminationManager::getGlobalRun(RenderingRunType runType)
557{
558        if(globalSharedRuns.getRun(runType) == 0)
559                createGlobalRun(runType);
560        return globalSharedRuns.getRun(runType);
561}
562
563GlobalUseRenderTarget* OgreIlluminationManager::getGlobalTarget(GlobalTargetType type)
564{
565        std::map<GlobalTargetType, GlobalUseRenderTarget*>::iterator it = globalTargets.find(type);
566       
567        if( it != globalTargets.end())
568                return (*it).second;
569
570        return 0;
571}
572
573void OgreIlluminationManager::addGlobalTarget(GlobalTargetType type, GlobalUseRenderTarget* target)
574{
575        globalTargets[type] = target; 
576}
577
578void OgreIlluminationManager::updateGlobalRun(RenderingRunType runType, unsigned long frameNum)
579{
580        globalSharedRuns.updateRun(runType, frameNum);
581}
582
583void OgreIlluminationManager::createPerLightRun(String lightName, RenderingRunType runType)
584{
585        OgreSharedRuns* runs = 0;
586       
587        if(perLightRuns.find(lightName) == perLightRuns.end())
588        {///create sharedruns
589                OgreSharedRuns* newruns = new OgreSharedRuns();
590                perLightRuns[lightName] = newruns;
591        }
592
593        runs = perLightRuns[lightName];
594
595    switch(runType)
596        {
597                case ILLUMRUN_DEPTH_SHADOWMAP:
598                if(runs->getRun(ILLUMRUN_DEPTH_SHADOWMAP) == 0)
599                {
600                        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
601                        OgreDepthShadowMapRenderingRun* run  = new OgreDepthShadowMapRenderingRun(
602                                runs,
603                                lightName + "DEPTH_SHADOW_MAP",
604                                sm->getLight(lightName),
605                                shadowMapSize,
606                                shadowMapSize,
607                                shadowMapMaterialName //TODO
608                                );
609                        runs->addRun(ILLUMRUN_DEPTH_SHADOWMAP, run);
610                       
611                }               
612                break;
613        }       
614}
615
616RenderingRun* OgreIlluminationManager::getPerLightRun(String lightName, RenderingRunType runType)
617{
618        return perLightRuns[lightName]->getRun(runType);
619}
620
621void OgreIlluminationManager::updatePerLightRun(String lightName, RenderingRunType runType, unsigned long frameNum)
622{
623        perLightRuns[lightName]->updateRun(runType, frameNum);
624}
625
Note: See TracBrowser for help on using the repository browser.