source: OGRE/trunk/ogrenew/Samples/DeferredShading/src/DeferredShading.cpp @ 692

Revision 692, 11.5 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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        rttTex->bindSurface(0, mTexture0->getBuffer()->getRenderTarget());
271        rttTex->bindSurface(1, mTexture1->getBuffer()->getRenderTarget());
272        rttTex->setAutoUpdated( false );
273
274        // Setup viewport on 'fat' render target
275        Viewport* v = rttTex->addViewport( mCamera );
276        v->setClearEveryFrame( false );
277        v->setOverlaysEnabled( false );
278        v->setBackgroundColour( ColourValue( 0, 0, 0, 0) );
279        compMan.addCompositor(v, "DeferredShading/Fat");
280
281        // Create lights material generator
282        setupMaterial(MaterialManager::getSingleton().getByName("DeferredShading/LightMaterialQuad"));
283        setupMaterial(MaterialManager::getSingleton().getByName("DeferredShading/LightMaterial"));
284        if(Root::getSingleton().getRenderSystem()->getName()=="OpenGL Rendering Subsystem")
285                mLightMaterialGenerator = new LightMaterialGenerator("glsl");
286        else
287                mLightMaterialGenerator = new LightMaterialGenerator("hlsl");
288
289        // Create filters
290        mInstance[DSM_SINGLEPASS] = compMan.addCompositor(mViewport, "DeferredShading/Single");
291        mInstance[DSM_MULTIPASS] = compMan.addCompositor(mViewport, "DeferredShading/Multi");
292        mInstance[DSM_SHOWNORMALS] = compMan.addCompositor(mViewport, "DeferredShading/ShowNormal");
293        mInstance[DSM_SHOWDSP] = compMan.addCompositor(mViewport, "DeferredShading/ShowDepthSpecular");
294        mInstance[DSM_SHOWCOLOUR] = compMan.addCompositor(mViewport, "DeferredShading/ShowColour");
295
296        // Add material setup callback
297        for(int i=0; i<DSM_COUNT; ++i)
298                mInstance[i]->addListener(this);
299}
300void DeferredShadingSystem::setupMaterial(const MaterialPtr &mat)
301{
302        for(unsigned short i=0; i<mat->getNumTechniques(); ++i)
303        {
304                Pass *pass = mat->getTechnique(i)->getPass(0);
305                pass->getTextureUnitState(0)->setTextureName(mTexture0->getName());
306                pass->getTextureUnitState(1)->setTextureName(mTexture1->getName());
307        }
308}
309
310MLight *DeferredShadingSystem::createMLight()
311{
312        MLight *rv = new MLight(mLightMaterialGenerator);
313        rv->setVisibilityFlags(PostVisibilityMask);
314        mLights.insert(rv);
315
316        return rv;
317}
318void DeferredShadingSystem::destroyMLight(MLight *m)
319{
320        mLights.erase(m);
321        delete m;
322}
323
324void DeferredShadingSystem::update()
325{
326        rttTex->update();
327}
328
329void DeferredShadingSystem::notifyMaterialSetup(uint32 pass_id, MaterialPtr &mat)
330{
331        /// Local pass identifier 1 is the render quad pass
332        if(pass_id == 1)
333        {
334                setupMaterial(mat);
335        }
336}
Note: See TracBrowser for help on using the repository browser.