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

Revision 2475, 9.2 KB checked in by szirmay, 17 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 + "NoBlur",
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
54
55   
56         texPtr = Ogre::TextureManager::getSingleton().createManual(name,
57                                                                                                                                                "default",
58                                                                                                                                                TEX_TYPE_2D,
59                                                                                                                                                resolution,
60                                                                                                                                                resolution,
61                                                                                                                                                0,                                                                                                                                             
62                                                                                                                                                0,
63                                                                                                                                                PF_FLOAT16_RGBA,
64                                                                                                                                                TU_RENDERTARGET);
65        lightVolumeTexture2 = texPtr.getPointer();
66        hpb = (lightVolumeTexture2->getBuffer()).getPointer();
67        rt = hpb->getRenderTarget();
68        v = rt->addViewport(lightVolumeCamera);
69        v->setOverlaysEnabled(false);
70        v->setBackgroundColour(ColourValue::White);
71        rt->setAutoUpdated(false);
72        v->setClearEveryFrame(true);
73        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
74        RenderQueue *rq = sm->getRenderQueue();
75        sm->setFindVisibleObjects(false);
76        rq->clear();
77        v->update();
78        sm->setFindVisibleObjects(true);
79        v->setClearEveryFrame(false);
80
81         if(textureDepth > 1)
82         {
83                TexturePtr texPtr3D = Ogre::TextureManager::getSingleton().createManual(name + "3D",
84                                                                                                                                                "default",
85                                                                                                                                                TEX_TYPE_3D,
86                                                                                                                                                resolution,
87                                                                                                                                                resolution,
88                                                                                                                                                textureDepth + 1,
89                                                                                                                                                0,
90                                                                                                                                                PF_FLOAT16_RGBA,
91                                                                                                                                                TU_DYNAMIC);
92                lightVolumeTexture3D = texPtr3D.getPointer();
93         }
94}
95
96void OgreLightVolumeRenderingRun::createVolumeBuffer()
97{
98                unsigned int buffersize = resolution * resolution * 4 * 2 * (textureDepth + 1);
99                volumeBuffer = new unsigned char[buffersize];
100
101                SceneManager* sm = Ogre::Root::getSingleton()._getCurrentSceneManager();
102                RenderQueue* rq = sm->getRenderQueue();
103                RenderTarget* rt = lightVolumeTexture->getBuffer().getPointer()->getRenderTarget();
104                rq->clear();
105                //clear screen
106                sm->setFindVisibleObjects(false);
107                rt->update();
108                sm->setFindVisibleObjects(true);
109                //copy first slice
110                PixelBox volumePB(resolution, resolution, 3,PF_FLOAT16_RGBA, volumeBuffer);
111                PixelBox pb(resolution, resolution, 1,PF_FLOAT16_RGBA, volumeBuffer);
112                lightVolumeTexture->getBuffer()->blitToMemory(pb);
113                lightVolumeTexture3D->getBuffer()->blitFromMemory(volumePB);
114       
115}
116
117void OgreLightVolumeRenderingRun::updateFrame(unsigned long frameNum)
118{
119        if(textureDepth > 1 && volumeBuffer == 0)
120                createVolumeBuffer();
121
122        refreshLight();
123
124        SceneManager* sm = Ogre::Root::getSingleton()._getCurrentSceneManager();
125        RenderQueue* rq = sm->getRenderQueue();
126        rq->clear();
127
128        //((OgreSharedRuns*)sharedRuns->getRoot(ILLUMRUN_LIGHTVOLUME_MAP))->notifyCamera(lightVolumeCamera);
129        ((OgreSharedRuns*)sharedRuns->getRoot(ILLUMRUN_LIGHTVOLUME_MAP))->addRenderablesToQueue(rq, false);
130       
131        setMaterialForRenderables(materialName,rq);
132       
133        if(textureDepth == 1)
134        {
135                RenderTarget* rt = lightVolumeTexture->getBuffer().getPointer()->getRenderTarget();
136                rt->update();
137                restoreMaterials();
138
139        //      rt->writeContentsToFile(name+"_lightVolume.bmp");
140                //do blending
141            rt = lightVolumeTexture2->getBuffer().getPointer()->getRenderTarget();
142            Material*  mat = (Material*) MaterialManager::getSingleton().getByName("GameTools/BlurLightVolume").getPointer();
143                mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(lightVolumeTexture->getName());
144                renderFullscreenQuad("GameTools/BlurLightVolume", rt);         
145
146        //      rt->writeContentsToFile(name+"_blurredlightVolume.bmp");
147        /*     
148                static int framecount = 0;
149                String filename = "lightvolume";
150                filename.append(this->name);
151                //filename.append(StringConverter::toString(framecount));
152                filename.append(".bmp");
153                if(framecount % 5 == 0)
154                        rt->writeContentsToFile(filename);
155                framecount++;
156*/
157        }
158        else
159        {
160                //for(unsigned int i = 0; i < textureDepth; i++)
161                unsigned int i = frameNum % textureDepth;
162                {
163                        //set camera nearplane
164                        Matrix4 proj;
165                        proj = Matrix4::IDENTITY;
166                        float fustrumDepth = (i + 1) * systemRadius / ((float) textureDepth);
167                        proj.setScale(Vector3(1.0 / systemRadius, 1.0 / systemRadius, -2.0 / fustrumDepth));
168                        proj.setTrans(Vector3(0,0,-1));
169                        lightVolumeCamera->setCustomProjectionMatrix(true,proj);
170                        //render
171                        RenderTarget* rt = lightVolumeTexture->getBuffer().getPointer()->getRenderTarget();
172                        rt->update();
173                        //copy texture data
174                        PixelBox volumePB(resolution, resolution, textureDepth, PF_FLOAT16_RGBA, volumeBuffer);
175                        PixelBox pb(resolution, resolution, 1,PF_FLOAT16_RGBA,
176                                                volumeBuffer + (i + 1) * resolution * resolution * 4 * 2);
177                        lightVolumeTexture->getBuffer()->blitToMemory(pb);
178                        lightVolumeTexture3D->getBuffer()->blitFromMemory(volumePB);
179                }
180                restoreMaterials();
181        }
182       
183       
184
185       
186
187        /*
188        PixelBox volumePB(resolution, resolution, 3,PF_FLOAT16_RGBA, volumeBuffer);
189        PixelBox pb(resolution, resolution, 1,PF_FLOAT16_RGBA, volumeBuffer);
190        lightVolumeTexture->getBuffer()->blitToMemory(pb);
191        lightVolumeTexture3D->getBuffer()->blitFromMemory(volumePB);
192        */
193       
194       
195
196       
197       
198}
199
200void OgreLightVolumeRenderingRun::refreshLight()
201{
202        Vector3 center = sharedRuns->getRootPosition(ILLUMRUN_LIGHTVOLUME_MAP);
203                       
204        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
205        LightList list;
206        sm->_populateLightList(center, 100000, list);
207       
208        light = *(list.begin());
209
210        //if herarchical
211        float baseRad = 0.0;
212        RenderingRun* run = sharedRuns->getRun(ILLUMRUN_HPP_IMPOSTOR);
213        if( run != 0)
214        {
215                OgreChildPSystemRenderingRun* rrun = (OgreChildPSystemRenderingRun*) run->asOgreRenderingRun();
216                baseRad = rrun->getSmallSysRadius();
217                //set gpu program params
218                Material* m = (Material*) MaterialManager::getSingleton().getByName(materialName).getPointer();
219                GpuProgramParametersSharedPtr vp = m->getTechnique(0)->getPass(0)->getVertexProgramParameters();
220                vp->setNamedConstant("baseRadius",baseRad);             
221        }
222
223        if(light!= 0)
224        {
225                if(light->getType() == Light::LT_DIRECTIONAL)
226                {
227                        Vector3 dir = light->getDirection();
228                        dir.normalise();
229                        lightVolumeCamera->setDirection( dir );
230                        Real r = sharedRuns->getRootBoundingSphere(ILLUMRUN_LIGHTVOLUME_MAP).getRadius();
231                        //r += baseRad;
232                        systemRadius = r;
233                        lightVolumeCamera->setPosition( sharedRuns->getRootPosition(ILLUMRUN_LIGHTVOLUME_MAP) - dir * r);
234                        lightVolumeCamera->setProjectionType(PT_ORTHOGRAPHIC);
235                        Matrix4 proj;
236                        proj = Matrix4::IDENTITY;
237                        proj.setScale(Vector3(1.0/r, 1.0/r, -1.0/r));
238                        proj.setTrans(Vector3(0,0,-1));
239                        lightVolumeCamera->setCustomProjectionMatrix(true,proj);
240                }
241                else
242                {                       
243                        Vector3 pos = light->getDerivedPosition();
244                        Vector3 dir = center - pos;
245                        Real r = sharedRuns->getRootBoundingSphere(ILLUMRUN_LIGHTVOLUME_MAP).getRadius();
246                        //r += baseRad;
247                        Real d = dir.length();
248                        dir.normalise();
249                        /*float mindist = 1.5 * r;
250                        if(d < mindist)
251                        {
252                                pos -= dir * (mindist - d) ;
253                                d = mindist;
254                        }*/
255                        lightVolumeCamera->setPosition( center - dir * d);
256                        lightVolumeCamera->lookAt( center );                   
257                        lightVolumeCamera->setProjectionType(PT_ORTHOGRAPHIC);
258                        Matrix4 proj;
259                        proj = Matrix4::IDENTITY;
260                        proj.setScale(Vector3(1.0/r, 1.0/r, -1/r));
261                        proj.setTrans(Vector3(0,0,-1));
262                        lightVolumeCamera->setCustomProjectionMatrix(true,proj);
263                }
264        }
265}
266
267void OgreLightVolumeRenderingRun::freeAllResources()
268{
269        this->lightVolumeTexture = 0;
270        this->lightVolumeTexture2 = 0;
271        this->lightVolumeTextureLast = 0;
272        this->lightVolumeTextureThis = 0;
273        this->lightVolumeTexture3D = 0;
274        TextureManager::getSingleton().remove(name);
275        TextureManager::getSingleton().remove(name + "NoBlur");
276        Root::getSingleton()._getCurrentSceneManager()->destroyCamera(name + "_CAMERA");       
277}
278
279
280 
Note: See TracBrowser for help on using the repository browser.