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

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