Пример #1
0
	void UiManager::resizeTexture(const QSize &aSize, const Ogre::MaterialPtr &aMaterial, const Ogre::TexturePtr &aTexture)
	{
		assert(!aMaterial.isNull());
		assert(!aTexture.isNull());
		
		// get the smallest power of two dimension that is at least as large as the new UI size
		Ogre::uint newTexWidth = nextHigherPowerOfTwo(aSize.width());
		Ogre::uint newTexHeight = nextHigherPowerOfTwo(aSize.height());
	
		if (!aTexture.isNull())
		{
			std::string txtrName = aTexture->getName();
			
			// remove the old texture
			aTexture->unload();
			aMaterial->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
			Ogre::TextureManager::getSingleton().remove(aTexture->getHandle());
	
			Ogre::TexturePtr newTxtr = Ogre::TextureManager::getSingleton().createManual(
					txtrName, "General", Ogre::TEX_TYPE_2D, newTexWidth, newTexHeight, 0, Ogre::PF_A8R8G8B8,
					Ogre::TU_DYNAMIC_WRITE_ONLY);
	
			// add the new texture
			Ogre::TextureUnitState* txtrUstate = aMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(txtrName);
	
			// adjust it to stay aligned and scaled to the window
			Ogre::Real txtrUScale = (Ogre::Real)newTexWidth / aSize.width();
			Ogre::Real txtrVScale = (Ogre::Real)newTexHeight / aSize.height();
			txtrUstate->setTextureScale(txtrUScale, txtrVScale);
			txtrUstate->setTextureScroll((1 / txtrUScale) / 2 - 0.5, (1 / txtrVScale) / 2 - 0.5);
		}
	}
Пример #2
0
bool Simple::compileMaterial(Ogre::MaterialPtr material, std::set<std::string>& managedTextures) const
{
	material->removeAllTechniques();
	Ogre::Technique* technique = material->createTechnique();
	if (!mTerrainPageSurfaces.empty()) {
		//First add a base pass
		auto surfaceLayer = mTerrainPageSurfaces.begin()->second;
		Ogre::Pass* pass = technique->createPass();
		pass->setLightingEnabled(false);
		Ogre::TextureUnitState * textureUnitState = pass->createTextureUnitState();
		textureUnitState->setTextureScale(1.0f / surfaceLayer->getScale(), 1.0f / surfaceLayer->getScale());
		textureUnitState->setTextureName(surfaceLayer->getDiffuseTextureName());
		textureUnitState->setTextureCoordSet(0);

		for (auto& layer : mLayers) {
			addPassToTechnique(*mGeometry, technique, layer, managedTextures);
		}
	}
	if (mTerrainPageShadow) {
		addShadow(technique, mTerrainPageShadow, material, managedTextures);
	}

//	addLightingPass(technique, managedTextures);

	material->load();
	if (material->getNumSupportedTechniques() == 0) {
		S_LOG_WARNING("The material '" << material->getName() << "' has no supported techniques. The reason for this is: \n" << material->getUnsupportedTechniquesExplanation());
		return false;
	}
	return true;
}
Пример #3
0
bool Simple::compileMaterial(Ogre::MaterialPtr material)
{
	material->removeAllTechniques();
	Ogre::Technique* technique = material->createTechnique();
	for (SurfaceLayerStore::const_iterator I = mTerrainPageSurfaces.begin(); I != mTerrainPageSurfaces.end(); ++I) {
		const TerrainPageSurfaceLayer* surfaceLayer = I->second;
		if (I == mTerrainPageSurfaces.begin()) {
			Ogre::Pass* pass = technique->createPass();
			pass->setLightingEnabled(false);
			//add the first layer of the terrain, no alpha or anything
			Ogre::TextureUnitState * textureUnitState = pass->createTextureUnitState();
			textureUnitState->setTextureScale(1.0f / surfaceLayer->getScale(), 1.0f / surfaceLayer->getScale());
			textureUnitState->setTextureName(surfaceLayer->getDiffuseTextureName());
			textureUnitState->setTextureCoordSet(0);
		} else {
			if (surfaceLayer->intersects(*mGeometry)) {
				addPassToTechnique(*mGeometry, technique, surfaceLayer);
			}
		}
	}
	if (mTerrainPageShadow) {
		addShadow(technique, mTerrainPageShadow, material);
	}
	material->load();
	if (material->getNumSupportedTechniques() == 0) {
		S_LOG_WARNING("The material '" << material->getName() << "' has no supported techniques. The reason for this is: \n" << material->getUnsupportedTechniquesExplanation());
		return false;
	}
	return true;
}
Пример #4
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
}
Пример #5
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());
    }
Пример #6
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;

}