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

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