Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Samples/DeferredShading/src/DeferredShading.cpp @ 1

Last change on this file since 1 was 1, checked in by landauf, 17 years ago
File size: 11.8 KB
Line 
1/******************************************************************************
2Copyright (c) W.J. van der Laan
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of
5this software  and associated documentation files (the "Software"), to deal in
6the Software without restriction, including without limitation the rights to use,
7copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
8Software, and to permit persons to whom the Software is furnished to do so, subject
9to the following conditions:
10
11The above copyright notice and this permission notice shall be included in all copies
12or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
18OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE
19SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20******************************************************************************/
21
22#include "DeferredShading.h"
23
24#include "OgreConfigFile.h"
25#include "OgreStringConverter.h"
26#include "OgreException.h"
27
28#include "OgreHardwarePixelBuffer.h"
29#include "OgreRoot.h"
30#include "OgreRenderSystem.h"
31#include "OgreMaterialManager.h"
32
33#include "OgreEntity.h"
34#include "OgreSubEntity.h"
35#include "OgreRoot.h"
36
37#include "OgreCompositor.h"
38#include "OgreCompositorManager.h"
39#include "OgreCompositorChain.h"
40#include "OgreCompositorInstance.h"
41#include "OgreCompositionTechnique.h"
42#include "OgreCompositionPass.h"
43#include "OgreCompositionTargetPass.h"
44
45#include "MLight.h"
46#include "LightMaterialGenerator.h"
47
48#include "OgreHighLevelGpuProgram.h"
49#include "OgreHighLevelGpuProgramManager.h"
50
51using namespace Ogre;
52
53/// XXX make this a .compositor script
54void createPostFilters()
55{
56        /** Postfilter for rendering to fat render target. Excludes skies, backgrounds and other unwanted
57                objects.
58        */
59        CompositorPtr comp7 = CompositorManager::getSingleton().create(
60                                "DeferredShading/Fat", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
61                        );
62        {
63                CompositionTechnique *t = comp7->createTechnique();
64                {
65                        CompositionTargetPass *tp = t->getOutputTargetPass();
66                        tp->setInputMode(CompositionTargetPass::IM_NONE);
67                        tp->setVisibilityMask(DeferredShadingSystem::SceneVisibilityMask);
68                        /// Clear
69                        {       CompositionPass *pass = tp->createPass();
70                                pass->setType(CompositionPass::PT_CLEAR);
71                                pass->setClearColour(ColourValue(0,0,0,0));
72                        }
73                        /// Render geometry
74                        {       CompositionPass *pass = tp->createPass();
75                                pass->setType(CompositionPass::PT_RENDERSCENE);
76                                pass->setFirstRenderQueue(RENDER_QUEUE_1);
77                                pass->setLastRenderQueue(RENDER_QUEUE_9);
78                        }
79                }
80        }
81        /** Postfilter doing full deferred shading with two lights in one pass
82        */
83        CompositorPtr comp = CompositorManager::getSingleton().create(
84                                "DeferredShading/Single", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
85                        );
86        {
87                CompositionTechnique *t = comp->createTechnique();
88                {
89                        CompositionTargetPass *tp = t->getOutputTargetPass();
90                        tp->setInputMode(CompositionTargetPass::IM_NONE);
91                        tp->setVisibilityMask(DeferredShadingSystem::PostVisibilityMask);
92                        /// Render skies
93                        {       CompositionPass *pass = tp->createPass();
94                                pass->setType(CompositionPass::PT_RENDERSCENE);
95                                pass->setFirstRenderQueue(RENDER_QUEUE_SKIES_EARLY);
96                                pass->setLastRenderQueue(RENDER_QUEUE_SKIES_EARLY);
97                        }
98                        /// Render ambient pass
99                        {       CompositionPass *pass = tp->createPass();
100                                pass->setType(CompositionPass::PT_RENDERQUAD);
101                                pass->setMaterialName("DeferredShading/Post/Single");
102                                pass->setIdentifier(1);
103                        }
104                        /// Render overlayed geometry
105                        {       CompositionPass *pass = tp->createPass();
106                                pass->setType(CompositionPass::PT_RENDERSCENE);
107                                pass->setFirstRenderQueue(RENDER_QUEUE_1);
108                                pass->setLastRenderQueue(RENDER_QUEUE_9);
109                        }
110                }
111        }
112        /** Postfilter doing full deferred shading with an ambient pass and multiple light passes
113        */
114        CompositorPtr comp2 = CompositorManager::getSingleton().create(
115                                "DeferredShading/Multi", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
116                        );
117        {
118                CompositionTechnique *t = comp2->createTechnique();
119                {
120                        CompositionTargetPass *tp = t->getOutputTargetPass();
121                        tp->setInputMode(CompositionTargetPass::IM_NONE);
122                        tp->setVisibilityMask(DeferredShadingSystem::PostVisibilityMask);
123                        /// Render skies
124                        {       CompositionPass *pass = tp->createPass();
125                                pass->setType(CompositionPass::PT_RENDERSCENE);
126                                pass->setFirstRenderQueue(RENDER_QUEUE_SKIES_EARLY);
127                                pass->setLastRenderQueue(RENDER_QUEUE_SKIES_EARLY);
128                        }
129                        /// Render ambient pass
130                        {       CompositionPass *pass = tp->createPass();
131                                pass->setType(CompositionPass::PT_RENDERQUAD);
132                                pass->setMaterialName("DeferredShading/Post/Multi");
133                                pass->setIdentifier(1);
134                        }
135                        /// Render overlayed geometry
136                        {
137                                CompositionPass *pass = tp->createPass();
138                                pass->setType(CompositionPass::PT_RENDERSCENE);
139                                pass->setFirstRenderQueue(RENDER_QUEUE_1);
140                                pass->setLastRenderQueue(RENDER_QUEUE_9);
141                        }
142                }
143        }       
144        /** Postfilter that shows the normal channel
145        */
146        CompositorPtr comp3 = CompositorManager::getSingleton().create(
147                                "DeferredShading/ShowNormal", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
148                        );
149        {
150                CompositionTechnique *t = comp3->createTechnique();
151                {
152                        CompositionTargetPass *tp = t->getOutputTargetPass();
153                        tp->setInputMode(CompositionTargetPass::IM_NONE);
154                        {       CompositionPass *pass = tp->createPass();
155                                pass->setType(CompositionPass::PT_RENDERQUAD);
156                                pass->setMaterialName("DeferredShading/Post/ShowNormal");
157                                pass->setIdentifier(1);
158                        }
159                }
160        }       
161        /** Postfilter that shows the depth and specular channel
162        */
163        CompositorPtr comp4 = CompositorManager::getSingleton().create(
164                                "DeferredShading/ShowDepthSpecular", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
165                        );
166        {
167                CompositionTechnique *t = comp4->createTechnique();
168                {
169                        CompositionTargetPass *tp = t->getOutputTargetPass();
170                        tp->setInputMode(CompositionTargetPass::IM_NONE);
171                        {       CompositionPass *pass = tp->createPass();
172                                pass->setType(CompositionPass::PT_RENDERQUAD);
173                                pass->setMaterialName("DeferredShading/Post/ShowDS");
174                                pass->setIdentifier(1);
175                        }
176                }
177        }       
178        /** Postfilter that shows the depth and specular channel
179        */
180        CompositorPtr comp5 = CompositorManager::getSingleton().create(
181                                "DeferredShading/ShowColour", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
182                        );
183        {
184                CompositionTechnique *t = comp5->createTechnique();
185                {
186                        CompositionTargetPass *tp = t->getOutputTargetPass();
187                        tp->setInputMode(CompositionTargetPass::IM_NONE);
188                        {       CompositionPass *pass = tp->createPass();
189                                pass->setType(CompositionPass::PT_RENDERQUAD);
190                                pass->setMaterialName("DeferredShading/Post/ShowColour");
191                                pass->setIdentifier(1);
192                        }
193                }
194        }
195}
196
197
198DeferredShadingSystem::DeferredShadingSystem(
199                Viewport *vp, SceneManager *sm,  Camera *cam
200        ):
201        mSceneMgr(sm), mViewport(vp), mCamera(cam),
202                mLightMaterialGenerator(0)
203{
204        for(int i=0; i<DSM_COUNT; ++i)
205                mInstance[i]=0;
206
207        mActive = true;
208        mCurrentMode = DSM_MULTIPASS;
209
210        rttTex = 0;
211
212        createPostFilters();
213
214        createResources();
215        // Hide post geometry
216        mSceneMgr->setVisibilityMask(mSceneMgr->getVisibilityMask() & ~PostVisibilityMask);
217        // Default to normal deferred shading mode
218        setMode(mCurrentMode);
219        setActive(true);
220}
221
222DeferredShadingSystem::~DeferredShadingSystem()
223{
224        // Delete mini lights
225        for(std::set<MLight*>::iterator i=mLights.begin(); i!=mLights.end(); ++i)
226        {
227                delete (*i);
228        }
229
230        Ogre::CompositorChain *chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mViewport);
231        for(int i=0; i<DSM_COUNT; ++i)
232                chain->_removeInstance(mInstance[i]);
233
234        delete mLightMaterialGenerator;
235}
236void DeferredShadingSystem::setMode(DSMode mode)
237{
238        for(int i=0; i<DSM_COUNT; ++i)
239        {
240                if(i == mode)
241                        mInstance[i]->setEnabled(mActive);
242                else
243                        mInstance[i]->setEnabled(false);
244        }
245        mCurrentMode = mode;
246}
247void DeferredShadingSystem::setActive(bool active)
248{
249        mActive = active;
250        setMode(mCurrentMode);
251}
252void DeferredShadingSystem::createResources(void)
253{
254        Ogre::CompositorManager &compMan = Ogre::CompositorManager::getSingleton();
255        // Create 'fat' render target
256        unsigned int width = mViewport->getActualWidth();
257        unsigned int height = mViewport->getActualHeight();
258        PixelFormat format = PF_FLOAT16_RGBA;
259        //PixelFormat format = PF_SHORT_RGBA;
260
261        mTexture0 = TextureManager::getSingleton().createManual("RttTex0", 
262                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 
263                width, height, 0, format, TU_RENDERTARGET );
264        mTexture1 = TextureManager::getSingleton().createManual("RttTex1", 
265                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 
266                width, height, 0, format, TU_RENDERTARGET );
267        //assert(mTexture0->getFormat() == format);
268        //assert(mTexture1->getFormat() == format);
269        rttTex = Ogre::Root::getSingleton().getRenderSystem()->createMultiRenderTarget("MRT");
270    RenderTexture* rt0 = mTexture0->getBuffer()->getRenderTarget();
271    RenderTexture* rt1 = mTexture1->getBuffer()->getRenderTarget();
272    rt0->setAutoUpdated(false);
273    rt1->setAutoUpdated(false);
274        rttTex->bindSurface(0, rt0);
275        rttTex->bindSurface(1, rt1);
276        rttTex->setAutoUpdated( false );
277
278        // Setup viewport on 'fat' render target
279        Viewport* v = rttTex->addViewport( mCamera );
280        v->setClearEveryFrame( false );
281        v->setOverlaysEnabled( false );
282    // Should disable skies for MRT due it's not designed for that, and
283    // will causing NVIDIA refusing write anything to other render targets
284    // for some reason.
285    v->setSkiesEnabled(false);
286        v->setBackgroundColour( ColourValue( 0, 0, 0, 0) );
287        compMan.addCompositor(v, "DeferredShading/Fat");
288
289        // Create lights material generator
290        setupMaterial(MaterialManager::getSingleton().getByName("DeferredShading/LightMaterialQuad"));
291        setupMaterial(MaterialManager::getSingleton().getByName("DeferredShading/LightMaterial"));
292        if(Root::getSingleton().getRenderSystem()->getName()=="OpenGL Rendering Subsystem")
293                mLightMaterialGenerator = new LightMaterialGenerator("glsl");
294        else
295                mLightMaterialGenerator = new LightMaterialGenerator("hlsl");
296
297        // Create filters
298        mInstance[DSM_SINGLEPASS] = compMan.addCompositor(mViewport, "DeferredShading/Single");
299        mInstance[DSM_MULTIPASS] = compMan.addCompositor(mViewport, "DeferredShading/Multi");
300        mInstance[DSM_SHOWNORMALS] = compMan.addCompositor(mViewport, "DeferredShading/ShowNormal");
301        mInstance[DSM_SHOWDSP] = compMan.addCompositor(mViewport, "DeferredShading/ShowDepthSpecular");
302        mInstance[DSM_SHOWCOLOUR] = compMan.addCompositor(mViewport, "DeferredShading/ShowColour");
303
304        // Add material setup callback
305        for(int i=0; i<DSM_COUNT; ++i)
306                mInstance[i]->addListener(this);
307}
308void DeferredShadingSystem::setupMaterial(const MaterialPtr &mat)
309{
310        for(unsigned short i=0; i<mat->getNumTechniques(); ++i)
311        {
312                Pass *pass = mat->getTechnique(i)->getPass(0);
313                pass->getTextureUnitState(0)->setTextureName(mTexture0->getName());
314                pass->getTextureUnitState(1)->setTextureName(mTexture1->getName());
315        }
316}
317
318MLight *DeferredShadingSystem::createMLight()
319{
320        MLight *rv = new MLight(mLightMaterialGenerator);
321        rv->setVisibilityFlags(PostVisibilityMask);
322        mLights.insert(rv);
323
324        return rv;
325}
326void DeferredShadingSystem::destroyMLight(MLight *m)
327{
328        mLights.erase(m);
329        delete m;
330}
331
332void DeferredShadingSystem::update()
333{
334        rttTex->update();
335}
336
337void DeferredShadingSystem::notifyMaterialSetup(uint32 pass_id, MaterialPtr &mat)
338{
339        /// Local pass identifier 1 is the render quad pass
340        if(pass_id == 1)
341        {
342                setupMaterial(mat);
343        }
344}
Note: See TracBrowser for help on using the repository browser.