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);
        }
    }
}