1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6
7 Copyright (c) 2000-2013 Torus Knot Software Ltd
8 Also see acknowledgements in Readme.html
9
10 You may use this sample code for anything you like, it is not covered by the
11 same license as the rest of the engine.
12 -----------------------------------------------------------------------------
13 */
14
15 #ifndef _CompositorDemo_H_
16 #define _CompositorDemo_H_
17
18 #include "OgreConfigFile.h"
19 #include "OgreStringConverter.h"
20 #include "OgreException.h"
21
22 #include "SdkSample.h"
23 #include "SamplePlugin.h"
24
25 using namespace Ogre;
26 using namespace OgreBites;
27
28 #define COMPOSITORS_PER_PAGE 8
29
30 class _OgreSampleClassExport Sample_Compositor : public SdkSample
31 {
32 public:
33 Sample_Compositor();
34
35 void setupContent(void);
36 void cleanupContent(void);
37 StringVector getRequiredPlugins();
38
39 bool frameRenderingQueued(const FrameEvent& evt);
40
41 void checkBoxToggled(OgreBites::CheckBox * box);
42 void buttonHit(OgreBites::Button* button);
43 void itemSelected(OgreBites::SelectMenu* menu);
44
45 protected:
46
47 void setupView(void);
48 void setupControls(void);
49 void setupScene(void);
50 void createEffects(void);
51 void createTextures(void);
52
53 void registerCompositors();
54 void changePage(size_t pageNum);
55
56 SceneNode * mSpinny;
57 StringVector mCompositorNames;
58 size_t mActiveCompositorPage;
59 size_t mNumCompositorPages;
60
61 //Used to unregister compositor logics and free memory
62 typedef map<String, CompositorLogic*>::type CompositorLogicMap;
63 CompositorLogicMap mCompositorLogics;
64
65 String mDebugCompositorName;
66 SelectMenu* mDebugTextureSelectMenu;
67 TextureUnitState* mDebugTextureTUS;
68
69 };
70
71 /**
72 @file
73 Compositor.cpp
74 @brief
75 Shows OGRE's Compositor feature
76 @author
77 W.J. :wumpus: van der Laan
78 Ogre compositor framework
79 Manuel Bua
80 Postfilter ideas and original out-of-core implementation
81 Jeff (nfz) Doyle
82 added gui framework to demo
83 */
84
85 #include <Ogre.h>
86
87 #include "HelperLogics.h"
88
89 /*************************************************************************
90 Sample_Compositor Methods
91 *************************************************************************/
Sample_Compositor()92 Sample_Compositor::Sample_Compositor()
93 {
94 mInfo["Title"] = "Compositor";
95 mInfo["Description"] = "A demo of Ogre's post-processing framework.";
96 mInfo["Thumbnail"] = "thumb_comp.png";
97 mInfo["Category"] = "Effects";
98 }
99 //--------------------------------------------------------------------------
setupView()100 void Sample_Compositor::setupView()
101 {
102 SdkSample::setupView();
103 mCamera->setPosition(Ogre::Vector3(0,0,0));
104 mCamera->lookAt(Ogre::Vector3(0,0,-300));
105 mCamera->setNearClipDistance(1);
106 }
107 //-----------------------------------------------------------------------------------
setupContent(void)108 void Sample_Compositor::setupContent(void)
109 {
110 // Register the compositor logics
111 // See comment in beginning of HelperLogics.h for explanation
112 Ogre::CompositorManager& compMgr = Ogre::CompositorManager::getSingleton();
113 mCompositorLogics["GaussianBlur"] = new GaussianBlurLogic;
114 mCompositorLogics["HDR"] = new HDRLogic;
115 mCompositorLogics["HeatVision"] = new HeatVisionLogic;
116 compMgr.registerCompositorLogic("GaussianBlur", mCompositorLogics["GaussianBlur"]);
117 compMgr.registerCompositorLogic("HDR", mCompositorLogics["HDR"]);
118 compMgr.registerCompositorLogic("HeatVision", mCompositorLogics["HeatVision"]);
119
120 createTextures();
121 /// Create a couple of hard coded postfilter effects as an example of how to do it
122 /// but the preferred method is to use compositor scripts.
123 createEffects();
124
125 setupScene();
126
127 registerCompositors();
128
129 setupControls();
130
131 #if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS
132 setDragLook(true);
133 #endif
134 }
getRequiredPlugins()135 StringVector Sample_Compositor::getRequiredPlugins()
136 {
137 StringVector names;
138 if (!GpuProgramManager::getSingleton().isSyntaxSupported("glsles") && !GpuProgramManager::getSingleton().isSyntaxSupported("glsl150"))
139 names.push_back("Cg Program Manager");
140 return names;
141 }
142 //-----------------------------------------------------------------------------------
registerCompositors(void)143 void Sample_Compositor::registerCompositors(void)
144 {
145 Ogre::Viewport *vp = mViewport;
146
147 //iterate through Compositor Managers resources and add name keys to menu
148 Ogre::CompositorManager::ResourceMapIterator resourceIterator =
149 Ogre::CompositorManager::getSingleton().getResourceIterator();
150
151 // add all compositor resources to the view container
152 while (resourceIterator.hasMoreElements())
153 {
154 Ogre::ResourcePtr resource = resourceIterator.getNext();
155 const Ogre::String& compositorName = resource->getName();
156 // Don't add base Ogre/Scene compositor to view
157 if (Ogre::StringUtil::startsWith(compositorName, "Ogre/Scene/", false))
158 continue;
159 // Don't add the deferred shading compositors, thats a different demo.
160 if (Ogre::StringUtil::startsWith(compositorName, "DeferredShading", false))
161 continue;
162 // Don't add the SSAO compositors, thats a different demo.
163 if (Ogre::StringUtil::startsWith(compositorName, "SSAO", false))
164 continue;
165 // Don't add the TestMRT compositor, it needs extra scene setup so doesn't currently work.
166 if (Ogre::StringUtil::startsWith(compositorName, "TestMRT", false))
167 continue;
168
169 mCompositorNames.push_back(compositorName);
170 int addPosition = -1;
171 if (compositorName == "HDR")
172 {
173 // HDR must be first in the chain
174 addPosition = 0;
175 }
176 try
177 {
178 Ogre::CompositorManager::getSingleton().addCompositor(vp, compositorName, addPosition);
179 Ogre::CompositorManager::getSingleton().setCompositorEnabled(vp, compositorName, false);
180 } catch (...) {
181 /// Warn user
182 LogManager::getSingleton().logMessage("Could not load compositor " + compositorName, LML_CRITICAL);
183 }
184 }
185
186 mNumCompositorPages = (mCompositorNames.size() / COMPOSITORS_PER_PAGE) +
187 ((mCompositorNames.size() % COMPOSITORS_PER_PAGE == 0) ? 0 : 1);
188 }
189 //-----------------------------------------------------------------------------------
changePage(size_t pageNum)190 void Sample_Compositor::changePage(size_t pageNum)
191 {
192 assert(pageNum < mNumCompositorPages);
193
194 mActiveCompositorPage = pageNum;
195 size_t maxCompositorsInPage = mCompositorNames.size() - (pageNum * COMPOSITORS_PER_PAGE);
196 for (size_t i=0; i < COMPOSITORS_PER_PAGE; i++)
197 {
198 String checkBoxName = "Compositor_" + Ogre::StringConverter::toString(i);
199 CheckBox* cb = static_cast<CheckBox*>(mTrayMgr->getWidget(TL_TOPLEFT, checkBoxName));
200 if (i < maxCompositorsInPage)
201 {
202 String compositorName = mCompositorNames[pageNum * COMPOSITORS_PER_PAGE + i];
203 CompositorInstance *tmpCompo = CompositorManager::getSingleton().getCompositorChain(mViewport)
204 ->getCompositor(compositorName);
205
206 cb->setCaption(compositorName);
207
208 if( tmpCompo )
209 {
210 cb->setChecked( tmpCompo->getEnabled(), false );
211 cb->show();
212 }
213 else
214 {
215 cb->setChecked( false, false );
216 cb->hide();
217 }
218
219 }
220 else
221 {
222 cb->hide();
223 }
224 }
225
226 OgreBites::Button* pageButton = static_cast<OgreBites::Button*>(mTrayMgr->getWidget(TL_TOPLEFT, "PageButton"));
227 Ogre::StringStream ss;
228 ss << "Compositors " << pageNum + 1 << "/" << mNumCompositorPages;
229 pageButton->setCaption(ss.str());
230 }
231 //-----------------------------------------------------------------------------------
cleanupContent(void)232 void Sample_Compositor::cleanupContent(void)
233 {
234 mDebugTextureTUS->setContentType(TextureUnitState::CONTENT_NAMED);
235 CompositorManager::getSingleton().removeCompositorChain(mViewport);
236 mCompositorNames.clear();
237
238 TextureManager::getSingleton().remove("DitherTex");
239 TextureManager::getSingleton().remove("HalftoneVolume");
240
241 Ogre::CompositorManager& compMgr = Ogre::CompositorManager::getSingleton();
242 CompositorLogicMap::const_iterator itor = mCompositorLogics.begin();
243 CompositorLogicMap::const_iterator end = mCompositorLogics.end();
244 while( itor != end )
245 {
246 compMgr.unregisterCompositorLogic( itor->first );
247 delete itor->second;
248 ++itor;
249 }
250 mCompositorLogics.clear();
251 MeshManager::getSingleton().remove("Myplane");
252 }
253 //-----------------------------------------------------------------------------------
setupControls(void)254 void Sample_Compositor::setupControls(void)
255 {
256 mTrayMgr->createButton(TL_TOPLEFT, "PageButton", "Compositors", 175);
257
258 for (size_t i=0; i < COMPOSITORS_PER_PAGE; i++)
259 {
260 String checkBoxName = "Compositor_" + Ogre::StringConverter::toString(i);
261 CheckBox* cb = mTrayMgr->createCheckBox(TL_TOPLEFT, checkBoxName, "Compositor", 175);
262 cb->hide();
263 }
264
265 changePage(0);
266
267 mDebugTextureSelectMenu = mTrayMgr->createThickSelectMenu(TL_TOPRIGHT, "DebugRTTSelectMenu", "Debug RTT", 180, 5);
268 mDebugTextureSelectMenu->addItem("None");
269
270 mTrayMgr->createSeparator(TL_TOPRIGHT, "DebugRTTSep1"); // this is a hack to give the debug RTT a bit more room
271
272 DecorWidget* debugRTTPanel = mTrayMgr->createDecorWidget(TL_NONE, "DebugRTTPanel", "SdkTrays/Picture");
273 OverlayContainer* debugRTTContainer = (OverlayContainer*)debugRTTPanel->getOverlayElement();
274 mDebugTextureTUS = debugRTTContainer->getMaterial()->getBestTechnique()->getPass(0)->getTextureUnitState(0);
275 //mDebugTextureTUS->setTextureName("CompositorDemo/DebugView");
276 debugRTTContainer->setDimensions(128, 128);
277 debugRTTContainer->getChild("DebugRTTPanel/PictureFrame")->setDimensions(144, 144);
278 debugRTTPanel->hide();
279
280 mTrayMgr->createSeparator(TL_TOPRIGHT, "DebugRTTSep2"); // this is a hack to give the debug RTT a bit more room
281
282 mTrayMgr->showCursor();
283 mTrayMgr->showLogo(TL_BOTTOMLEFT);
284 mTrayMgr->toggleAdvancedFrameStats();
285 }
286 //-----------------------------------------------------------------------------------
checkBoxToggled(OgreBites::CheckBox * box)287 void Sample_Compositor::checkBoxToggled(OgreBites::CheckBox * box)
288 {
289 if (Ogre::StringUtil::startsWith(box->getName(), "Compositor_", false))
290 {
291 String compositorName = box->getCaption();
292
293 String activeTex = mDebugTextureSelectMenu->getSelectedItem();
294
295 if (!box->isChecked())
296 {
297 //Remove the items from the debug menu and remove debug texture if from disabled compositor
298 bool debuggingRemovedTex = StringUtil::startsWith(activeTex, compositorName, false);
299 if (debuggingRemovedTex)
300 {
301 mDebugTextureTUS->setContentType(TextureUnitState::CONTENT_NAMED);
302 mDebugTextureSelectMenu->selectItem(0, true);
303 }
304 for (unsigned int i = 1; i < mDebugTextureSelectMenu->getNumItems(); i++)
305 {
306 if (StringUtil::startsWith(mDebugTextureSelectMenu->getItems()[i], compositorName, false))
307 {
308 mDebugTextureSelectMenu->removeItem(i);
309 i--;
310 }
311 }
312 if (!debuggingRemovedTex)
313 {
314 //Selection clears itself when removing items. Restore.
315 mDebugTextureSelectMenu->selectItem(activeTex, false);
316 }
317 }
318
319 CompositorManager::getSingleton().setCompositorEnabled(mViewport, compositorName, box->isChecked());
320
321
322 if (box->isChecked())
323 {
324 //Add the items to the selectable texture menu
325 CompositorInstance* instance = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor(compositorName);
326 if (instance)
327 {
328 CompositionTechnique::TextureDefinitionIterator it = instance->getTechnique()->getTextureDefinitionIterator();
329 while (it.hasMoreElements())
330 {
331 CompositionTechnique::TextureDefinition* texDef = it.getNext();
332 size_t numTextures = texDef->formatList.size();
333 if (numTextures > 1)
334 {
335 for (size_t i=0; i<numTextures; i++)
336 {
337 //Dirty string composition. NOT ROBUST!
338 mDebugTextureSelectMenu->addItem(compositorName + ";" + texDef->name + ";" +
339 Ogre::StringConverter::toString((Ogre::uint32)i));
340 }
341 }
342 else
343 {
344 mDebugTextureSelectMenu->addItem(compositorName + ";" + texDef->name);
345 }
346 }
347 mDebugTextureSelectMenu->selectItem(activeTex, false);
348 }
349 }
350 }
351 }
352 //-----------------------------------------------------------------------------------
buttonHit(OgreBites::Button * button)353 void Sample_Compositor::buttonHit(OgreBites::Button* button)
354 {
355 size_t nextPage = (mActiveCompositorPage + 1) % mNumCompositorPages;
356 changePage(nextPage);
357 }
358 //-----------------------------------------------------------------------------------
itemSelected(OgreBites::SelectMenu * menu)359 void Sample_Compositor::itemSelected(OgreBites::SelectMenu* menu)
360 {
361 if (menu->getSelectionIndex() == 0)
362 {
363 mDebugTextureTUS->setContentType(TextureUnitState::CONTENT_NAMED);
364 mTrayMgr->getWidget("DebugRTTPanel")->hide();
365 mTrayMgr->removeWidgetFromTray("DebugRTTPanel");
366 return;
367 }
368
369 mTrayMgr->getWidget("DebugRTTPanel")->show();
370 mTrayMgr->moveWidgetToTray("DebugRTTPanel", TL_TOPRIGHT, static_cast<unsigned int>(mTrayMgr->getNumWidgets(TL_TOPRIGHT) - 1));
371 StringVector parts = StringUtil::split(menu->getSelectedItem(), ";");
372 mDebugTextureTUS->setContentType(TextureUnitState::CONTENT_COMPOSITOR);
373
374 if (parts.size() == 2)
375 {
376 mDebugTextureTUS->setCompositorReference(parts[0], parts[1]);
377 }
378 else
379 {
380 mDebugTextureTUS->setCompositorReference(parts[0], parts[1],
381 StringConverter::parseUnsignedInt(parts[2]));
382 }
383 }
384 //-----------------------------------------------------------------------------------
setupScene(void)385 void Sample_Compositor::setupScene(void)
386 {
387 mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_TEXTURE_MODULATIVE);
388 mSceneMgr->setShadowFarDistance(1000);
389
390 Ogre::MovableObject::setDefaultVisibilityFlags(0x00000001);
391
392 // Set ambient light
393 mSceneMgr->setAmbientLight(Ogre::ColourValue(0.3, 0.3, 0.2));
394
395 Ogre::Light* l = mSceneMgr->createLight("Light2");
396 Ogre::Vector3 dir(-1,-1,0);
397 dir.normalise();
398 l->setType(Ogre::Light::LT_DIRECTIONAL);
399 l->setDirection(dir);
400 l->setDiffuseColour(1, 1, 0.8);
401 l->setSpecularColour(1, 1, 1);
402
403
404 Ogre::Entity* pEnt;
405
406 // House
407 pEnt = mSceneMgr->createEntity( "1", "tudorhouse.mesh" );
408 Ogre::SceneNode* n1 = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(350, 450, -200));
409 n1->attachObject( pEnt );
410
411 pEnt = mSceneMgr->createEntity( "2", "tudorhouse.mesh" );
412 Ogre::SceneNode* n2 = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(-350, 450, -200));
413 n2->attachObject( pEnt );
414
415 pEnt = mSceneMgr->createEntity( "3", "knot.mesh" );
416 mSpinny = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(0, 0, 300));
417 mSpinny->attachObject( pEnt );
418 pEnt->setMaterialName("Examples/MorningCubeMap");
419
420 mSceneMgr->setSkyBox(true, "Examples/MorningSkyBox");
421
422
423 Ogre::Plane plane;
424 plane.normal = Ogre::Vector3::UNIT_Y;
425 plane.d = 100;
426 Ogre::MeshManager::getSingleton().createPlane("Myplane",
427 Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
428 1500, 1500, 10, 10, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);
429 Ogre::Entity* pPlaneEnt = mSceneMgr->createEntity( "plane", "Myplane" );
430 pPlaneEnt->setMaterialName("Examples/Rockwall");
431 pPlaneEnt->setCastShadows(false);
432 mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
433
434 mCamera->setPosition(-400, 50, 900);
435 mCamera->lookAt(0,80,0);
436 }
437 //-----------------------------------------------------------------------------------
frameRenderingQueued(const FrameEvent & evt)438 bool Sample_Compositor::frameRenderingQueued(const FrameEvent& evt)
439 {
440 mSpinny->yaw(Ogre::Degree(10 * evt.timeSinceLastFrame));
441 return SdkSample::frameRenderingQueued(evt);
442 }
443 //-----------------------------------------------------------------------------------
444 /// Create the hard coded postfilter effects
createEffects(void)445 void Sample_Compositor::createEffects(void)
446 {
447 // Bloom compositor is loaded from script but here is the hard coded equivalent
448 // CompositorPtr comp = CompositorManager::getSingleton().create(
449 // "Bloom", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
450 // );
451 // {
452 // CompositionTechnique *t = comp->createTechnique();
453 // {
454 // CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("rt0");
455 // def->width = 128;
456 // def->height = 128;
457 // def->format = PF_A8R8G8B8;
458 // }
459 // {
460 // CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("rt1");
461 // def->width = 128;
462 // def->height = 128;
463 // def->format = PF_A8R8G8B8;
464 // }
465 // {
466 // CompositionTargetPass *tp = t->createTargetPass();
467 // tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
468 // tp->setOutputName("rt1");
469 // }
470 // {
471 // CompositionTargetPass *tp = t->createTargetPass();
472 // tp->setInputMode(CompositionTargetPass::IM_NONE);
473 // tp->setOutputName("rt0");
474 // CompositionPass *pass = tp->createPass();
475 // pass->setType(CompositionPass::PT_RENDERQUAD);
476 // pass->setMaterialName("Ogre/Compositor/Blur0");
477 // pass->setInput(0, "rt1");
478 // }
479 // {
480 // CompositionTargetPass *tp = t->createTargetPass();
481 // tp->setInputMode(CompositionTargetPass::IM_NONE);
482 // tp->setOutputName("rt1");
483 // CompositionPass *pass = tp->createPass();
484 // pass->setType(CompositionPass::PT_RENDERQUAD);
485 // pass->setMaterialName("Ogre/Compositor/Blur1");
486 // pass->setInput(0, "rt0");
487 // }
488 // {
489 // CompositionTargetPass *tp = t->getOutputTargetPass();
490 // tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
491 // { CompositionPass *pass = tp->createPass();
492 // pass->setType(CompositionPass::PT_RENDERQUAD);
493 // pass->setMaterialName("Ogre/Compositor/BloomBlend");
494 // pass->setInput(0, "rt1");
495 // }
496 // }
497 // }
498 // Glass compositor is loaded from script but here is the hard coded equivalent
499 /// Glass effect
500 // CompositorPtr comp2 = CompositorManager::getSingleton().create(
501 // "Glass", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
502 // );
503 // {
504 // CompositionTechnique *t = comp2->createTechnique();
505 // {
506 // CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("rt0");
507 // def->width = 0;
508 // def->height = 0;
509 // def->format = PF_R8G8B8;
510 // }
511 // {
512 // CompositionTargetPass *tp = t->createTargetPass();
513 // tp->setInputMode(CompositionTargetPass::IM_PREVIOUS);
514 // tp->setOutputName("rt0");
515 // }
516 // {
517 // CompositionTargetPass *tp = t->getOutputTargetPass();
518 // tp->setInputMode(CompositionTargetPass::IM_NONE);
519 // { CompositionPass *pass = tp->createPass();
520 // pass->setType(CompositionPass::PT_RENDERQUAD);
521 // pass->setMaterialName("Ogre/Compositor/GlassPass");
522 // pass->setInput(0, "rt0");
523 // }
524 // }
525 // }
526 /// Motion blur effect
527 Ogre::CompositorPtr comp3 = Ogre::CompositorManager::getSingleton().create(
528 "Motion Blur", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
529 );
530 {
531 Ogre::CompositionTechnique *t = comp3->createTechnique();
532 {
533 Ogre::CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("scene");
534 def->width = 0;
535 def->height = 0;
536 def->formatList.push_back(Ogre::PF_R8G8B8);
537 }
538 {
539 Ogre::CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("sum");
540 def->width = 0;
541 def->height = 0;
542 def->formatList.push_back(Ogre::PF_R8G8B8);
543 }
544 {
545 Ogre::CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("temp");
546 def->width = 0;
547 def->height = 0;
548 def->formatList.push_back(Ogre::PF_R8G8B8);
549 }
550 /// Render scene
551 {
552 Ogre::CompositionTargetPass *tp = t->createTargetPass();
553 tp->setInputMode(Ogre::CompositionTargetPass::IM_PREVIOUS);
554 tp->setOutputName("scene");
555 }
556 /// Initialisation pass for sum texture
557 {
558 Ogre::CompositionTargetPass *tp = t->createTargetPass();
559 tp->setInputMode(Ogre::CompositionTargetPass::IM_PREVIOUS);
560 tp->setOutputName("sum");
561 tp->setOnlyInitial(true);
562 }
563 /// Do the motion blur
564 {
565 Ogre::CompositionTargetPass *tp = t->createTargetPass();
566 tp->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
567 tp->setOutputName("temp");
568 { Ogre::CompositionPass *pass = tp->createPass();
569 pass->setType(Ogre::CompositionPass::PT_RENDERQUAD);
570 pass->setMaterialName("Ogre/Compositor/Combine");
571 pass->setInput(0, "scene");
572 pass->setInput(1, "sum");
573 }
574 }
575 /// Copy back sum texture
576 {
577 Ogre::CompositionTargetPass *tp = t->createTargetPass();
578 tp->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
579 tp->setOutputName("sum");
580 { Ogre::CompositionPass *pass = tp->createPass();
581 pass->setType(Ogre::CompositionPass::PT_RENDERQUAD);
582 pass->setMaterialName("Ogre/Compositor/Copyback");
583 pass->setInput(0, "temp");
584 }
585 }
586 /// Display result
587 {
588 Ogre::CompositionTargetPass *tp = t->getOutputTargetPass();
589 tp->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
590 { Ogre::CompositionPass *pass = tp->createPass();
591 pass->setType(Ogre::CompositionPass::PT_RENDERQUAD);
592 pass->setMaterialName("Ogre/Compositor/MotionBlur");
593 pass->setInput(0, "sum");
594 }
595 }
596 }
597 /// Heat vision effect
598 Ogre::CompositorPtr comp4 = Ogre::CompositorManager::getSingleton().create(
599 "Heat Vision", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME
600 );
601 {
602 Ogre::CompositionTechnique *t = comp4->createTechnique();
603 t->setCompositorLogicName("HeatVision");
604 {
605 Ogre::CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("scene");
606 def->width = 256;
607 def->height = 256;
608 def->formatList.push_back(Ogre::PF_R8G8B8);
609 }
610 {
611 Ogre::CompositionTechnique::TextureDefinition *def = t->createTextureDefinition("temp");
612 def->width = 256;
613 def->height = 256;
614 def->formatList.push_back(Ogre::PF_R8G8B8);
615 }
616 /// Render scene
617 {
618 Ogre::CompositionTargetPass *tp = t->createTargetPass();
619 tp->setInputMode(Ogre::CompositionTargetPass::IM_PREVIOUS);
620 tp->setOutputName("scene");
621 }
622 /// Light to heat pass
623 {
624 Ogre::CompositionTargetPass *tp = t->createTargetPass();
625 tp->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
626 tp->setOutputName("temp");
627 {
628 Ogre::CompositionPass *pass = tp->createPass();
629 pass->setType(Ogre::CompositionPass::PT_RENDERQUAD);
630 pass->setIdentifier(0xDEADBABE); /// Identify pass for use in listener
631 pass->setMaterialName("Fury/HeatVision/LightToHeat");
632 pass->setInput(0, "scene");
633 }
634 }
635 /// Display result
636 {
637 Ogre::CompositionTargetPass *tp = t->getOutputTargetPass();
638 tp->setInputMode(Ogre::CompositionTargetPass::IM_NONE);
639 {
640 Ogre::CompositionPass *pass = tp->createPass();
641 pass->setType(Ogre::CompositionPass::PT_RENDERQUAD);
642 pass->setMaterialName("Fury/HeatVision/Blur");
643 pass->setInput(0, "temp");
644 }
645 }
646 }
647 }
648 //--------------------------------------------------------------------------
createTextures(void)649 void Sample_Compositor::createTextures(void)
650 {
651 using namespace Ogre;
652
653 TexturePtr tex = TextureManager::getSingleton().createManual(
654 "HalftoneVolume",
655 "General",
656 TEX_TYPE_3D,
657 64,64,64,
658 0,
659 PF_L8,
660 TU_DYNAMIC_WRITE_ONLY
661 );
662
663 if(!tex.isNull())
664 {
665 HardwarePixelBufferSharedPtr ptr = tex->getBuffer(0,0);
666 ptr->lock(HardwareBuffer::HBL_DISCARD);
667 const PixelBox &pb = ptr->getCurrentLock();
668 Ogre::uint8 *data = static_cast<Ogre::uint8*>(pb.data);
669
670 size_t height = pb.getHeight();
671 size_t width = pb.getWidth();
672 size_t depth = pb.getDepth();
673 size_t rowPitch = pb.rowPitch;
674 size_t slicePitch = pb.slicePitch;
675
676 for (size_t z = 0; z < depth; ++z)
677 {
678 for (size_t y = 0; y < height; ++y)
679 {
680 for(size_t x = 0; x < width; ++x)
681 {
682 float fx = 32-(float)x+0.5f;
683 float fy = 32-(float)y+0.5f;
684 float fz = 32-((float)z)/3+0.5f;
685 float distanceSquare = fx*fx+fy*fy+fz*fz;
686 data[slicePitch*z + rowPitch*y + x] = 0x00;
687 if (distanceSquare < 1024.0f)
688 data[slicePitch*z + rowPitch*y + x] += 0xFF;
689 }
690 }
691 }
692 ptr->unlock();
693 }
694 Ogre::Viewport *vp = mWindow->getViewport(0);
695
696 TexturePtr tex2 = TextureManager::getSingleton().createManual(
697 "DitherTex",
698 "General",
699 TEX_TYPE_2D,
700 vp->getActualWidth(),vp->getActualHeight(),1,
701 0,
702 PF_L8,
703 TU_DYNAMIC_WRITE_ONLY
704 );
705
706 HardwarePixelBufferSharedPtr ptr2 = tex2->getBuffer(0,0);
707 ptr2->lock(HardwareBuffer::HBL_DISCARD);
708 const PixelBox &pb2 = ptr2->getCurrentLock();
709 Ogre::uint8 *data2 = static_cast<Ogre::uint8*>(pb2.data);
710
711 size_t height2 = pb2.getHeight();
712 size_t width2 = pb2.getWidth();
713 size_t rowPitch2 = pb2.rowPitch;
714
715 for (size_t y = 0; y < height2; ++y)
716 {
717 for(size_t x = 0; x < width2; ++x)
718 {
719 data2[rowPitch2*y + x] = Ogre::Math::RangeRandom(64.0,192);
720 }
721 }
722
723 ptr2->unlock();
724 }
725
726 #endif // end _CompositorDemo_H_
727