This is the source for MOGRE Intermediate Tutorial 6.
IntermediateTutorial6.cs
using System; namespace Mogre.Demo.IntermediateTutorial6 { class Program { static void Main() { try { new IntermediateTutorial6().Go(); } catch { if (OgreException.IsThrown) ExampleApplication.Example.ShowOgreException(); else throw; } } } public class IntermediateTutorial6 : ExampleApplication.Example { SceneNode mProjectorNode; Frustum mDecalFrustum; Frustum mFilterFrustum; public override void CreateScene() { sceneMgr.AmbientLight = new ColourValue(0.2f, 0.2f, 0.2f); Light light = sceneMgr.CreateLight("MainLight"); light.Position = new Vector3(20, 80, 50); camera.Position = new Vector3(60, 200, 70); camera.LookAt(0, 0, 0); //set up the ogre heads Entity ent = null; for (int i = 0; i < 6; i++) { SceneNode headNode = sceneMgr.RootSceneNode.CreateChildSceneNode(); ent = sceneMgr.CreateEntity("head" + i.ToString(), "ogrehead.mesh"); headNode.AttachObject(ent); Radian angle = new Radian(i + Math.TWO_PI / 6); headNode.Position = new Vector3(75 * Math.Cos(angle), 0, 75 * Math.Sin(angle)); } //create the projector and turn it on CreateProjector(); for (uint i = 0; i < ent.NumSubEntities; i++) { MakeMaterialRecieveDecal(ent.GetSubEntity(i).MaterialName); } root.FrameRenderingQueued += FrameRenderingQueued; } bool FrameRenderingQueued(FrameEvent evt) { //make the projector rotate around mProjectorNode.Rotate(Vector3.UNIT_Y, new Degree(evt.timeSinceLastFrame * 10)); return true; } void CreateProjector() { //set up the first frustum to be projected mDecalFrustum = new Frustum(); mProjectorNode = sceneMgr.RootSceneNode.CreateChildSceneNode("DecalProjectorNode"); mProjectorNode.AttachObject(mDecalFrustum); mProjectorNode.Position = new Vector3(0, 5, 0); //mDecalFrustum.ProjectionType = ProjectionType.PT_ORTHOGRAPHIC; //mDecalFrustum.OrthoWindowHeight = 100; //create the filter for the projector mFilterFrustum = new Frustum { ProjectionType = ProjectionType.PT_ORTHOGRAPHIC }; SceneNode filterNode = mProjectorNode.CreateChildSceneNode("DecalFilterNode"); filterNode.AttachObject(mFilterFrustum); filterNode.Orientation = new Quaternion(new Degree(90), Vector3.UNIT_Y); } void MakeMaterialRecieveDecal(String matName) { //get the material information so that we can modify it MaterialPtr mat = (MaterialPtr)MaterialManager.Singleton.GetByName(matName); Pass pass = mat.GetTechnique(0).CreatePass(); //set the scene blending so that we don't get smears at the edge of our texture pass.SetSceneBlending(SceneBlendType.SBT_TRANSPARENT_ALPHA); pass.SetDepthBias(1); pass.LightingEnabled = false; //If you want the decal in your application to be affected by the scene lighting - del this TextureUnitState texState = pass.CreateTextureUnitState("decal.png"); texState.SetProjectiveTexturing(true, mDecalFrustum); texState.SetTextureAddressingMode(TextureUnitState.TextureAddressingMode.TAM_CLAMP); texState.SetTextureFiltering(FilterOptions.FO_POINT, FilterOptions.FO_LINEAR, FilterOptions.FO_NONE); texState = pass.CreateTextureUnitState("decal_filter.png"); texState.SetProjectiveTexturing(true, mFilterFrustum); texState.SetTextureAddressingMode(TextureUnitState.TextureAddressingMode.TAM_CLAMP); texState.SetTextureFiltering(TextureFilterOptions.TFO_NONE); } } }