Esempio n. 1
0
void CubeWorld::createWorldChunks (void)
{
	//std::vector<int> VertexArray;
	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create("BoxColor", "General", true );
	Ogre::Technique* tech = mat->getTechnique(0);
	Ogre::Pass* pass = tech->getPass(0);
	Ogre::TextureUnitState* tex = pass->createTextureUnitState();
	tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, Ogre::ColourValue(0, 0.5, 0));

	Ogre::ManualObject* MeshChunk = new Ogre::ManualObject("MeshMatChunk");
	MeshChunk->begin("TerrainImage");

	for (int z = 0; z < WORLD_SIZE; z += CHUNK_SIZE)
	{
		for (int y = 0; y < WORLD_SIZE; y += CHUNK_SIZE)
		{
			for (int x = 0; x < WORLD_SIZE; x += CHUNK_SIZE)
			{
				createChunk(MeshChunk, x,y,z); /* WFaces or not */
				//createChunkWater(x, y, z);
			}
		}
	}

}
Esempio n. 2
0
void CubeWorld::displaySimpleWorld (void)
{
	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create("BoxColor", "General", true );
	Ogre::Technique* tech = mat->getTechnique(0);
	Ogre::Pass* pass = tech->getPass(0);
	Ogre::TextureUnitState* tex = pass->createTextureUnitState();
	tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, Ogre::ColourValue(0, 0.5, 0));

	Ogre::ManualObject* testBox  = createCubeMesh("TestBox1", "BoxColor");
        Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
	Ogre::MeshPtr Mesh = testBox->convertToMesh("TestBox2");
	Ogre::StaticGeometry* pGeom = new Ogre::StaticGeometry (mSceneMgr, "Boxes");

	Ogre::Entity* pEnt = mSceneMgr->createEntity("TestBox2");

	pGeom->setRegionDimensions(Ogre::Vector3(300, 300, 300));

	for (int z = 0; z < WORLD_SIZE; ++z)
	{
		for (int y = 0; y < WORLD_SIZE; ++y)
		{
			for (int x = 0; x < WORLD_SIZE; ++x)
			{
				if (GetBlock(x,y,z)) pGeom->addEntity(pEnt, Ogre::Vector3(x,y,z));
			}
		}
	}

	pGeom->build ();
}
Esempio n. 3
0
void CubeWorld::updateSkyTextureLight (void)
{
	if (m_SkyMaterial.isNull())
		return;

	Ogre::Technique* tech = m_SkyMaterial->getTechnique(0);
#if defined(__linux__) || defined(__APPLE__)
	if (tech == NULL) return;
#else
	if (tech == nullptr) return;

#endif
	Ogre::Pass* pass = tech->getPass(0);
#if defined(__linux__) || defined(__APPLE__)
	if (pass == NULL) return;
#else
	if (pass == nulptr) return;
#endif

	Ogre::TextureUnitState* tex = pass->getTextureUnitState(1);
#if defined(__linux__) || defined(__APPLE__)
	if (tex == NULL) return;
#else
	if (tex == nullptr) return;
#endif

	// Update the texture unit's color operation with the world light level
	tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, m_LightColor);
}
	//--------------------------------------------------------------------------------
	void MaterialUtil::updateSelectedVersion(const MaterialPtr& _material)
	{
		String name = _material->getName();
		String selName = getSelectedVersionName(name);
		MaterialPtr material, selectedMaterial;
		if(selName == name)
		{
			name = getUnselectedVersionName(selName);
			selectedMaterial = _material;
			material = MaterialManager::getSingleton().getByName(name);
		}
		else
		{
			material = _material;
			selectedMaterial = MaterialManager::getSingleton().getByName(selName);
		}
		
		if(!material.isNull() && !selectedMaterial.isNull())
		{
			material->copyDetailsTo(selectedMaterial);
			Ogre::Technique* technique = selectedMaterial->getBestTechnique();
			Pass* pass0 = technique->getPass(0);
			Pass* passNew = technique->createPass();
			passNew->setDiffuse(1, 1, 1, 1);
			passNew->setPolygonMode(Ogre::PM_WIREFRAME);

			if(pass0->getNumTextureUnitStates() != 0)
			{
				Ogre::TextureUnitState* tu = pass0->getTextureUnitState(0);
				tu->setColourOperationEx(Ogre::LBX_MODULATE, 
					Ogre::LBS_TEXTURE, Ogre::LBS_MANUAL,
					ColourValue::White, ColourValue(1, 0.6f, 0.6f, 1));
			}
		}
	}
Esempio n. 5
0
void OgreBtDebugDrawer::initialize(Ogre::SceneManager* const sceneManager,
		const bool drawTrajectory) {
	mDrawTrajectory = drawTrajectory;
	mContactPoints = &mContactPoints1;
	mLines = new Ogre::ManualObject("BulletPhysicsLines1");
	mLines2 = new Ogre::ManualObject("BulletPhysicsLines2");

	mTriangles = new Ogre::ManualObject("BulletPhysicsTriangles1");
	mTriangles2 = new Ogre::ManualObject("BulletPhysicsTriangles2");

	mLines->setDynamic(true);
	mLines2->setDynamic(true);
	mTriangles->setDynamic(true);
	mTriangles2->setDynamic(true);
	//mLines->estimateVertexCount( 100000 );
	//mLines->estimateIndexCount( 0 );

	sceneManager->getRootSceneNode()->attachObject(mLines);
	sceneManager->getRootSceneNode()->attachObject(mLines2);
	sceneManager->getRootSceneNode()->attachObject(mTriangles);
	sceneManager->getRootSceneNode()->attachObject(mTriangles2);

	static const char* matName = "OgreBulletCollisionsDebugDefault";
	Ogre::MaterialPtr mtl =
			Ogre::MaterialManager::getSingleton().getDefaultSettings()->clone(
					matName);
	mtl->setReceiveShadows(false);
	mtl->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
	mtl->setDepthBias(0.1, 0);
	Ogre::TextureUnitState * tu =
			mtl->getTechnique(0)->getPass(0)->createTextureUnitState();

	tu->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_DIFFUSE);
	mtl->getTechnique(0)->setLightingEnabled(false);
	//mtl->getTechnique(0)->setSelfIllumination( ColourValue::White );

	//for the ogre text
	Ogre::Root::getSingleton().addFrameListener(this);
	//TODO: Add 3D text writing capability to ogreBtdebugdrawer #133.
//	olm = Ogre::OverlayManager::getSingletonPtr();
//	panel = static_cast<Ogre::OverlayContainer*>(olm->createOverlayElement(
//			"Panel", "OGREBTDEBUGDRAWER_GUI"));
//	panel->setMetricsMode(Ogre::GMM_PIXELS);
//	panel->setPosition(0, 0);
//	panel->setDimensions(1.0f, 1.0f);
//	overlay = olm->create("OGREBTDEBUGDRAWER_OVERLAY");
//	overlay->add2D(panel);
//
//	szElement = "element_";
//	overlay = olm->getByName("OGREBTDEBUGDRAWER_OVERLAY");
//	panel = static_cast<Ogre::OverlayContainer*>(olm->getOverlayElement(
//			"OGREBTDEBUGDRAWER_GUI"));
//	textArea =
//			static_cast<Ogre::TextAreaOverlayElement*>(olm->createOverlayElement(
//					"TextArea", szElement));
//	panel->addChild(textArea);
//	overlay->show();

}
Esempio n. 6
0
void CubeWorld::createSolidTexture (const TCHAR* pName)
{
	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create("BoxColor", "General", true );
	Ogre::Technique* tech = mat->getTechnique(0);
	Ogre::Pass* pass = tech->getPass(0);
	Ogre::TextureUnitState* tex = pass->createTextureUnitState();
	tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, Ogre::ColourValue(0, 0.5, 0));
}
Esempio n. 7
0
static void
SubEntity_tintColour(
    SubEntity* self,
    const String& groupName,
    const String& materialName,
    const Ogre::ColourValue& colour
) {
    Ogre::MaterialPtr baseMaterial = Ogre::MaterialManager::getSingleton().getByName(materialName);
    Ogre::MaterialPtr materialPtr = baseMaterial->clone(groupName);
    materialPtr->compile();
    Ogre::TextureUnitState* ptus = materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0);
    ptus->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_TEXTURE, colour);
    self->setMaterial(materialPtr);
}
Esempio n. 8
0
 void
 setupMaterial() {
     Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getDefaultSettings()->clone(
         MATERIAL_NAME
     );
     material->setReceiveShadows(false);
     material->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
     material->setDepthBias(0.1, 0);
     Ogre::TextureUnitState* textureUnitState = material->getTechnique(0)->getPass(0)->createTextureUnitState();
     textureUnitState->setColourOperationEx(
         Ogre::LBX_SOURCE1,
         Ogre::LBS_DIFFUSE
     );
     material->getTechnique(0)->setLightingEnabled(false);
 }
Esempio n. 9
0
void CubeWorld::createWaterTexture (const TCHAR* pName)
{
	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(pName, "General", true );
	Ogre::Technique* tech = mat->getTechnique(0);
	Ogre::Pass* pass = tech->getPass(0);
	Ogre::TextureUnitState* tex = pass->createTextureUnitState();

	tech->setLightingEnabled(false);

	pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
	pass->setDepthWriteEnabled(false);

	tex->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, Ogre::ColourValue(0, 0, 1));
	tex->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, 0.5);
}
Esempio n. 10
0
void CubeWorld::createTexture (const TCHAR* pName, const TCHAR* pImageFilename)
{
	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(pName, "General", true );
	Ogre::Technique* tech = mat->getTechnique(0);
	Ogre::Pass* pass = tech->getPass(0);
	Ogre::TextureUnitState* tex = pass->createTextureUnitState();

	tex->setTextureName(pImageFilename);
	tex->setNumMipmaps(4);
	tex->setTextureAnisotropy(1);
	tex->setTextureFiltering(Ogre::FO_POINT, Ogre::FO_POINT, Ogre::FO_POINT);

	pass->setVertexColourTracking(Ogre::TVC_DIFFUSE);
	tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_DIFFUSE, Ogre::LBS_TEXTURE);

	tech->setLightingEnabled(false);
}
Ogre::MaterialPtr OgrePlanarReflectionMaterial::createMaterial(const Ogre::TexturePtr& texture, const Ogre::Camera& projectionCamera)
{
    using namespace::Ogre;

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

    matPtr->compile();
    return matPtr;
}
Esempio n. 12
0
void CubeWorld::createSkyTexture(const TCHAR* pName)
{
	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(pName, "General", true);
	Ogre::Technique* tech = mat->getTechnique(0);
	Ogre::Pass* pass = tech->getPass(0);
	Ogre::TextureUnitState* tex = pass->createTextureUnitState();

	pass->setLightingEnabled(false);
	pass->setDepthCheckEnabled(false);
	pass->setDepthWriteEnabled(false);
	pass->setFog(true);

	tex->setTextureName("clouds.jpg");
	tex->setScrollAnimation(0.05, 0);

	// This is a new texture state to simulate lightning
	tex = pass->createTextureUnitState();
	tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, Ogre::ColourValue(1, 1, 1));

	m_SkyMaterial = mat;
	updateSkyTextureLight();
}
Esempio n. 13
0
// void TerrainPageSurfaceCompiler::addTextureUnitsToPass(Ogre::Pass* pass, const Ogre::String& splatTextureName) {
//
// 	if (getMaxTextureUnits() - pass->getNumTextureUnitStates() < 2 || pass->getParent()->getNumPasses() > 1)  {
// 		addPassToTechnique(pass->getParent(), splatTextureName);
// // 		S_LOG_WARNING("Trying to add texture units to pass with too few available texture unit states.");
// 		return;
// 	}
//
// 	S_LOG_VERBOSE("Adding new texture unit (detailtexture: " << mTextureName << " alphatexture: " << splatTextureName << ") to pass nr " << pass->getIndex() << " in technique for material " << pass->getParent()->getParent()->getName());
//
// /*	pass->setSelfIllumination(Ogre::ColourValue(1,1,1));
// 	pass->setAmbient(Ogre::ColourValue(1,1,1));
// 	pass->setDiffuse(Ogre::ColourValue(1,1,1));
// 	pass->setLightingEnabled(true);*/
// 	Ogre::TextureUnitState * textureUnitStateSplat = pass->createTextureUnitState();
//     textureUnitStateSplat->setTextureName(splatTextureName);
//
//     textureUnitStateSplat->setTextureCoordSet(0);
// 	textureUnitStateSplat->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
// 	textureUnitStateSplat->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_TEXTURE, Ogre::LBS_TEXTURE);
// 	textureUnitStateSplat->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_CURRENT, Ogre::LBS_CURRENT);
//     textureUnitStateSplat->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
// // 	textureUnitStateSplat->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA, Ogre::LBS_CURRENT, Ogre::LBS_TEXTURE);
// //	textureUnitStateSplat->setColourOperationEx(Ogre::LBX_BLEND_TEXTURE_ALPHA, Ogre::LBS_CURRENT, Ogre::LBS_TEXTURE);
//
// 	Ogre::TextureUnitState * textureUnitState = pass->createTextureUnitState();
//     textureUnitState->setTextureName(mTextureName);
//     textureUnitState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
// /*	textureUnitState->setTextureCoordSet(0);*/
// 	textureUnitState->setTextureScale(0.025, 0.025);
// 	textureUnitState->setColourOperationEx(Ogre::LBX_BLEND_CURRENT_ALPHA, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT);
//
// /*	Ogre::TextureUnitState * alphaTextureState= pass->createTextureUnitState();
//     alphaTextureState->setTextureName(mTextureName);
// //     alphaTextureState->setTextureName(splatTextureName);
//     alphaTextureState->setTextureCoordSet(0);
// 	alphaTextureState->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
//     alphaTextureState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
//  	alphaTextureState->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA, Ogre::LBS_CURRENT, Ogre::LBS_TEXTURE);
//
//
//
// // 	detailTextureState->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_TEXTURE, Ogre::LBS_TEXTURE);
// // 	detailTextureState->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_CURRENT, Ogre::LBS_CURRENT);
//
// 	Ogre::TextureUnitState * detailTextureState  = pass->createTextureUnitState();
//     detailTextureState ->setTextureName(splatTextureName);
// //     detailTextureState ->setTextureName(mTextureName);
//     detailTextureState ->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
// 	detailTextureState ->setTextureCoordSet(0);
// 	detailTextureState ->setTextureScale(0.01, 0.01);
// 	//detailTextureState ->setColourOperationEx(Ogre::LBX_BLEND_CURRENT_ALPHA, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT);*/
//
// }
//
Ogre::Pass* Simple::addPassToTechnique(const TerrainPageGeometry& geometry, Ogre::Technique* technique, const Layer& layer, std::set<std::string>& managedTextures) const
{
	//check if we instead can reuse the existing pass
	// 	if (technique->getNumPasses() != 0) {
	// 		Ogre::Pass* pass = technique->getPass(technique->getNumPasses() - 1);
	// 		if (4 - pass->getNumTextureUnitStates() >= 2) {
	// 			//there's more than two texture units available, use those instead of creating a new pass
	// 			S_LOG_VERBOSE("Reusing existing pass. ("<< pass->getNumTextureUnitStates() << " of "<< mNumberOfTextureUnitsOnCard << " texture unit used)");
	// 			addTextureUnitsToPass(pass, splatTextureName);
	// 			return pass;
	// 		}
	//
	// 	}

	const OgreImage& ogreImage = *layer.blendMap;
	Ogre::Image image;

	image.loadDynamicImage(const_cast<unsigned char*>(ogreImage.getData()), ogreImage.getResolution(), ogreImage.getResolution(), 1, Ogre::PF_A8);

	std::stringstream splatTextureNameSS;
	splatTextureNameSS << "terrain_" << mPage.getWFPosition().x() << "_" << mPage.getWFPosition().y() << "_" << technique->getNumPasses();
	const Ogre::String splatTextureName(splatTextureNameSS.str());
	Ogre::TexturePtr blendMapTexture;
	if (Ogre::Root::getSingletonPtr()->getTextureManager()->resourceExists(splatTextureName)) {
		blendMapTexture = static_cast<Ogre::TexturePtr>(Ogre::Root::getSingletonPtr()->getTextureManager()->getByName(splatTextureName));
		blendMapTexture->loadImage(image);

		Ogre::HardwarePixelBufferSharedPtr hardwareBuffer(blendMapTexture->getBuffer());
		//blit the whole image to the hardware buffer
		Ogre::PixelBox sourceBox(image.getPixelBox());
		hardwareBuffer->blitFromMemory(sourceBox);
	} else {
		blendMapTexture = Ogre::Root::getSingletonPtr()->getTextureManager()->loadImage(splatTextureName, "General", image, Ogre::TEX_TYPE_2D, 0);
		managedTextures.insert(blendMapTexture->getName());
	}

	//we need to create the image, update it and then destroy it again (to keep the memory usage down)
	//	if (layer->getBlendMapTextureName() == "") {
	//		//no texture yet; let's create one
	//		layer->createBlendMapImage();
	//		layer->updateBlendMapImage(geometry);
	//		layer->createTexture();
	//	} else {
	//		//a texture exists, so we just need to update the image
	//		layer->updateBlendMapImage(geometry); //calling this will also update the texture since the method will blit the image onto it
	//	}

	Ogre::Pass* pass = technique->createPass();

	pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
	pass->setAmbient(1, 1, 1);
	pass->setDiffuse(1, 1, 1, 1);
	pass->setLightingEnabled(false);

	Ogre::TextureUnitState * textureUnitState = pass->createTextureUnitState();
	textureUnitState->setTextureName(layer.surfaceLayer.getDiffuseTextureName());
	textureUnitState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
	textureUnitState->setTextureCoordSet(0);
	textureUnitState->setTextureScale(1.0f / layer.surfaceLayer.getScale(), 1.0f / layer.surfaceLayer.getScale());

	Ogre::TextureUnitState * textureUnitStateSplat = pass->createTextureUnitState();
	textureUnitStateSplat->setTextureName(blendMapTexture->getName());

	textureUnitStateSplat->setTextureCoordSet(0);
	textureUnitStateSplat->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
	textureUnitStateSplat->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
	//	textureUnitStateSplat->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_TEXTURE, Ogre::LBS_TEXTURE);
	textureUnitStateSplat->setAlphaOperation(Ogre::LBX_BLEND_DIFFUSE_COLOUR, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT);
	textureUnitStateSplat->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_CURRENT, Ogre::LBS_CURRENT);
	return pass;

}
Esempio n. 14
0
void gkMaterialLoader::loadSubMeshMaterial(gkSubMesh* mesh, const gkString& group)
{
	using namespace Ogre;

	gkMaterialProperties& gma = mesh->getMaterial();
	if (gma.m_name.empty())
		gma.m_name = "<gkBuiltin/DefaultMaterial>";

	Ogre::MaterialPtr oma = Ogre::MaterialManager::getSingleton().getByName(gma.m_name.c_str(), group);
	if (!oma.isNull())
		return;

	oma = Ogre::MaterialManager::getSingleton().create(gma.m_name, group);

	if (gma.m_mode & gkMaterialProperties::MA_INVISIBLE)
	{
		// disable writing to this material
		oma->setReceiveShadows(false);
		oma->setColourWriteEnabled(false);
		oma->setDepthWriteEnabled(false);
		oma->setDepthCheckEnabled(false);
		oma->setLightingEnabled(false);
		return;
	}

	if (gma.m_mode & gkMaterialProperties::MA_TWOSIDE)
	{
		oma->setCullingMode(Ogre::CULL_NONE);
		oma->setManualCullingMode(Ogre::MANUAL_CULL_NONE);
	}

	// apply lighting params

	bool enableLights = (gma.m_mode & gkMaterialProperties::MA_LIGHTINGENABLED) != 0;
	oma->setReceiveShadows((gma.m_mode & gkMaterialProperties::MA_RECEIVESHADOWS) != 0);

	oma->setLightingEnabled(enableLights);
	if (enableLights)
	{
		gkColor emissive, ambient, specular, diffuse;

		emissive    = gma.m_diffuse * gma.m_emissive;
		ambient     = gma.m_diffuse * gma.m_ambient;
		specular    = gma.m_specular * gma.m_spec;
		diffuse     = gma.m_diffuse * (gma.m_emissive + gma.m_refraction);

		emissive.a = ambient.a = specular.a = 1.f;

		oma->setSelfIllumination(emissive);
		oma->setAmbient(ambient);
		oma->setSpecular(specular);
		oma->setDiffuse(diffuse);
		oma->setShininess(gma.m_hardness);
	}
	
	Ogre::Pass* pass = oma->getTechnique(0)->getPass(0);

	bool matBlending = gkEngine::getSingleton().getUserDefs().matblending;

	if (matBlending && (gma.m_mode & gkMaterialProperties::MA_HASRAMPBLEND))
	{
		switch (gma.m_rblend)
		{
		case GK_BT_MULTIPLY:			
			pass->setSceneBlending(SBT_MODULATE);			
			break;
		case GK_BT_SUBTRACT:			
			pass->setSceneBlending(SBF_ONE_MINUS_SOURCE_COLOUR, SBF_ONE);
			break;
		case GK_BT_DARKEN:
			pass->setSceneBlendingOperation(SBO_MIN);
			pass->setSceneBlending(SBF_ONE, SBF_ONE);
			break;
		case GK_BT_LIGHTEN:
			pass->setSceneBlendingOperation(SBO_MAX);
			pass->setSceneBlending(SBF_ONE, SBF_ONE);
			break;
		case GK_BT_SCREEN:			
			pass->setSceneBlending(SBF_ONE_MINUS_DEST_COLOUR, SBF_ONE);
			break;
		case GK_BT_ADDITIVE:
			pass->setSceneBlending(SBT_ADD);
			break;
		case GK_BT_MIXTURE:
		default:
			pass->setSceneBlending(SBF_ONE, SBF_ZERO);
			break;
		}
	}

	bool hasNormap = false;
	bool rtss = gkEngine::getSingleton().getUserDefs().rtss;

	for (int i = 0; i < gma.m_totaltex; ++i)
	{		
		gkTextureProperties& gte = gma.m_textures[i];

#ifdef OGREKIT_USE_RTSHADER_SYSTEM
		if (gte.m_mode & gkTextureProperties::TM_NORMAL)
		{
			hasNormap = true;
			continue;
		}
#endif
		Ogre::TextureUnitState* otus = pass->createTextureUnitState(gte.m_name, gte.m_layer);

		LayerBlendOperationEx op = LBX_MODULATE;

		switch (gte.m_blend)
		{
		case GK_BT_ADDITIVE:
			op = LBX_ADD;
			break;

		case GK_BT_SUBTRACT:			
			op = LBX_SUBTRACT;
			break;

		case GK_BT_DARKEN:	
		case GK_BT_LIGHTEN:	
		case GK_BT_SCREEN:
		case GK_BT_COLOR:
			//break; TODO: support more mode

		case GK_BT_MULTIPLY:
		case GK_BT_MIXTURE:
		default:
			op = LBX_MODULATE;
			break;
		}

		if (i == 0)
			otus->setColourOperationEx(op, LBS_DIFFUSE, LBS_TEXTURE);		
		else
			otus->setColourOperationEx(op);

		otus->setTextureScale(gte.m_scale[0],gte.m_scale[1]);
	}



	if (gma.m_mode & gkMaterialProperties::MA_ALPHABLEND)
	{
		pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
		pass->setDepthWriteEnabled(false);
	}

	if (gma.m_mode & gkMaterialProperties::MA_ALPHACLIP)
	{
		pass->setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL, 254);
	}

#ifdef OGREKIT_USE_RTSHADER_SYSTEM
	
	if (rtss)
	{
		//pass->setSpecular(ColourValue::Black);
		//pass->setShininess(0.0);

		RTShader::RenderState* rs = 0;
		RTShader::ShaderGenerator* sg = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
		bool ok = sg->createShaderBasedTechnique(gma.m_name, group, 
			Ogre::MaterialManager::DEFAULT_SCHEME_NAME, Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);

		if (ok && hasNormap)
		{
			rs = sg->getRenderState(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, gma.m_name, 0);
			rs->reset();

			for (int i = 0; i < gma.m_totaltex; ++i)
			{
				gkTextureProperties& gte = gma.m_textures[i];

				if (gte.m_mode & gkTextureProperties::TM_NORMAL)
				{
					GK_ASSERT(rs);

					RTShader::SubRenderState* srs= sg->createSubRenderState(RTShader::NormalMapLighting::Type);
				
					RTShader::NormalMapLighting* nsrs = static_cast<RTShader::NormalMapLighting*>(srs);
					if (gte.m_texmode & gkTextureProperties::TX_OBJ_SPACE)
						nsrs->setNormalMapSpace(RTShader::NormalMapLighting::NMS_OBJECT);
					else
						nsrs->setNormalMapSpace(RTShader::NormalMapLighting::NMS_TANGENT);
					nsrs->setNormalMapTextureName(gte.m_name);
					nsrs->setTexCoordIndex(gte.m_layer);

					rs->addTemplateSubRenderState(srs);
				}
			}

			sg->invalidateMaterial(RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME, gma.m_name);
		}
	}
#endif
}
Esempio n. 15
0
// 设置选中的外观颜色.
void CEditDobject_NT::SetSelectLook(Ogre::ColourValue color)
{

	if(0 == m_materialSelVector.size())
	{
		// 选中材质的名字.
		Ogre::String strCloneName;
		int iCount = m_EntityList.size();
		Ogre::Entity* pEntity = NULL;

		for(int i = 0; i < iCount; i++)
		{
			pEntity = m_EntityList[i].pEntity;
			if(pEntity)
			{
				Ogre::SubEntity* pSubEntiy = pEntity->getSubEntity(0);
				if(pSubEntiy)
				{
					
					Ogre::MaterialPtr pMaterial = pSubEntiy->getMaterial();
					
					if(pMaterial.isNull())
					{
						return;
					}//

					const Ogre::String& strName = pMaterial->getName();

					if("BaseWhite" == strName)
					{
						continue;
					}

					strCloneName = strName;
					strCloneName += "_select";
					
					Ogre::MaterialManager* pMaterialManager = (Ogre::MaterialManager*)(pMaterial->getCreator());

					if(NULL == pMaterialManager)
					{
						return;
					}

					Ogre::MaterialPtr pMaterialClone = pMaterialManager->getByName(strCloneName); 
						
					if(pMaterialClone.isNull())
					{
						pMaterialClone = pMaterial->clone(strCloneName);
					}
					//if(!pMaterialClone)
					//{
					//	return;
					//}//

					Ogre::Technique* pTechnique = pMaterialClone->getBestTechnique();
					Ogre::Pass* pPass = pTechnique->getPass(0);

					//pPass->setSceneBlending(SBT_ADD);
					//pPass->setSceneBlending(SBF_SOURCE_ALPHA , SBF_ONE_MINUS_SOURCE_ALPHA );
					//pTextureState->setAlphaOperation(LBX_MODULATE, LBS_TEXTURE, LBS_MANUAL, 1, Transparence, 1);//
				
					Ogre::TextureUnitState* pTextureState = pPass->getTextureUnitState(0);
					pTextureState->setColourOperationEx(Ogre::LBX_ADD , Ogre::LBS_TEXTURE , Ogre::LBS_MANUAL, color, color );
					pSubEntiy->setMaterialName(strCloneName);
					m_materialSelVector.push_back(pMaterialClone);
					m_materilaOldVector.push_back(pMaterial);
					
				}

			}
		}
	}
	else
	{
		int iIndex = 0;

		int iCount = m_EntityList.size();
		Ogre::Entity* pEntity = NULL;

		for(int i = 0; i < iCount; i++)
		{
			pEntity = m_EntityList[i].pEntity;
			if(pEntity)
			{
				Ogre::SubEntity* pSubEntiy = pEntity->getSubEntity(0);
				
				if(pSubEntiy)
				{
					if(iIndex >= (int)m_materialSelVector.size())
					{
						continue;
					}

					std::string strMaterialName = m_materialSelVector[iIndex]->getName();
					pSubEntiy->setMaterialName(strMaterialName);	
					iIndex++;
				}

			}
		}
	}
}
Esempio n. 16
0
bool LagomPlayerBase::Update(float time_elapsed)
{
	_health += getIntFactory().HealthRegeneration*time_elapsed/1000.0f;
	if(_health >= getIntFactory().Health)
		_health = getIntFactory().Health;
	
	_factoryHighlightRemaining -= time_elapsed;
	if(_factoryHighlightRemaining < 0.0f)
		_factoryHighlightRemaining = 0.0f;

	float newCooldown = _buildCooldown - time_elapsed;
	if( (newCooldown > 0.0f) != (_buildCooldown > 0.0f))
		_factoryHighlightRemaining = getIntFactory().ConstructionHighlightTime;
	_buildCooldown = newCooldown;

	Ogre::ColourValue playerColor = Lagom::getSingleton().GetPlayerColor();

	Ogre::ColourValue staticColor = playerColor*.05f + Ogre::ColourValue(.1,.1,.1,.0f);
	Ogre::ColourValue pulseColor = playerColor * _state.GetPulsePower();

	_materialInstance->setCustomParameter(0,Ogre::Vector4(staticColor.r,staticColor.g,staticColor.b,.0f));
	_materialInstance->setCustomParameter(1,Ogre::Vector4(pulseColor.r,pulseColor.g,pulseColor.b,_state.GetPulseTime()));
	
	if(	_selectedActorFactory !=_actorFactories.end() && _selectedActorFactory->second != _constructionObject)
	{
		if(_constructionObject)
			_sceneNode->removeChild(_constructionObject);
		_constructionObject=_selectedActorFactory->second;
		_constructionObject->setPosition(getIntFactory().ConstructionOffset);
		if(_constructionObject)
			_sceneNode->addChild(_constructionObject);
	}

	if(_constructionObject)
	{
		Ogre::ColourValue constructionColour(0.0f,0.0f,0.0f,0.0f);
		float constructionAlpha = 1.0f;

		if(_draggingConstruction)
		{
			if(checkConstructionRestriction(_selectedActorFactory->first,_currentDragLocation))
				constructionColour=playerColor;
			else
				constructionColour=Ogre::ColourValue::Black;
		}
		else if(_buildCooldown <= 0.0f)
		{
			if(_hoverConstructing)
				constructionColour = Ogre::ColourValue::White;
			else if(_factoryHighlightRemaining>= 0.0f)
			{
				float highlight = _factoryHighlightRemaining / getIntFactory().ConstructionHighlightTime;
				float rev_h = 1.0f - highlight;
				constructionColour = Ogre::ColourValue(playerColor.r*rev_h + highlight,playerColor.g*rev_h + highlight,playerColor.b*rev_h + highlight,1.0f);
			}
			else
				constructionColour=playerColor;
		}
		else
		{
			constructionAlpha = std::max(std::min(1.0f - _buildCooldown / _buildCooldownMax,1.0f),0.0f);
			constructionAlpha *= getIntFactory().ConstructionAlphaFactor;
		}

		Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().getByName(getIntFactory().ConstructingMaterial);

		Ogre::TextureUnitState* ptus = materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0); //1st pass, first texture unit
		Ogre::TextureUnitState* ptus2 = materialPtr->getTechnique(0)->getPass(1)->getTextureUnitState(0); //2nd pass, first texture unit
		ptus->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_MANUAL, Ogre::LBS_TEXTURE, constructionColour);
		ptus->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_MANUAL, Ogre::LBS_TEXTURE, .25f * constructionAlpha);
		ptus2->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_MANUAL, Ogre::LBS_TEXTURE, constructionColour);
		ptus2->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_MANUAL, Ogre::LBS_TEXTURE, .25f* constructionAlpha);

		if(!_draggingConstruction)
		{
			float rotation_speed = time_elapsed / 500.0f;
			Ogre::Quaternion rot1;
			rot1.FromAngleAxis(Ogre::Radian(rotation_speed), Ogre::Vector3( 0.0f , 1.0f, 0.0f).normalisedCopy() );
			_constructionObject->rotate( rot1);
		}
		else
		{
			_constructionObject->setOrientation(1.0f,0.0f,0.0f,0.0f);
			static_cast<Ogre::Entity*>(_constructionObject->getAttachedObject(0))->setMaterialName(getIntFactory().ConstructingMaterial);
		}

			
	}

	_energy = 1000.0f;

	if(_health <= 0.0f)
		return false;

	return true;
}
Esempio n. 17
0
    Ogre::MaterialPtr MaterialGenerator::create(bool renderCompositeMap, bool displayCompositeMap)
    {
        assert(!renderCompositeMap || !displayCompositeMap);

        static int count = 0;
        std::stringstream name;
        name << "terrain/mat" << count++;

        if (!mShaders)
        {
            Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(name.str(),
                                                               Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
            Ogre::Technique* technique = mat->getTechnique(0);
            technique->removeAllPasses();

            if (displayCompositeMap)
            {
                Ogre::Pass* pass = technique->createPass();
                pass->setVertexColourTracking(Ogre::TVC_AMBIENT|Ogre::TVC_DIFFUSE);
                pass->createTextureUnitState(mCompositeMap)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
            }
            else
            {
                assert(mLayerList.size() == mBlendmapList.size()+1);
                std::vector<Ogre::TexturePtr>::iterator blend = mBlendmapList.begin();
                for (std::vector<LayerInfo>::iterator layer = mLayerList.begin(); layer != mLayerList.end(); ++layer)
                {
                    Ogre::Pass* pass = technique->createPass();
                    pass->setLightingEnabled(false);
                    pass->setVertexColourTracking(Ogre::TVC_NONE);
                    // TODO: How to handle fog?
                    pass->setFog(true, Ogre::FOG_NONE);

                    bool first = (layer == mLayerList.begin());

                    Ogre::TextureUnitState* tus;

                    if (!first)
                    {
                        pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
                        pass->setDepthFunction(Ogre::CMPF_EQUAL);

                        tus = pass->createTextureUnitState((*blend)->getName());
                        tus->setAlphaOperation(Ogre::LBX_BLEND_TEXTURE_ALPHA,
                                               Ogre::LBS_TEXTURE,
                                               Ogre::LBS_TEXTURE);
                        tus->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA,
                                                  Ogre::LBS_TEXTURE,
                                                  Ogre::LBS_TEXTURE);
                        tus->setIsAlpha(true);
                        tus->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);

                        float scale = (16/(16.f+1.f));
                        tus->setTextureScale(1.f/scale,1.f/scale);
                    }

                    // Add the actual layer texture on top of the alpha map.
                    tus = pass->createTextureUnitState(layer->mDiffuseMap);
                    if (!first)
                        tus->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA,
                                                  Ogre::LBS_TEXTURE,
                                                  Ogre::LBS_CURRENT);

                    tus->setTextureScale(1/16.f,1/16.f);

                    if (!first)
                        ++blend;
                }

                if (!renderCompositeMap)
                {
                    Ogre::Pass* lightingPass = technique->createPass();
                    lightingPass->setSceneBlending(Ogre::SBT_MODULATE);
                    lightingPass->setVertexColourTracking(Ogre::TVC_AMBIENT|Ogre::TVC_DIFFUSE);
                    lightingPass->setFog(true, Ogre::FOG_NONE);
                }
            }

            return mat;
        }
#if TERRAIN_USE_SHADER
        else
        {
            sh::MaterialInstance* material = sh::Factory::getInstance().createMaterialInstance (name.str());
            material->setProperty ("allow_fixed_function", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(false)));

            if (displayCompositeMap)
            {
                sh::MaterialInstancePass* p = material->createPass ();

                p->setProperty ("vertex_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_vertex")));
                p->setProperty ("fragment_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_fragment")));
                p->mShaderProperties.setProperty ("is_first_pass", sh::makeProperty(new sh::BooleanValue(true)));
                p->mShaderProperties.setProperty ("render_composite_map", sh::makeProperty(new sh::BooleanValue(false)));
                p->mShaderProperties.setProperty ("display_composite_map", sh::makeProperty(new sh::BooleanValue(true)));
                p->mShaderProperties.setProperty ("num_layers", sh::makeProperty (new sh::StringValue("0")));
                p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty (new sh::StringValue("0")));
                p->mShaderProperties.setProperty ("normal_map_enabled", sh::makeProperty (new sh::BooleanValue(false)));
                p->mShaderProperties.setProperty ("parallax_enabled", sh::makeProperty (new sh::BooleanValue(false)));
                p->mShaderProperties.setProperty ("normal_maps",
                                                  sh::makeProperty (new sh::IntValue(0)));

                sh::MaterialInstanceTextureUnit* tex = p->createTextureUnit ("compositeMap");
                tex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(mCompositeMap)));
                tex->setProperty ("tex_address_mode", sh::makeProperty (new sh::StringValue("clamp")));

                // shadow. TODO: repeated, put in function
                if (mShadows)
                {
                    for (int i = 0; i < (mSplitShadows ? 3 : 1); ++i)
                    {
                        sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i));
                        shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow")));
                    }
                }
                p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty (new sh::StringValue(
                    Ogre::StringConverter::toString(1))));

                p->mShaderProperties.setProperty ("pass_index", sh::makeProperty(new sh::IntValue(0)));
            }
            else
            {

                bool shadows = mShadows && !renderCompositeMap;

                int layerOffset = 0;
                while (layerOffset < (int)mLayerList.size())
                {
                    int blendmapOffset = (layerOffset == 0) ? 1 : 0; // the first layer of the first pass is the base layer and does not need a blend map

                    // Check how many layers we can fit in this pass
                    int numLayersInThisPass = 0;
                    int numBlendTextures = 0;
                    std::vector<std::string> blendTextures;
                    int remainingTextureUnits = OGRE_MAX_TEXTURE_LAYERS;
                    if (shadows)
                        remainingTextureUnits -= (mSplitShadows ? 3 : 1);
                    while (remainingTextureUnits && layerOffset + numLayersInThisPass < (int)mLayerList.size())
                    {
                        int layerIndex = numLayersInThisPass + layerOffset;

                        int neededTextureUnits=0;
                        int neededBlendTextures=0;

                        if (layerIndex != 0)
                        {
                            std::string blendTextureName = mBlendmapList[getBlendmapIndexForLayer(layerIndex)]->getName();
                            if (std::find(blendTextures.begin(), blendTextures.end(), blendTextureName) == blendTextures.end())
                            {
                                blendTextures.push_back(blendTextureName);
                                ++neededBlendTextures;
                                ++neededTextureUnits; // blend texture
                            }
                        }
                        ++neededTextureUnits; // layer texture

                        // Check if this layer has a normal map
                        if (mNormalMapping && !mLayerList[layerIndex].mNormalMap.empty() && !renderCompositeMap)
                            ++neededTextureUnits; // normal map
                        if (neededTextureUnits <= remainingTextureUnits)
                        {
                            // We can fit another!
                            remainingTextureUnits -= neededTextureUnits;
                            numBlendTextures += neededBlendTextures;
                            ++numLayersInThisPass;
                        }
                        else
                            break; // We're full
                    }


                    sh::MaterialInstancePass* p = material->createPass ();
                    p->setProperty ("vertex_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_vertex")));
                    p->setProperty ("fragment_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_fragment")));
                    if (layerOffset != 0)
                    {
                        p->setProperty ("scene_blend", sh::makeProperty(new sh::StringValue("alpha_blend")));
                        // Only write if depth is equal to the depth value written by the previous pass.
                        p->setProperty ("depth_func", sh::makeProperty(new sh::StringValue("equal")));
                    }

                    p->mShaderProperties.setProperty ("render_composite_map", sh::makeProperty(new sh::BooleanValue(renderCompositeMap)));
                    p->mShaderProperties.setProperty ("display_composite_map", sh::makeProperty(new sh::BooleanValue(displayCompositeMap)));

                    p->mShaderProperties.setProperty ("num_layers", sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(numLayersInThisPass))));
                    p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(numBlendTextures))));
                    p->mShaderProperties.setProperty ("normal_map_enabled",
                                                      sh::makeProperty (new sh::BooleanValue(false)));

                    // blend maps
                    // the index of the first blend map used in this pass
                    int blendmapStart;
                    if (mLayerList.size() == 1) // special case. if there's only one layer, we don't need blend maps at all
                        blendmapStart = 0;
                    else
                        blendmapStart = getBlendmapIndexForLayer(layerOffset+blendmapOffset);
                    for (int i = 0; i < numBlendTextures; ++i)
                    {
                        sh::MaterialInstanceTextureUnit* blendTex = p->createTextureUnit ("blendMap" + Ogre::StringConverter::toString(i));
                        blendTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(mBlendmapList[blendmapStart+i]->getName())));
                        blendTex->setProperty ("tex_address_mode", sh::makeProperty (new sh::StringValue("clamp")));
                    }

                    // layer maps
                    bool anyNormalMaps = false;
                    bool anyParallax = false;
                    size_t normalMaps = 0;
                    for (int i = 0; i < numLayersInThisPass; ++i)
                    {
                        const LayerInfo& layer = mLayerList[layerOffset+i];
                        // diffuse map
                        sh::MaterialInstanceTextureUnit* diffuseTex = p->createTextureUnit ("diffuseMap" + Ogre::StringConverter::toString(i));
                        diffuseTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(layer.mDiffuseMap)));

                        // normal map (optional)
                        bool useNormalMap = mNormalMapping && !mLayerList[layerOffset+i].mNormalMap.empty() && !renderCompositeMap;
                        bool useParallax = useNormalMap && mParallaxMapping && layer.mParallax;
                        bool useSpecular = layer.mSpecular;
                        if (useNormalMap)
                        {
                            anyNormalMaps = true;
                            anyParallax = anyParallax || useParallax;
                            sh::MaterialInstanceTextureUnit* normalTex = p->createTextureUnit ("normalMap" + Ogre::StringConverter::toString(i));
                            normalTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(layer.mNormalMap)));
                        }
                        p->mShaderProperties.setProperty ("use_normal_map_" + Ogre::StringConverter::toString(i),
                                                          sh::makeProperty (new sh::BooleanValue(useNormalMap)));
                        p->mShaderProperties.setProperty ("use_parallax_" + Ogre::StringConverter::toString(i),
                                                          sh::makeProperty (new sh::BooleanValue(useParallax)));
                        p->mShaderProperties.setProperty ("use_specular_" + Ogre::StringConverter::toString(i),
                                                          sh::makeProperty (new sh::BooleanValue(useSpecular)));
                        boost::hash_combine(normalMaps, useNormalMap);
                        boost::hash_combine(normalMaps, useNormalMap && layer.mParallax);
                        boost::hash_combine(normalMaps, useSpecular);

                        if (i+layerOffset > 0)
                        {
                            int blendTextureIndex = getBlendmapIndexForLayer(layerOffset+i);
                            std::string blendTextureComponent = getBlendmapComponentForLayer(layerOffset+i);
                            p->mShaderProperties.setProperty ("blendmap_component_" + Ogre::StringConverter::toString(i),
                                                              sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(blendTextureIndex-blendmapStart) + "." + blendTextureComponent)));
                        }
                        else
                        {
                            // just to make it shut up about blendmap_component_0 not existing in the first pass.
                            // it might be retrieved, but will never survive the preprocessing step.
                            p->mShaderProperties.setProperty ("blendmap_component_" + Ogre::StringConverter::toString(i),
                                sh::makeProperty (new sh::StringValue("")));
                        }
                    }
                    p->mShaderProperties.setProperty ("normal_map_enabled",
                                                      sh::makeProperty (new sh::BooleanValue(anyNormalMaps)));
                    p->mShaderProperties.setProperty ("parallax_enabled",
                                                      sh::makeProperty (new sh::BooleanValue(anyParallax)));
                    // Since the permutation handler can't handle dynamic property names,
                    // combine normal map settings for all layers into one value
                    p->mShaderProperties.setProperty ("normal_maps",
                                                      sh::makeProperty (new sh::IntValue(normalMaps)));

                    // shadow
                    if (shadows)
                    {
                        for (int i = 0; i < (mSplitShadows ? 3 : 1); ++i)
                        {
                            sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i));
                            shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow")));
                        }
                    }
                    p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty (new sh::StringValue(
                        Ogre::StringConverter::toString(numBlendTextures + numLayersInThisPass))));

                    // Make sure the pass index is fed to the permutation handler, because blendmap components may be different
                    p->mShaderProperties.setProperty ("pass_index", sh::makeProperty(new sh::IntValue(layerOffset)));

                    assert ((int)p->mTexUnits.size() == OGRE_MAX_TEXTURE_LAYERS - remainingTextureUnits);

                    layerOffset += numLayersInThisPass;
                }
            }
        }
#endif
        return Ogre::MaterialManager::getSingleton().getByName(name.str());
    }