void TerrainProjectionMarker::AddMaterial(const string& matName)
	{
		// check if material is already added or there's no material
		if( _targetMaterials.find(matName) != _targetMaterials.end() ||
			matName.empty() )
		{
			return;
		}

		string matName2 = "StoreMat";

		// get the material ptr
		Ogre::MaterialPtr mat = (Ogre::MaterialPtr)Ogre::MaterialManager::getSingleton().getByName(matName);

		// create a new pass in the material to render the decal
		Ogre::Pass* pass = mat->getTechnique(0)->createPass();

		// set up the decal's texture unit
		Ogre::TextureUnitState *texState = pass->createTextureUnitState(GetTextureName());
		texState->setProjectiveTexturing(true, _projectionFrustum);
		texState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
		texState->setTextureFiltering(Ogre::FO_POINT, Ogre::FO_LINEAR, Ogre::FO_NONE);
		texState->setAlphaOperation(Ogre::LBX_ADD);

		// set our pass to blend the decal over the model's regular texture
		pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
		pass->setDepthBias(2.5f, 2.5f);
		pass->setDepthCheckEnabled(false);

		// set the decal to be self illuminated instead of lit by scene lighting
		pass->setLightingEnabled(false);

		// save pass in map
		_targetMaterials[matName] = pass;
	}
	void Decal::registerPass(Ogre::Pass* _Pass)
	{
		unregister();

		_Pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
		_Pass->setCullingMode(Ogre::CULL_NONE);
        _Pass->setDepthBias(1,1);
        _Pass->setLightingEnabled(false);
		_Pass->setDepthWriteEnabled(false);

		Ogre::TextureUnitState *DecalTexture = _Pass->createTextureUnitState(mTextureName);
        DecalTexture->setProjectiveTexturing(true, mProjector);
		DecalTexture->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
		DecalTexture->setTextureFiltering(Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE);
		DecalTexture->setAlphaOperation(Ogre::LBX_MODULATE, Ogre::LBS_TEXTURE, Ogre::LBS_MANUAL, 1.0, mTransparency);

		mRegisteredPass = _Pass;
	}
Ogre::MaterialPtr OgrePlanarReflectionMaterial::createMaterial(const Ogre::TexturePtr& texture, const Ogre::Camera& projectionCamera)
{
    using namespace::Ogre;

    Ogre::MaterialPtr matPtr = MaterialManager::getSingleton().create(this->getName(),"General");
    Ogre::TextureUnitState* t;
    if(! textureFilename.getValue().empty() )
    {
        t = matPtr->getTechnique(0)->getPass(0)->createTextureUnitState(textureFilename.getValue());
    }
    t = matPtr->getTechnique(0)->getPass(0)->createTextureUnitState(texture->getName() );
    t->setColourOperationEx(Ogre::LBX_BLEND_MANUAL, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT,
            Ogre::ColourValue::White, Ogre::ColourValue::White,
            blendingFactor.getValue());
    t->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
    t->setProjectiveTexturing(true,&projectionCamera);

    matPtr->compile();
    return matPtr;
}
    //-----------------------------------------------------------------------
    void TerrainLiquidObject::_prepareProjector(void)
    {
        if (mProjectorName.empty() || !mProjectorSize)
            return;

        Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(mMaterialName);
        if (material.isNull())
            return;

        bool hasProjector = false;
        {
            Ogre::Material::TechniqueIterator ti = material->getTechniqueIterator();
            while (ti.hasMoreElements())
            {
                Ogre::Technique* technique = ti.getNext();
                Ogre::Technique::PassIterator pi = technique->getPassIterator();
                while (pi.hasMoreElements())
                {
                    Ogre::Pass* pass = pi.getNext();
                    Ogre::Pass::TextureUnitStateIterator tusi = pass->getTextureUnitStateIterator();
                    while (tusi.hasMoreElements())
                    {
                        Ogre::TextureUnitState* tus = tusi.getNext();
                        if (Ogre::StringUtil::startsWith(tus->getName(), "Fairy/Projector", false))
                        {
                            hasProjector = true;
                        }
                    }
                }
            }
        }
        if (!hasProjector)
            return;

        ObjectPtr object = mSystem->getSceneInfo()->findObjectByName(mProjectorName);
        if (!object)
            return;

        Variant directionValue = object->getProperty("direction");
        if (directionValue.empty() || directionValue.type() != typeid(Ogre::Vector3))
            return;

        Ogre::Vector3 direction = VariantCast<Ogre::Vector3>(directionValue);
        direction.normalise();

       Ogre::String name = material->getName() + Ogre::StringConverter::toString((Ogre::ulong)this);

        mProjectionCamera = mTerrainLiquid->getParentSceneNode()->getCreator()->createCamera(name);
        mProjectionCamera->setAutoAspectRatio(false);
        mProjectionCamera->setAspectRatio(1.0f);
        mProjectionCamera->setFixedYawAxis(false);
        mProjectionCamera->setProjectionType(Ogre::PT_ORTHOGRAPHIC);
        mProjectionCamera->setFOVy(Ogre::Degree(90));
        mProjectionCamera->setDirection(-direction);
        mProjectionCamera->setNearClipDistance(mProjectorSize / 2);
        mProjectionCamera->setFarClipDistance(mProjectorSize + 5000.0f);

        mTerrainLiquid->setProjectionCamera(mProjectionCamera);

        mProjectionMaterial = material->clone(name);
        {
            Ogre::Material::TechniqueIterator ti = mProjectionMaterial->getTechniqueIterator();
            while (ti.hasMoreElements())
            {
                Ogre::Technique* technique = ti.getNext();
                Ogre::Technique::PassIterator pi = technique->getPassIterator();
                while (pi.hasMoreElements())
                {
                    Ogre::Pass* pass = pi.getNext();
                    Ogre::Pass::TextureUnitStateIterator tusi = pass->getTextureUnitStateIterator();
                    while (tusi.hasMoreElements())
                    {
                        Ogre::TextureUnitState* tus = tusi.getNext();
                        if (Ogre::StringUtil::startsWith(tus->getName(), "Fairy/Projector", false))
                        {
                            tus->setProjectiveTexturing(true, mProjectionCamera);
                        }
                    }
                }
            }
        }
        mProjectionMaterial->load();
    }