Beispiel #1
0
//-----------------------------------------------------------------------------
///
void BatchPage::build()
{
	m_pBatchGeom->build();
	BatchedGeometry::TSubBatchIterator it = m_pBatchGeom->getSubBatchIterator();

	while (it.hasMoreElements())
   {
		BatchedGeometry::SubBatch *subBatch = it.getNext();
		const MaterialPtr &ptrMat = subBatch->getMaterial();

		//Disable specular unless a custom shader is being used.
		//This is done because the default shader applied by BatchPage
		//doesn't support specular, and fixed-function needs to look
		//the same as the shader (for computers with no shader support)
		for (unsigned short t = 0, tCnt = ptrMat->getNumTechniques(); t < tCnt; ++t)
      {
			Technique *tech = ptrMat->getTechnique(t);
			for (unsigned short p = 0, pCnt = tech->getNumPasses(); p < pCnt; ++p)
         {
				Pass *pass = tech->getPass(p);
				//if (pass->getVertexProgramName() == "")
				//	pass->setSpecular(0, 0, 0, 1);
            if (!pass->hasVertexProgram())
               pass->setSpecular(0.f, 0.f, 0.f, 1.f);
			}
		}

		//Store the original materials
		m_vecUnfadedMaterials.push_back(subBatch->getMaterial());
	}

	_updateShaders();
}
void BatchPage::build()
{
	batch->build();

	BatchedGeometry::SubBatchIterator it = batch->getSubBatchIterator();
	while (it.hasMoreElements()){
		BatchedGeometry::SubBatch *subBatch = it.getNext();
		MaterialPtr mat = subBatch->getMaterial();

		//Disable specular unless a custom shader is being used.
		//This is done because the default shader applied by BatchPage
		//doesn't support specular, and fixed-function needs to look
		//the same as the shader (for computers with no shader support)
		for (int t = 0; t < mat->getNumTechniques(); ++t){
			Technique *tech = mat->getTechnique(t);
			for (int p = 0; p < tech->getNumPasses(); ++p){
				Pass *pass = tech->getPass(p);
				if (pass->getVertexProgramName() == "")
					pass->setSpecular(0, 0, 0, 1);
			}
		}

		//Store the original materials
		unfadedMaterials.push_back(subBatch->getMaterial());
	}

	_updateShaders();
}
Beispiel #3
0
int GameScript::getSafeTextureUnitState(TextureUnitState **tu, const String materialName, int techniqueNum, int passNum, int textureUnitNum)
{
	try
	{
		MaterialPtr m = MaterialManager::getSingleton().getByName(materialName);
		if (m.isNull()) return 1;

		// verify technique
		if (techniqueNum < 0 || techniqueNum > m->getNumTechniques()) return 2;
		Technique *t = m->getTechnique(techniqueNum);
		if (!t) return 2;

		//verify pass
		if (passNum < 0 || passNum > t->getNumPasses()) return 3;
		Pass *p = t->getPass(passNum);
		if (!p) return 3;

		//verify texture unit
		if (textureUnitNum < 0 || textureUnitNum > p->getNumTextureUnitStates()) return 4;
		TextureUnitState *tut = p->getTextureUnitState(textureUnitNum);
		if (!tut) return 4;

		*tu = tut;
		return 0;
	} catch(Exception e)
	{
		SLOG("Exception in getSafeTextureUnitState(): " + e.getFullDescription());
	}
	return 1;
}
	void LightInstanceBatchHW::injectRender()
	{
		if( (mRenderOperation.numberOfInstances = updateVertexBuffer( mCurrentCamera )) )
		{
			Technique* tech = mMaterial->getBestTechnique();

			for (size_t i=0; i<tech->getNumPasses(); ++i)
			{
				mManager->_injectRenderWithPass(tech->getPass(i), this, false);
			}
		}
	}
//! [schemenotfound]
Technique* GBufferSchemeHandler::handleSchemeNotFound(unsigned short schemeIndex, 
        const String& schemeName, Material* originalMaterial, unsigned short lodIndex, 
        const Renderable* rend)
{
    Ogre::MaterialManager& matMgr = Ogre::MaterialManager::getSingleton();
    String curSchemeName = matMgr.getActiveScheme();
    matMgr.setActiveScheme(MaterialManager::DEFAULT_SCHEME_NAME);
    Technique* originalTechnique = originalMaterial->getBestTechnique(lodIndex, rend);
    matMgr.setActiveScheme(curSchemeName);

    Technique* gBufferTech = originalMaterial->createTechnique();
    gBufferTech->removeAllPasses();
    gBufferTech->setSchemeName(schemeName);

#ifdef OGRE_BUILD_COMPONENT_RTSHADERSYSTEM
    RTShader::ShaderGenerator& rtShaderGen = RTShader::ShaderGenerator::getSingleton();
    rtShaderGen.createShaderBasedTechnique(originalTechnique, "NoGBuffer");
#else
    Technique* noGBufferTech = originalMaterial->createTechnique();
    noGBufferTech->removeAllPasses();
    noGBufferTech->setSchemeName("NoGBuffer");
#endif

    for (unsigned short i=0; i<originalTechnique->getNumPasses(); i++)
    {
        Pass* originalPass = originalTechnique->getPass(i);
        PassProperties props = inspectPass(originalPass, lodIndex, rend);
        
        if (!props.isDeferred)
        {
#ifdef OGRE_BUILD_COMPONENT_RTSHADERSYSTEM
            rtShaderGen.validateMaterial("NoGBuffer", originalMaterial->getName(), originalMaterial->getGroup());
#else
            //Just copy the technique so it gets rendered regularly
            Pass* clonePass = noGBufferTech->createPass();
            *clonePass = *originalPass;
#endif
            continue;
        }

        Pass* newPass = gBufferTech->createPass();
        MaterialGenerator::Perm perm = getPermutation(props);

        const Ogre::MaterialPtr& templateMat = mMaterialGenerator.getMaterial(perm);
        
        //We assume that the GBuffer technique contains only one pass. But its true.
        *newPass = *(templateMat->getTechnique(0)->getPass(0));
        fillPass(newPass, originalPass, props);    
    }
    
    return gBufferTech;
}
	// 把地形的障碍区域显示Pass移除
	void TerrainEditorPlugin::removeTerrainBlockerPass(ETTerrain *terrain)
	{
		MaterialPtr mat = terrain->getTerrainImpl()->getMaterial();
		Technique *tech = mat->getTechnique(0);
		// 看有没有这个Blocker的Pass,如果有就删除之
		for(size_t i = 0 ; i < tech->getNumPasses() ; i ++)
		{
			if(tech->getPass(i)->getName() == "Blocker")
			{
				tech->removePass(i);
				return;
			}
		}
	}
//-----------------------------------------------------------------------------
void SGMaterialSerializerListener::createSGPassList(Material* mat, SGPassList& passList)
{
	for (unsigned short techniqueIndex = 0; techniqueIndex < mat->getNumTechniques(); ++techniqueIndex)
	{
		Technique* curTechnique = mat->getTechnique(techniqueIndex);

		for (unsigned short passIndex = 0; passIndex < curTechnique->getNumPasses(); ++passIndex)
		{
			Pass* curPass = curTechnique->getPass(passIndex);		
			const Any& passUserData = curPass->getUserObjectBindings().getUserAny(ShaderGenerator::SGPass::UserKey);

			// Case this pass created by the shader generator.
			if (passUserData.isEmpty() == false)	
			{
				ShaderGenerator::SGPass* passEntry = any_cast<ShaderGenerator::SGPass*>(passUserData);

				passList.push_back(passEntry);
			}								
		}
	}
}
	// 为地形添加一个障碍区域的显示Pass
	void TerrainEditorPlugin::addTerrainBlockerPass(ETTerrain *terrain)
	{
		MaterialPtr mat = terrain->getTerrainImpl()->getMaterial();
		Technique *tech = mat->getTechnique(0);
		// 看有没有这个Blocker的Pass,如果有就不用添加了
		for(size_t i = 0 ; i < tech->getNumPasses() ; i ++)
		{
			if(tech->getPass(i)->getName() == "Blocker")
				return;
		}
		Pass *blockerPass = mat->getTechnique(0)->createPass();
		blockerPass->setName("Blocker");
		// 使用透明渲染
		blockerPass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
		blockerPass->setVertexProgram("ET/Programs/VSLodMorph2");
		//blockerPass->setPolygonMode(PM_WIREFRAME);
		//blockerPass->setLightingEnabled(false);
		blockerPass->setCullingMode(CULL_ANTICLOCKWISE);
		//blockerPass->setDepthCheckEnabled(false);
		// 创建个贴图
		TextureUnitState *state = blockerPass->createTextureUnitState(terrain->getBlockerTexture()->getName());
		state->setTextureFiltering(TFO_NONE);

	}
Beispiel #9
0
	//-----------------------------------------------------------------------------
	ShadowCaster::ShadowRenderableListIterator
	ManualObject::getShadowVolumeRenderableIterator(
		ShadowTechnique shadowTechnique, const Light* light,
		HardwareIndexBufferSharedPtr* indexBuffer,
		bool extrude, Real extrusionDistance, unsigned long flags)
	{
		assert(indexBuffer && "Only external index buffers are supported right now");		

        EdgeData* edgeList = getEdgeList();
        if (!edgeList)
        {
            return ShadowRenderableListIterator(
                mShadowRenderables.begin(), mShadowRenderables.end());
        }

		// Calculate the object space light details
		Vector4 lightPos = light->getAs4DVector();
		Matrix4 world2Obj = mParentNode->_getFullTransform().inverseAffine();
		lightPos = world2Obj.transformAffine(lightPos);


		// Init shadow renderable list if required (only allow indexed)
		bool init = mShadowRenderables.empty() && mAnyIndexed;

		EdgeData::EdgeGroupList::iterator egi;
		ShadowRenderableList::iterator si, siend;
		ManualObjectSectionShadowRenderable* esr = 0;
		SectionList::iterator seci;
		if (init)
			mShadowRenderables.resize(edgeList->edgeGroups.size());

		siend = mShadowRenderables.end();
		egi = edgeList->edgeGroups.begin();
		seci = mSectionList.begin();
		for (si = mShadowRenderables.begin(); si != siend; ++seci)
		{
            // Skip non-indexed geometry
            if (!(*seci)->getRenderOperation()->useIndexes)
            {
                continue;
            }

			if (init)
			{
				// Create a new renderable, create a separate light cap if
				// we're using a vertex program (either for this model, or
				// for extruding the shadow volume) since otherwise we can
				// get depth-fighting on the light cap
				MaterialPtr mat = (*seci)->getMaterial();
				mat->load();
				bool vertexProgram = false;
				Technique* t = mat->getBestTechnique(0, *seci);
				for (unsigned short p = 0; p < t->getNumPasses(); ++p)
				{
					Pass* pass = t->getPass(p);
					if (pass->hasVertexProgram())
					{
						vertexProgram = true;
						break;
					}
				}
				*si = OGRE_NEW ManualObjectSectionShadowRenderable(this, indexBuffer,
					egi->vertexData, vertexProgram || !extrude);
			}
			// Get shadow renderable
			esr = static_cast<ManualObjectSectionShadowRenderable*>(*si);
			HardwareVertexBufferSharedPtr esrPositionBuffer = esr->getPositionBuffer();
			// Extrude vertices in software if required
			if (extrude)
			{
				extrudeVertices(esrPositionBuffer,
					egi->vertexData->vertexCount,
					lightPos, extrusionDistance);

			}

            ++si;
            ++egi;
		}
		// Calc triangle light facing
		updateEdgeListLightFacing(edgeList, lightPos);

		// Generate indexes and update renderables
		generateShadowVolume(edgeList, *indexBuffer, light,
			mShadowRenderables, flags);


		return ShadowRenderableListIterator(
			mShadowRenderables.begin(), mShadowRenderables.end());


	}
//-----------------------------------------------------------------------------
///
void WindBatchPage::_updateShaders()
{
	if (!m_bShadersSupported)
		return;

	unsigned int i = 0;
	BatchedGeometry::TSubBatchIterator it = m_pBatchGeom->getSubBatchIterator();
	while (it.hasMoreElements())
   {
      BatchedGeometry::SubBatch *subBatch = it.getNext();
		const MaterialPtr &ptrMat = m_vecUnfadedMaterials[i++];

		//Check if lighting should be enabled
		bool lightingEnabled = false;
		for (unsigned short t = 0, techCnt = ptrMat->getNumTechniques(); t < techCnt; ++t)
      {
			Technique *tech = ptrMat->getTechnique(t);
			for (unsigned short p = 0, passCnt = tech->getNumPasses(); p < passCnt; ++p)
         {
            if (tech->getPass(p)->getLightingEnabled())
            {
					lightingEnabled = true;
					break;
				}
			}

			if (lightingEnabled)
            break;
		}

		//Compile the shader script based on various material / fade options
		StringUtil::StrStreamType tmpName;
		tmpName << "BatchPage_";
		if (m_bFadeEnabled)
			tmpName << "fade_";
		if (lightingEnabled)
			tmpName << "lit_";
		if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
			tmpName << "clr_";

		for (unsigned short i = 0; i < subBatch->m_pVertexData->vertexDeclaration->getElementCount(); ++i)
      {
			const VertexElement *el = subBatch->m_pVertexData->vertexDeclaration->getElement(i);
			if (el->getSemantic() == VES_TEXTURE_COORDINATES)
         {
				String uvType;
            switch (el->getType())
            {
            case VET_FLOAT1: uvType = "1"; break;
            case VET_FLOAT2: uvType = "2"; break;
            case VET_FLOAT3: uvType = "3"; break;
            case VET_FLOAT4: uvType = "4"; break;
            }
            tmpName << uvType << '_';
			}
		}

		tmpName << "vp";

		const String vertexProgName = tmpName.str();

		String shaderLanguage;
		if (Root::getSingleton().getRenderSystem()->getName() == "Direct3D9 Rendering Subsystem")
			shaderLanguage = "hlsl";
		else if(Root::getSingleton().getRenderSystem()->getName() == "OpenGL Rendering Subsystem")
			shaderLanguage = "glsl";
		else
			shaderLanguage = "cg";

		//If the shader hasn't been created yet, create it
		if (HighLevelGpuProgramManager::getSingleton().getByName(vertexProgName).isNull())
		{
			Pass *pass = ptrMat->getTechnique(0)->getPass(0);
			String vertexProgSource;

			if(!shaderLanguage.compare("hlsl") || !shaderLanguage.compare("cg"))
			{

				vertexProgSource =
					"void main( \n"
					"	float4 iPosition : POSITION, \n"
					"	float3 normal	 : NORMAL, \n"
					"	out float4 oPosition : POSITION, \n";

				if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
				{
					vertexProgSource += 
						"	float4 iColor	 : COLOR, \n";
				}

				int texNum = 0;

				unsigned short texCoordCount = 0;
				for (unsigned short j = 0; j < subBatch->m_pVertexData->vertexDeclaration->getElementCount(); ++j) 
				{
					const VertexElement *el = subBatch->m_pVertexData->vertexDeclaration->getElement(j);
					if (el->getSemantic() == VES_TEXTURE_COORDINATES) 
					{
						++ texCoordCount;
					}
				}

				for (unsigned short i = 0; i < subBatch->m_pVertexData->vertexDeclaration->getElementCount(); ++i)
				{
					const VertexElement *el = subBatch->m_pVertexData->vertexDeclaration->getElement(i);
					if (el->getSemantic() == VES_TEXTURE_COORDINATES)
					{
						if (el->getIndex() == texCoordCount - 2)
						{
							vertexProgSource += 
								"	float4 params 	: TEXCOORD" + StringConverter::toString(texCoordCount-2) + ", \n";
						}
						else
						{
							if (el->getIndex() == texCoordCount - 1)
							{
								vertexProgSource += 
									"	float4 originPos 	: TEXCOORD" + StringConverter::toString(texCoordCount-1) + ", \n";
							}
							else
							{
								String uvType = "";
								switch (el->getType())
								{
									case VET_FLOAT1: uvType = "float"; break;
									case VET_FLOAT2: uvType = "float2"; break;
									case VET_FLOAT3: uvType = "float3"; break;
									case VET_FLOAT4: uvType = "float4"; break;
								}

								vertexProgSource += 
									"	" + uvType + " iUV" + StringConverter::toString(texNum) + "			: TEXCOORD" + StringConverter::toString(texNum) + ", \n"
									"	out " + uvType + " oUV" + StringConverter::toString(texNum) + "		: TEXCOORD" + StringConverter::toString(texNum) + ", \n";
							}
							++texNum;
						}
					}
				}

				vertexProgSource +=
					"	out float oFog : FOG, \n"
					"	out float4 oColor : COLOR, \n";

				if (lightingEnabled)
				{
					 vertexProgSource +=
						"	uniform float4 objSpaceLight, \n"
						"	uniform float4 lightDiffuse, \n"
						"	uniform float4 lightAmbient, \n";
				}

				if (m_bFadeEnabled)
				{
					vertexProgSource +=
						"	uniform float3 camPos, \n"
						"	uniform float fadeGap, \n"
						"	uniform float invisibleDist, \n";
				}

				vertexProgSource +=
					"	uniform float4x4 worldViewProj,\n"
					"	uniform float time) \n "
					"{	\n";

				if (lightingEnabled)
				{
					//Perform lighting calculations (no specular)
					vertexProgSource +=
						"	float3 light = normalize(objSpaceLight.xyz - (iPosition.xyz * objSpaceLight.w)); \n"
						"	float diffuseFactor = max(dot(normal, light), 0); \n";

					if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
					{
						vertexProgSource +=
							"	oColor = (lightAmbient + diffuseFactor * lightDiffuse) * iColor; \n";
					}
					else
					{
						vertexProgSource +=
							"	oColor = (lightAmbient + diffuseFactor * lightDiffuse); \n";
					}
				}
				else
				{
					if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
					{
						vertexProgSource +=
							"	oColor = iColor; \n";
					}
					else
					{
						vertexProgSource +=
							"	oColor = float4(1, 1, 1, 1); \n";
					}
				}

				if (m_bFadeEnabled)
				{
					//Fade out in the distance
					 vertexProgSource +=
						"	float dist = distance(camPos.xz, iPosition.xz); \n"
						"	oColor.a *= (invisibleDist - dist) / fadeGap; \n";
				}

				for (unsigned short i = 0; i < texCoordCount - 2; ++i)
				{
					vertexProgSource += 
						"	oUV" + StringConverter::toString(i) + " = iUV" + StringConverter::toString(i) + "; \n";
				}

				vertexProgSource +=
					"	float radiusCoeff = params.x; \n"
					"	float heightCoeff = params.y; \n"
					"	float factorX = params.z; \n"
					"	float factorY = params.w; \n"
					"	float4 tmpPos = iPosition; \n"

					/* 
					2 different methods are used to for the sin calculation :
					- the first one gives a better effect but at the cost of a few fps because of the 2 sines
					- the second one uses less ressources but is a bit less realistic

						a sin approximation could be use to optimize performances
					*/
	#if 0
					"	tmpPos.y += sin(time + originPos.z + tmpPos.y + tmpPos.x) * radiusCoeff * radiusCoeff * factorY; \n"
					"	tmpPos.x += sin(time + originPos.z ) * heightCoeff * heightCoeff * factorX ; \n"
	#else
					"	float sinval = sin(time + originPos.z ); \n"
					"	tmpPos.y += sinval * radiusCoeff * radiusCoeff * factorY; \n"
					"	tmpPos.x += sinval * heightCoeff * heightCoeff * factorX ; \n"
	#endif
					"	oPosition = mul(worldViewProj, tmpPos); \n"
					"	oFog = oPosition.z; \n"
					"}";
			}

			if(!shaderLanguage.compare("glsl"))
			{
				unsigned short texCoordCount = 0;
				for (unsigned short j = 0; j < subBatch->m_pVertexData->vertexDeclaration->getElementCount(); ++j) 
				{
					const VertexElement *el = subBatch->m_pVertexData->vertexDeclaration->getElement(j);
					if (el->getSemantic() == VES_TEXTURE_COORDINATES) 
					{
						++ texCoordCount;
					}
				}

				if (lightingEnabled)
				{
					 vertexProgSource +=
						"uniform vec4 objSpaceLight; \n"
						"uniform vec4 lightDiffuse; \n"
						"uniform vec4 lightAmbient; \n";
				}

				if (m_bFadeEnabled)
				{
					 vertexProgSource +=
						"uniform vec3 camPos; \n"
						"uniform float fadeGap; \n"
						"uniform float invisibleDist; \n";
				}

				vertexProgSource +=
					"uniform float time; \n"
					"void main() \n"
					"{ \n";

				int texNum = 0;

				for (unsigned short i = 0; i < subBatch->m_pVertexData->vertexDeclaration->getElementCount(); ++i)
				{
					const VertexElement *el = subBatch->m_pVertexData->vertexDeclaration->getElement(i);
					if (el->getSemantic() == VES_TEXTURE_COORDINATES)
					{
						if (el->getIndex() == texCoordCount - 2)
						{
							vertexProgSource += 
								"	vec4 params = gl_MultiTexCoord" + StringConverter::toString(texCoordCount-2) + "; \n";
						}
						else
						{
							if (el->getIndex() == texCoordCount - 1)
							{
								vertexProgSource += 
									"	vec4 originPos = gl_MultiTexCoord" + StringConverter::toString(texCoordCount-1) + "; \n";
							}
							else
							{
								vertexProgSource += 
								"	gl_TexCoord[" + StringConverter::toString(texNum) + "]	= gl_MultiTexCoord" + StringConverter::toString(texNum) + "; \n";
							}
							++texNum;
						}
					}
				}

				if (lightingEnabled)
				{
					//Perform lighting calculations (no specular)
					vertexProgSource +=
						"	vec3 light = normalize(objSpaceLight.xyz - (gl_Vertex.xyz * objSpaceLight.w)); \n"
						"	float diffuseFactor = max(dot(gl_Normal.xyz, light), 0.0); \n";

					if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
					{
						vertexProgSource +=
							"	gl_FrontColor = (lightAmbient + diffuseFactor * lightDiffuse) * gl_Color; \n";
					}
					else
					{
						vertexProgSource +=
							"	gl_FrontColor = (lightAmbient + diffuseFactor * lightDiffuse); \n";
					}
				}
				else
				{
					if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
					{
						vertexProgSource += "	gl_FrontColor = gl_Color; \n";
					}
					else
					{
						vertexProgSource += "	gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0); \n";
					}
				}

				if (m_bFadeEnabled)
				{
					//Fade out in the distance
					vertexProgSource +=
						"	float dist = distance(camPos.xz, gl_Vertex.xz);	\n"
						"	gl_FrontColor.a *= (invisibleDist - dist) / fadeGap; \n";
				}

				vertexProgSource +=
					"	float radiusCoeff = params.x; \n"
					"	float heightCoeff = params.y; \n"
					"	float factorX = params.z; \n"
					"	float factorY = params.w; \n"
					"	vec4 tmpPos = gl_Vertex; \n"
					
					/* 
					2 different methods are used to for the sin calculation :
					- the first one gives a better effect but at the cost of a few fps because of the 2 sines
					- the second one uses less ressources but is a bit less realistic

					a sin approximation could be use to optimize performances
					*/
	#if 1
					"	tmpPos.y += sin(time + originPos.z + tmpPos.y + tmpPos.x) * radiusCoeff * radiusCoeff * factorY; \n"
					"	tmpPos.x += sin(time + originPos.z ) * heightCoeff * heightCoeff * factorX; \n"
	#else
	 				
					"	float sinval = sin(time + originPos.z ); \n"
					"	tmpPos.y += sinval * radiusCoeff * radiusCoeff * factorY; \n"
					"	tmpPos.x += sinval * heightCoeff * heightCoeff * factorX; \n"
	#endif
					"	gl_Position = gl_ModelViewProjectionMatrix * tmpPos; \n"
					"	gl_FogFragCoord = gl_Position.z; \n"
					"}";
			}

			// test for shader source
			//std::ofstream shaderOutput;
			//shaderOutput.open((vertexProgName+std::string(".cg")).c_str());
			//shaderOutput << vertexProgSource;
			//shaderOutput.close();

			// end test for shader source

			HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram(
				vertexProgName,
				ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
				shaderLanguage, GPT_VERTEX_PROGRAM);

			vertexShader->setSource(vertexProgSource);

			if (shaderLanguage == "hlsl")
			{
				vertexShader->setParameter("target", "vs_1_1");
				vertexShader->setParameter("entry_point", "main");
			}
			else if(shaderLanguage == "cg")
			{
				vertexShader->setParameter("profiles", "vs_1_1 arbvp1");
				vertexShader->setParameter("entry_point", "main");
			}
			// GLSL can only have one entry point "main".

			vertexShader->load();
		}

		//Now that the shader is ready to be applied, apply it
		StringUtil::StrStreamType materialSignature;
		materialSignature << "BatchMat|";
		materialSignature << ptrMat->getName() << "|";
		if (m_bFadeEnabled)
      {
			materialSignature << m_fVisibleDist << "|";
			materialSignature << m_fInvisibleDist << "|";
		}

		//Search for the desired material
		MaterialPtr generatedMaterial = MaterialManager::getSingleton().getByName(materialSignature.str());
		if (generatedMaterial.isNull())
      {
			//Clone the material
			generatedMaterial = ptrMat->clone(materialSignature.str());

			//And apply the fade shader
			for (unsigned short t = 0; t < generatedMaterial->getNumTechniques(); ++t){
				Technique *tech = generatedMaterial->getTechnique(t);
				for (unsigned short p = 0; p < tech->getNumPasses(); ++p){
					Pass *pass = tech->getPass(p);

					//Setup vertex program
					if (pass->getVertexProgramName() == "")
						pass->setVertexProgram(vertexProgName);

					try{
						GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();

						if (lightingEnabled) {
							params->setNamedAutoConstant("objSpaceLight", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE);
							params->setNamedAutoConstant("lightDiffuse", GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR);
							params->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR);
							//params->setNamedAutoConstant("matAmbient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
						}

						params->setNamedConstantFromTime("time", 1);

						if(shaderLanguage.compare("glsl"))
						{
							//glsl can use the built in gl_ModelViewProjectionMatrix
							params->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
						}

						if (m_bFadeEnabled)
                  {
							params->setNamedAutoConstant("camPos", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);

							//Set fade ranges
							params->setNamedAutoConstant("invisibleDist", GpuProgramParameters::ACT_CUSTOM);
							params->setNamedConstant("invisibleDist", m_fInvisibleDist);

							params->setNamedAutoConstant("fadeGap", GpuProgramParameters::ACT_CUSTOM);
							params->setNamedConstant("fadeGap", m_fInvisibleDist - m_fVisibleDist);

							if (pass->getAlphaRejectFunction() == CMPF_ALWAYS_PASS)
								pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
						}
					}
					catch (const Ogre::Exception &e)
					{
						// test for shader source	
						std::ofstream shaderOutput;
						shaderOutput.open("exception.log");
						shaderOutput << e.getDescription();
						shaderOutput.close();
					}
					catch (...)
               {
						OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR,
                     "Error configuring batched geometry transitions. If you're using materials with custom\
                     vertex shaders, they will need to implement fade transitions to be compatible with BatchPage.",
                     "BatchPage::_updateShaders()");
					}
				}
			}

		}

		//Apply the material
		subBatch->setMaterial(generatedMaterial);
	}
void BatchPage::_updateShaders()
{
	if (!shadersSupported)
		return;

	uint32 i = 0;
	BatchedGeometry::SubBatchIterator it = batch->getSubBatchIterator();
	while (it.hasMoreElements()){
		BatchedGeometry::SubBatch *subBatch = it.getNext();
		MaterialPtr mat = unfadedMaterials[i++];

		//Check if lighting should be enabled
		bool lightingEnabled = false;
		for (unsigned short t = 0; t < mat->getNumTechniques(); ++t){
			Technique *tech = mat->getTechnique(t);
			for (unsigned short p = 0; p < tech->getNumPasses(); ++p){
				Pass *pass = tech->getPass(p);
				if (pass->getLightingEnabled()) {
					lightingEnabled = true;
					break;
				}
			}
			if (lightingEnabled)
				break;
		}

		//Compile the CG shader script based on various material / fade options
		StringUtil::StrStreamType tmpName;
		tmpName << "BatchPage_";
		if (fadeEnabled)
			tmpName << "fade_";
		if (lightingEnabled)
			tmpName << "lit_";
		if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
			tmpName << "clr_";

		for (unsigned short i = 0; i < subBatch->vertexData->vertexDeclaration->getElementCount(); ++i)
		{
			const VertexElement *el = subBatch->vertexData->vertexDeclaration->getElement(i);
			if (el->getSemantic() == VES_TEXTURE_COORDINATES) {
				String uvType = "";
				switch (el->getType()) {
						case VET_FLOAT1: uvType = "1"; break;
						case VET_FLOAT2: uvType = "2"; break;
						case VET_FLOAT3: uvType = "3"; break;
						case VET_FLOAT4: uvType = "4"; break;
				}
				tmpName << uvType << '_';
			}
		}

		tmpName << "vp";

		const String vertexProgName = tmpName.str();

		String shaderLanguage;
		if (Root::getSingleton().getRenderSystem()->getName() == "Direct3D9 Rendering Subsystem")
			shaderLanguage = "hlsl";
		else if(Root::getSingleton().getRenderSystem()->getName() == "OpenGL Rendering Subsystem")
			shaderLanguage = "glsl";
		else
			shaderLanguage = "cg";

		//If the shader hasn't been created yet, create it
		if (HighLevelGpuProgramManager::getSingleton().getByName(vertexProgName).isNull())
		{
			Pass *pass = mat->getTechnique(0)->getPass(0);
			String vertexProgSource;

			if(!shaderLanguage.compare("hlsl") || !shaderLanguage.compare("cg"))
			{

				vertexProgSource =
					"void main( \n"
					"	float4 iPosition : POSITION, \n"
					"	float3 normal    : NORMAL,	\n"
					"	out float4 oPosition : POSITION, \n";

				if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL) vertexProgSource +=
					"	float4 iColor    : COLOR, \n";

				unsigned texNum = 0;
				for (unsigned short i = 0; i < subBatch->vertexData->vertexDeclaration->getElementCount(); ++i) {
					const VertexElement *el = subBatch->vertexData->vertexDeclaration->getElement(i);
					if (el->getSemantic() == VES_TEXTURE_COORDINATES) {
						String uvType = "";
						switch (el->getType()) {
							case VET_FLOAT1: uvType = "float"; break;
							case VET_FLOAT2: uvType = "float2"; break;
							case VET_FLOAT3: uvType = "float3"; break;
							case VET_FLOAT4: uvType = "float4"; break;
						}

						vertexProgSource +=
						"	" + uvType + " iUV" + StringConverter::toString(texNum) + "			: TEXCOORD" + StringConverter::toString(texNum) + ",	\n"
						"	out " + uvType + " oUV" + StringConverter::toString(texNum) + "		: TEXCOORD" + StringConverter::toString(texNum) + ",	\n";

						++texNum;
					}
				}

				vertexProgSource +=
					"	out float oFog : FOG,	\n"
					"	out float4 oColor : COLOR, \n";

				if (lightingEnabled) vertexProgSource +=
					"	uniform float4 objSpaceLight,	\n"
					"	uniform float4 lightDiffuse,	\n"
					"	uniform float4 lightAmbient,	\n";

				if (fadeEnabled) vertexProgSource +=
					"	uniform float3 camPos, \n";

				vertexProgSource +=
					"	uniform float4x4 worldViewProj,	\n"
					"	uniform float fadeGap, \n"
					"   uniform float invisibleDist )\n"
					"{	\n";

				if (lightingEnabled) {
					//Perform lighting calculations (no specular)
					vertexProgSource +=
					"	float3 light = normalize(objSpaceLight.xyz - (iPosition.xyz * objSpaceLight.w)); \n"
					"	float diffuseFactor = max(dot(normal, light), 0); \n";
					if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
						vertexProgSource += "oColor = (lightAmbient + diffuseFactor * lightDiffuse) * iColor; \n";
					else
						vertexProgSource += "oColor = (lightAmbient + diffuseFactor * lightDiffuse); \n";
				} else {
					if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
						vertexProgSource += "oColor = iColor; \n";
					else
						vertexProgSource += "oColor = float4(1, 1, 1, 1); \n";
				}

				if (fadeEnabled) vertexProgSource +=
					//Fade out in the distance
					"	float dist = distance(camPos.xz, iPosition.xz);	\n"
					"	oColor.a *= (invisibleDist - dist) / fadeGap;   \n";

				texNum = 0;
				for (unsigned short i = 0; i < subBatch->vertexData->vertexDeclaration->getElementCount(); ++i) {
					const VertexElement *el = subBatch->vertexData->vertexDeclaration->getElement(i);
					if (el->getSemantic() == VES_TEXTURE_COORDINATES) {
						vertexProgSource +=
						"	oUV" + StringConverter::toString(texNum) + " = iUV" + StringConverter::toString(texNum) + ";	\n";
						++texNum;
					}
				}

				vertexProgSource +=
					"	oPosition = mul(worldViewProj, iPosition);  \n"
					"	oFog = oPosition.z; \n"
					"}";
			}

			if(!shaderLanguage.compare("glsl"))
			{
				vertexProgSource =
					"uniform float fadeGap;        \n"
					"uniform float invisibleDist;   \n";

				if (lightingEnabled) vertexProgSource +=
					"uniform vec4 objSpaceLight;   \n"
					"uniform vec4 lightDiffuse;	   \n"
					"uniform vec4 lightAmbient;	   \n";

				if (fadeEnabled) vertexProgSource +=
					"uniform vec3 camPos;          \n";

				vertexProgSource +=
					"void main() \n"
					"{ \n";

				if (lightingEnabled)
				{
					//Perform lighting calculations (no specular)
					vertexProgSource +=
					"   vec3 light = normalize(objSpaceLight.xyz - (gl_Vertex.xyz * objSpaceLight.w)); \n"
					"   float diffuseFactor = max(dot(gl_Normal, light), 0.0); \n";
					if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
					{
						vertexProgSource += "   gl_FrontColor = (lightAmbient + diffuseFactor * lightDiffuse) * gl_Color; \n";
					}
					else
					{
						vertexProgSource += "   gl_FrontColor = (lightAmbient + diffuseFactor * lightDiffuse); \n";
					}
				}
				else
				{
					if (subBatch->vertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
					{
						vertexProgSource += "   gl_FrontColor = gl_Color; \n";
					}
					else
					{
						vertexProgSource += "   gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0); \n";
					}
				}

				if (fadeEnabled)
				{
					vertexProgSource +=
					//Fade out in the distance
					"   float dist = distance(camPos.xz, gl_Vertex.xz);	\n"
					"   gl_FrontColor.a *= (invisibleDist - dist) / fadeGap;   \n";
				}

				unsigned texNum = 0;
				for (unsigned short i = 0; i < subBatch->vertexData->vertexDeclaration->getElementCount(); ++i)
				{
					const VertexElement *el = subBatch->vertexData->vertexDeclaration->getElement(i);
					if (el->getSemantic() == VES_TEXTURE_COORDINATES)
					{
						vertexProgSource +=
						"   gl_TexCoord[" + StringConverter::toString(texNum) + "] = gl_MultiTexCoord" + StringConverter::toString(texNum) + ";	\n";
						++texNum;
					}
				}

				vertexProgSource +=
					"   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  \n"
					"   gl_FogFragCoord = gl_Position.z; \n"
					"}";
			}


			HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram(
				vertexProgName,
				ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
				shaderLanguage, GPT_VERTEX_PROGRAM);

			vertexShader->setSource(vertexProgSource);

			if (shaderLanguage == "hlsl")
			{
				vertexShader->setParameter("target", "vs_1_1");
				vertexShader->setParameter("entry_point", "main");
			}
			else if(shaderLanguage == "cg")
			{
				vertexShader->setParameter("profiles", "vs_1_1 arbvp1");
				vertexShader->setParameter("entry_point", "main");
			}
			// GLSL can only have one entry point "main".

			vertexShader->load();
		}

		//Now that the shader is ready to be applied, apply it
		StringUtil::StrStreamType materialSignature;
		materialSignature << "BatchMat|";
		materialSignature << mat->getName() << "|";
		if (fadeEnabled){
			materialSignature << visibleDist << "|";
			materialSignature << invisibleDist << "|";
		}

		//Search for the desired material
		MaterialPtr generatedMaterial = MaterialManager::getSingleton().getByName(materialSignature.str());
		if (generatedMaterial.isNull()){
			//Clone the material
			generatedMaterial = mat->clone(materialSignature.str());

			//And apply the fade shader
			for (unsigned short t = 0; t < generatedMaterial->getNumTechniques(); ++t){
				Technique *tech = generatedMaterial->getTechnique(t);
				for (unsigned short p = 0; p < tech->getNumPasses(); ++p){
					Pass *pass = tech->getPass(p);

					//Setup vertex program
					if (pass->getVertexProgramName() == "")
						pass->setVertexProgram(vertexProgName);

					try{
						GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();

						if (lightingEnabled) {
							params->setNamedAutoConstant("objSpaceLight", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE);
							params->setNamedAutoConstant("lightDiffuse", GpuProgramParameters::ACT_DERIVED_LIGHT_DIFFUSE_COLOUR);
							params->setNamedAutoConstant("lightAmbient", GpuProgramParameters::ACT_DERIVED_AMBIENT_LIGHT_COLOUR);
							//params->setNamedAutoConstant("matAmbient", GpuProgramParameters::ACT_SURFACE_AMBIENT_COLOUR);
						}

						if(shaderLanguage.compare("glsl"))
						{
							//glsl can use the built in gl_ModelViewProjectionMatrix
							params->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
						}

						if (fadeEnabled)
						{
							params->setNamedAutoConstant("camPos", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);

							//Set fade ranges
							params->setNamedAutoConstant("invisibleDist", GpuProgramParameters::ACT_CUSTOM);
							params->setNamedConstant("invisibleDist", invisibleDist);

							params->setNamedAutoConstant("fadeGap", GpuProgramParameters::ACT_CUSTOM);
							params->setNamedConstant("fadeGap", invisibleDist - visibleDist);

							if (pass->getAlphaRejectFunction() == CMPF_ALWAYS_PASS)
								pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
						}
					}
					catch (...) {
						OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Error configuring batched geometry transitions. If you're using materials with custom vertex shaders, they will need to implement fade transitions to be compatible with BatchPage.", "BatchPage::_updateShaders()");
					}
				}
			}

		}

		//Apply the material
		subBatch->setMaterial(generatedMaterial);
	}

}
Beispiel #12
0
void MeshObject::loadMesh()
{
    try
    {
        Ogre::String resourceGroup = Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME;
        mesh = static_cast<Ogre::MeshPtr>(Ogre::MeshManager::getSingleton().create(meshName, resourceGroup));
        if(backgroundLoading)
        {
            mesh->setBackgroundLoaded(true);
            mesh->addListener(this);
            ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(
                         Ogre::MeshManager::getSingletonPtr()->getResourceType(),
                         mesh->getName(),
                         resourceGroup,
                         false,
                         0,
                         0,
                         0);

            // try to load its textures in the background
            for(int i=0; i<mesh->getNumSubMeshes(); i++)
            {
                SubMesh *sm = mesh->getSubMesh(i);
                String materialName = sm->getMaterialName();
                Ogre::MaterialPtr mat = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().getByName(materialName)); //, resourceGroup));
                if(mat.isNull()) continue;
                for(int tn=0; tn<mat->getNumTechniques(); tn++)
                {
                    Technique *t = mat->getTechnique(tn);
                    for(int pn=0; pn<t->getNumPasses(); pn++)
                    {
                        Pass *p = t->getPass(pn);
                        for(int tun=0; tun<p->getNumTextureUnitStates(); tun++)
                        {
                            TextureUnitState *tu = p->getTextureUnitState(tun);
                            String textureName = tu->getTextureName();
                            // now add this texture to the background loading queue
                            Ogre::TexturePtr tex = static_cast<Ogre::TexturePtr>(Ogre::TextureManager::getSingleton().create(textureName, resourceGroup));
                            tex->setBackgroundLoaded(true);
                            tex->addListener(this);
                            ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(
                                         Ogre::TextureManager::getSingletonPtr()->getResourceType(),
                                         tex->getName(),
                                         resourceGroup,
                                         false,
                                         0,
                                         0,
                                         0);

                        }
                    }

                }
            }
        }

        if(!backgroundLoading)
            postProcess();
    }
    catch (Ogre::Exception* e)
    {
        LOG("exception while loading mesh: " + e->getFullDescription());
    }

}
//-----------------------------------------------------------------------------
///
MaterialPtr StaticBillboardSet::getFadeMaterial(const Ogre::MaterialPtr &protoMaterial,
                                                Real visibleDist_, Real invisibleDist_)
{
   assert(!protoMaterial.isNull());

   StringUtil::StrStreamType materialSignature;
   materialSignature << mEntityName << "|";
   materialSignature << visibleDist_ << "|";
   materialSignature << invisibleDist_ << "|";
   materialSignature << protoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureUScroll() << "|";
   materialSignature << protoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureVScroll() << "|";

   FadedMaterialMap::iterator it = s_mapFadedMaterial.find(materialSignature.str());
   if (it != s_mapFadedMaterial.end())
      return it->second; //Use the existing fade material
   else
   {
      MaterialPtr fadeMaterial = protoMaterial->clone(getUniqueID("ImpostorFade"));

      bool isglsl = Root::getSingleton().getRenderSystem()->getName() == "OpenGL Rendering Subsystem" ? true : false;

      //And apply the fade shader
      for (unsigned short t = 0; t < fadeMaterial->getNumTechniques(); ++t)
      {
         Technique *tech = fadeMaterial->getTechnique(t);
         for (unsigned short p = 0; p < tech->getNumPasses(); ++p)
         {
            Pass *pass = tech->getPass(p);

            //Setup vertex program
            pass->setVertexProgram("SpriteFade_vp");
            GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();

            //glsl can use the built in gl_ModelViewProjectionMatrix
            if (!isglsl)
               params->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);

            static const Ogre::String uScroll = "uScroll", vScroll = "vScroll",
               preRotatedQuad0 = "preRotatedQuad[0]", preRotatedQuad1 = "preRotatedQuad[1]",
               preRotatedQuad2 = "preRotatedQuad[2]", preRotatedQuad3 = "preRotatedQuad[3]",
               camPos = "camPos", fadeGap = "fadeGap", invisibleDist = "invisibleDist";

            params->setNamedAutoConstant(uScroll, GpuProgramParameters::ACT_CUSTOM);
            params->setNamedAutoConstant(vScroll, GpuProgramParameters::ACT_CUSTOM);
            params->setNamedAutoConstant(preRotatedQuad0, GpuProgramParameters::ACT_CUSTOM);
            params->setNamedAutoConstant(preRotatedQuad1, GpuProgramParameters::ACT_CUSTOM);
            params->setNamedAutoConstant(preRotatedQuad2, GpuProgramParameters::ACT_CUSTOM);
            params->setNamedAutoConstant(preRotatedQuad3, GpuProgramParameters::ACT_CUSTOM);

            params->setNamedAutoConstant(camPos, GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
            params->setNamedAutoConstant(fadeGap, GpuProgramParameters::ACT_CUSTOM);
            params->setNamedAutoConstant(invisibleDist, GpuProgramParameters::ACT_CUSTOM);

            //Set fade ranges
            params->setNamedConstant(invisibleDist, invisibleDist_);
            params->setNamedConstant(fadeGap, invisibleDist_ - visibleDist_);

            pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
            //pass->setAlphaRejectFunction(CMPF_ALWAYS_PASS);
            //pass->setDepthWriteEnabled(false);

         }  // for Pass

      }  // for Technique

      //Add it to the list so it can be reused later
      s_mapFadedMaterial.insert(std::pair<String, MaterialPtr>(materialSignature.str(), fadeMaterial));

      return fadeMaterial;
   }
}
//-----------------------------------------------------------------------------
///
void WindBatchPage::_updateShaders()
{
	if (!m_bShadersSupported)
		return;

	unsigned int i = 0;
	BatchedGeometry::TSubBatchIterator it = m_pBatchGeom->getSubBatchIterator();
	while (it.hasMoreElements())
	{
		BatchedGeometry::SubBatch *subBatch = it.getNext();
		const MaterialPtr &ptrMat = m_vecUnfadedMaterials[i++];

		//Check if lighting should be enabled
		bool lightingEnabled = false;
		for (unsigned short t = 0, techCnt = ptrMat->getNumTechniques(); t < techCnt; ++t)
		{
			Technique *tech = ptrMat->getTechnique(t);
			for (unsigned short p = 0, passCnt = tech->getNumPasses(); p < passCnt; ++p)
			{
				if (tech->getPass(p)->getLightingEnabled())
				{
					lightingEnabled = true;
					break;
				}
			}

			if (lightingEnabled)
				break;
		}

		//Compile the shader script based on various material / fade options
		StringUtil::StrStreamType tmpName;
		tmpName << "BatchPage_";
		if (m_bFadeEnabled)
			tmpName << "fade_";
		if (lightingEnabled)
			tmpName << "lit_";
		if (subBatch->m_pVertexData->vertexDeclaration->findElementBySemantic(VES_DIFFUSE) != NULL)
			tmpName << "clr_";

		for (unsigned short i = 0; i < subBatch->m_pVertexData->vertexDeclaration->getElementCount(); ++i)
		{
			const VertexElement *el = subBatch->m_pVertexData->vertexDeclaration->getElement(i);
			if (el->getSemantic() == VES_TEXTURE_COORDINATES)
			{
				String uvType;
				switch (el->getType())
				{
				case VET_FLOAT1: uvType = "1"; break;
				case VET_FLOAT2: uvType = "2"; break;
				case VET_FLOAT3: uvType = "3"; break;
				case VET_FLOAT4: uvType = "4"; break;
				}
				tmpName << uvType << '_';
			}
		}

		tmpName << "vp";

		const String vertexProgName = tmpName.str();

		String shaderLanguage;
		if (Root::getSingleton().getRenderSystem()->getName() == "Direct3D9 Rendering Subsystem")
			shaderLanguage = "hlsl";
		else if(Root::getSingleton().getRenderSystem()->getName() == "OpenGL Rendering Subsystem")
			shaderLanguage = "glsl";
		else
			shaderLanguage = "cg";

		///T removed code for shader creation (we have our own shader)


		//Now that the shader is ready to be applied, apply it
		StringUtil::StrStreamType materialSignature;
		materialSignature << "BatchMat|";
		materialSignature << ptrMat->getName() << "|";
		if (m_bFadeEnabled)
		{
			materialSignature << m_fVisibleDist << "|";
			materialSignature << m_fInvisibleDist << "|";
		}

		//Search for the desired material
		/*
		MaterialPtr generatedMaterial = MaterialManager::getSingleton().getByName(materialSignature.str());
		if (generatedMaterial.isNull())
		{
			//Clone the material
			std::cout << ptrMat->getName() << std::endl;
			sh::MaterialInstance* m = sh::Factory::getInstance ().createMaterialInstance (materialSignature.str(), ptrMat->getName());
			//generatedMaterial = ptrMat->clone(materialSignature.str());

			//And apply the fade shader
		}
		*/
		//Apply the material
		Ogre::MaterialPtr m = ptrMat;
		subBatch->setMaterial(m);
	}
}
    //-------------------------------------------------------------------------
    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);
                        }
                    }

                }
            }
        }

    }