Exemplo n.º 1
0
HighLevelGpuProgramPtr WaterMaterialGenerator::createFragmentProgram()
{
	HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
	std::string progName = mDef->getName() + "_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);

	if(MRTSupported())
		ret->setParameter("profiles", "ps_4_0 ps_3_0 fp40");
	else
		ret->setParameter("profiles", "ps_4_0 ps_3_0 fp40 arbfp1");	

	ret->setParameter("entry_point", "main_fp");

	StringUtil::StrStreamType outStream;
	generateFragmentProgramSource(outStream);
	ret->setSource(outStream.str());
	ret->load();

	GpuProgramParametersSharedPtr params = ret->getDefaultParameters();
	fragmentProgramParams(ret);
	
	return ret;
}
Exemplo n.º 2
0
HighLevelGpuProgramPtr WaterMaterialGenerator::createVertexProgram()
{
	HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
	std::string progName = mDef->getName() + "_VP";

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

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

	if(MRTSupported())
	{
		ret->setParameter("profiles", "vs_4_0 vs_3_0 vp40");
	}
	else
	{
		ret->setParameter("profiles", "vs_4_0 vs_2_x vp40 arbvp1");
	}
	ret->setParameter("entry_point", "main_vp");

	StringUtil::StrStreamType outStream;
	generateVertexProgramSource(outStream);
	ret->setSource(outStream.str());
	ret->load();

	vertexProgramParams(ret);
	
	return ret;
}
Exemplo n.º 3
0
HighLevelGpuProgramPtr ParticleMaterialGenerator::createSoftParticleVertexProgram()
{
	HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
	std::string progName = mDef->getName() + "_ambient_VP";

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

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

	ret->setParameter("profiles", "vs_4_0 vs_1_1 arbvp1");
	ret->setParameter("entry_point", "main_vp");

	StringUtil::StrStreamType sourceStr;
	
	sourceStr <<
	"void main_vp( 	float4 position 					: POSITION, \n"
	"	float4 color 						: COLOR,  \n"
	"	float2 texCoord 					: TEXCOORD0,  \n"
	"	out float4 oPosition			 	: POSITION,  \n"
	"	out float4 objectPos				: COLOR,  \n"
	"	out float4 oTexCoord				: TEXCOORD0,  \n"
	"	out float4 oVertexColour				: TEXCOORD1,  \n"
	"	out float4 oScreenPosition				: TEXCOORD2,  \n"
	"	out float4 oWorldPosition				: TEXCOORD3,  \n"
	"	uniform float enableFog,  \n"
	"	uniform float4 fogParams,  \n"
	"	uniform float4x4 wvpMat,  \n"
	"	uniform float4x4 wMat  \n"
	")  \n"
	"{  \n"
	"	oVertexColour = color;  \n"
	"	oPosition = mul(wvpMat, position);  \n"
	"	oWorldPosition = mul(wMat, position);  \n"
	"	oScreenPosition = oPosition; \n"
	"	oTexCoord = float4(texCoord.x, texCoord.y, 1, 1);  \n"
	"	objectPos = position;  \n"
	"	objectPos.w = enableFog * saturate(fogParams.x * (oPosition.z - fogParams.y) * fogParams.w);  \n"
	"} \n";
	
	ret->setSource(sourceStr.str());
	ret->load();
	
	// params
	GpuProgramParametersSharedPtr params = ret->getDefaultParameters();
	params->setIgnoreMissingParams(true);
	params->setNamedAutoConstant("wvpMat", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
	params->setNamedAutoConstant("wMat", GpuProgramParameters::ACT_WORLD_MATRIX);
	params->setNamedAutoConstant("fogParams", GpuProgramParameters::ACT_FOG_PARAMS);
	params->setNamedConstant("enableFog", mDef->mProps->fog ? Real(1.0) : Real(0.0));
	
	return ret;
}
Exemplo n.º 4
0
    //-----------------------------------------------------------------------
    void CgProgram::createLowLevelImpl(void)
    {
		// ignore any previous error
		if (mSelectedCgProfile != CG_PROFILE_UNKNOWN && !mCompileError)
		{

			if ( false
// the hlsl 4 profiles are only supported in OGRE from CG 2.2
#if(CG_VERSION_NUM >= 2200)
				|| mSelectedCgProfile == CG_PROFILE_VS_4_0
				 || mSelectedCgProfile == CG_PROFILE_PS_4_0
#endif
				 )
			{
				// Create a high-level program, give it the same name as us
				HighLevelGpuProgramPtr vp = 
					HighLevelGpuProgramManager::getSingleton().createProgram(
					mName, mGroup, "hlsl", mType);
				String hlslSourceFromCg = cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM);
				
				vp->setSource(hlslSourceFromCg);
				vp->setParameter("target", mSelectedProfile);
				vp->setParameter("entry_point", "main");

				vp->load();

				mAssemblerProgram = vp;
			}
			else
			{

				String shaderAssemblerCode = cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM);

                if (mType == GPT_FRAGMENT_PROGRAM) {
                    //HACK : http://developer.nvidia.com/forums/index.php?showtopic=1063&pid=2378&mode=threaded&start=#entry2378
                    //Still happens in CG 2.2. Remove hack when fixed.
                    shaderAssemblerCode = StringUtil::replaceAll(shaderAssemblerCode, "oDepth.z", "oDepth");
                }
				// Create a low-level program, give it the same name as us
				mAssemblerProgram = 
					GpuProgramManager::getSingleton().createProgramFromString(
					mName, 
					mGroup,
					shaderAssemblerCode,
					mType, 
					mSelectedProfile);
			}
			// Shader params need to be forwarded to low level implementation
			mAssemblerProgram->setAdjacencyInfoRequired(isAdjacencyInfoRequired());
		}
    }
Exemplo n.º 5
0
	//-----------------------------------------------------------------------
	void CgProgram::createLowLevelImpl(void)
	{
		if (mDelegate)
			return;

		// ignore any previous error
		if (mSelectedCgProfile != CG_PROFILE_UNKNOWN && !mCompileError)
		{

			if ( false
// the hlsl 4 profiles are only supported in OGRE from CG 2.2
#if(CG_VERSION_NUM >= 2200)
				|| mSelectedCgProfile == CG_PROFILE_VS_4_0
				|| mSelectedCgProfile == CG_PROFILE_PS_4_0
#endif
#if(CG_VERSION_NUM >= 3000)
				|| mSelectedCgProfile == CG_PROFILE_VS_5_0
				|| mSelectedCgProfile == CG_PROFILE_PS_5_0
				|| mSelectedCgProfile == CG_PROFILE_DS_5_0
				|| mSelectedCgProfile == CG_PROFILE_HS_5_0
#endif
				 )
			{
				// Create a high-level program, give it the same name as us
                HighLevelGpuProgramManager::getSingleton().remove(mName, mGroup);
				HighLevelGpuProgramPtr vp = 
					HighLevelGpuProgramManager::getSingleton().createProgram(
					mName, mGroup, "hlsl", mType);
				vp->setSource(mProgramString);
				vp->setParameter("target", mSelectedProfile);
				vp->setParameter("entry_point", "main");

				vp->load();

				mAssemblerProgram = vp;
			}
			else
			{
				// Create a low-level program, give it the same name as us
                mAssemblerProgram = 
					GpuProgramManager::getSingleton().createProgramFromString(
					mName, 
					mGroup,
					mProgramString,
					mType, 
					mSelectedProfile);
			}
			// Shader params need to be forwarded to low level implementation
			mAssemblerProgram->setAdjacencyInfoRequired(isAdjacencyInfoRequired());
		}
	}
	//---------------------------------------------------------------------
	HighLevelGpuProgramPtr 
	TerrainMaterialGeneratorC::SM2Profile::ShaderHelper::generateFragmentProgram(
		const SM2Profile* prof, const Terrain* terrain, TechniqueType tt)
	{
		HighLevelGpuProgramPtr ret = createFragmentProgram(prof, terrain, tt);
 
		StringUtil::StrStreamType sourceStr;
		generateFragmentProgramSource(prof, terrain, tt, sourceStr);
		ret->setSource(sourceStr.str());
		ret->load();
		defaultFpParams(prof, terrain, tt, ret);
 
#if 1
		LogManager::getSingleton().stream(LML_TRIVIAL) << "*** Terrain Fragment Program: " 
			<< ret->getName() << " ***\n" << ret->getSource() << "\n***   ***";
#endif
 
		return ret;
	}
Exemplo n.º 7
0
	//-----------------------------------------------------------------------------------
	GpuProgramPtr ShaderManager::createGpuProgram(const String& name, const String& code, HlmsDatablock* dataBlock)
	{
		HighLevelGpuProgramPtr gpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(name,
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, dataBlock->getLanguage(), dataBlock->getShaderType());

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

		gpuProgram->setSource(code);

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

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

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

		return gpuProgram;
	}
//-----------------------------------------------------------------------------
///
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 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;
		}
    }
Exemplo n.º 10
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;
}
Exemplo n.º 11
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);
	}

}
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;
}
//-----------------------------------------------------------------------------
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.º 14
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.º 15
0
void GrassLayerBase::_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 = ShaderHelper::getShaderLanguage();
        HighLevelGpuProgramPtr vertexShader = HighLevelGpuProgramManager::getSingleton().getByName(vsName);
        if (vertexShader.isNull()) {

          //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";
            if (geom->getSceneManager()->getFogMode() == Ogre::FOG_EXP2) {
              vertexProgSource += "	gl_FogFragCoord = clamp(exp(- gl_Fog.density * gl_Fog.density * gl_Position.z * gl_Position.z), 0.0, 1.0); \n";
            } else {
              vertexProgSource += "	gl_FogFragCoord = gl_Position.z; \n";
            }

            vertexProgSource += "}";
          }

          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).

        tmpMat->load();
        Ogre::Material::TechniqueIterator techIterator = tmpMat->getSupportedTechniqueIterator();
        while (techIterator.hasMoreElements()) {
          Ogre::Technique* tech = techIterator.getNext();
          //Apply the shader to the material
          Pass *pass = tech->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->setNamedConstant("time", 1.0f);
            params->setNamedConstant("frequency", 1.0f);
            params->setNamedConstant("direction", Ogre::Vector4::ZERO);
          }

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

    Ogre::Technique* tech = material->getBestTechnique();
    if (tech && tech->getNumPasses()) {
      Ogre::Pass* pass = tech->getPass(0);
      if (pass->hasVertexProgram()) {
        Ogre::GpuProgramParametersSharedPtr params = pass->getVertexProgramParameters();
        if (!params.isNull()) {
          params->setIgnoreMissingParams(true);
        }
      }
    }
  }
}
Exemplo n.º 16
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.º 17
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.º 18
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.º 19
0
//-----------------------------------------------------------------------------
/// 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.º 20
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;
		}

	}
//-----------------------------------------------------------------------------
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.º 22
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);
	}
}