Introduction
This small snippets shows how to use the class ViewOgreTechniqueSwitcher from the wxOgreMVC ogreaddons project to switch between textured, solid, wireframe and hidden lines render modes.
This snippet has a forum support topic here.
Table of contents
Prerequisites
Because wxOgreMVC is licensed under the MIT license, and thus cannot be hosted here, you need to grab the ViewOgreTechniqueSwitcher class from the repository:
https://ogreaddons.svn.sourceforge.net/svnroot/ogreaddons/trunk/wxOgreMVC/src/OgreMVCViewOgreWindow.cpp
https://ogreaddons.svn.sourceforge.net/svnroot/ogreaddons/trunk/wxOgreMVC/include/OgreMVCGeneral.h
Implementation
When you've grabbed the two files above, you need to modify your code to make use of it.
Header
- Put this forward declaration in your header:
Copy to clipboardclass ViewOgreTechniqueSwitcher; - This enum goes into your class:
Copy to clipboardenum ViewDetail { WIREFRAME = 0, HIDDEN_LINE = 1, SHADED = 2, TEXTURED = 3 }; - Add the following three class member declarations somewhere in your class:
Copy to clipboardViewDetail mViewDetail; ViewOgreTechniqueSwitcher* mTechSwitcher; Ogre::ColourValue mBackgroundColour; - Add a declaration for a setViewDetail member function to your class:
Copy to clipboardvoid setViewDetail(ViewDetail v);
Source
In your implementation file (cpp) do the following:
- Copy the struct RenderableContext from 'OgreMVCGeneral.h' into the implementation file.
It's an internally used struct, so let's just put it in the implementation as a static local struct. - Copy the ViewOgreTechniqueSwitcher class from 'OgreMVCViewOgreWindow.cpp' into your implementation file.
- Add the following two lines to ViewOgreTechniqueSwitcher::renderableQueued, just before the '// Always render normally' comment.
Copy to clipboardif((groupID <= Ogre::RENDER_QUEUE_2) || (groupID >= Ogre::RENDER_QUEUE_8)) return true;
The idea is to skip render queues lower than 3 and higher than 7, which means that skyboxes and overlays is going to be unaffected by the view details techniques. - Add these three initializations to your class constructors initializer list:
Copy to clipboardmViewDetail(TEXTURED), mTechSwitcher(0), mBackgroundColour(0.4, 0.4, 0.4) - This goes in the destructor of your class:
Copy to clipboarddelete mTechSwitcher; - Now, just before starting rendering, add these three lines of code:
Copy to clipboardmTechSwitcher = new ViewOgreTechniqueSwitcher(mBackgroundColour); mCamera->getSceneManager()->getRenderQueue()->setRenderableListener(mTechSwitcher); setViewDetail(TEXTURED); - The setViewDetail function definition:
Copy to clipboardvoid HiddenLines::setViewDetail(ViewDetail v) { mViewDetail = v; mTechSwitcher->detail = v; } - Put this in your keyPressed function:
Copy to clipboardelse if (arg.key == OIS::KC_R) // cycle view detail mode { Ogre::String newVal; ViewDetail newMode; switch (mViewDetail) { case HIDDEN_LINE: newVal = "Wireframe"; newMode = WIREFRAME; break; case WIREFRAME: newVal = "Flat Shaded"; newMode = SHADED; break; case SHADED: newVal = "Textured"; newMode = TEXTURED; break; case TEXTURED: newVal = "Hidden Line"; newMode = HIDDEN_LINE; break; } setViewDetail(newMode); mDetailsPanel->setParamValue(10, newVal); }
And that's it. ๐
One More Trick
Well, there's one more neat trick to play..
Remember the RenderableContext struct you copied into your implementation file?
Let's make use of it in our createScene function (or similar):
void createScene() // Create the scene Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh"); Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); headNode->attachObject(ogreHead); // Set ambient light mSceneMgr->setAmbientLight(Ogre::ColourValue(0.0, 0.0, 0.0)); // Create a light Ogre::Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20,80,50); // create a floor mesh resource Ogre::MeshManager::getSingleton().createPlane("floor", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3::UNIT_Y, -30), 1000, 1000, 10, 10, true, 1, 8, 8, Ogre::Vector3::UNIT_Z); // create a floor entity, give it a material, and place it at the origin Ogre::Entity* floor = mSceneMgr->createEntity("Floor", "floor"); floor->setMaterialName("Examples/BumpyMetal"); Ogre::SceneNode* planeNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); planeNode->attachObject(floor); RenderableContext ctx; ctx.ignoreViewDetail = true; floor->getSubEntity(0)->setUserAny(Ogre::Any(ctx)); mSceneMgr->setSkyDome(true, "Examples/CloudySky"); }
Notice the last bit of code which create a RenderableContext and sets it's 'ignoreViewDetail' member to true, before giving it to 'floor' as a UserAny.
Now the 'floor' is not going to be affected by the render view effect.
Adding a skydome to demonstrate that sky geometry is not affected by the render effect either.