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

Revision 1639, 16.6 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       
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->_findVisibleObjects(rt->getViewport(i)->getCamera(),false);
404                fillVisibleList(rq);   
405
406//              int l = visibleObjects.size(); //debug
407               
408                joinSharedRuns();
409
410//              int ll = sharedRunRoots.size(); //debug
411
412                //update precomputings                         
413                std::vector<const Renderable*>::iterator iter = visibleObjects.begin();
414                const std::vector<const Renderable*>::iterator iend = visibleObjects.end();
415
416                preAllUpdates();
417
418                while(iter != iend)
419                {
420                        const Renderable* rend = *iter;
421                        OgreTechniqueGroup* techniqueGroup = (OgreTechniqueGroup*) rend->getRenderTechniqueGroup();
422                        if(techniqueGroup != 0)
423                        {
424                                techniqueGroup->update(frameNumber);
425                        }
426                        iter++;
427                }
428
429                postAllUpdates();
430
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                                "GameTools/ShadowMapDepth" //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.