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

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

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10You may use this sample code for anything you like, it is not covered by the
11LGPL like the rest of the engine.
12-----------------------------------------------------------------------------
13*/
14
15/**
16    \file
17        Compositor.cpp
18    \brief
19        Shows OGRE's Compositor feature
20        \author
21                W.J. :wumpus: van der Laan
22                        Ogre composition framework
23                Manuel Bua
24                        Postfilter ideas and original out-of-core implementation
25*/
26
27#include "ExampleApplication.h"
28#include "ExampleFrameListener.h"
29
30#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
31#define WIN32_LEAN_AND_MEAN
32#include "windows.h"
33#endif
34#include <OgreCompositor.h>
35#include <OgreCompositorManager.h>
36#include <OgreCompositorChain.h>
37#include <OgreCompositorInstance.h>
38#include <OgreCompositionTechnique.h>
39#include <OgreCompositionPass.h>
40#include <OgreCompositionTargetPass.h>
41
42
43    /** Listener that keeps and updates private parameters for a HeatVision instance.
44    */
45    class HeatVisionListener: public CompositorInstance::Listener
46    {
47    public:
48        HeatVisionListener()
49        {
50            timer = PlatformManager::getSingleton().createTimer();
51            start = end = curr = 0.0f;
52        }
53        virtual ~HeatVisionListener()
54        {
55            PlatformManager::getSingleton().destroyTimer(timer);
56        }
57        virtual void notifyMaterialSetup(uint32 pass_id, MaterialPtr &mat)
58        {
59            if(pass_id == 0xDEADBABE)
60            {
61                timer->reset();
62                fpParams =
63                    mat->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
64            }
65        }
66        virtual void notifyMaterialRender(uint32 pass_id, MaterialPtr &mat)
67        {
68            if(pass_id == 0xDEADBABE)
69            {
70                // "random_fractions" parameter
71                fpParams->setNamedConstant("random_fractions", Vector4(Math::RangeRandom(0.0, 1.0), Math::RangeRandom(0, 1.0), 0, 0));
72
73                // "depth_modulator" parameter
74                float inc = ((float)timer->getMilliseconds())/1000.0f;
75                if ( (abs(curr-end) <= 0.001) ) {
76                    // take a new value to reach
77                    end = Math::RangeRandom(0.95, 1.0);
78                    start = curr;
79                } else {
80                    if (curr > end) curr -= inc;
81                    else curr += inc;
82                }
83                timer->reset();
84
85                fpParams->setNamedConstant("depth_modulator", Vector4(curr, 0, 0, 0));
86            }
87        }
88    protected:
89        GpuProgramParametersSharedPtr fpParams;
90        float start, end, curr;
91        Timer *timer;
92    };
93
94    class CompositorFrameListener : public ExampleFrameListener
95    {
96    protected:
97        float timeoutDelay;
98        HeatVisionListener *hvListener;
99
100        struct CompositorEntry
101        {
102            String CompositorName;
103            String DisplayName;
104            bool Enabled;
105            KeyCode KCode;
106
107            CompositorEntry(void) : Enabled(false), KCode(KC_A) {}
108            CompositorEntry(const String& compName, const String& dispName, KeyCode keyCode)
109                : CompositorName(compName)
110                , DisplayName(dispName)
111                , Enabled(false)
112                , KCode(keyCode)
113                {}
114        };
115
116        typedef std::vector<CompositorEntry> CompositorEntryContainer;
117        typedef CompositorEntryContainer::iterator CompositorEntryIterator;
118
119        CompositorEntryContainer mRegisteredCompositors;
120
121        OverlayElement* mDescText;
122
123    public:
124        CompositorFrameListener(RenderWindow* window, Camera* maincam)
125            :ExampleFrameListener(window, maincam)
126            , hvListener(0)
127        {
128            timeoutDelay = 0;
129            mDescText = OverlayManager::getSingleton().getOverlayElement("Example/Compositor/ActiveText");
130            mDescText->setCaption("None");
131            mRegisteredCompositors.reserve(15);
132
133            registerCompositors();
134        }
135        ~CompositorFrameListener()
136        {
137            delete hvListener;
138        }
139
140        void registerCompositors(void)
141        {
142            mRegisteredCompositors.push_back(CompositorEntry("Bloom",       "[Bloom] ",         KC_1));
143            mRegisteredCompositors.push_back(CompositorEntry("Embossed",    "[Embossed] ",              KC_2));
144            mRegisteredCompositors.push_back(CompositorEntry("Glass",       "[Glass] ",         KC_3));
145            mRegisteredCompositors.push_back(CompositorEntry("MotionBlur",  "[Motion Blur] ",   KC_4));
146            mRegisteredCompositors.push_back(CompositorEntry("Old TV",      "[Old TV] ",        KC_6));
147            mRegisteredCompositors.push_back(CompositorEntry("B&W",         "[B&W]",            KC_7));
148            mRegisteredCompositors.push_back(CompositorEntry("DOF",         "[DOF] ",           KC_8));
149
150            Viewport *vp = mWindow->getViewport(0);
151
152            CompositorEntryIterator currentCompEntry = mRegisteredCompositors.begin();
153            while (currentCompEntry != mRegisteredCompositors.end())
154            {
155                /// Add compositors to main viewport
156                CompositorManager::getSingleton().addCompositor(vp, currentCompEntry->CompositorName);
157                CompositorManager::getSingleton().setCompositorEnabled(vp, currentCompEntry->CompositorName, false);
158
159                ++currentCompEntry;
160            }
161
162            hvListener = new HeatVisionListener();
163            CompositorInstance *instance = CompositorManager::getSingleton().addCompositor(vp, "HeatVision");
164            mRegisteredCompositors.push_back(CompositorEntry("HeatVision",  "[Heat Vision] ",   KC_5));
165            CompositorManager::getSingleton().setCompositorEnabled(vp, "HeatVision", false);
166            if(instance)
167                instance->addListener(hvListener);
168        }
169
170        bool frameStarted(const FrameEvent& evt)
171        {
172            bool result = ExampleFrameListener::frameStarted(evt);
173
174            return result;
175        }
176
177        virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
178        {
179            bool retval = ExampleFrameListener::processUnbufferedKeyInput(evt);
180            timeoutDelay -= evt.timeSinceLastFrame;
181
182            if(timeoutDelay < 0.0f)
183            {
184
185                timeoutDelay = 0.0f;
186                Viewport *vp = mWindow->getViewport(0);
187
188                CompositorEntryIterator currentCompEntry = mRegisteredCompositors.begin();
189                while (currentCompEntry != mRegisteredCompositors.end())
190                {
191                    if(mInputDevice->isKeyDown(currentCompEntry->KCode))
192                    {
193                        currentCompEntry->Enabled = !currentCompEntry->Enabled;
194                        CompositorManager::getSingleton().setCompositorEnabled(vp, currentCompEntry->CompositorName, currentCompEntry->Enabled);
195                        timeoutDelay = 0.5f;
196                    }
197
198                    ++currentCompEntry;
199                }
200
201                if (timeoutDelay >= 0.5f)
202                {
203                    StringUtil::StrStreamType txt;
204
205                    currentCompEntry = mRegisteredCompositors.begin();
206                    while (currentCompEntry != mRegisteredCompositors.end())
207                    {
208                        if(currentCompEntry->Enabled)
209                        {
210                            txt << currentCompEntry->DisplayName;
211                        }
212
213                        ++currentCompEntry;
214                    }
215
216                    if (txt.str().empty())
217                        txt << "None ";
218
219                    mDescText->setCaption(txt.str());
220                }
221            }
222            return retval;
223        }
224    };
225
226// ********** Currently not used
227//    class SceneEffectController :  public RenderTargetListener
228//    {
229//        void preRenderTargetUpdate(const RenderTargetEvent& evt)
230//        {
231//            // Hide plane
232//            mPlaneEnt->setVisible(false);
233//
234//        }
235//        void postRenderTargetUpdate(const RenderTargetEvent& evt)
236//        {
237//            // Show plane
238//            mPlaneEnt->setVisible(true);
239//        }
240//
241//    protected:
242//
243//        MovablePlane* mPlane;
244//        Entity* mPlaneEnt;
245//        SceneNode* mPlaneNode;
246//
247//    public:
248//        SceneEffectController() : mPlane(0) {}
249//        ~SceneEffectController()
250//        {
251//            delete mPlane;
252//        }
253//
254//
255//    };
256
257class CompositorApplication : public ExampleApplication
258{
259
260public:
261    CompositorApplication() {}
262    ~CompositorApplication()
263    {
264    }
265
266protected:
267
268    // render target events
269
270        /// Create the postfilter effects
271        /// This will be replaced with a .compositor script as soon as the script parser is
272        /// finished.
273        void createEffects()
274        {
275            // Bloom compositor is loaded from script but here is the hard coded equivalent
276//              CompositorPtr comp = CompositorManager::getSingleton().create(
277//                              "Bloom", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
278//                      );
279//              {
280//                      CompositionTechnique *t = comp->createTechnique();
281//                      {
282//                              CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("rt0");
283//                              def->width = 128;
284//                              def->height = 128;
285//                              def->format = PF_A8R8G8B8;
286//                      }
287//                      {
288//                              CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("rt1");
289//                              def->width = 128;
290//                              def->height = 128;
291//                              def->format = PF_A8R8G8B8;
292//                      }
293//                      {
294//                              CompositionTargetPass *tp = t->createTargetPass();
295//                              tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
296//                              tp->setOutputName("rt1");
297//                      }
298//                      {
299//                              CompositionTargetPass *tp = t->createTargetPass();
300//                              tp->setInputMode(CompositionTargetPass::IM_NONE);
301//                              tp->setOutputName("rt0");
302//                              CompositionPass *pass = tp->createPass();
303//                              pass->setType(CompositionPass::PT_RENDERQUAD);
304//                              pass->setMaterialName("Ogre/Compositor/Blur0");
305//                              pass->setInput(0, "rt1");
306//                      }
307//                      {
308//                              CompositionTargetPass *tp = t->createTargetPass();
309//                              tp->setInputMode(CompositionTargetPass::IM_NONE);
310//                              tp->setOutputName("rt1");
311//                              CompositionPass *pass = tp->createPass();
312//                              pass->setType(CompositionPass::PT_RENDERQUAD);
313//                              pass->setMaterialName("Ogre/Compositor/Blur1");
314//                              pass->setInput(0, "rt0");
315//                      }
316//                      {
317//                              CompositionTargetPass *tp = t->getOutputTargetPass();
318//                              tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
319//                              { CompositionPass *pass = tp->createPass();
320//                              pass->setType(CompositionPass::PT_RENDERQUAD);
321//                              pass->setMaterialName("Ogre/Compositor/BloomBlend");
322//                              pass->setInput(0, "rt1");
323//                              }
324//                      }
325//              }
326            // Glass compositor is loaded from script but here is the hard coded equivalent
327                /// Glass effect
328//              CompositorPtr comp2 = CompositorManager::getSingleton().create(
329//                              "Glass", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
330//                      );
331//              {
332//                      CompositionTechnique *t = comp2->createTechnique();
333//                      {
334//                              CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("rt0");
335//                              def->width = 0;
336//                              def->height = 0;
337//                              def->format = PF_R8G8B8;
338//                      }
339//                      {
340//                              CompositionTargetPass *tp = t->createTargetPass();
341//                              tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
342//                              tp->setOutputName("rt0");
343//                      }
344//                      {
345//                              CompositionTargetPass *tp = t->getOutputTargetPass();
346//                              tp->setInputMode(CompositionTargetPass::IM_NONE);
347//                              { CompositionPass *pass = tp->createPass();
348//                              pass->setType(CompositionPass::PT_RENDERQUAD);
349//                              pass->setMaterialName("Ogre/Compositor/GlassPass");
350//                              pass->setInput(0, "rt0");
351//                              }
352//                      }
353//              }
354                /// Motion blur effect
355                CompositorPtr comp3 = CompositorManager::getSingleton().create(
356                                "MotionBlur", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
357                        );
358                {
359                        CompositionTechnique *t = comp3->createTechnique();
360                        {
361                                CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("scene");
362                                def->width = 0;
363                                def->height = 0;
364                                def->format = PF_R8G8B8;
365                        }
366                        {
367                                CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("sum");
368                                def->width = 0;
369                                def->height = 0;
370                                def->format = PF_R8G8B8;
371                        }
372                        {
373                                CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("temp");
374                                def->width = 0;
375                                def->height = 0;
376                                def->format = PF_R8G8B8;
377                        }
378                        /// Render scene
379                        {
380                                CompositionTargetPass *tp = t->createTargetPass();
381                                tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
382                                tp->setOutputName("scene");
383                        }
384                        /// Initialisation pass for sum texture
385                        {
386                                CompositionTargetPass *tp = t->createTargetPass();
387                                tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
388                                tp->setOutputName("sum");
389                                tp->setOnlyInitial(true);
390                        }
391                        /// Do the motion blur
392                        {
393                                CompositionTargetPass *tp = t->createTargetPass();
394                                tp->setInputMode(CompositionTargetPass::IM_NONE);
395                                tp->setOutputName("temp");
396                                { CompositionPass *pass = tp->createPass();
397                                pass->setType(CompositionPass::PT_RENDERQUAD);
398                                pass->setMaterialName("Ogre/Compositor/Combine");
399                                pass->setInput(0, "scene");
400                                pass->setInput(1, "sum");
401                                }
402                        }
403                        /// Copy back sum texture
404                        {
405                                CompositionTargetPass *tp = t->createTargetPass();
406                                tp->setInputMode(CompositionTargetPass::IM_NONE);
407                                tp->setOutputName("sum");
408                                { CompositionPass *pass = tp->createPass();
409                                pass->setType(CompositionPass::PT_RENDERQUAD);
410                                pass->setMaterialName("Ogre/Compositor/Copyback");
411                                pass->setInput(0, "temp");
412                                }
413                        }
414                        /// Display result
415                        {
416                                CompositionTargetPass *tp = t->getOutputTargetPass();
417                                tp->setInputMode(CompositionTargetPass::IM_NONE);
418                                { CompositionPass *pass = tp->createPass();
419                                pass->setType(CompositionPass::PT_RENDERQUAD);
420                                pass->setMaterialName("Ogre/Compositor/MotionBlur");
421                                pass->setInput(0, "sum");
422                                }
423                        }
424                }
425                /// Heat vision effect
426                CompositorPtr comp4 = CompositorManager::getSingleton().create(
427                                "HeatVision", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
428                        );
429                {
430                        CompositionTechnique *t = comp4->createTechnique();
431                        {
432                                CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("scene");
433                                def->width = 256;
434                                def->height = 256;
435                                def->format = PF_R8G8B8;
436                        }
437                        {
438                                CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("temp");
439                                def->width = 256;
440                                def->height = 256;
441                                def->format = PF_R8G8B8;
442                        }
443                        /// Render scene
444                        {
445                                CompositionTargetPass *tp = t->createTargetPass();
446                                tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
447                                tp->setOutputName("scene");
448                        }
449                        /// Light to heat pass
450                        {
451                                CompositionTargetPass *tp = t->createTargetPass();
452                                tp->setInputMode(CompositionTargetPass::IM_NONE);
453                                tp->setOutputName("temp");
454                                {
455                                        CompositionPass *pass = tp->createPass();
456                                        pass->setType(CompositionPass::PT_RENDERQUAD);
457                                        pass->setIdentifier(0xDEADBABE); /// Identify pass for use in listener
458                                        pass->setMaterialName("Fury/HeatVision/LightToHeat");
459                                        pass->setInput(0, "scene");
460                                }
461                        }
462                        /// Display result
463                        {
464                                CompositionTargetPass *tp = t->getOutputTargetPass();
465                                tp->setInputMode(CompositionTargetPass::IM_NONE);
466                                {
467                                        CompositionPass *pass = tp->createPass();
468                                        pass->setType(CompositionPass::PT_RENDERQUAD);
469                                        pass->setMaterialName("Fury/HeatVision/Blur");
470                                        pass->setInput(0, "temp");
471                                }
472                        }
473                }
474        }
475
476    // Just override the mandatory create scene method
477    void createScene(void)
478    {
479                MovableObject::setDefaultVisibilityFlags(0x00000001);
480
481                //mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE);
482                //mSceneMgr->setShowDebugShadows(true);
483
484                // Set ambient light
485                mSceneMgr->setAmbientLight(ColourValue(0.0, 0.0, 0.0));
486
487                Light* l = mSceneMgr->createLight("Light2");
488                Vector3 dir(-1,-1,0);
489                dir.normalise();
490                l->setType(Light::LT_DIRECTIONAL);
491                l->setDirection(dir);
492                l->setDiffuseColour(1, 1, 0.8);
493                l->setSpecularColour(1, 1, 1);
494
495
496                Entity* pEnt;
497                pEnt = mSceneMgr->createEntity( "1", "robot.mesh" );
498                mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject( pEnt );
499
500                // pre-load to generate tangents
501                MeshPtr msh = MeshManager::getSingleton().load("knot.mesh",
502                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
503                unsigned short src, dest;
504                if (!msh->suggestTangentVectorBuildParams(src, dest))
505                {
506                        msh->buildTangentVectors(src, dest);
507                }
508
509                // Does not receive shadows
510                pEnt = mSceneMgr->createEntity( "3", "knot.mesh" );
511                pEnt->setMaterialName("Examples/EnvMappedRustySteel");
512                MaterialPtr mat2 = MaterialManager::getSingleton().getByName("Examples/EnvMappedRustySteel");
513                mat2->setReceiveShadows(false);
514                SceneNode* n2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-200, 0, -200));
515                n2->attachObject( pEnt );
516
517                // Transparent object
518                pEnt = mSceneMgr->createEntity( "3.5", "knot.mesh" );
519                pEnt->setMaterialName("Examples/TransparentTest");
520                MaterialPtr mat3 = MaterialManager::getSingleton().getByName("Examples/TransparentTest");
521                pEnt->setCastShadows(false);
522                SceneNode* n3 = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(350, 0, -200));
523                n3->attachObject( pEnt );
524
525                pEnt = mSceneMgr->createEntity( "4", "knot.mesh" );
526                pEnt->setMaterialName("Examples/BumpMapping/MultiLightSpecular");
527                SceneNode* n4 = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(100, 0, 200));
528                n4->attachObject( pEnt );
529
530
531                ParticleSystem* pSys2 = mSceneMgr->createParticleSystem("smoke",
532                        "Examples/Smoke");
533                SceneNode* n5 = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(-300, -100, 200));
534                n5->attachObject(pSys2);
535
536
537                mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
538
539
540                Plane plane;
541                plane.normal = Vector3::UNIT_Y;
542                plane.d = 100;
543                MeshManager::getSingleton().createPlane("Myplane",
544                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
545                        1500,1500,10,10,true,1,5,5,Vector3::UNIT_Z);
546                Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
547                pPlaneEnt->setMaterialName("2 - Default");
548                pPlaneEnt->setCastShadows(false);
549                mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
550
551                mCamera->setPosition(180, 54, 823);
552                mCamera->lookAt(0,20,0);
553
554                /// Create the postfilter effects
555                /// This will be replaced with a .compositor script as soon as the script parser is
556                /// finished.
557                createEffects();
558
559
560                // show overlay
561                Overlay* pOver = OverlayManager::getSingleton().getByName("Example/CompositorOverlay");
562                pOver->show();
563
564    }
565
566    void createFrameListener(void)
567    {
568        mFrameListener= new CompositorFrameListener(mWindow, mCamera);
569        mRoot->addFrameListener(mFrameListener);
570    }
571
572};
573
574#ifdef __cplusplus
575extern "C" {
576#endif
577
578#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
579        INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
580#else
581        int main(int argc, char *argv[])
582#endif
583{
584   // Create application object
585    CompositorApplication app;
586
587    try {
588        app.go();
589    } catch( Exception& e ) {
590#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
591        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
592#else
593        std::cerr << "An exception has occured: " << e.getFullDescription();
594#endif
595    }
596
597
598    return 0;
599}
600
601#ifdef __cplusplus
602}
603#endif
Note: See TracBrowser for help on using the repository browser.