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

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