source: GTP/trunk/Lib/Illum/IllumModule/OgreIllumModule/src/RenderingRuns/OgreLightVolumeRenderingRun.cpp @ 1722

Revision 1722, 7.4 KB checked in by szirmay, 18 years ago (diff)
Line 
1#include "OgreLightVolumeRenderingRun.h"
2#include "OgreIlluminationManager.h"
3#include "OgreChildPSystemRenderingRun.h"
4
5
6
7OgreLightVolumeRenderingRun::OgreLightVolumeRenderingRun(OgreSharedRuns* sharedRuns,
8                                                                                                                   String name,
9                                                                                                                   unsigned long startFrame,
10                                                                                                                        unsigned long updateInterval,
11                                                                                                                        unsigned int resolution,
12                                                                                                                        unsigned int textureDepth,
13                                                                                                                   String materialName
14                                                                                                                   )
15                                                                                                                   :LightVolumeRenderingRun( startFrame, updateInterval, resolution, textureDepth)
16                                                                                                                   , OgreRenderingRun(startFrame, updateInterval)
17                                                                                                                   , RenderingRun(startFrame, updateInterval)
18{
19        this->sharedRuns = sharedRuns;
20        this->name = name;     
21        this->light = 0;
22        this->materialName = materialName;
23
24        volumeBuffer = 0;
25       
26               
27
28        createLightVolumeMap();
29}
30
31void OgreLightVolumeRenderingRun::createLightVolumeMap()
32{
33        TexturePtr texPtr = Ogre::TextureManager::getSingleton().createManual(name,
34                                                                                                                                                "default",
35                                                                                                                                                TEX_TYPE_2D,
36                                                                                                                                                resolution,
37                                                                                                                                                resolution,
38                                                                                                                                                0,                                                                                                                                             
39                                                                                                                                                0,
40                                                                                                                                                PF_FLOAT16_RGBA,
41                                                                                                                                                TU_RENDERTARGET);
42        lightVolumeTexture = texPtr.getPointer();
43         lightVolumeCamera = Root::getSingleton()._getCurrentSceneManager()->createCamera(name + "_CAMERA");
44         //add viewport to rendertarget
45         HardwarePixelBuffer* hpb = (lightVolumeTexture->getBuffer()).getPointer();
46         RenderTarget* rt = hpb->getRenderTarget();
47         Viewport* v = rt->addViewport(lightVolumeCamera);
48         //Viewport* v = rt->addViewport(OgreIlluminationManager::getSingleton().getMainCamera());
49         v->setOverlaysEnabled(false);
50         v->setBackgroundColour(ColourValue::White);
51         rt->setAutoUpdated(false);
52
53         if(textureDepth > 1)
54         {
55                TexturePtr texPtr3D = Ogre::TextureManager::getSingleton().createManual(name + "3D",
56                                                                                                                                                "default",
57                                                                                                                                                TEX_TYPE_3D,
58                                                                                                                                                resolution,
59                                                                                                                                                resolution,
60                                                                                                                                                textureDepth + 1,
61                                                                                                                                                0,
62                                                                                                                                                PF_FLOAT16_RGBA,
63                                                                                                                                                TU_DYNAMIC);
64                lightVolumeTexture3D = texPtr3D.getPointer();
65         }
66}
67
68void OgreLightVolumeRenderingRun::createVolumeBuffer()
69{
70                unsigned int buffersize = resolution * resolution * 4 * 2 * (textureDepth + 1);
71                volumeBuffer = new unsigned char[buffersize];
72
73                SceneManager* sm = Ogre::Root::getSingleton()._getCurrentSceneManager();
74                RenderQueue* rq = sm->getRenderQueue();
75                RenderTarget* rt = lightVolumeTexture->getBuffer().getPointer()->getRenderTarget();
76                rq->clear();
77                //clear screen
78                sm->setFindVisibleObjects(false);
79                rt->update();
80                sm->setFindVisibleObjects(true);
81                //copy first slice
82                PixelBox volumePB(resolution, resolution, 3,PF_FLOAT16_RGBA, volumeBuffer);
83                PixelBox pb(resolution, resolution, 1,PF_FLOAT16_RGBA, volumeBuffer);
84                lightVolumeTexture->getBuffer()->blitToMemory(pb);
85                lightVolumeTexture3D->getBuffer()->blitFromMemory(volumePB);
86       
87}
88
89void OgreLightVolumeRenderingRun::updateFrame(unsigned long frameNum)
90{
91        if(textureDepth > 1 && volumeBuffer == 0)
92                createVolumeBuffer();
93
94        refreshLight();
95
96        SceneManager* sm = Ogre::Root::getSingleton()._getCurrentSceneManager();
97        RenderQueue* rq = sm->getRenderQueue();
98        rq->clear();
99
100        //((OgreSharedRuns*)sharedRuns->getRoot(ILLUMRUN_LIGHTVOLUME_MAP))->notifyCamera(lightVolumeCamera);
101        ((OgreSharedRuns*)sharedRuns->getRoot(ILLUMRUN_LIGHTVOLUME_MAP))->addRenderablesToQueue(rq, false);
102       
103        setMaterialForRenderables(materialName,rq);
104       
105        if(textureDepth == 1)
106        {
107                RenderTarget* rt = lightVolumeTexture->getBuffer().getPointer()->getRenderTarget();
108                rt->update();
109        }
110        else
111        {
112                //for(unsigned int i = 0; i < textureDepth; i++)
113                unsigned int i = frameNum % textureDepth;
114                {
115                        //set camera nearplane
116                        Matrix4 proj;
117                        proj = Matrix4::IDENTITY;
118                        float fustrumDepth = (i + 1) * systemRadius / ((float) textureDepth);
119                        proj.setScale(Vector3(1.0 / systemRadius, 1.0 / systemRadius, -2.0 / fustrumDepth));
120                        proj.setTrans(Vector3(0,0,-1));
121                        lightVolumeCamera->setCustomProjectionMatrix(true,proj);
122                        //render
123                        RenderTarget* rt = lightVolumeTexture->getBuffer().getPointer()->getRenderTarget();
124                        rt->update();
125                        //copy texture data
126                        PixelBox volumePB(resolution, resolution, textureDepth, PF_FLOAT16_RGBA, volumeBuffer);
127                        PixelBox pb(resolution, resolution, 1,PF_FLOAT16_RGBA,
128                                                volumeBuffer + (i + 1) * resolution * resolution * 4 * 2);
129                        lightVolumeTexture->getBuffer()->blitToMemory(pb);
130                        lightVolumeTexture3D->getBuffer()->blitFromMemory(volumePB);
131                }
132
133        }
134       
135        restoreMaterials();
136
137        /*
138        PixelBox volumePB(resolution, resolution, 3,PF_FLOAT16_RGBA, volumeBuffer);
139        PixelBox pb(resolution, resolution, 1,PF_FLOAT16_RGBA, volumeBuffer);
140        lightVolumeTexture->getBuffer()->blitToMemory(pb);
141        lightVolumeTexture3D->getBuffer()->blitFromMemory(volumePB);
142        */
143        /*
144        static int framecount = 0;
145        String filename = "lightvolume";
146        filename.append(this->name);
147        //filename.append(StringConverter::toString(framecount));
148        filename.append(".bmp");
149        if(framecount % 5 == 0)
150                rt->writeContentsToFile(filename);
151        framecount++;*/
152       
153
154       
155       
156}
157
158void OgreLightVolumeRenderingRun::refreshLight()
159{
160        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
161        LightList list;
162        sm->_populateLightList(((OgreSharedRuns*)sharedRuns)->getRootPosition(ILLUMRUN_LIGHTVOLUME_MAP),100000, list);
163       
164        light = *(list.begin());
165
166        //if herarchical
167        float baseRad = 0.0;
168        RenderingRun* run = sharedRuns->getRun(ILLUMRUN_HPP_IMPOSTOR);
169        if( run != 0)
170        {
171                OgreChildPSystemRenderingRun* rrun = (OgreChildPSystemRenderingRun*) run->asOgreRenderingRun();
172                baseRad = rrun->getSmallSysRadius();
173                //set gpu program params
174                Material* m = (Material*) MaterialManager::getSingleton().getByName(materialName).getPointer();
175                GpuProgramParametersSharedPtr vp = m->getTechnique(0)->getPass(0)->getVertexProgramParameters();
176                vp->setNamedConstant("baseRadius",baseRad);             
177        }
178
179        if(light!= 0)
180        {
181                if(light->getType() == Light::LT_DIRECTIONAL)
182                {
183                        Vector3 dir = light->getDirection();
184                        dir.normalise();
185                        lightVolumeCamera->setDirection( dir );
186                        Real r = sharedRuns->getRootBoundingSphere(ILLUMRUN_LIGHTVOLUME_MAP).getRadius();
187                        r += baseRad;
188                        systemRadius = r;
189                        lightVolumeCamera->setPosition( sharedRuns->getRootPosition(ILLUMRUN_LIGHTVOLUME_MAP) - dir * r);
190                        lightVolumeCamera->setProjectionType(PT_ORTHOGRAPHIC);
191                        Matrix4 proj;
192                        proj = Matrix4::IDENTITY;
193                        proj.setScale(Vector3(1.0/r, 1.0/r, -1.0/r));
194                        proj.setTrans(Vector3(0,0,-1));
195                        lightVolumeCamera->setCustomProjectionMatrix(true,proj);
196                }
197                else
198                {                       
199                        Vector3 pos = light->getParentSceneNode()->getPosition();
200                        Vector3 dir = sharedRuns->getRootPosition(ILLUMRUN_LIGHTVOLUME_MAP) - pos;
201                        dir.normalise();
202                        Real r = sharedRuns->getRootBoundingSphere(ILLUMRUN_LIGHTVOLUME_MAP).getRadius();
203                        r += baseRad;
204                        lightVolumeCamera->setPosition( sharedRuns->getRootPosition(ILLUMRUN_LIGHTVOLUME_MAP) - dir * r);
205                        lightVolumeCamera->lookAt( sharedRuns->getRootPosition(ILLUMRUN_LIGHTVOLUME_MAP) );                     
206                        lightVolumeCamera->setProjectionType(PT_ORTHOGRAPHIC);
207                        Matrix4 proj;
208                        proj = Matrix4::IDENTITY;
209                        proj.setScale(Vector3(1.0/r, 1.0/r, -1/r));
210                        proj.setTrans(Vector3(0,0,-1));
211                        lightVolumeCamera->setCustomProjectionMatrix(true,proj);
212                }
213        }
214}
215
216
217 
Note: See TracBrowser for help on using the repository browser.