History: Technique Switcher
Source of version: 10 (current)
Copy to clipboard
!Introduction
This small snippets shows how to use the class {MONO()}ViewOgreTechniqueSwitcher{MONO} from the {MONO()}wxOgreMVC{MONO} ogreaddons project to switch between textured, solid, wireframe and hidden lines render modes.
%help% This snippet has a forum support topic [http://www.ogre3d.org/forums/viewtopic.php?f=5&t=58672&start=0|here].
{maketoc}
{CUT()}
{img fileId="1805" thumb="y" alt="" width="400" rel="box[g]" stylebox="border" desc="Rendering the Ogre head in Hidden Lines mode"}
---
{img fileId="1806" thumb="y" alt="" rel="box[g]" width="400" stylebox="border" desc="Rendering the Ogre head in Solid mode"}
{CUT}
%clear%
!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:
+ {CODE(wrap="1", colors="c++")}class ViewOgreTechniqueSwitcher;{CODE}
# This enum goes into your class:
+ {CODE(wrap="1", colors="c++")}
enum ViewDetail
{
WIREFRAME = 0,
HIDDEN_LINE = 1,
SHADED = 2,
TEXTURED = 3
};
{CODE}
# Add the following three class member declarations somewhere in your class:
+ {CODE(wrap="1", colors="c++")}ViewDetail mViewDetail;
ViewOgreTechniqueSwitcher* mTechSwitcher;
Ogre::ColourValue mBackgroundColour;{CODE}
# Add a declaration for a setViewDetail member function to your class:
+ {CODE(wrap="1", colors="c++")}void setViewDetail(ViewDetail v);{CODE}
!!Source
In your implementation file (cpp) do the following:
# Copy the struct {MONO()}RenderableContext{MONO} 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 {MONO()}ViewOgreTechniqueSwitcher{MONO} class from '''OgreMVCViewOgreWindow.cpp''' into your implementation file.
# Add the following two lines to {MONO()}ViewOgreTechniqueSwitcher::renderableQueued{MONO}, just before the '''// Always render normally''' comment.
+ {CODE(wrap="1", colors="c++")}if((groupID <= Ogre::RENDER_QUEUE_2) || (groupID >= Ogre::RENDER_QUEUE_8))
return true;{CODE}
+ 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:
+ {CODE(wrap="1", colors="c++")}mViewDetail(TEXTURED),
mTechSwitcher(0),
mBackgroundColour(0.4, 0.4, 0.4){CODE}
# This goes in the destructor of your class:
+ {CODE(wrap="1", colors="c++")}delete mTechSwitcher;{CODE}
# Now, just before starting rendering, add these three lines of code:
+ {CODE(wrap="1", colors="c++")}mTechSwitcher = new ViewOgreTechniqueSwitcher(mBackgroundColour);
mCamera->getSceneManager()->getRenderQueue()->setRenderableListener(mTechSwitcher);
setViewDetail(TEXTURED);{CODE}
# The setViewDetail function definition:
+ {CODE(wrap="1", colors="c++")}void HiddenLines::setViewDetail(ViewDetail v)
{
mViewDetail = v;
mTechSwitcher->detail = v;
}{CODE}
# Put this in your {MONO()}keyPressed{MONO} function:
+ {CODE(wrap="1", colors="c++")} else 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);
}{CODE}
And that's it. :)
!One More Trick
Well, there's one more neat trick to play..
Remember the {MONO()}RenderableContext{MONO} struct you copied into your implementation file?
Let's make use of it in our createScene function (or similar):
{CODE(wrap="1", colors="c++")}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");
}{CODE}
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.