//-----------------------------------------------------------------------
void PagingLandScapeTexture_InstantBaseTextureEdit::_loadMaterial()
{
    if (mMaterial.isNull())
    {
        const String filename  = PagingLandScapeOptions::getSingleton().landscape_filename;
        const String extname   = PagingLandScapeOptions::getSingleton().TextureExtension;
        const String groupName = PagingLandScapeOptions::getSingleton().groupName;

        const String commonName = StringConverter::toString(mDataZ) +
                                  String(".") +
                                  StringConverter::toString(mDataX);
        const String matname = String("InstantBaseMaterial.") + commonName + filename;
        const String texname = filename + ".Base." + commonName + ".";

        String finalTexName;
        if (PagingLandScapeOptions::getSingleton().Deformable &&
                ResourceGroupManager::getSingleton().resourceExists(groupName,
                        texname + "modif." +extname))
        {
            finalTexName = texname + "modif." + extname;
        }
        else
        {
            finalTexName = texname + extname;
        }

        if (!mBaseData)
        {
            mImage.load (finalTexName, groupName);
            mBaseData = mImage.getData();
        }

        // check need of material loading
        mMaterial = MaterialManager::getSingleton().getByName(matname);
        if (mMaterial.isNull())
        {
            MaterialPtr templateMaterial;
            if (PagingLandScapeOptions::getSingleton ().VertexCompression)
            {
                templateMaterial = MaterialManager::getSingleton().getByName(String ("InstantBaseMaterialVertexPixelShaded"));

                // Create a new texture using the base image
                mMaterial = templateMaterial->clone(matname, true, groupName);

                GpuProgramParametersSharedPtr params = mMaterial->getTechnique(0)->getPass(0)->getVertexProgramParameters();

//                    params->setNamedConstant("FogSettings", Vector4(PagingLandScapeOptions::getSingleton().scale.x * PagingLandScapeOptions::getSingleton().PageSize,
//                                                                    PagingLandScapeOptions::getSingleton().scale.y / 65535,
//                                                                    PagingLandScapeOptions::getSingleton().scale.z * PagingLandScapeOptions::getSingleton().PageSize,
//                                                                    0.0f));
                // Check to see if custom param is already there
                GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator();
                bool found = false;
                while (aci.hasMoreElements())
                {
                    const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext();
                    if (ace.paramType == GpuProgramParameters::ACT_CUSTOM &&
                            ace.data == MORPH_CUSTOM_PARAM_ID)
                    {
                        found = true;
                    }
                }
                if (!found)
                {
                    params->setNamedAutoConstant("compressionSettings",
                                                 GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
                }

            }
            else
            {
                templateMaterial = MaterialManager::getSingleton().getByName(String ("InstantBaseMaterial"));
                // Create a new texture using the base image
                mMaterial = templateMaterial->clone(matname, true, groupName);
            }

            // assign this texture to the material
            _LoadTexture(finalTexName, groupName);
            mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName (finalTexName);

            mMaterial->load();
            mMaterial->setLightingEnabled( PagingLandScapeOptions::getSingleton().lit );
        }
        else
            _LoadTexture(finalTexName, groupName);

    }
}
    //-----------------------------------------------------------------------
    void PagingLandScapeTexture_Splatting5::_loadMaterial()
    {
	    if (mMaterial.isNull() )
	    {
            // Create a new texture using the base image
            const String commonName = StringConverter::toString(mDataZ) + String(".") + StringConverter::toString(mDataX);
            //const String prefilename = PagingLandScapeOptions::getSingleton().landscape_filename;
            //const String postfilename = commonName + "." + PagingLandScapeOptions::getSingleton().TextureExtension;


            String Materialname;
            if (PagingLandScapeOptions::getSingleton().VertexCompression)
            {
                mMaterial = (MaterialManager::getSingleton().getByName("SplattingMaterial5Decompress"));


                GpuProgramParametersSharedPtr params = mMaterial->getTechnique(0)->getPass(0)->getVertexProgramParameters();
	            params->setNamedConstant("splatSettings", Vector4(PagingLandScapeOptions::getSingleton().matHeight[1], 
                                                                    PagingLandScapeOptions::getSingleton().matHeight[2], 
                                                                    PagingLandScapeOptions::getSingleton().maxValue, 
                                                                    0.0));
    //            params->setNamedConstant("compressionSettings", Vector4(PagingLandScapeOptions::getSingleton().scale.x * PagingLandScapeOptions::getSingleton().PageSize, 
    //                                                                PagingLandScapeOptions::getSingleton().scale.y / 65535, 
    //                                                                PagingLandScapeOptions::getSingleton().scale.z * PagingLandScapeOptions::getSingleton().PageSize, 
    //                                                                0.0));
                // Check to see if custom param is already there
                GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator();
                bool found = false;
                while (aci.hasMoreElements())
                {
                    const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext();
                    if (ace.paramType == GpuProgramParameters::ACT_CUSTOM && 
                        ace.data == MORPH_CUSTOM_PARAM_ID)
                    {
                        found = true;
                    }
                }
                if (!found)
                {                        
                    params->setNamedAutoConstant("compressionSettings", 
                        GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);                       
                }
            }
            else
            {
                mMaterial = MaterialManager::getSingleton().getByName("SplattingMaterial5");


                GpuProgramParametersSharedPtr params = mMaterial->getTechnique(0)->getPass(0)->getVertexProgramParameters();
	            params->setNamedConstant("splatSettings", Vector4(PagingLandScapeOptions::getSingleton().matHeight[1], 
                                                                    PagingLandScapeOptions::getSingleton().matHeight[2], 
                                                                    PagingLandScapeOptions::getSingleton().maxValue, 
                                                                    0.0));
                    
            }

            //  should really be done only once...
    //        GpuProgramParametersSharedPtr params = mMaterial->getTechnique(0)->getPass(0)->getVertexProgramParameters();
    //	    params->setNamedConstant("configSettings", Vector4(PagingLandScapeOptions::getSingleton().matHeight[0], 
    //                                                            PagingLandScapeOptions::getSingleton().matHeight[1], 
    //                                                            PagingLandScapeOptions::getSingleton().maxValue, 
    //                                                            0.0));

            // Now that we have all the resources in place, we load the material
            mMaterial->load(); 
	    }
    }
    //-----------------------------------------------------------------------
    void PagingLandScapeTexture_Image::_loadMaterial()
    {
	    if ( mMaterial.isNull() )
	    {
            if (PagingLandScapeOptions::getSingleton().ImageNameLoad)
            {  
                const String filename = PagingLandScapeOptions::getSingleton().image_filename;
                const String commonName = StringConverter::toString(mDataZ) + 
                                            String(".") +
                                            StringConverter::toString(mDataX);
                const String matname = String("ImageTexture.") + commonName + filename;
                mMaterial = MaterialManager::getSingleton().getByName(matname);
                if (mMaterial.isNull())
                {
                    MaterialPtr templateMaterial;
                    if (PagingLandScapeOptions::getSingleton ().VertexCompression)
                    {
                        templateMaterial = MaterialManager::getSingleton().getByName(String ("PagingLandScape.Template.VertexPixelShaded"));
                        mMaterial = templateMaterial->clone(matname);    

                        GpuProgramParametersSharedPtr params = mMaterial->getTechnique(0)->getPass(0)->getVertexProgramParameters();
    	                
    //                    params->setNamedConstant("compressionSettings", Vector4(PagingLandScapeOptions::getSingleton().scale.x * PagingLandScapeOptions::getSingleton().PageSize, 
    //                                                                        PagingLandScapeOptions::getSingleton().scale.y / 65535, 
    //                                                                        PagingLandScapeOptions::getSingleton().scale.z * PagingLandScapeOptions::getSingleton().PageSize, 
    //                                                                        0.0));
                        // Check to see if custom param is already there
                        GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator();
                        bool found = false;
                        while (aci.hasMoreElements())
                        {
                            const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext();
                            if (ace.paramType == GpuProgramParameters::ACT_CUSTOM && 
                                ace.data == MORPH_CUSTOM_PARAM_ID)
                            {
                                found = true;
                            }
                        }
                        if (!found)
                        {                        
                            params->setNamedAutoConstant("compressionSettings", 
                                GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);                       
                        }
                    }
                    else
                    {
                        templateMaterial = MaterialManager::getSingleton().getByName(String ("PagingLandScape.Template"));
                        mMaterial = templateMaterial->clone(matname);
                    }   
          
                }
                const String texname = filename + "." +
                    commonName + "." + PagingLandScapeOptions::getSingleton().TextureExtension;       
                // assign this texture to the material
                mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(texname);
            }
            else
            {
                // JEFF - all material settings configured through material script
                mMaterial = (MaterialManager::getSingleton().getByName("PagingLandScape." +
                    StringConverter::toString( mDataZ ) + "." + 
                    StringConverter::toString( mDataX )));
            }
               
		    mMaterial->load(); 
            mMaterial->setLightingEnabled( PagingLandScapeOptions::getSingleton().lit );
	    }
    }
    //-------------------------------------------------------------------------
    void TerrainSceneManager::setupTerrainMaterial(void)
    {
        if (mCustomMaterialName == "")
        {
            // define our own material
            mOptions.terrainMaterial = 
                MaterialManager::getSingleton().getByName(TERRAIN_MATERIAL_NAME);
			// Make unique terrain material name
			StringUtil::StrStreamType s;
			s << mName << "/Terrain";
			mOptions.terrainMaterial = MaterialManager::getSingleton().getByName(s.str());
            if (mOptions.terrainMaterial.isNull())
            {
                mOptions.terrainMaterial = MaterialManager::getSingleton().create(
                    s.str(),
                    ResourceGroupManager::getSingleton().getWorldResourceGroupName());

            }
            else
            {
                mOptions.terrainMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
            }

            Pass* pass = mOptions.terrainMaterial->getTechnique(0)->getPass(0);

            if ( mWorldTextureName != "" )
            {
                pass->createTextureUnitState( mWorldTextureName, 0 );
            }
            if ( mDetailTextureName != "" )
            {
                pass->createTextureUnitState( mDetailTextureName, 1 );
            }

            mOptions.terrainMaterial -> setLightingEnabled( mOptions.lit );

            if (mOptions.lodMorph && 
                mDestRenderSystem->getCapabilities()->hasCapability(RSC_VERTEX_PROGRAM) &&
				GpuProgramManager::getSingleton().getByName("Terrain/VertexMorph").isNull())
            {
                // Create & assign LOD morphing vertex program
                String syntax;
                if (GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1"))
                {
                    syntax = "arbvp1";
                }
                else
                {
                    syntax = "vs_1_1";
                }

                // Get source, and take into account current fog mode
                FogMode fm = getFogMode();
                const String& source = TerrainVertexProgram::getProgramSource(
                    fm, syntax);

                GpuProgramPtr prog = GpuProgramManager::getSingleton().createProgramFromString(
                    "Terrain/VertexMorph", ResourceGroupManager::getSingleton().getWorldResourceGroupName(), 
                    source, GPT_VERTEX_PROGRAM, syntax);

                // Attach
                pass->setVertexProgram("Terrain/VertexMorph");

                // Get params
                GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();

                // worldviewproj
                params->setAutoConstant(0, GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
                // morph factor
                params->setAutoConstant(4, GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
                // fog exp density(if relevant)
                if (fm == FOG_EXP || fm == FOG_EXP2)
                {
                    params->setConstant(5, Vector3(getFogDensity(), 0, 0));
                    // Override scene fog since otherwise it's applied twice
                    // Set to linear and we derive [0,1] fog value in the shader
                    pass->setFog(true, FOG_LINEAR, getFogColour(), 0, 1, 0);
                }

				// Also set shadow receiver program
				const String& source2 = TerrainVertexProgram::getProgramSource(
					fm, syntax, true);

				prog = GpuProgramManager::getSingleton().createProgramFromString(
					"Terrain/VertexMorphShadowReceive", 
					ResourceGroupManager::getSingleton().getWorldResourceGroupName(), 
					source2, GPT_VERTEX_PROGRAM, syntax);
				pass->setShadowReceiverVertexProgram("Terrain/VertexMorphShadowReceive");
				params = pass->getShadowReceiverVertexProgramParameters();
				// worldviewproj
				params->setAutoConstant(0, GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
				// world
				params->setAutoConstant(4, GpuProgramParameters::ACT_WORLD_MATRIX);
				// texture view / proj
				params->setAutoConstant(8, GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX);
				// morph factor
				params->setAutoConstant(12, GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
				
				if (mDetailTextureName != "")
				{
					pass->getTextureUnitState(1)->setTextureCoordSet(1);
				}


                // Set param index
                mLodMorphParamName = "";
                mLodMorphParamIndex = 4;
            }

            mOptions.terrainMaterial->load();

        }
        else
        {
            // Custom material
            mOptions.terrainMaterial = 
                MaterialManager::getSingleton().getByName(mCustomMaterialName);
			if (mOptions.terrainMaterial.isNull()){
				OGRE_EXCEPT(Exception::ERR_ITEM_NOT_FOUND, 
					"Material " + mCustomMaterialName + " not found.", 
					"TerrainSceneManager::setupTerrainMaterial");
			}
            mOptions.terrainMaterial->load();

        }

        // now set up the linkage between vertex program and LOD morph param
        if (mOptions.lodMorph)
        {
            Technique* t = mOptions.terrainMaterial->getBestTechnique();
            for (ushort i = 0; i < t->getNumPasses(); ++i)
            {
                Pass* p = t->getPass(i);
                if (p->hasVertexProgram())
                {
                    // we have to assume vertex program includes LOD morph capability
                    GpuProgramParametersSharedPtr params = 
                        p->getVertexProgramParameters();
                    // Check to see if custom param is already there
                    GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator();
                    bool found = false;
                    while (aci.hasMoreElements())
                    {
                        const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext();
                        if (ace.paramType == GpuProgramParameters::ACT_CUSTOM && 
                            ace.data == MORPH_CUSTOM_PARAM_ID)
                        {
                            found = true;
                        }
                    }
                    if (!found)
                    {
                        if(mLodMorphParamName != "")
                        {
                            params->setNamedAutoConstant(mLodMorphParamName, 
                                GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
                        }
                        else
                        {
                            params->setAutoConstant(mLodMorphParamIndex, 
                                GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);
                        }
                    }

                }
            }
        }

    }