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

Revision 2174, 16.8 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}
116
117OgreIlluminationManager::~OgreIlluminationManager()
118{
119       
120}
121
122OgreIlluminationManager& OgreIlluminationManager::getSingleton()
123{
124        if(instance == NULL)
125                instance= new OgreIlluminationManager();
126
127        return *instance;
128}
129
130void OgreIlluminationManager::fillVisibleList(  RenderQueue * rq )
131{
132        visibleObjects.clear();
133
134        RenderQueue::QueueGroupIterator queueIt = rq->_getQueueGroupIterator();
135   
136    while (queueIt.hasMoreElements())
137    {
138        RenderQueueGroup* pGroup = queueIt.getNext();
139               
140        RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
141
142                while (groupIt.hasMoreElements())
143                {
144                        RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
145                        const QueuedRenderableCollection& solids = pPriorityGrp->getSolidsBasic();
146                        const QueuedRenderableCollection& transparents = pPriorityGrp->getTransparents();
147                                                                       
148                        solids.acceptVisitor(visitor, QueuedRenderableCollection::OM_PASS_GROUP);
149                        transparents.acceptVisitor(visitor, QueuedRenderableCollection::OM_SORT_ASCENDING);             
150                }                       
151    }
152
153        rq->clear();   
154}
155
156BillboardSet* OgreIlluminationManager::findRenderableInParticleSystem(ParticleSystem* system)
157{
158        ParticleSystemRenderer* renderer = system->getRenderer();
159       
160        const String rendererType = renderer->getType();
161        if(rendererType == "billboard")
162        {
163                BillboardSet* bbSet = ((BillboardParticleRenderer*) renderer)->getBillboardSet();
164                return bbSet;
165        }
166
167        if(rendererType == "sprite")
168        {
169                BillboardSet* bbSet = ((SpriteParticleRenderer*) renderer)->getSpriteSet();
170                return bbSet;
171        }
172       
173        OGRE_EXCEPT(0, "Unsupported particle renderable type", "OgreIlluminationManager::findRenderableInParticleSystem");
174
175        return NULL;
176}
177
178void OgreIlluminationManager::initTechniques(Entity* e)
179{
180        if( e->getParentSceneNode() == 0 )//Entity not attached
181                return;
182
183        OgreSharedRuns* sharedruns = 0;
184       
185        for(unsigned int s = 0; s < e->getNumSubEntities(); s++)
186        {
187                SubEntity* sube = e->getSubEntity(s);
188
189                Material* mat = sube->getMaterial().getPointer();
190               
191                OgreRenderable* rend = 0;       
192                OgreTechniqueGroup* group = 0;
193       
194                for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
195                {
196                        Technique* tech = mat->getTechnique(t);
197
198                        for(unsigned int p = 0; p< tech->getNumPasses(); p++)
199                        {
200                                Pass* pass = tech->getPass(p);
201
202                                std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
203                                std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
204                                std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
205                               
206                                while( i != iend)
207                                {
208                                        IllumTechniqueParams* params = *i;
209                                       
210                                        if(rend == 0)
211                                        {
212                                                rend = new OgreRenderable(e, s);
213                                                group = new OgreTechniqueGroup();
214                                                sube->setRenderTechniqueGroup(group);                                                   
215                                               
216                                                if( sharedruns == 0)
217                                                {                                                                       
218                                                        sharedruns  = new OgreSharedRuns();
219                                                        addSharedRuns(sharedruns);
220                                                }
221
222                                                group->addSharedRun(sharedruns);
223                                                sharedruns->addRenderable(rend);
224                                                sharedruns->updateBounds();
225                                        }
226                                       
227                                        createTechnique(params, pass, rend, sharedruns);
228
229                                        i++;
230                                }
231                        }
232                }
233        }
234
235               
236}
237
238
239void OgreIlluminationManager::initTechniques(BillboardSet* bbs, ParticleSystem* sys)
240{
241        if( bbs->getParentSceneNode() == 0 )//billboardset not attached
242                return;
243
244        OgreSharedRuns* sharedruns = 0;
245
246        Material* mat = bbs->getMaterial().getPointer();
247       
248        OgreRenderable* rend = 0;       
249        OgreTechniqueGroup* group = 0;
250
251        for(unsigned int t = 0 ; t < mat->getNumTechniques() ; t++)
252        {
253                Technique* tech = mat->getTechnique(t);
254
255                for(unsigned int p = 0; p< tech->getNumPasses(); p++)
256                {
257                        Pass* pass = tech->getPass(p);
258
259                        std::vector<IllumTechniqueParams*>& techniques = pass->getIllumTechniques();
260                        std::vector<IllumTechniqueParams*>::iterator i = techniques.begin();
261                        std::vector<IllumTechniqueParams*>::iterator iend = techniques.end();
262                       
263                        while( i != iend)
264                        {
265                                IllumTechniqueParams* params = *i;
266                               
267                                if(rend == 0)
268                                {
269                                        rend = new OgreRenderable(bbs, sys);
270                                        group = new OgreTechniqueGroup();
271                                        bbs->setRenderTechniqueGroup(group);                                                   
272                                       
273                                        if( sharedruns == 0)
274                                        {                                                                       
275                                                sharedruns  = new OgreSharedRuns();
276                                                addSharedRuns(sharedruns);
277                                        }
278
279                                        group->addSharedRun(sharedruns);
280                                        sharedruns->addRenderable(rend);
281                                        sharedruns->updateBounds();
282                                }
283                               
284                                createTechnique(params, pass, rend, sharedruns);
285
286                                i++;
287                        }
288                }
289        }
290                       
291}
292
293void OgreIlluminationManager::initTechniques()
294{
295        {
296                //Entities
297                SceneManager::MovableObjectIterator it = Root::getSingleton()._getCurrentSceneManager()
298                                                                                                        ->getMovableObjectIterator("Entity");
299                while(it.hasMoreElements())
300                {
301                        MovableObject* o = it.getNext();
302                        Entity* e = (Entity*) o;
303               
304                        initTechniques(e);
305                }
306        }
307        {
308                //ParticleSystems
309                SceneManager::MovableObjectIterator it = Root::getSingleton()._getCurrentSceneManager()
310                                                                                                        ->getMovableObjectIterator("ParticleSystem");
311                while(it.hasMoreElements())
312                {
313                        MovableObject* o = it.getNext();
314                        ParticleSystem* psys = (ParticleSystem*) o;
315                       
316                        try
317                        {
318                         BillboardSet* bbset = findRenderableInParticleSystem(psys);
319                         bbset->setMaterialName(psys->getMaterialName());
320                         initTechniques(bbset, psys);
321                        }
322                        catch( ... )
323                        {
324                                //unsupported particle renderer, skip init
325                        }
326                }
327        }
328}
329
330void OgreIlluminationManager::createTechnique(IllumTechniqueParams* params, Pass* pass, OgreRenderable* rend, OgreSharedRuns* sRuns)
331{
332        std::list<RenderTechniqueFactory*>::iterator it = techniqueFactories.begin();
333        std::list<RenderTechniqueFactory*>::iterator itend = techniqueFactories.end();
334
335        OgreTechniqueGroup* group = (OgreTechniqueGroup*) rend->getRenderable()->getRenderTechniqueGroup();     
336       
337                       
338        while(it != itend)
339        {
340                RenderTechniqueFactory* factory = *it;
341               
342               
343                if(factory->isType(params->getTypeName()))
344                {
345                       
346                        RenderTechnique* newTechnique = factory->createInstance(params,
347                                                                                                                                        pass,
348                                                                                                                                        rend,
349                                                                                                                                        group );
350
351                        group->addRenderTechnique(newTechnique);
352                       
353                }
354
355                it++;
356        }
357}
358void OgreIlluminationManager::preAllUpdates()
359{
360        std::vector<UpdateListener*>::iterator it = updateListeners.begin();
361        std::vector<UpdateListener*>::iterator itend = updateListeners.end();
362
363        while(it != itend)
364        {
365                UpdateListener* l = *it;
366                l->preAllUpdates();
367                it++;
368        }
369}
370
371void OgreIlluminationManager::postAllUpdates()
372{
373        std::vector<UpdateListener*>::iterator it = updateListeners.begin();
374        std::vector<UpdateListener*>::iterator itend = updateListeners.end();
375
376        while(it != itend)
377        {
378                UpdateListener* l = *it;
379                l->postAllUpdates();
380                it++;
381        }
382}
383
384void OgreIlluminationManager::update(unsigned long frameNumber, RenderTarget* rt)
385{
386
387        RenderSystem* renderSystem = Root::getSingleton().getRenderSystem();
388        SceneManager* sceneManager = Root::getSingleton()._getCurrentSceneManager();
389       
390        for(unsigned short i = 0; i<rt->getNumViewports();i++)
391        {
392                //find visible objects from the camera
393                RenderQueue* rq = sceneManager->getRenderQueue();
394                rq->clear();
395                RenderQueue::QueueGroupIterator groupIter = rq->_getQueueGroupIterator();
396                while (groupIter.hasMoreElements())
397                {
398                        RenderQueueGroup* g = groupIter.getNext();
399                        //g->addOrganisationMode(QueuedRenderableCollection::OM_SORT_ASCENDING);
400                        g->defaultOrganisationMode();
401                }
402               
403                //sceneManager->_findVisibleObjectsOC(rt->getViewport(i)->getCamera(), rt->getViewport(i), false, true, false);
404                sceneManager->_findVisibleObjects(rt->getViewport(i)->getCamera(), false);
405               
406                fillVisibleList(rq);   
407
408//              int l = visibleObjects.size(); //debug
409               
410                joinSharedRuns();
411
412//              int ll = sharedRunRoots.size(); //debug
413
414                //update precomputings                         
415                std::vector<const Renderable*>::iterator iter = visibleObjects.begin();
416                const std::vector<const Renderable*>::iterator iend = visibleObjects.end();
417
418                preAllUpdates();
419
420                while(iter != iend)
421                {
422                        const Renderable* rend = *iter;
423                        OgreTechniqueGroup* techniqueGroup = (OgreTechniqueGroup*) rend->getRenderTechniqueGroup();
424                        if(techniqueGroup != 0)
425                        {
426                                techniqueGroup->update(frameNumber);
427                        }
428                        iter++;
429                }
430
431                postAllUpdates();
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.