//-----------------------------------------------------------------------------
///
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 TerrainMaterialGeneratorC::SM2Profile::addTechnique(
		const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt)
	{
		Technique* tech = mat->createTechnique();
		tech->setSchemeName("GBuffer");
 
		// Only supporting one pass
		Pass* pass = tech->createPass();
		//pass->setName("NO_DEFERRED");
 
		GpuProgramManager& gmgr = GpuProgramManager::getSingleton();
		HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton();
		if (!mShaderGen)
		{
			if (hmgr.isLanguageSupported("cg"))
				mShaderGen = OGRE_NEW ShaderHelperCg();
			else
			{
				// todo
			}
 
			// check SM3 features
			mSM3Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0");
			mSM4Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0");
 
		}
		HighLevelGpuProgramPtr vprog = mShaderGen->generateVertexProgram(this, terrain, tt);
		HighLevelGpuProgramPtr fprog = mShaderGen->generateFragmentProgram(this, terrain, tt);
 
		pass->setVertexProgram(vprog->getName());
		pass->setFragmentProgram(fprog->getName());
 
		if (tt == HIGH_LOD || tt == RENDER_COMPOSITE_MAP)
		{
			// global normal map
			TextureUnitState* tu = pass->createTextureUnitState();
			tu->setTextureName(terrain->getTerrainNormalMap()->getName());
			tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
 
			// global colour map
			if (terrain->getGlobalColourMapEnabled() && isGlobalColourMapEnabled())
			{
				tu = pass->createTextureUnitState(terrain->getGlobalColourMap()->getName());
				tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
			}
 
			// light map
			if (isLightmapEnabled())
			{
				tu = pass->createTextureUnitState(terrain->getLightmap()->getName());
				tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
			}
 
			// blend maps
			uint maxLayers = getMaxLayers(terrain);
			uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount());
			uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
			for (uint i = 0; i < numBlendTextures; ++i)
			{
				tu = pass->createTextureUnitState(terrain->getBlendTextureName(i));
				tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
			}
 
			// layer textures
			for (uint i = 0; i < numLayers; ++i)
			{
				// diffuse / specular
				pass->createTextureUnitState(terrain->getLayerTextureName(i, 0));
 
				// normal / height
				pass->createTextureUnitState(terrain->getLayerTextureName(i, 1));
			}
 
		}
		else
		{
			// LOW_LOD textures
			// composite map
			TextureUnitState* tu = pass->createTextureUnitState();
			tu->setTextureName(terrain->getCompositeMap()->getName());
			tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
 
			// That's it!
 
		}
	}
Exemplo n.º 3
0
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);
	}

}
	//---------------------------------------------------------------------
	void TerrainMaterialGeneratorA::SM2Profile::ShaderHelper::defaultFpParams(
		const SM2Profile* prof, const Terrain* terrain, TechniqueType tt, const HighLevelGpuProgramPtr& prog)
	{
		GpuProgramParametersSharedPtr params = prog->getDefaultParameters();
		params->setIgnoreMissingParams(true);

		params->setNamedAutoConstant("ambient", GpuProgramParameters::ACT_AMBIENT_LIGHT_COLOUR);
		params->setNamedAutoConstant("lightPosObjSpace", GpuProgramParameters::ACT_LIGHT_POSITION_OBJECT_SPACE, 0);
		params->setNamedAutoConstant("lightDiffuseColour", GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR, 0);
		params->setNamedAutoConstant("lightSpecularColour", GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR, 0);
		params->setNamedAutoConstant("eyePosObjSpace", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
		params->setNamedAutoConstant("fogColour", GpuProgramParameters::ACT_FOG_COLOUR);

		if (prof->isShadowingEnabled(tt, terrain))
		{
			uint numTextures = 1;
			if (prof->getReceiveDynamicShadowsPSSM())
			{
				PSSMShadowCameraSetup* pssm = prof->getReceiveDynamicShadowsPSSM();
				numTextures = (uint)pssm->getSplitCount();
				Vector4 splitPoints;
				const PSSMShadowCameraSetup::SplitPointList& splitPointList = pssm->getSplitPoints();
				// Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
				for (uint i = 1; i < numTextures; ++i)
				{
					splitPoints[i-1] = splitPointList[i];
				}
				params->setNamedConstant("pssmSplitPoints", splitPoints);
			}

			if (prof->getReceiveDynamicShadowsDepth())
			{
				size_t samplerOffset = (tt == HIGH_LOD) ? mShadowSamplerStartHi : mShadowSamplerStartLo;
				for (uint i = 0; i < numTextures; ++i)
				{
					params->setNamedAutoConstant("inverseShadowmapSize" + StringConverter::toString(i), 
						GpuProgramParameters::ACT_INVERSE_TEXTURE_SIZE, i + samplerOffset);
				}
			}
		}

        // Explicitly bind samplers for GLSL
        if ((prof->_getShaderLanguage() == "glsl") || (prof->_getShaderLanguage() == "glsles"))
        {
            int numSamplers = 0;
            if (tt == LOW_LOD)
            {
                params->setNamedConstant("compositeMap", (int)numSamplers++);
            }
            else
            {
                params->setNamedConstant("globalNormal", (int)numSamplers++);

                if (terrain->getGlobalColourMapEnabled() && prof->isGlobalColourMapEnabled())
                {
                    params->setNamedConstant("globalColourMap", (int)numSamplers++);
                }
                if (prof->isLightmapEnabled())
                {
                    params->setNamedConstant("lightMap", (int)numSamplers++);
                }

                uint maxLayers = prof->getMaxLayers(terrain);
                uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount());
                uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
                // Blend textures - sampler definitions
                for (uint i = 0; i < numBlendTextures; ++i)
                {
                    params->setNamedConstant("blendTex" + StringConverter::toString(i), (int)numSamplers++);
                }

                // Layer textures - sampler definitions & UV multipliers
                for (uint i = 0; i < numLayers; ++i)
                {
                    params->setNamedConstant("difftex" + StringConverter::toString(i), (int)numSamplers++);
                    params->setNamedConstant("normtex" + StringConverter::toString(i), (int)numSamplers++);
                }

                uint numShadowTextures = 1;
                if (prof->getReceiveDynamicShadowsPSSM())
                    numShadowTextures = (uint)prof->getReceiveDynamicShadowsPSSM()->getSplitCount();

                for (uint i = 0; i < numShadowTextures; ++i)
                {
                    if (prof->isShadowingEnabled(tt, terrain))
                        params->setNamedConstant("shadowMap" + StringConverter::toString(i), (int)numSamplers++);
                }
            }
        }
	}
//-----------------------------------------------------------------------------
void GLSLProgramProcessor::bindSubShaders(Program* program, GpuProgramPtr pGpuProgram)
{
	if (program->getDependencyCount() > 0)
	{
		// Get all attached shaders so we do not attach shaders twice.
		// maybe GLSLProgram should take care of that ( prevent add duplicate shaders )
		String attachedShaders = pGpuProgram->getParameter("attach");
		String subShaderDef = "";

		for (unsigned int i=0; i < program->getDependencyCount(); ++i)
		{
			// Here we append _VS and _FS to the library shaders (so max each lib shader
			// is compiled twice once as vertex and once as fragment shader)
			String subShaderName = program->getDependency(i);
			if (program->getType() == GPT_VERTEX_PROGRAM)
			{
				subShaderName += "_VS";
			}
			else
			{
				subShaderName += "_FS";
			}					

			// Check if the library shader already compiled
			if(!HighLevelGpuProgramManager::getSingleton().resourceExists(subShaderName))
			{
				// Create the library shader
				HighLevelGpuProgramPtr pSubGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(subShaderName,
					ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TargetLanguage, program->getType());

				// Set the source name
				String sourceName = program->getDependency(i) + "." + TargetLanguage;
				pSubGpuProgram->setSourceFile(sourceName);
                pSubGpuProgram->load();

                // Prepend the current GLSL version
                String versionLine = "#version " + StringConverter::toString(Root::getSingleton().getRenderSystem()->getNativeShadingLanguageVersion()) + "\n";
                pSubGpuProgram->setSource(versionLine + pSubGpuProgram->getSource());

				// If we have compile errors than stop processing
				if (pSubGpuProgram->hasCompileError())
				{
					OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
						"Could not compile shader library from the source file: " + sourceName, 
						"GLSLProgramProcessor::bindSubShaders" );	
				}

				mLibraryPrograms.push_back(subShaderName);
			}

			// Check if the lib shader already attached to this shader
			if (attachedShaders.find(subShaderName) == String::npos)
			{
				// Append the shader name to subShaders
				subShaderDef += subShaderName + " ";
			}
		}

		// Check if we have something to attach
		if (subShaderDef.length() > 0)
		{
			pGpuProgram->setParameter("attach", subShaderDef);
		}
	}
	
}
Exemplo n.º 6
0
//-----------------------------------------------------------------------------
GpuProgramPtr ProgramManager::createGpuProgram(Program* shaderProgram, 
                                               ProgramWriter* programWriter,
                                               const String& language,
                                               const String& profiles,
                                               const StringVector& profilesList,
                                               const String& cachePath)
{
    stringstream sourceCodeStringStream;

    // Generate source code.
    programWriter->writeSourceCode(sourceCodeStringStream, shaderProgram);
    String source = sourceCodeStringStream.str();

    // Generate program name.
    String programName = generateHash(source);

    if (shaderProgram->getType() == GPT_VERTEX_PROGRAM)
    {
        programName += "_VS";
    }
    else if (shaderProgram->getType() == GPT_FRAGMENT_PROGRAM)
    {
        programName += "_FS";
    }

    // Try to get program by name.
    HighLevelGpuProgramPtr pGpuProgram =
        HighLevelGpuProgramManager::getSingleton().getByName(
            programName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME);

    if(pGpuProgram) {
        return static_pointer_cast<GpuProgram>(pGpuProgram);
    }

    // Case the program doesn't exist yet.
    // Create new GPU program.
    pGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName,
        ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, language, shaderProgram->getType());

    // Case cache directory specified -> create program from file.
    if (!cachePath.empty())
    {
        const String  programFullName = programName + "." + language;
        const String  programFileName = cachePath + programFullName;
        std::ifstream programFile;

        // Check if program file already exist.
        programFile.open(programFileName.c_str());

        // Case we have to write the program to a file.
        if (!programFile)
        {
            std::ofstream outFile(programFileName.c_str());

            if (!outFile)
                return GpuProgramPtr();

            outFile << source;
            outFile.close();
        }
        else
        {
            // use program file version
            StringStream buffer;
            programFile >> buffer.rdbuf();
            source = buffer.str();
        }
    }

    pGpuProgram->setSource(source);

    pGpuProgram->setParameter("entry_point", shaderProgram->getEntryPointFunction()->getName());

    if (language == "hlsl")
    {
        // HLSL program requires specific target profile settings - we have to split the profile string.
        StringVector::const_iterator it = profilesList.begin();
        StringVector::const_iterator itEnd = profilesList.end();
        
        for (; it != itEnd; ++it)
        {
            if (GpuProgramManager::getSingleton().isSyntaxSupported(*it))
            {
                pGpuProgram->setParameter("target", *it);
                break;
            }
        }

        pGpuProgram->setParameter("enable_backwards_compatibility", "true");
        pGpuProgram->setParameter("column_major_matrices", StringConverter::toString(shaderProgram->getUseColumnMajorMatrices()));
    }
    
    pGpuProgram->setParameter("profiles", profiles);
    pGpuProgram->load();

    // Case an error occurred.
    if (pGpuProgram->hasCompileError())
    {
        //! [debug_break]
        pGpuProgram.reset();
        //! [debug_break]
        return GpuProgramPtr(pGpuProgram);
    }

    // Add the created GPU program to local cache.
    if (pGpuProgram->getType() == GPT_VERTEX_PROGRAM)
    {
        mVertexShaderMap[programName] = pGpuProgram;
    }
    else if (pGpuProgram->getType() == GPT_FRAGMENT_PROGRAM)
    {
        mFragmentShaderMap[programName] = pGpuProgram;
    }
    
    return static_pointer_cast<GpuProgram>(pGpuProgram);
}
Exemplo n.º 7
0
GpuProgramPtr GBufferMaterialGeneratorImpl::generateVertexShader(MaterialGenerator::Perm permutation)
{
	StringStream ss;

    if(mIsGLSL)
    {
        ss << "#version 150" << std::endl;
        ss << "in vec4 vertex;" << std::endl;
        ss << "in vec3 normal;" << std::endl;

        uint32 numTexCoords = (permutation & GBufferMaterialGenerator::GBP_TEXCOORD_MASK) >> 8;
        for (uint32 i=0; i<numTexCoords; i++)
        {
            ss << "in vec2 uv" << i << ';' << std::endl;
        }

        if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
        {
            ss << "in vec3 tangent;" << std::endl;
        }

        //TODO : Skinning inputs
        ss << std::endl;

#ifdef WRITE_LINEAR_DEPTH
        ss << "out vec3 oViewPos;" << std::endl;
#else
        ss << "out float oDepth;" << std::endl;
#endif
        ss << "out vec3 oNormal;" << std::endl;
        if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
        {
            ss << "out vec3 oTangent;" << std::endl;
            ss << "out vec3 oBiNormal;" << std::endl;
        }
        for (uint32 i=0; i<numTexCoords; i++)
        {
            ss << "out vec2 oUv" << i << ";" << std::endl;
        }

        ss << std::endl;

        ss << "uniform mat4 cWorldViewProj;" << std::endl;
        ss << "uniform mat4 cWorldView;" << std::endl;

        ss << "void main()" << std::endl;

        ss << "{" << std::endl;
        ss << "	gl_Position = cWorldViewProj * vertex;" << std::endl;
        ss << "	oNormal = (cWorldView * vec4(normal,0)).xyz;" << std::endl;
        if (permutation & GBufferMaterialGenerator::GBP_NORMAL_MAP)
        {
            ss << "	oTangent = (cWorldView * vec4(tangent,0)).xyz;" << std::endl;
            ss << "	oBiNormal = cross(oNormal, oTangent);" << std::endl;
        }

#ifdef WRITE_LINEAR_DEPTH
        ss << "	oViewPos = (cWorldView * vertex).xyz;" << std::endl;
#else
        ss << "	oDepth = gl_Position.w;" << std::endl;
#endif

        for (uint32 i=0; i<numTexCoords; i++) {
            ss << "	oUv" << i << " = uv" << i << ';' << std::endl;
        }

        ss << "}" << std::endl;

        String programSource = ss.str();
        String programName = mBaseName + "VP_" + StringConverter::toString(permutation);

#if OGRE_DEBUG_MODE
        LogManager::getSingleton().getDefaultLog()->logMessage(programSource);
#endif

        // Create shader object
        HighLevelGpuProgramPtr ptrProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName,
                                                                                                     ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                                                                                                     "glsl", GPT_VERTEX_PROGRAM);
        ptrProgram->setSource(programSource);
        ptrProgram->setParameter("syntax", "glsl150");

        const GpuProgramParametersSharedPtr& params = ptrProgram->getDefaultParameters();
        params->setNamedAutoConstant("cWorldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
        params->setNamedAutoConstant("cWorldView", GpuProgramParameters::ACT_WORLDVIEW_MATRIX);
        ptrProgram->load();
        
        return GpuProgramPtr(ptrProgram);
    }
    else
    {
Exemplo n.º 8
0
void Shader::prepare()
{
    // determining shader level and generating a part of the level string 
    std::string levelString = "_basic";
    if (shaderLevel == LEVEL_INTERMEDIATE) {
        levelString = "_intermediate";
    } else if (shaderLevel == LEVEL_ADVANCED) {
        levelString = "_advanced";
    }

    std::string vertexString;
    std::string geometryString;
    std::string fragmentString;

    // trying to use actual shader level, choosing basic as default/backup
    if (ResourceGroupManager::getSingleton()
            .resourceExistsInAnyGroup(shaderName + levelString + ".vert")) {
        vertexString = shaderName + levelString + ".vert";
    } else {
        vertexString = shaderName + "_basic.vert";
    }

    if (ResourceGroupManager::getSingleton()
            .resourceExistsInAnyGroup(shaderName + levelString + ".geom")) {
        geometryString = shaderName + levelString + ".geom";
    } else {
        geometryString = shaderName + "_basic.geom";
    }

    if (ResourceGroupManager::getSingleton()
            .resourceExistsInAnyGroup(shaderName + levelString + ".frag")) {
        fragmentString = shaderName + levelString + ".frag";
    } else {
        fragmentString = shaderName + "_basic.frag";
    }

    // creating new material
    material = MaterialManager::getSingletonPtr()->create(materialName + shaderName,
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

    pass = material->getTechnique(0)->getPass(0);

    // with dynamic lighting only geometry with normals will be displayed
    pass->setLightingEnabled(true);
    material->setReceiveShadows(true);

    // loading vertex shader if there is one
    if (ResourceGroupManager::getSingleton()
            .resourceExistsInAnyGroup(vertexString)) {
        HighLevelGpuProgramPtr vertex =
                HighLevelGpuProgramManager::getSingletonPtr()->createProgram(
                shaderName + "_v",
                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                "glsl", GpuProgramType::GPT_VERTEX_PROGRAM);
        vertex->setSourceFile(vertexString);
        pass->setVertexProgram(vertex->getName());
    }

    // loading geometry shader if there is one
    if (ResourceGroupManager::getSingleton()
            .resourceExistsInAnyGroup(geometryString)) {
        geometry = HighLevelGpuProgramManager::getSingletonPtr()->createProgram(
                shaderName + "_g",
                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "glsl",
                GpuProgramType::GPT_GEOMETRY_PROGRAM);
        geometry->setSourceFile(geometryString);
        pass->setGeometryProgram(geometry->getName());
    }

    // loading fragment shader if there is one
    if (ResourceGroupManager::getSingleton()
            .resourceExistsInAnyGroup(fragmentString)) {
        HighLevelGpuProgramPtr fragment =
                HighLevelGpuProgramManager::
                getSingletonPtr()->createProgram(shaderName + "_f",
                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
                "glsl", GpuProgramType::GPT_FRAGMENT_PROGRAM);
        fragment->setSourceFile(fragmentString);
        pass->setFragmentProgram(fragment->getName());
    }
    entity->getOgreEntity()->setMaterialName(material->getName());
}
//-----------------------------------------------------------------------------
/// Constructor
StaticBillboardSet::StaticBillboardSet(SceneManager *mgr, SceneNode *rootSceneNode, BillboardMethod method) :
mVisible                (true),
mFadeEnabled            (false),
mRenderMethod           (method),
mpSceneMgr              (mgr),
mpSceneNode             (NULL),
mpEntity                (NULL),
mfUFactor               (1.f),
mfVFactor               (1.f),
mpFallbackBillboardSet  (NULL),
mBBOrigin               (BBO_CENTER),
mFadeVisibleDist        (0.f),
mFadeInvisibleDist      (0.f)
{
   assert(rootSceneNode);

   //Fall back to BB_METHOD_COMPATIBLE if vertex shaders are not available
   if (method == BB_METHOD_ACCELERATED)
   {
      const RenderSystemCapabilities *caps = Root::getSingleton().getRenderSystem()->getCapabilities();
      if (!caps->hasCapability(RSC_VERTEX_PROGRAM))
         mRenderMethod = BB_METHOD_COMPATIBLE;
   }

   mpSceneNode = rootSceneNode->createChildSceneNode();
   mEntityName = getUniqueID("SBSentity");

   if (mRenderMethod == BB_METHOD_ACCELERATED)
   {
      //Load vertex shader to align billboards to face the camera (if not loaded already)
      if (s_nSelfInstances == 0)
      {
         const Ogre::String &renderName = Root::getSingleton().getRenderSystem()->getName();
         s_isGLSL = renderName == "OpenGL Rendering Subsystem" ? true : false;
         Ogre::String shaderLanguage = s_isGLSL ? "glsl" : renderName == "Direct3D9 Rendering Subsystem" ? "hlsl" : "cg";

         //First shader, simple camera-alignment
         String vertexProg;
         if (!s_isGLSL) // DirectX HLSL or nVidia CG
         {
            vertexProg =
               "void Sprite_vp(	\n"
               "	float4 position : POSITION,	\n"
               "	float3 normal   : NORMAL,	\n"
               "	float4 color	: COLOR,	\n"
               "	float2 uv       : TEXCOORD0,	\n"
               "	out float4 oPosition : POSITION,	\n"
               "	out float2 oUv       : TEXCOORD0,	\n"
               "	out float4 oColor    : COLOR, \n"
               "	out float oFog       : FOG,	\n"
               "	uniform float4x4 worldViewProj,	\n"
               "	uniform float    uScroll, \n"
               "	uniform float    vScroll, \n"
               "	uniform float4   preRotatedQuad[4] )	\n"
               "{	\n"
               //Face the camera
               "	float4 vCenter = float4( position.x, position.y, position.z, 1.0f );	\n"
               "	float4 vScale = float4( normal.x, normal.y, normal.x, 1.0f );	\n"
               "	oPosition = mul( worldViewProj, vCenter + (preRotatedQuad[normal.z] * vScale) );  \n"

               //Color
               "	oColor = color;   \n"

               //UV Scroll
               "	oUv = uv;	\n"
               "	oUv.x += uScroll; \n"
               "	oUv.y += vScroll; \n"

               //Fog
               "	oFog = oPosition.z; \n"
               "}";
         }
         else     // OpenGL GLSL
         {
            vertexProg =
               "uniform float uScroll; \n"
               "uniform float vScroll; \n"
               "uniform vec4  preRotatedQuad[4]; \n"

               "void main() { \n"
               //Face the camera
               "	vec4 vCenter = vec4( gl_Vertex.x, gl_Vertex.y, gl_Vertex.z, 1.0 ); \n"
               "	vec4 vScale = vec4( gl_Normal.x, gl_Normal.y, gl_Normal.x , 1.0 ); \n"
               "	gl_Position = gl_ModelViewProjectionMatrix * (vCenter + (preRotatedQuad[int(gl_Normal.z)] * vScale) ); \n"

               //Color
               "	gl_FrontColor = gl_Color; \n"

               //UV Scroll
               "	gl_TexCoord[0] = gl_MultiTexCoord0; \n"
               "	gl_TexCoord[0].x += uScroll; \n"
               "	gl_TexCoord[0].y += vScroll; \n"

               //Fog
               "	gl_FogFragCoord = gl_Position.z; \n"
               "}";
         }
		#if OGRE_VERSION_MAJOR <= 1
			#if OGRE_VERSION_MINOR <= 8
				  HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().getByName("Sprite_vp");
			#else
				HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().getByName("Sprite_vp").staticCast<HighLevelGpuProgram>();
			#endif
		#endif
		 
         assert(vertexShader.isNull() && "Sprite_vp already exist");

         vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram(
            "Sprite_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, shaderLanguage, GPT_VERTEX_PROGRAM);
         vertexShader->setSource(vertexProg);

         // Set entry point for vertex program. GLSL can only have one entry point "main".
         if (!s_isGLSL)
         {
            if (shaderLanguage == "hlsl")
            {
               vertexShader->setParameter("target", "vs_1_1");
               vertexShader->setParameter("entry_point", "Sprite_vp");
            }
            else if(shaderLanguage == "cg")
            {
               vertexShader->setParameter("profiles", "vs_1_1 arbvp1");
               vertexShader->setParameter("entry_point", "Sprite_vp");
            }
            else
            {
               assert(false && "Unknown shader language");
            }
         }

         // compile vertex shader
         vertexShader->load();


         //====================================================================
         //Second shader, camera alignment and distance based fading
         String vertexProg2;
         if (!s_isGLSL) // DirectX HLSL or nVidia CG
         {
            vertexProg2 =
               "void SpriteFade_vp(	\n"
               "	float4 position : POSITION,	\n"
               "	float3 normal   : NORMAL,	\n"
               "	float4 color	: COLOR,	\n"
               "	float2 uv       : TEXCOORD0,	\n"
               "	out float4 oPosition : POSITION,	\n"
               "	out float2 oUv       : TEXCOORD0,	\n"
               "	out float4 oColor    : COLOR, \n"
               "	out float oFog       : FOG,	\n"
               "	uniform float4x4 worldViewProj,	\n"

               "	uniform float3 camPos, \n"
               "	uniform float fadeGap, \n"
               "   uniform float invisibleDist, \n"

               "	uniform float    uScroll, \n"
               "	uniform float    vScroll, \n"
               "	uniform float4   preRotatedQuad[4] )	\n"
               "{	\n"
               //Face the camera
               "	float4 vCenter = float4( position.x, position.y, position.z, 1.0f );	\n"
               "	float4 vScale = float4( normal.x, normal.y, normal.x, 1.0f );	\n"
               "	oPosition = mul( worldViewProj, vCenter + (preRotatedQuad[normal.z] * vScale) );  \n"

               "	oColor.rgb = color.rgb;   \n"

               //Fade out in the distance
               "	float dist = distance(camPos.xz, position.xz);	\n"
               "	oColor.a = (invisibleDist - dist) / fadeGap;   \n"

               //UV scroll
               "	oUv = uv;	\n"
               "	oUv.x += uScroll; \n"
               "	oUv.y += vScroll; \n"

               //Fog
               "	oFog = oPosition.z; \n"
               "}";
         }
         else        // OpenGL GLSL
         {
            vertexProg2 =
               "uniform vec3  camPos; \n"
               "uniform float fadeGap; \n"
               "uniform float invisibleDist; \n"
               "uniform float uScroll; \n"
               "uniform float vScroll; \n"
               "uniform vec4  preRotatedQuad[4]; \n"

               "void main() { \n"
               //Face the camera
               "	vec4 vCenter = vec4( gl_Vertex.x, gl_Vertex.y, gl_Vertex.z, 1.0 ); \n"
               "	vec4 vScale = vec4( gl_Normal.x, gl_Normal.y, gl_Normal.x , 1.0 ); \n"
               "	gl_Position = gl_ModelViewProjectionMatrix * (vCenter + (preRotatedQuad[int(gl_Normal.z)] * vScale) ); \n"

               "	gl_FrontColor.xyz = gl_Color.xyz; \n"

               //Fade out in the distance
               "	vec4 position = gl_Vertex; \n"
               "	float dist = distance(camPos.xz, position.xz); \n"
               "	gl_FrontColor.w = (invisibleDist - dist) / fadeGap; \n"

               //UV scroll
               "	gl_TexCoord[0] = gl_MultiTexCoord0; \n"
               "	gl_TexCoord[0].x += uScroll; \n"
               "	gl_TexCoord[0].y += vScroll; \n"

               //Fog
               "	gl_FogFragCoord = gl_Position.z; \n"
               "}";
         }
		#if OGRE_VERSION_MAJOR <= 1
			#if OGRE_VERSION_MINOR <= 8
				  HighLevelGpuProgramPtr vertexShader2 = HighLevelGpuProgramManager::getSingleton().getByName("SpriteFade_vp");
			#else
				HighLevelGpuProgramPtr vertexShader2 = HighLevelGpuProgramManager::getSingleton().getByName("SpriteFade_vp").staticCast<HighLevelGpuProgram>();
			#endif
		#endif
		 
         assert(vertexShader2.isNull() && "SpriteFade_vp already exist");
         vertexShader2 = HighLevelGpuProgramManager::getSingleton().createProgram("SpriteFade_vp",
            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, shaderLanguage, GPT_VERTEX_PROGRAM);
         vertexShader2->setSource(vertexProg2);

         // Set entry point. GLSL can only have one entry point "main".
         if (!s_isGLSL)
         {

            if (shaderLanguage == "hlsl")
            {
               vertexShader2->setParameter("target", "vs_1_1");
               vertexShader2->setParameter("entry_point", "SpriteFade_vp");
            }
            else if(shaderLanguage == "cg")
            {
               vertexShader2->setParameter("profiles", "vs_1_1 arbvp1");
               vertexShader2->setParameter("entry_point", "SpriteFade_vp");
            }
         }
         // compile it
         vertexShader2->load();
      }
   }
   else
   {
      //Compatible billboard method
      mpFallbackBillboardSet = mgr->createBillboardSet(getUniqueID("SBS"), 100);
      mpSceneNode->attachObject(mpFallbackBillboardSet);
      mfUFactor = mfVFactor = Ogre::Real(0.);
   }


   ++s_nSelfInstances;
}
Exemplo n.º 10
0
void BillboardObject::init(const String& textureName,
                    const float initialSize,
                    const Vector3& position,
                    SceneNode* rootNode)
{
    SceneManager* sceneMgr = rootNode->getCreator();

    Vector3 finalPosition = position.normalisedCopy() * 1000.f;

    static unsigned int bodyCount=0;

    /// \todo These billboards are not 100% correct, might want to revisit them later
    mBBSet = sceneMgr->createBillboardSet("SkyBillboardSet"+StringConverter::toString(bodyCount), 1);
    mBBSet->setDefaultDimensions(550.f*initialSize, 550.f*initialSize);
    mBBSet->setBillboardType(BBT_PERPENDICULAR_COMMON);
    mBBSet->setCommonDirection( -position.normalisedCopy() );
    mBBSet->setVisibilityFlags(RV_Sky);
    mNode = rootNode->createChildSceneNode();
    mNode->setPosition(finalPosition);
    mNode->attachObject(mBBSet);
    mBBSet->createBillboard(0,0,0);
    mBBSet->setCastShadows(false);

    mMaterial = MaterialManager::getSingleton().create("BillboardMaterial"+StringConverter::toString(bodyCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    mMaterial->removeAllTechniques();
    Pass* p = mMaterial->createTechnique()->createPass();
    p->setSceneBlending(SBT_TRANSPARENT_ALPHA);
    p->setDepthCheckEnabled(false);
    p->setDepthWriteEnabled(false);
    p->setSelfIllumination(1.0,1.0,1.0);
    p->setDiffuse(0.0,0.0,0.0,1.0);
    p->setAmbient(0.0,0.0,0.0);
    p->setPolygonModeOverrideable(false);
    p->createTextureUnitState(textureName);
    mBBSet->setMaterialName("BillboardMaterial"+StringConverter::toString(bodyCount));

    HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
    HighLevelGpuProgramPtr vshader;
    if (mgr.resourceExists("BBO_VP"))
        vshader = mgr.getByName("BBO_VP");
    else
        vshader = mgr.createProgram("BBO_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM);
    vshader->setParameter("profiles", "vs_2_x arbvp1");
    vshader->setParameter("entry_point", "main_vp");
    StringUtil::StrStreamType outStream;
    outStream <<
    "void main_vp(	\n"
    "	float4 position : POSITION,	\n"
    "   in float2 uv : TEXCOORD0, \n"
    "   out float2 oUV : TEXCOORD0, \n"
    "	out float4 oPosition : POSITION,	\n"
    "	uniform float4x4 worldViewProj	\n"
    ")	\n"
    "{	\n"
    "   oUV = uv; \n"
    "	oPosition = mul( worldViewProj, position );  \n"
    "}";
    vshader->setSource(outStream.str());
    vshader->load();
    vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
    mMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());

    HighLevelGpuProgramPtr fshader;
    if (mgr.resourceExists("BBO_FP"))
        fshader = mgr.getByName("BBO_FP");
    else
        fshader = mgr.createProgram("BBO_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_FRAGMENT_PROGRAM);

    fshader->setParameter("profiles", "ps_2_x arbfp1");
    fshader->setParameter("entry_point", "main_fp");
    StringUtil::StrStreamType outStream2;
    outStream2 <<
    "void main_fp(	\n"
    "   in float2 uv : TEXCOORD0, \n"
    "	out float4 oColor    : COLOR, \n";
    if (RenderingManager::useMRT()) outStream2 <<
        "   out float4 oColor1 : COLOR1, \n";
    outStream2 <<
    "   uniform sampler2D texture : TEXUNIT0, \n"
    "   uniform float4 diffuse, \n"
    "   uniform float4 emissive \n"
    ")	\n"
    "{	\n"
    "   float4 tex = tex2D(texture, uv); \n"
    "   oColor = float4(emissive.xyz,1) * tex * float4(1,1,1,diffuse.a); \n";
    if (RenderingManager::useMRT()) outStream2 <<
        "   oColor1 = float4(1, 0, 0, 1); \n";
    outStream2 <<
    "}";
    fshader->setSource(outStream2.str());
    fshader->load();
    fshader->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
    fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
    mMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());

    bodyCount++;
}
Exemplo n.º 11
0
HighLevelGpuProgramPtr ParticleMaterialGenerator::createSoftParticleFragmentProgram()
{
	HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
	std::string progName = mDef->getName() + "_ambient_FP";

	HighLevelGpuProgramPtr ret = mgr.getByName(progName);
	if (!ret.isNull())
		mgr.remove(progName);

	ret = mgr.createProgram(progName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
		"cg", GPT_FRAGMENT_PROGRAM);

	ret->setParameter("profiles", "ps_4_0 ps_3_0 ps_2_0 arbfp1");
	ret->setParameter("entry_point", "main_fp");

	StringUtil::StrStreamType sourceStr;
	
	sourceStr <<
	"	void main_fp(	in float4 iPosition : POSITION,  \n"
	"	in float4 position : COLOR,  \n"
	"	in float4 texCoord : TEXCOORD0,  \n"
	"	in float4 vertexColour : TEXCOORD1,  \n"
	"	in float4 positionScreen : TEXCOORD2,  \n"
	"	in float4 positionWorld : TEXCOORD3,  \n"
	"	uniform sampler2D diffuseMap : TEXUNIT0,  \n";
	
	if(MRTSupported())
	{
		sourceStr <<
			"	uniform sampler2D depthMap : TEXUNIT1, \n"
			"	uniform float useSoftParticles, \n";
	}
	
	sourceStr <<
	"	out float4 oColor : COLOR0,  \n"
	"	uniform float3 fogColor  \n";
	
	if(MRTSupported())
	{
		sourceStr <<
		",	uniform	float4 viewportSize \n"
		",	uniform float4 cameraPositionWorld	//world space \n"
		",	uniform float far  \n"	
		",  uniform half flip \n";
	}
	
	sourceStr <<
	")  \n"
	"{  \n"
	"	float4 diffuseTex = tex2D(diffuseMap, texCoord.xy);  \n"
	"	float4 color1 = diffuseTex;  \n"
	"	color1 *= vertexColour;  \n"
	"	oColor = lerp(color1, float4(fogColor,1), position.w);  \n";

	if(MRTSupported())
	{
		sourceStr <<
		"	//calculate depth at the real position \n"
		"	positionScreen /= positionScreen.w; \n"
		"	float2 depthTexCoord = float2(positionScreen) * float2(0.5f, -0.5f) + float2(0.5f, 0.5f); \n"
		"	float2 uvOffset= (viewportSize.zw)*0.5; \n"
		"	depthTexCoord += uvOffset; \n"
		"	depthTexCoord.y =(1-saturate(flip))+flip*depthTexCoord.y; \n"
        "	float depth = tex2D(depthMap, depthTexCoord).x; \n"
		"	if(useSoftParticles > 0) \n"	
		"	{ \n"	
		"	float distanceToPixel = length(positionWorld.xyz-cameraPositionWorld.xyz); \n"	
		"	float thickness = 0.5;//position_scale[3] * thicknessColour[0]; \n"
		"	float tNear = distanceToPixel - thickness; \n"
		"	float tFar = distanceToPixel + thickness; \n"
		"	depth *= far; \n"
		"	float depthAlpha = saturate(depth - distanceToPixel); \n"
		//these are debug values for the effect ,please don't remove
		//"	depthAlpha*=depthAlpha; \n"
		//"	//modify depth to get a good looking fog effect \n"
		//"	depthAlpha = log(depthAlpha) * 0.7f; \n"
		//"	oColor = float4(depth/20,depth/20,depth/20,1); \n"
		//"	oColor = float4(distanceToPixel,distanceToPixel,distanceToPixel,1); \n"
		//"	oColor = float4(depthAlpha,depthAlpha,depthAlpha,1); \n"
		"	oColor.a *=depthAlpha; \n"
		"	} \n";
	}

	sourceStr << "}  \n";

	
	ret->setSource(sourceStr.str());
	ret->load();
	
	// params
	GpuProgramParametersSharedPtr params = ret->getDefaultParameters();
	params->setNamedAutoConstant("fogColor", GpuProgramParameters::ACT_FOG_COLOUR);
	if(MRTSupported())
	{
		params->setNamedAutoConstant("far", GpuProgramParameters::ACT_FAR_CLIP_DISTANCE);
		params->setNamedAutoConstant("flip", GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING);
		//depth
		params->setNamedAutoConstant("viewportSize", GpuProgramParameters::ACT_VIEWPORT_SIZE);
		//depthAlpha
		params->setNamedAutoConstant("cameraPositionWorld", GpuProgramParameters::ACT_CAMERA_POSITION);
	}
	return ret;
}
Exemplo n.º 12
0
void SkyManager::create()
{
    /// \todo preload all the textures and meshes that are used for sky rendering

    // Create overlay used for thunderstorm
    MaterialPtr material = MaterialManager::getSingleton().create( "ThunderMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
    Pass* pass = material->getTechnique(0)->getPass(0);
    pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
    mThunderTextureUnit = pass->createTextureUnitState();
    mThunderTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(1.f, 1.f, 1.f));
    mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f);
    OverlayManager& ovm = OverlayManager::getSingleton();
    mThunderOverlay = ovm.create( "ThunderOverlay" );
    OverlayContainer* overlay_panel;
    overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", "ThunderPanel");
    overlay_panel->_setPosition(0, 0);
    overlay_panel->_setDimensions(1, 1);
    overlay_panel->setMaterialName( "ThunderMaterial" );
    overlay_panel->show();
    mThunderOverlay->add2D(overlay_panel);
    mThunderOverlay->hide();

    mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(-0.4, 0.4, 0.5), mRootNode);
    mSecunda->setType(Moon::Type_Secunda);
    mSecunda->setRenderQueue(RQG_SkiesEarly+4);

    mMasser = new Moon("textures\\tx_masser_full.dds", 0.75, Vector3(-0.4, 0.4, 0.5), mRootNode);
    mMasser->setRenderQueue(RQG_SkiesEarly+3);
    mMasser->setType(Moon::Type_Masser);

    mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode);
    mSun->setRenderQueue(RQG_SkiesEarly+4);
    mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode);
    mSunGlare->setRenderQueue(RQG_SkiesLate);
    mSunGlare->setVisibilityFlags(RV_Glare);


    HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();

    // Stars
    /// \todo sky_night_02.nif (available in Bloodmoon)
    MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
    Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
    night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1);
    night1_ent->setVisibilityFlags(RV_Sky);
    night1_ent->setCastShadows(false);

    mAtmosphereNight = mRootNode->createChildSceneNode();
    mAtmosphereNight->attachObject(night1_ent);

    // Stars vertex shader
    HighLevelGpuProgramPtr stars_vp = mgr.createProgram("Stars_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
        "cg", GPT_VERTEX_PROGRAM);
    stars_vp->setParameter("profiles", "vs_2_x arbvp1");
    stars_vp->setParameter("entry_point", "main_vp");
    StringUtil::StrStreamType outStream4;
    outStream4 <<
    "void main_vp(	\n"
    "	float4 position : POSITION,	\n"
    "   in float2 uv : TEXCOORD0, \n"
    "   out float2 oUV : TEXCOORD0, \n"
    "   out float oFade : TEXCOORD1, \n"
    "	out float4 oPosition : POSITION,	\n"
    "	uniform float4x4 worldViewProj	\n"
    ")	\n"
    "{	\n"
    "   oUV = uv; \n"
    "   oFade = (position.z > 50) ? 1.f : 0.f; \n"
    "	oPosition = mul( worldViewProj, position );  \n"
    "}";
    stars_vp->setSource(outStream4.str());
    stars_vp->load();
    stars_vp->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);

    // Stars fragment shader
    HighLevelGpuProgramPtr stars_fp = mgr.createProgram("Stars_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
        "cg", GPT_FRAGMENT_PROGRAM);
    stars_fp->setParameter("profiles", "ps_2_x arbfp1");
    stars_fp->setParameter("entry_point", "main_fp");
    StringUtil::StrStreamType outStream5;
    outStream5 <<
    "void main_fp(	\n"
    "   in float2 uv : TEXCOORD0, \n"
    "	out float4 oColor    : COLOR, \n";
    if (RenderingManager::useMRT()) outStream5 <<
        "   out float4 oColor1 : COLOR1, \n";
    outStream5 <<
    "   in float fade : TEXCOORD1, \n"
    "   uniform sampler2D texture : TEXUNIT0, \n"
    "   uniform float opacity, \n"
    "   uniform float4 diffuse, \n"
    "   uniform float4 emissive \n"
    ")	\n"
    "{	\n"
    "   oColor =  tex2D(texture, uv) * float4(emissive.xyz, 1) * float4(1,1,1,fade*diffuse.a); \n";
    if (RenderingManager::useMRT()) outStream5 <<
        "   oColor1 = float4(1, 0, 0, 1); \n";
    outStream5 <<
    "}";
    stars_fp->setSource(outStream5.str());
    stars_fp->load();
    stars_fp->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
    stars_fp->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);

    for (unsigned int i=0; i<night1_ent->getNumSubEntities(); ++i)
    {
        MaterialPtr mp = night1_ent->getSubEntity(i)->getMaterial();
        mp->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
        mp->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
        mp->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 1.0);
        mp->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
        mp->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
        mp->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
        mp->getTechnique(0)->getPass(0)->setVertexProgram(stars_vp->getName());
        mp->getTechnique(0)->getPass(0)->setFragmentProgram(stars_fp->getName());
        mp->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
        mStarsMaterials[i] = mp;
    }

    // Atmosphere (day)
    mesh = NifOgre::NIFLoader::load("meshes\\sky_atmosphere.nif");
    Entity* atmosphere_ent = mSceneMgr->createEntity("meshes\\sky_atmosphere.nif");
    atmosphere_ent->setCastShadows(false);

    ModVertexAlpha(atmosphere_ent, 0);

    atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly);
    atmosphere_ent->setVisibilityFlags(RV_Sky);
    mAtmosphereDay = mRootNode->createChildSceneNode();
    mAtmosphereDay->attachObject(atmosphere_ent);
    mAtmosphereMaterial = atmosphere_ent->getSubEntity(0)->getMaterial();
    mAtmosphereMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);

    // Atmosphere shader
    HighLevelGpuProgramPtr vshader = mgr.createProgram("Atmosphere_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
        "cg", GPT_VERTEX_PROGRAM);

    vshader->setParameter("profiles", "vs_2_x arbvp1");
    vshader->setParameter("entry_point", "main_vp");

    StringUtil::StrStreamType outStream;
    outStream <<
    "void main_vp(	\n"
    "	float4 position : POSITION,	\n"
    "	in float4 color	: COLOR,	\n"
    "	out float4 oPosition : POSITION,	\n"
    "	out float4 oVertexColor    : TEXCOORD0, \n"
    "	uniform float4x4 worldViewProj	\n"
    ")	\n"
    "{	\n"
    "	oPosition = mul( worldViewProj, position );  \n"
    "   oVertexColor = color; \n"
    "}";
    vshader->setSource(outStream.str());
    vshader->load();

    vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
    mAtmosphereMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());

    HighLevelGpuProgramPtr fshader = mgr.createProgram("Atmosphere_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
        "cg", GPT_FRAGMENT_PROGRAM);

    fshader->setParameter("profiles", "ps_2_x arbfp1");
    fshader->setParameter("entry_point", "main_fp");

    StringUtil::StrStreamType _outStream;
    _outStream <<
    "void main_fp(	\n"
    "	in float4 iVertexColor	: TEXCOORD0,	\n"
    "	out float4 oColor    : COLOR, \n";
    if (RenderingManager::useMRT()) _outStream <<
        "   out float4 oColor1 : COLOR1, \n";
    _outStream <<
    "   uniform float4 emissive \n"
    ")	\n"
    "{	\n"
    "   oColor = iVertexColor * emissive; \n";
    if (RenderingManager::useMRT()) _outStream <<
        "   oColor1 = float4(1, 0, 0, 1); \n";
    _outStream <<
    "}";
    fshader->setSource(_outStream.str());
    fshader->load();

    fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
    mAtmosphereMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());

    // Clouds
    NifOgre::NIFLoader::load("meshes\\sky_clouds_01.nif");
    Entity* clouds_ent = mSceneMgr->createEntity("meshes\\sky_clouds_01.nif");
    clouds_ent->setVisibilityFlags(RV_Sky);
    clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5);
    SceneNode* clouds_node = mRootNode->createChildSceneNode();
    clouds_node->attachObject(clouds_ent);
    mCloudMaterial = clouds_ent->getSubEntity(0)->getMaterial();
    mCloudMaterial->getTechnique(0)->getPass(0)->setPolygonModeOverrideable(false);
    clouds_ent->setCastShadows(false);

    // Clouds vertex shader
    HighLevelGpuProgramPtr vshader2 = mgr.createProgram("Clouds_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
        "cg", GPT_VERTEX_PROGRAM);
    vshader2->setParameter("profiles", "vs_2_x arbvp1");
    vshader2->setParameter("entry_point", "main_vp");
    StringUtil::StrStreamType outStream3;
    outStream3 <<
    "void main_vp(	\n"
    "	float4 position : POSITION,	\n"
    "	in float4 color	: COLOR,	\n"
    "   out float4 oColor : TEXCOORD1, \n"
    "   in float2 uv : TEXCOORD0, \n"
    "   out float2 oUV : TEXCOORD0, \n"
    "	out float4 oPosition : POSITION,	\n"
    "	uniform float4x4 worldViewProj	\n"
    ")	\n"
    "{	\n"
    "   oUV = uv; \n"
    "   oColor = color; \n"
    "	oPosition = mul( worldViewProj, position );  \n"
    "}";
    vshader2->setSource(outStream3.str());
    vshader2->load();
    vshader2->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
    mCloudMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader2->getName());

    // Clouds fragment shader
    mCloudFragmentShader = mgr.createProgram("Clouds_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
        "cg", GPT_FRAGMENT_PROGRAM);
    mCloudFragmentShader->setParameter("profiles", "ps_2_x arbfp1");
    mCloudFragmentShader->setParameter("entry_point", "main_fp");
    StringUtil::StrStreamType outStream2;
    outStream2 <<
    "void main_fp(	\n"
    "   in float2 uv : TEXCOORD0, \n"
    "   in float4 color : TEXCOORD1, \n"
    "	out float4 oColor    : COLOR, \n";
    if (RenderingManager::useMRT()) outStream2 <<
        "   out float4 oColor1 : COLOR1, \n";
    outStream2 <<
    "   uniform sampler2D texture : TEXUNIT0, \n"
    "   uniform sampler2D secondTexture : TEXUNIT1, \n"
    "   uniform float transitionFactor, \n"
    "   uniform float time, \n"
    "   uniform float speed, \n"
    "   uniform float opacity, \n"
    "   uniform float4 emissive \n"
    ")	\n"
    "{	\n"
    "   uv += float2(0,1) * time * speed * 0.003; \n" // Scroll in y direction
    "   float4 tex = lerp(tex2D(texture, uv), tex2D(secondTexture, uv), transitionFactor); \n"
    "   oColor = color * float4(emissive.xyz,1) * tex * float4(1,1,1,opacity); \n";
    if (RenderingManager::useMRT()) outStream2 <<
        "   oColor1 = float4(1, 0, 0, 1); \n";
    outStream2 <<
    "}";
    mCloudFragmentShader->setSource(outStream2.str());
    mCloudFragmentShader->load();
    mCloudFragmentShader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
    mCloudMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(mCloudFragmentShader->getName());
    setCloudsOpacity(0.75);

    ModVertexAlpha(clouds_ent, 1);

    // I'm not sure if the materials are being used by any other objects
    // Make a unique "modifiable" copy of the materials to be sure
    mCloudMaterial = mCloudMaterial->clone("Clouds");
    clouds_ent->getSubEntity(0)->setMaterial(mCloudMaterial);
    mAtmosphereMaterial = mAtmosphereMaterial->clone("Atmosphere");
    atmosphere_ent->getSubEntity(0)->setMaterial(mAtmosphereMaterial);

    mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
    mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDiffuse(0.0, 0.0, 0.0, 0.0);
    mAtmosphereMaterial->getTechnique(0)->getPass(0)->setAmbient(0.0, 0.0, 0.0);
    mCloudMaterial->getTechnique(0)->getPass(0)->setSelfIllumination(1.0, 1.0, 1.0);
    mCloudMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
    mAtmosphereMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
    mAtmosphereMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);
    mCloudMaterial->getTechnique(0)->getPass(0)->setSceneBlending(SBT_TRANSPARENT_ALPHA);

    mCloudMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
    mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("textures\\tx_sky_cloudy.dds");
    mCloudMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("");

    mCreated = true;
}
Exemplo n.º 13
0
Moon::Moon( const String& textureName,
                    const float initialSize,
                    const Vector3& position,
                    SceneNode* rootNode)
{
    init(textureName, initialSize, position, rootNode);

    HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
    HighLevelGpuProgramPtr vshader;
    if (mgr.resourceExists("Moon_VP"))
        vshader = mgr.getByName("Moon_VP");
    else
        vshader = mgr.createProgram("Moon_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_VERTEX_PROGRAM);
    vshader->setParameter("profiles", "vs_2_x arbvp1");
    vshader->setParameter("entry_point", "main_vp");
    StringUtil::StrStreamType outStream;
    outStream <<
    "void main_vp(	\n"
    "	float4 position : POSITION,	\n"
    "   in float2 uv : TEXCOORD0, \n"
    "   out float2 oUV : TEXCOORD0, \n"
    "	out float4 oPosition : POSITION,	\n"
    "	uniform float4x4 worldViewProj	\n"
    ")	\n"
    "{	\n"
    "   oUV = uv; \n"
    "	oPosition = mul( worldViewProj, position );  \n"
    "}";
    vshader->setSource(outStream.str());
    vshader->load();
    vshader->getDefaultParameters()->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
    mMaterial->getTechnique(0)->getPass(0)->setVertexProgram(vshader->getName());

    HighLevelGpuProgramPtr fshader;
    if (mgr.resourceExists("Moon_FP"))
        fshader = mgr.getByName("Moon_FP");
    else
        fshader = mgr.createProgram("Moon_FP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "cg", GPT_FRAGMENT_PROGRAM);

    fshader->setParameter("profiles", "ps_2_x arbfp1");
    fshader->setParameter("entry_point", "main_fp");
    StringUtil::StrStreamType outStream2;
    outStream2 <<
    "void main_fp(	\n"
    "   in float2 uv : TEXCOORD0, \n"
    "	out float4 oColor    : COLOR, \n";
    if (RenderingManager::useMRT()) outStream2 <<
        "   out float4 oColor1 : COLOR1, \n";
    outStream2 <<
    "   uniform sampler2D texture : TEXUNIT0, \n"
    "   uniform float4 skyColour, \n"
    "   uniform float4 diffuse, \n"
    "   uniform float4 emissive \n"
    ")	\n"
    "{	\n"
    "   float4 tex = tex2D(texture, uv); \n"
    "   oColor = float4(emissive.xyz,1) * tex; \n";
    if (RenderingManager::useMRT()) outStream2 <<
        "   oColor1 = float4(1, 0, 0, 1); \n";
    outStream2 <<
    // use a circle for the alpha (compute UV distance to center)
    // looks a bit bad because its not filtered on the edges,
    // but it's cheaper than a seperate alpha texture.
    "   float sqrUVdist = pow(uv.x-0.5,2) + pow(uv.y-0.5, 2); \n"
    "   oColor.a = diffuse.a * (sqrUVdist >= 0.24 ? 0 : 1); \n"
    "   oColor.rgb += (1-tex.a) * oColor.a * skyColour.rgb; \n"//fill dark side of moon with skycolour
    "   oColor.rgb += (1-diffuse.a) * skyColour.rgb; \n"//fade bump
    "}";
    fshader->setSource(outStream2.str());
    fshader->load();
    fshader->getDefaultParameters()->setNamedAutoConstant("diffuse", GpuProgramParameters::ACT_SURFACE_DIFFUSE_COLOUR);
    fshader->getDefaultParameters()->setNamedAutoConstant("emissive", GpuProgramParameters::ACT_SURFACE_EMISSIVE_COLOUR);
    mMaterial->getTechnique(0)->getPass(0)->setFragmentProgram(fshader->getName());

    setVisibility(1.0);

    mPhase = Moon::Phase_Full;
}
	//---------------------------------------------------------------------
	FixedFuncPrograms * FixedFuncEmuShaderManager::_createShaderPrograms( const String & generatorName, 
		const VertexBufferDeclaration & vertexBufferDeclaration, FixedFuncState & fixedFuncState )
	{

		const String vertexProgramName = "VS";
		const String fragmentProgramName = "FP";

		FixedFuncEmuShaderGenerator * fixedFuncEmuShaderGenerator = mFixedFuncEmuShaderGeneratorMap[generatorName];
		String shaderSource = fixedFuncEmuShaderGenerator->getShaderSource(
			vertexProgramName,
			fragmentProgramName,
			vertexBufferDeclaration,
			fixedFuncState
			);

		// Vertex program details
		GpuProgramUsage * vertexProgramUsage = new GpuProgramUsage(GPT_VERTEX_PROGRAM);
		// Fragment program details
		GpuProgramUsage * fragmentProgramUsage = new GpuProgramUsage(GPT_FRAGMENT_PROGRAM);


		HighLevelGpuProgramPtr vs;
		HighLevelGpuProgramPtr fs;

		class LoadFromSourceGpuProgram : public HighLevelGpuProgram
		{
		public:
			void doLoadFromSource(void)
			{
				loadFromSource();
			};
		};

		static size_t shaderCount = 0;
		shaderCount++;
		vs = HighLevelGpuProgramManager::getSingleton().
			createProgram("VS_" + StringConverter::toString(shaderCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
			fixedFuncEmuShaderGenerator->getLanguageName(), GPT_VERTEX_PROGRAM);	
		vs->setSource(shaderSource);
		vs->setParameter("entry_point",vertexProgramName);
		vs->setParameter("target",fixedFuncEmuShaderGenerator->getVpTarget());
		static_cast<LoadFromSourceGpuProgram *>(vs.get())->doLoadFromSource();

		vertexProgramUsage->setProgram(GpuProgramPtr(vs));
		vertexProgramUsage->setParameters(vs->createParameters());

		fs = HighLevelGpuProgramManager::getSingleton().
			createProgram("FS_" + StringConverter::toString(shaderCount), ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
			fixedFuncEmuShaderGenerator->getLanguageName(), GPT_FRAGMENT_PROGRAM);	
		fs->setSource(shaderSource);
		fs->setParameter("entry_point",fragmentProgramName);
		fs->setParameter("target",fixedFuncEmuShaderGenerator->getFpTarget());
		static_cast<LoadFromSourceGpuProgram *>(fs.get())->doLoadFromSource();

		fragmentProgramUsage->setProgram(GpuProgramPtr(fs));
		fragmentProgramUsage->setParameters(fs->createParameters());

		FixedFuncPrograms * newPrograms = fixedFuncEmuShaderGenerator->createFixedFuncPrograms();
		mLanguage2State2Declaration2ProgramsMap[generatorName][fixedFuncState][vertexBufferDeclaration] = newPrograms;
		newPrograms->setVertexProgramUsage(vertexProgramUsage);
		newPrograms->setFragmentProgramUsage(fragmentProgramUsage);
		newPrograms->setFixedFuncState(fixedFuncState);

		mProgramsToDeleteAtTheEnd.push_back(newPrograms);
		return newPrograms;
	}
//-----------------------------------------------------------------------------
GpuProgramPtr ProgramManager::createGpuProgram(Program* shaderProgram, 
											   ProgramWriter* programWriter,
											   const String& language,
											   const String& profiles,
											   const StringVector& profilesList,
											   const String& cachePath)
{

	
#if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID
	Ogre::StringSerialiser sourceCodeStringStream;
#else
	std::stringstream sourceCodeStringStream;
#endif
	_StringHash stringHash;
	uint32 programHashCode;
	String programName;

	// Generate source code.
	programWriter->writeSourceCode(sourceCodeStringStream, shaderProgram);

	// Generate program hash code.
	programHashCode = static_cast<uint32>(stringHash(sourceCodeStringStream.str()));

	// Generate program name.
	programName = StringConverter::toString(programHashCode);
	
	if (shaderProgram->getType() == GPT_VERTEX_PROGRAM)
	{
		programName += "_VS";
	}
	else if (shaderProgram->getType() == GPT_FRAGMENT_PROGRAM)
	{
		programName += "_FS";
	}

	HighLevelGpuProgramPtr pGpuProgram;

	// Try to get program by name.
	pGpuProgram = HighLevelGpuProgramManager::getSingleton().getByName(programName);

	// Case the program doesn't exist yet.
	if (pGpuProgram.isNull())
	{
		// Create new GPU program.
		pGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName,
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, language, shaderProgram->getType());

		// Case cache directory specified -> create program from file.
		if (cachePath.empty() == false)
		{
			const String  programFullName = programName + "." + language;
			const String  programFileName = cachePath + programFullName;	
			std::ifstream programFile;
			bool		  writeFile = true;


			// Check if program file already exist.
			programFile.open(programFileName.c_str());

			// Case no matching file found -> we have to write it.
			if (!programFile)
			{			
				writeFile = true;
			}
			else
			{
				writeFile = false;
				programFile.close();
			}

			// Case we have to write the program to a file.
			if (writeFile)
			{
				std::ofstream outFile(programFileName.c_str());

				if (!outFile)
					return GpuProgramPtr();

				outFile << sourceCodeStringStream.str();
				outFile.close();
			}

			pGpuProgram->setSourceFile(programFullName);
		}

		// No cache directory specified -> create program from system memory.
		else
		{
			pGpuProgram->setSource(sourceCodeStringStream.str());
		}
		
		
		pGpuProgram->setParameter("entry_point", shaderProgram->getEntryPointFunction()->getName());

		// HLSL program requires specific target profile settings - we have to split the profile string.
		if (language == "hlsl")
		{
			StringVector::const_iterator it = profilesList.begin();
			StringVector::const_iterator itEnd = profilesList.end();
			
			for (; it != itEnd; ++it)
			{
				if (GpuProgramManager::getSingleton().isSyntaxSupported(*it))
				{
					pGpuProgram->setParameter("target", *it);
					break;
				}
			}
		}
		
		pGpuProgram->setParameter("profiles", profiles);
		pGpuProgram->load();
	
		// Case an error occurred.
		if (pGpuProgram->hasCompileError())
		{
			pGpuProgram.setNull();
			return GpuProgramPtr(pGpuProgram);
		}

		// Add the created GPU program to local cache.
		if (pGpuProgram->getType() == GPT_VERTEX_PROGRAM)
		{
			mVertexShaderMap[programName] = pGpuProgram;			
		}
		else if (pGpuProgram->getType() == GPT_FRAGMENT_PROGRAM)
		{
			mFragmentShaderMap[programName] = pGpuProgram;	
		}				
	}
	
	return GpuProgramPtr(pGpuProgram);
}
Exemplo n.º 16
0
	//-----------------------------------------------------------------------------------
	Ogre::GpuProgramPtr ShaderManager::getGpuProgram(HlmsDatablock* dataBlock)
	{
		Ogre::uint32 hash = dataBlock->getHash();

		std::map<Ogre::uint32, Ogre::GpuProgramPtr>::iterator it = mShaderCache.find(hash);
		if (it != mShaderCache.end())
		{
			return (*it).second;
		}
		else
		{
			Ogre::String typeStr = FilePatterns[dataBlock->getShaderType()];

			std::stringstream sstream;
			sstream << std::hex << hash;
			std::string hashString = sstream.str();

			Ogre::String name = hashString + typeStr;

			// generate the shader code
			Ogre::String code = dataBlock->getTemplate()->getTemplate();
			code = ShaderGenerator::parse(code, *(dataBlock->getPropertyMap()), mShaderPiecesManager->getPieces(dataBlock->getLanguarge(), dataBlock->getShaderType()));

			HighLevelGpuProgramPtr gpuProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram(name,
				Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, dataBlock->getLanguarge(), dataBlock->getShaderType());

			gpuProgram->setSource(code);
			gpuProgram->setParameter("entry_point", "main");

			if (dataBlock->getLanguarge() == "hlsl")
			{
				// HLSL program requires specific target profile settings - we have to split the profile string.
				const Ogre::StringVector& profilesList = dataBlock->getProfileList();
				Ogre::StringVector::const_iterator it = profilesList.begin();
				Ogre::StringVector::const_iterator itEnd = profilesList.end();

				for (; it != itEnd; ++it)
				{
					if (Ogre::GpuProgramManager::getSingleton().isSyntaxSupported(*it))
					{
						gpuProgram->setParameter("target", *it);
						break;
					}
				}

				//gpuProgram->setParameter("enable_backwards_compatibility", "false");
				//gpuProgram->setParameter("column_major_matrices", Ogre::StringConverter::toString(shaderProgram->getUseColumnMajorMatrices()));
			}

			//gpuProgram->setParameter("profiles", profiles);
			gpuProgram->load();

			// Case an error occurred.
			if (gpuProgram->hasCompileError())
			{
				gpuProgram.setNull();
				return Ogre::GpuProgramPtr(gpuProgram);
			}

			mShaderCache[hash] = gpuProgram;

			return gpuProgram;
		}

	}
    //---------------------------------------------------------------------
    //---------------------------------------------------------------------
    void ShadowVolumeExtrudeProgram::initialise(void)
    {
		if (!mInitialised)
		{
			String syntax;
			bool vertexProgramFinite[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = 
			{
				false, false, false, false, 
					true, true, true, true
			};
			bool vertexProgramDebug[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = 
			{
				false, true, false, true, 
					false, true, false, true
			};
			Light::LightTypes vertexProgramLightTypes[OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS] = 
			{
				Light::LT_POINT, Light::LT_POINT, 
					Light::LT_DIRECTIONAL, Light::LT_DIRECTIONAL, 
					Light::LT_POINT, Light::LT_POINT, 
					Light::LT_DIRECTIONAL, Light::LT_DIRECTIONAL 
			};

			// load hardware extrusion programs for point & dir lights
			if (GpuProgramManager::getSingleton().isSyntaxSupported("arbvp1"))
			{
				// ARBvp1
				syntax = "arbvp1";
			}
			else if (GpuProgramManager::getSingleton().isSyntaxSupported("vs_1_1"))
			{
				syntax = "vs_1_1";
			}
			else if (GpuProgramManager::getSingleton().isSyntaxSupported("vs_4_0"))
			{
				syntax = "vs_4_0";
			}
			else
			{
				OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
					"Vertex programs are supposedly supported, but neither "
					"arbvp1, vs_1_1 nor vs_4_0 syntaxes are present.", 
					"SceneManager::initShadowVolumeMaterials");
			}
			// Create all programs
			for (unsigned short v = 0; v < OGRE_NUM_SHADOW_EXTRUDER_PROGRAMS; ++v)
			{
				// Create debug extruders
				if (GpuProgramManager::getSingleton().getByName(
					programNames[v]).isNull())
				{
					if (syntax == "vs_4_0")
					{
						HighLevelGpuProgramPtr vp = 
							HighLevelGpuProgramManager::getSingleton().createProgram(
							programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME,
							"hlsl", GPT_VERTEX_PROGRAM);
						vp->setSource(ShadowVolumeExtrudeProgram::getProgramSource(
							vertexProgramLightTypes[v], syntax, 
							vertexProgramFinite[v], vertexProgramDebug[v]));
						vp->setParameter("target", syntax);
						vp->setParameter("entry_point", "vs_main");			
						vp->load();

						if (frgProgramName.empty())
						{
							frgProgramName = "Ogre/ShadowFrgProgram";
							HighLevelGpuProgramPtr fp = 
								HighLevelGpuProgramManager::getSingleton().createProgram(
								frgProgramName, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME,
								"hlsl", GPT_FRAGMENT_PROGRAM);
							fp->setSource(mGeneralFs_4_0);
							fp->setParameter("target", "ps_4_0");
							fp->setParameter("entry_point", "fs_main");			
							fp->load();
						}
					}
					else
					{
						GpuProgramPtr vp = 
							GpuProgramManager::getSingleton().createProgramFromString(
							programNames[v], ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME,
							ShadowVolumeExtrudeProgram::getProgramSource(
							vertexProgramLightTypes[v], syntax, 
							vertexProgramFinite[v], vertexProgramDebug[v]),
							GPT_VERTEX_PROGRAM, syntax);
						vp->load();
					}

				}
			}
			mInitialised = true;
		}
    }
	//---------------------------------------------------------------------
	void TerrainMaterialGeneratorA::SM2Profile::addTechnique(
		const MaterialPtr& mat, const Terrain* terrain, TechniqueType tt)
	{
		Technique* tech = mat->createTechnique();

		// Only supporting one pass
		Pass* pass = tech->createPass();

		GpuProgramManager& gmgr = GpuProgramManager::getSingleton();
		HighLevelGpuProgramManager& hmgr = HighLevelGpuProgramManager::getSingleton();
		if (!mShaderGen)
		{
			bool check2x = mLayerNormalMappingEnabled || mLayerParallaxMappingEnabled;
			if (hmgr.isLanguageSupported("cg"))
            {
				mShaderGen = OGRE_NEW ShaderHelperCg();
            }
			else if (hmgr.isLanguageSupported("hlsl") &&
				((check2x && gmgr.isSyntaxSupported("ps_4_0")) ||
				(check2x && gmgr.isSyntaxSupported("ps_2_x")) ||
				(!check2x && gmgr.isSyntaxSupported("ps_2_0"))))
            {
				mShaderGen = OGRE_NEW ShaderHelperHLSL();
            }
			else if (hmgr.isLanguageSupported("glsl"))
            {
				mShaderGen = OGRE_NEW ShaderHelperGLSL();
            }
			else if (hmgr.isLanguageSupported("glsles"))
            {
				mShaderGen = OGRE_NEW ShaderHelperGLSLES();
            }
			
			// check SM3 features
			mSM3Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_3_0");
			mSM4Available = GpuProgramManager::getSingleton().isSyntaxSupported("ps_4_0");
		}

		HighLevelGpuProgramPtr vprog = mShaderGen->generateVertexProgram(this, terrain, tt);
		HighLevelGpuProgramPtr fprog = mShaderGen->generateFragmentProgram(this, terrain, tt);

		pass->setVertexProgram(vprog->getName());
		pass->setFragmentProgram(fprog->getName());

		if (tt == HIGH_LOD || tt == RENDER_COMPOSITE_MAP)
		{
			// global normal map
			TextureUnitState* tu = pass->createTextureUnitState();
			tu->setTextureName(terrain->getTerrainNormalMap()->getName());
			tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);

			// global colour map
			if (terrain->getGlobalColourMapEnabled() && isGlobalColourMapEnabled())
			{
				tu = pass->createTextureUnitState(terrain->getGlobalColourMap()->getName());
				tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
			}

			// light map
			if (isLightmapEnabled())
			{
				tu = pass->createTextureUnitState(terrain->getLightmap()->getName());
				tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
			}

			// blend maps
			uint maxLayers = getMaxLayers(terrain);
			uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount());
			uint numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount()));
			for (uint i = 0; i < numBlendTextures; ++i)
			{
				tu = pass->createTextureUnitState(terrain->getBlendTextureName(i));
				tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
			}

			// layer textures
			for (uint i = 0; i < numLayers; ++i)
			{
				// diffuse / specular
				pass->createTextureUnitState(terrain->getLayerTextureName(i, 0));
				// normal / height
				pass->createTextureUnitState(terrain->getLayerTextureName(i, 1));
			}

		}
		else
		{
			// LOW_LOD textures
			// composite map
			TextureUnitState* tu = pass->createTextureUnitState();
			tu->setTextureName(terrain->getCompositeMap()->getName());
			tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);

			// That's it!

		}

		// Add shadow textures (always at the end)
		if (isShadowingEnabled(tt, terrain))
		{
			uint numTextures = 1;
			if (getReceiveDynamicShadowsPSSM())
			{
				numTextures = (uint)getReceiveDynamicShadowsPSSM()->getSplitCount();
			}
			for (uint i = 0; i < numTextures; ++i)
			{
				TextureUnitState* tu = pass->createTextureUnitState();
				tu->setContentType(TextureUnitState::CONTENT_SHADOW);
				tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
				tu->setTextureBorderColour(ColourValue::White);
			}
		}

	}
Exemplo n.º 19
0
void GrassLayer::_updateShaders()
{
	if (shaderNeedsUpdate){
		shaderNeedsUpdate = false;

		//Proceed only if there is no custom vertex shader and the user's computer supports vertex shaders
		const RenderSystemCapabilities *caps = Root::getSingleton().getRenderSystem()->getCapabilities();
		if (caps->hasCapability(RSC_VERTEX_PROGRAM) && geom->getShadersEnabled())
		{
			//Calculate fade range
			float farViewDist = geom->getDetailLevels().front()->getFarRange();
			float fadeRange = farViewDist / 1.2247449f;
			//Note: 1.2247449 ~= sqrt(1.5), which is necessary since the far view distance is measured from the centers
			//of pages, while the vertex shader needs to fade grass completely out (including the closest corner)
			//before the page center is out of range.

			//Generate a string ID that identifies the current set of vertex shader options
			StringUtil::StrStreamType tmpName;
			tmpName << "GrassVS_";
			if (animate)
				tmpName << "anim_";
			if (blend)
				tmpName << "blend_";
			if (lighting)
				tmpName << "lighting_";
			tmpName << renderTechnique << "_";
			tmpName << fadeTechnique << "_";
			if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW)
				tmpName << maxHeight << "_";
			tmpName << farViewDist << "_";
			tmpName << "vp";
			const String vsName = tmpName.str();

			//Generate a string ID that identifies the material combined with the vertex shader
			const String matName = material->getName() + "_" + vsName;

			//Check if the desired material already exists (if not, create it)
			MaterialPtr tmpMat = MaterialManager::getSingleton().getByName(matName);
			if (tmpMat.isNull())
			{
				//Clone the original material
				tmpMat = material->clone(matName);

				//Disable lighting
				tmpMat->setLightingEnabled(false);
				//tmpMat->setReceiveShadows(false);

				//Check if the desired shader already exists (if not, compile it)
				String shaderLanguage;
				HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().getByName(vsName);
				if (vertexShader.isNull())
				{
					if (Root::getSingleton().getRenderSystem()->getName() == "Direct3D9 Rendering Subsystem")
						shaderLanguage = "hlsl";
					else if(Root::getSingleton().getRenderSystem()->getName() == "OpenGL Rendering Subsystem")
						shaderLanguage = "glsl";
					else
						shaderLanguage = "cg";

					//Generate the grass shader
					String vertexProgSource;

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

						vertexProgSource =
							"void main( \n"
							"	float4 iPosition : POSITION, \n"
							"	float4 iColor : COLOR, \n"
							"	float2 iUV       : TEXCOORD0,	\n"
							"	out float4 oPosition : POSITION, \n"
							"	out float4 oColor : COLOR, \n"
							"	out float2 oUV       : TEXCOORD0,	\n";

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

						if (animate) vertexProgSource +=
							"	uniform float time,	\n"
							"	uniform float frequency,	\n"
							"	uniform float4 direction,	\n";

						if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) vertexProgSource +=
							"	uniform float grassHeight,	\n";

						if (renderTechnique == GRASSTECH_SPRITE || lighting) vertexProgSource +=
							"   float4 iNormal : NORMAL, \n";

						vertexProgSource +=
							"	uniform float4x4 worldViewProj,	\n"
							"	uniform float3 camPos, \n"
							"	uniform float fadeRange ) \n"
							"{	\n"
							"	oColor.rgb = iColor.rgb;   \n"
							"	float4 position = iPosition;	\n"
							"	float dist = distance(camPos.xz, position.xz);	\n";

						if (lighting)
						{
							vertexProgSource +=
							"   float3 light = normalize(objSpaceLight.xyz - (iPosition.xyz * objSpaceLight.w)); \n"
							"   float diffuseFactor = max(dot(float4(0,1,0,0), light), 0); \n"
							"   oColor = (lightAmbient + diffuseFactor * lightDiffuse) * iColor; \n";
						}
						else
						{
							vertexProgSource +=
							"   oColor.rgb = iColor.rgb;               \n";
						}

						if (fadeTechnique == FADETECH_ALPHA || fadeTechnique == FADETECH_ALPHAGROW) vertexProgSource +=
							//Fade out in the distance
							"	oColor.a = 2.0f - (2.0f * dist / fadeRange);   \n";
						else vertexProgSource +=
							"	oColor.a = 1.0f;   \n";

						vertexProgSource +=
							"	float oldposx = position.x;	\n";

						if (renderTechnique == GRASSTECH_SPRITE) vertexProgSource +=
							//Face the camera
							"	float3 dirVec = (float3)position - (float3)camPos;		\n"
							"	float3 p = normalize(cross(float4(0,1,0,0), dirVec));	\n"
							"	position += float4(p.x * iNormal.x, iNormal.y, p.z * iNormal.x, 0);	\n";

						if (animate) vertexProgSource +=
							"	if (iUV.y == 0.0f){	\n"
							//Wave grass in breeze
							"		float offset = sin(time + oldposx * frequency);	\n"
							"		position += direction * offset;	\n"
							"	}	\n";

						if (blend && animate) vertexProgSource +=
							"	else {	\n";
						else if (blend) vertexProgSource +=
							"	if (iUV.y != 0.0f){	\n";

						if (blend) vertexProgSource +=
							//Blend the base of nearby grass into the terrain
							"		oColor.a = clamp(oColor.a, 0, 1) * 4.0f * ((dist / fadeRange) - 0.1f);	\n"
							"	}	\n";

						if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW) vertexProgSource +=
							"	float offset = (2.0f * dist / fadeRange) - 1.0f; \n"
							"	position.y -= grassHeight * clamp(offset, 0, 1); ";

						vertexProgSource +=
							"	oPosition = mul(worldViewProj, position);  \n";

						vertexProgSource +=
							"	oUV = iUV;\n"
							"}";
					}
					else
					{
						//Must be glsl
						if (lighting)
						{
							vertexProgSource =
							"uniform vec4 objSpaceLight; \n"
							"uniform vec4 lightDiffuse; \n"
							"uniform vec4 lightAmbient; \n";
						}

						if (animate)
						{
							vertexProgSource +=
							"uniform float time; \n"
							"uniform float frequency; \n"
							"uniform vec4 direction; \n";
						}

						if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW)
						{
							vertexProgSource +=
							"uniform float grassHeight;	\n";
						}

						vertexProgSource +=
							"uniform vec3 camPos; \n"
							"uniform float fadeRange; \n"
							"\n"
							"void main()"
							"{ \n"
							"    vec4 color = gl_Color; \n"
							"    vec4 position = gl_Vertex;	\n"
							"    float dist = distance(camPos.xz, position.xz);	\n";

						if (lighting)
						{
							vertexProgSource +=
							"    vec3 light = normalize(objSpaceLight.xyz - (gl_Vertex.xyz * objSpaceLight.w)); \n"
							"    float diffuseFactor = max( dot( vec3(0.0,1.0,0.0), light), 0.0); \n"
							"    color = (lightAmbient + diffuseFactor * lightDiffuse) * gl_Color; \n";
						}
						else
						{
							vertexProgSource +=
							"    color.xyz = gl_Color.xyz; \n";
						}

						if (fadeTechnique == FADETECH_ALPHA || fadeTechnique == FADETECH_ALPHAGROW)
						{
							vertexProgSource +=
							//Fade out in the distance
							"    color.w = 2.0 - (2.0 * dist / fadeRange); \n";
						}
						else
						{
							vertexProgSource +=
							"    color.w = 1.0; \n";
						}

						if (renderTechnique == GRASSTECH_SPRITE)
						{
							vertexProgSource +=
							//Face the camera
							"    vec3 dirVec = position.xyz - camPos.xyz; \n"
							"    vec3 p = normalize(cross(vec3(0.0,1.0,0.0), dirVec)); \n"
							"    position += vec4(p.x * gl_Normal.x, gl_Normal.y, p.z * gl_Normal.x, 0.0); \n";
						}

						if (animate)
						{
							vertexProgSource +=
							"    if (gl_MultiTexCoord0.y == 0.0) \n"
							"    { \n"
							//Wave grass in breeze
							"        position += direction * sin(time + gl_Vertex.x * frequency); \n"
							"    } \n";
						}

						if (blend && animate)
						{
							vertexProgSource +=
							"    else \n"
							"    { \n";
						}
						else if (blend)
						{
							vertexProgSource +=
							"    if (gl_MultiTexCoord0.y != 0.0) \n"
							"    { \n";
						}

						if (blend)
						{
							vertexProgSource +=
							//Blend the base of nearby grass into the terrain
							"        color.w = clamp(color.w, 0.0, 1.0) * 4.0 * ((dist / fadeRange) - 0.1); \n"
							"    } \n";
						}

						if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW)
						{
							vertexProgSource +=
							"    position.y -= grassHeight * clamp((2.0 * dist / fadeRange) - 1.0, 0.0, 1.0); \n";
						}

						vertexProgSource +=
						"    gl_Position = gl_ModelViewProjectionMatrix * position; \n"
						"    gl_FrontColor = color; \n"
						"    gl_TexCoord[0] = gl_MultiTexCoord0; \n"
						"    gl_FogFragCoord = gl_Position.z; \n"
						"}";
					}

					vertexShader = HighLevelGpuProgramManager::getSingleton().createProgram(
						vsName,
						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 the vertex shader (vertexShader) has either been found or just generated
				//(depending on whether or not it was already generated).

				//Apply the shader to the material
				Pass *pass = tmpMat->getTechnique(0)->getPass(0);
				pass->setVertexProgram(vsName);
				GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();

				if(shaderLanguage.compare("glsl"))
					//glsl can use the built in gl_ModelViewProjectionMatrix
					params->setNamedAutoConstant("worldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
				params->setNamedAutoConstant("camPos", GpuProgramParameters::ACT_CAMERA_POSITION_OBJECT_SPACE);
				params->setNamedAutoConstant("fadeRange", GpuProgramParameters::ACT_CUSTOM, 1);

				if (animate){
					params->setNamedAutoConstant("time", GpuProgramParameters::ACT_CUSTOM, 1);
					params->setNamedAutoConstant("frequency", GpuProgramParameters::ACT_CUSTOM, 1);
					params->setNamedAutoConstant("direction", GpuProgramParameters::ACT_CUSTOM, 4);
				}

				if (lighting){
					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);
				}

				if (fadeTechnique == FADETECH_GROW || fadeTechnique == FADETECH_ALPHAGROW){
					params->setNamedAutoConstant("grassHeight", GpuProgramParameters::ACT_CUSTOM, 1);
					params->setNamedConstant("grassHeight", maxHeight * 1.05f);
				}

				pass->getVertexProgramParameters()->setNamedConstant("fadeRange", fadeRange);
			}
			//Now the material (tmpMat) has either been found or just created (depending on whether or not it was already
			//created). The appropriate vertex shader should be applied and the material is ready for use.

			//Apply the new material
			material = tmpMat;
		}
	}
}
Exemplo n.º 20
0
void ImpostorMaterialGenerator::generate()
{
	//!
	// note that we only create the shaders (Sprite_vp, Sprite_fp) here. 
	// the rest (material creation, shader parameters, ...) is done by paged-geom for convenience.
	
	HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
	
	// ---------------- VERTEX -----------------------------------------------
	
	// ensure shader does not exist already.
	HighLevelGpuProgramPtr vshader = mgr.getByName("Sprite_vp");
	if (vshader.isNull())
	{
		vshader = mgr.createProgram("Sprite_vp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
			"cg", GPT_VERTEX_PROGRAM);

		if(MRTSupported())
		{
			vshader->setParameter("profiles", "vs_4_0 vs_3_0 vp40");
		}
		else
		{
			vshader->setParameter("profiles", "vs_4_0 vs_2_x arbvp1");
		}
		vshader->setParameter("entry_point", "Sprite_vp");
		
		StringUtil::StrStreamType outStream;
		
		outStream <<
		"void Sprite_vp(	\n"
		"	float4 position : POSITION,	\n"
		"	float3 normal   : NORMAL,	\n"
		"	float4 color	: COLOR,	\n"
		"	float2 uv       : TEXCOORD0,	\n"
		"	out float4 oPosition : POSITION,	\n"
		"	out float2 oUv       : TEXCOORD0,	\n"
		"	out float4 oColor    : COLOR, \n"
		"	out float oFog       : TEXCOORD1,	\n"
		"	uniform float4 fogParams, \n"
		"	uniform float4x4 worldViewProj,	\n"
		"	uniform float    uScroll, \n"
		"	uniform float    vScroll, \n"
		"	uniform float4   preRotatedQuad[4] )	\n"
		"{	\n"
		//Face the camera
		"	float4 vCenter = float4( position.x, position.y, position.z, 1.0f );	\n"
		"	float4 vScale = float4( normal.x, normal.y, normal.x, 1.0f );	\n"
		"	oPosition = mul( worldViewProj, vCenter + (preRotatedQuad[normal.z] * vScale) );  \n"

		//Color
		"	oColor = color;   \n"

		//UV Scroll
		"	oUv = uv;	\n"
		"	oUv.x += uScroll; \n"
		"	oUv.y += vScroll; \n"

		//Fog
		"	oFog = saturate(fogParams.x * (oPosition.z - fogParams.y) * fogParams.w); \n"
		"}";
		
		vshader->setSource(outStream.str());
		vshader->load();
		
		vshader->getDefaultParameters()->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
	}
	
	
	// ------------- FRAGMENT -----------------------------------------------
	
	// ensure shader does not exist already.
	HighLevelGpuProgramPtr fshader = mgr.getByName("Sprite_fp");
	if (fshader.isNull())
	{
		fshader = mgr.createProgram("Sprite_fp", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, 
			"cg", GPT_FRAGMENT_PROGRAM);
			
		if(MRTSupported())
		{
			fshader->setParameter("profiles", "ps_4_0 ps_3_0 fp40");
		}
		else
		{
			fshader->setParameter("profiles", "ps_4_0 ps_2_x arbfp1");	
		}
		fshader->setParameter("entry_point", "Sprite_fp");
		
		// simple pixel shader that only reads texture and fog
		StringUtil::StrStreamType outStream;
		outStream <<
		"void Sprite_fp( 	\n"
		"	uniform sampler2D texture, \n"
		"	float4 iPosition : POSITION,	\n"
		"	float2 texCoord : TEXCOORD0, \n"
		"	float4 iColor : COLOR,	\n"
		"	float fog : TEXCOORD1, \n"
		"	uniform float4 fogColor, \n"
		"	out float4 oColor : COLOR \n"
		") \n"
		"{ \n"
		"	float4 texColor = tex2D(texture, texCoord); \n"
		"	oColor = float4(lerp(texColor.xyz, fogColor.xyz, fog), texColor.a); \n"
		"	clip( oColor.a > 0.0f ? 1:-1); \n"
		"} \n";
		
		fshader->setSource(outStream.str());
		fshader->load();
		
		fshader->getDefaultParameters()->setNamedAutoConstant("fogColor", GpuProgramParameters::ACT_FOG_COLOUR);
	}
}