예제 #1
0
/**
 * Destroy / unload the memory of a material
 * @param	mat		MaterialName
 */
void GUIHelper::destroyMaterial(const Ogre::String &matName)
{
	Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(matName);
	if(mat.isNull()) return;

	Ogre::Material::TechniqueIterator tit = mat->getTechniqueIterator();
	while(tit.hasMoreElements()){
		Ogre::Technique *t = tit.peekNext();
		ASSERT(t);
		Ogre::Technique::PassIterator pit = t->getPassIterator();
		while(pit.hasMoreElements()){
			Ogre::Pass *pass = pit.peekNext();
			ASSERT(pass);
			Ogre::Pass::TextureUnitStateIterator tuit =
					pass->getTextureUnitStateIterator();

			while(tuit.hasMoreElements()){
				Ogre::TextureUnitState *tus = tuit.peekNext();
				ASSERT(tus);
				const Ogre::String &textName = tus->getTextureName();
				Ogre::TextureManager::getSingleton().unload(textName);
				Ogre::TextureManager::getSingleton().remove(textName);

				tuit.moveNext();
			}
			pit.moveNext();
		}

		tit.moveNext();
	}

	Ogre::MaterialManager::getSingleton().unload(matName);
	Ogre::MaterialManager::getSingleton().remove(matName);
}
예제 #2
0
 void ReplaceTextureOnMaterial(Ogre::MaterialPtr material, const std::string& original_name, const std::string& texture_name)
 {
     if (material.isNull())
         return;
     
     Ogre::TextureManager &tm = Ogre::TextureManager::getSingleton();
     Ogre::TexturePtr tex = tm.getByName(texture_name);
     
     Ogre::Material::TechniqueIterator iter = material->getTechniqueIterator();
     while(iter.hasMoreElements())
     {
         Ogre::Technique *tech = iter.getNext();
         assert(tech);
         Ogre::Technique::PassIterator passIter = tech->getPassIterator();
         while(passIter.hasMoreElements())
         {
             Ogre::Pass *pass = passIter.getNext();
             
             Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator();
             
             while(texIter.hasMoreElements())
             {
                 Ogre::TextureUnitState *texUnit = texIter.getNext();
                 if (texUnit->getTextureName() == original_name)
                 {
                     if (tex.get())
                         texUnit->setTextureName(texture_name);
                     else
                         texUnit->setTextureName("TextureMissing.png");
                 }
             }
         }
     }
 }
예제 #3
0
GBufferSchemeHandler::PassProperties GBufferSchemeHandler::inspectPass(
	Ogre::Pass* pass, unsigned short lodIndex, const Ogre::Renderable* rend)
{
	PassProperties props;
	
	//TODO : Use renderable to indicate whether this has skinning.
	//Probably use same const cast that renderSingleObject uses.
	if (pass->hasVertexProgram())
	{
		props.isSkinned = pass->getVertexProgram()->isSkeletalAnimationIncluded();
	}
	else 
	{
		props.isSkinned = false;
	}

	for (unsigned short i=0; i<pass->getNumTextureUnitStates(); i++) 
	{
		Ogre::TextureUnitState* tus = pass->getTextureUnitState(i);
		Ogre::String texName = tus->getTextureName();
		if (!checkNormalMap(tus, props))
		{
			props.regularTextures.push_back(tus);
		}
		if (tus->getEffects().size() > 0)
		{
			props.isDeferred = false;
		}
		
	}

    if (pass->getDiffuse() != Ogre::ColourValue::White)
    {
        props.hasDiffuseColour = true;
    }

    //Check transparency
    if (pass->getDestBlendFactor() != Ogre::SBF_ZERO)
    {
        //TODO : Better ways to do this
        props.isDeferred = false;
    }
	return props;
}
예제 #4
0
 void GetTextureNamesFromMaterial(Ogre::MaterialPtr material, StringVector& textures)
 {
     textures.clear();
     if (material.isNull())
         return;
     
     // Use a set internally to avoid duplicates
     std::set<std::string> textures_set;
     
     Ogre::Material::TechniqueIterator iter = material->getTechniqueIterator();
     while(iter.hasMoreElements())
     {
         Ogre::Technique *tech = iter.getNext();
         assert(tech);
         Ogre::Technique::PassIterator passIter = tech->getPassIterator();
         while(passIter.hasMoreElements())
         {
             Ogre::Pass *pass = passIter.getNext();
             
             Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator();
             
             while(texIter.hasMoreElements())
             {
                 Ogre::TextureUnitState *texUnit = texIter.getNext();
                 const std::string& texname = texUnit->getTextureName();
                 
                 if (!texname.empty())
                     textures_set.insert(texname);
             }
         }
     }
     
     std::set<std::string>::iterator i = textures_set.begin();
     
     while (i != textures_set.end())
     {
         textures.push_back(*i);
         ++i;
     }
 }
// unload all about this mesh. The mesh itself and the textures.
// BETWEEN FRAME OPERATION
void VisCalcFrustDist::unloadTheMesh(Ogre::MeshPtr meshP) {
	if (m_shouldCullTextures) {
		Ogre::Mesh::SubMeshIterator smi = meshP->getSubMeshIterator();
		while (smi.hasMoreElements()) {
			Ogre::SubMesh* oneSubMesh = smi.getNext();
			Ogre::String subMeshMaterialName = oneSubMesh->getMaterialName();
			Ogre::MaterialPtr subMeshMaterial = (Ogre::MaterialPtr)Ogre::MaterialManager::getSingleton().getByName(subMeshMaterialName);
			if (!subMeshMaterial.isNull()) {
				Ogre::Material::TechniqueIterator techIter = subMeshMaterial->getTechniqueIterator();
				while (techIter.hasMoreElements()) {
					Ogre::Technique* oneTech = techIter.getNext();
					Ogre::Technique::PassIterator passIter = oneTech->getPassIterator();
					while (passIter.hasMoreElements()) {
						Ogre::Pass* onePass = passIter.getNext();
						Ogre::Pass::TextureUnitStateIterator tusIter = onePass->getTextureUnitStateIterator();
						while (tusIter.hasMoreElements()) {
							Ogre::TextureUnitState* oneTus = tusIter.getNext();
							Ogre::String texName = oneTus->getTextureName();
							Ogre::TexturePtr texP = (Ogre::TexturePtr)Ogre::TextureManager::getSingleton().getByName(texName);
							if (!texP.isNull()) {
								// if (texP.useCount() <= 1) {
									texP->unload();
									LG::IncStat(LG::StatCullTexturesUnloaded);
									// LG::Log("unloadTheMesh: unloading texture %s", texName.c_str());
								// }
							}
						}
					}
				}
			}
		}
	}
	if (m_shouldCullMeshes) {
		LG::OLMeshTracker::Instance()->MakeUnLoaded(meshP->getName(), Ogre::String(), NULL);
		LG::IncStat(LG::StatCullMeshesUnloaded);
		// LG::Log("unloadTheMesh: unloading mesh %s", mshName.c_str());
	}
}
//-----------------------------------------------------------------------
void RTShaderSRSSegmentedLights::updateGpuProgramsParams(Renderable* rend, Pass* pass, const AutoParamDataSource* source, 
    const LightList* pLightList)
{
    if ((mLightParamsList.empty()) && (!mUseSegmentedLightTexture))
        return;

    const Matrix4& matWorld = source->getWorldMatrix();
    Light::LightTypes curLightType = Light::LT_DIRECTIONAL; 
    unsigned int curSearchLightIndex = 0;

    //update spot strength
    float spotIntensity = 1;
    
    // Update per light parameters.
    for (unsigned int i=0; i < mLightParamsList.size(); ++i)
    {
        const LightParams& curParams = mLightParamsList[i];

        if (curLightType != curParams.mType)
        {
            curLightType = curParams.mType;
            curSearchLightIndex = 0;
        }

        Light*      srcLight = NULL;
        Vector4     vParameter;
        ColourValue colour;

        // Search a matching light from the current sorted lights of the given renderable.
        for (unsigned int j = curSearchLightIndex; j < pLightList->size(); ++j)
        {
            if (pLightList->at(j)->getType() == curLightType)
            {               
                srcLight = pLightList->at(j);
                curSearchLightIndex = j + 1;
                break;
            }           
        }

        // No matching light found -> use a blank dummy light for parameter update.
        if (srcLight == NULL)
        {                       
            srcLight = &msBlankLight;
        }


        switch (curParams.mType)
        {
        case Light::LT_DIRECTIONAL:

            // Update light direction.
            vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true));
            curParams.mDirection->setGpuParameter(vParameter.ptr(),3,1);
            break;

        case Light::LT_POINT:

            // Update light position.
            vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true));
            curParams.mPosition->setGpuParameter(vParameter.ptr(),3,1);

            // Update light attenuation parameters.
            curParams.mSpotParams->setGpuParameter(Ogre::Vector3(1 / srcLight->getAttenuationRange(),0,0));
            break;

        case Light::LT_SPOTLIGHT:
            {                       
                Ogre::Vector3 vec3;
                Ogre::Matrix3 matWorldIT;


                // Update light position.
                vParameter = matWorld.transformAffine(srcLight->getAs4DVector(true));
                curParams.mPosition->setGpuParameter(vParameter.ptr(),3,1);


                // Update light direction.
                source->getInverseTransposeWorldMatrix().extract3x3Matrix(matWorldIT);
                vec3 = matWorldIT * srcLight->getDerivedDirection();
                vec3.normalise();

                vParameter.x = -vec3.x;
                vParameter.y = -vec3.y;
                vParameter.z = -vec3.z;
                vParameter.w = 0.0;
                curParams.mDirection->setGpuParameter(vParameter.ptr(),3,1);

                // Update spotlight parameters.
                Real phi   = Math::Cos(srcLight->getSpotlightOuterAngle().valueRadians() * 0.5f);
                Real theta = Math::Cos(srcLight->getSpotlightInnerAngle().valueRadians() * 0.5f);
                
                vec3.x = 1 / srcLight->getAttenuationRange();
                vec3.y = phi;
                vec3.z = 1 / (theta - phi);

                curParams.mSpotParams->setGpuParameter(vec3);
            }
            break;
        }

        float lightIntensity = 1;
        if (curParams.mType == Light::LT_SPOTLIGHT)
        {
            lightIntensity = spotIntensity;
        }

        // Update diffuse colour.
        colour = srcLight->getDiffuseColour() * lightIntensity;
        if ((mTrackVertexColourType & TVC_DIFFUSE) == 0)
        {
            colour = colour * pass->getDiffuse();
        }
        curParams.mDiffuseColour->setGpuParameter(colour.ptr(),3,1);    

        // Update specular colour if need to.
        if  ((mSpecularEnable) && (curParams.mType == Light::LT_DIRECTIONAL))
        {
            // Update diffuse colour.
            colour = srcLight->getSpecularColour() * lightIntensity;
            if ((mTrackVertexColourType & TVC_SPECULAR) == 0)
            {
                colour = colour * pass->getSpecular();
            }
            curParams.mSpecularColour->setGpuParameter(colour.ptr(),3,1);       
        }                                                                           
    }

    if (mUseSegmentedLightTexture)
    {
        unsigned int indexStart = 0, indexEnd = 0;
        Ogre::Vector4 lightBounds; 
        SegmentedDynamicLightManager::getSingleton().getLightListRange(rend, lightBounds, indexStart, indexEnd);
        mPSLightTextureIndexLimit->setGpuParameter(Ogre::Vector2((Ogre::Real)indexStart, (Ogre::Real)indexEnd));
        mPSLightTextureLightBounds->setGpuParameter(lightBounds);

        Ogre::TextureUnitState* pLightTexture = pass->getTextureUnitState(mLightSamplerIndex);
        const Ogre::String& textureName = SegmentedDynamicLightManager::getSingleton().getSDLTextureName();
        if (textureName != pLightTexture->getTextureName())
        {
            pLightTexture->setTextureName(textureName, Ogre::TEX_TYPE_2D);
        }
    }
}
예제 #7
0
	//-----------------------------------------------------------------------
	void ParticleRenderer::_createSoftMaterial(void)
	{
		Ogre::String newMaterialName = SOFT_PREFIX + mParentTechnique->getMaterialName();
		if (!Ogre::MaterialManager::getSingletonPtr()->getByName(newMaterialName).isNull())
		{
			mParentTechnique->setMaterialName(newMaterialName);
			return;
		}

		// Create a new material for soft particles
		if (mUseSoftParticles && mNotifiedDepthMap)
		{
			// Create Vertex program
			Ogre::String softVertexName = "ParticleUniverse_SoftVP"; // Use ParticleUniverse_ to avoid name conflicts.
			Ogre::HighLevelGpuProgramPtr vertexProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram( 
			softVertexName,
			Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
			"hlsl",
			Ogre::GPT_VERTEX_PROGRAM);
			vertexProgram->setSourceFile("pu_soft_sm20.hlsl");
			vertexProgram->setParameter("target", "vs_2_0");
			vertexProgram->setParameter("entry_point", "mainVP"); // Must be same name as in pu_soft_sm20.hlsl
			vertexProgram->load();

			Ogre::String softFragmentName = "ParticleUniverse_SoftFP"; // Use ParticleUniverse_ to avoid name conflicts.
			Ogre::HighLevelGpuProgramPtr fragmentProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram( 
				softFragmentName,
				Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
				"hlsl",
				Ogre::GPT_FRAGMENT_PROGRAM);
			fragmentProgram->setSourceFile("pu_soft_sm20.hlsl");
			fragmentProgram->setParameter("target", "ps_2_0");
			fragmentProgram->setParameter("entry_point", "mainFP"); // Must be same name as in pu_soft_sm20.hlsl
			fragmentProgram->load();

			Ogre::String resourceGroupName = mParentTechnique->getParentSystem() ? 
				mParentTechnique->getParentSystem()->getResourceGroupName() : 
				Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME;

			// Create material with depth texture
			Ogre::MaterialPtr newMaterial = Ogre::MaterialManager::getSingleton().getByName(newMaterialName);
			if (!newMaterial.getPointer())
			{
				newMaterial = Ogre::MaterialManager::getSingleton().create(newMaterialName, resourceGroupName);
				Ogre::Pass* newPass = newMaterial->getTechnique(0)->getPass(0);
				newPass->setDepthCheckEnabled(true);
				newPass->setDepthWriteEnabled(false);
				newPass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
				newPass->createTextureUnitState(ParticleSystemManager::getSingleton().getDepthTextureName());

				// Get the first texture from the old material (assume it has at least 1 technique and one pass)
				Ogre::Pass* oldPass = mParentTechnique->getMaterial()->getBestTechnique()->getPass(0);
				newPass->setLightingEnabled(oldPass->getLightingEnabled());
				if (oldPass->getNumTextureUnitStates() > 0)
				{
					Ogre::TextureUnitState* oldTextureUnitState = oldPass->getTextureUnitState(0);
					newPass->createTextureUnitState(oldTextureUnitState->getTextureName());
				}

				// Set the vertex and fragment parameters
				newPass->setVertexProgram(softVertexName);
				newPass->setFragmentProgram(softFragmentName);
				Ogre::GpuProgramParametersSharedPtr vertexParams = newPass->getVertexProgramParameters();
				vertexParams->setNamedAutoConstant("worldViewProj", Ogre::GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
				vertexParams->setNamedAutoConstant("depthRange", Ogre::GpuProgramParameters::ACT_SCENE_DEPTH_RANGE);

				// Depth scale must be the same as used in creation of the depth map
				vertexParams->setNamedConstant("depthScale", ParticleSystemManager::getSingleton().getDepthScale());

				Ogre::GpuProgramParametersSharedPtr fragmentParams = newPass->getFragmentProgramParameters();
				fragmentParams->setNamedConstant("contrastPower", mSoftParticlesContrastPower);
				fragmentParams->setNamedConstant("scale", mSoftParticlesScale);
				fragmentParams->setNamedConstant("delta", mSoftParticlesDelta);
			}

			// Set the new material
			mParentTechnique->setMaterialName(newMaterialName);
		}
	}
예제 #8
0
bool OgreMaterialResource::SetData(Foundation::AssetPtr source)
{
    // Remove old material if any
    RemoveMaterial();
    references_.clear();
    original_textures_.clear();

    Ogre::MaterialManager& matmgr = Ogre::MaterialManager::getSingleton();

    OgreRenderingModule::LogDebug("Parsing material " + source->GetId());

    if (!source)
    {
        OgreRenderingModule::LogError("Null source asset data pointer");
        return false;
    }
    if (!source->GetSize())
    {
        OgreRenderingModule::LogError("Zero sized material asset");
        return false;
    }

    Ogre::DataStreamPtr data = Ogre::DataStreamPtr(new Ogre::MemoryDataStream(const_cast<u8 *>(source->GetData()), source->GetSize()));

    static int tempname_count = 0;
    tempname_count++;
    std::string tempname = "TempMat" + ToString<int>(tempname_count);

    try
    {
        int num_materials = 0;
        int brace_level = 0;
        bool skip_until_next = false;
        int skip_brace_level = 0;
        // Parsed/modified material script
        std::ostringstream output;


        while (!data->eof())
        {
            Ogre::String line = data->getLine();

            // Skip empty lines & comments
            if ((line.length()) && (line.substr(0, 2) != "//"))
            {
                // Process opening/closing braces
                if (!ResourceHandler::ProcessBraces(line, brace_level))
                {
                    // If not a brace and on level 0, it should be a new material; replace name
                    if ((brace_level == 0) && (line.substr(0, 8) == "material"))
                    {
                        if (num_materials == 0)
                        {
                            line = "material " + tempname;
                            ++num_materials;
                        }
                        else
                        {
                            OgreRenderingModule::LogWarning("More than one material defined in material asset " + source->GetId() + " - only first one supported");
                            break;
                        }
                    }
                    else
                    {
                        // Check for textures
                        if ((line.substr(0, 8) == "texture ") && (line.length() > 8))
                        {
                            std::string tex_name = line.substr(8);
                            // Note: we assume all texture references are asset based. ResourceHandler checks later whether this is true,
                            // before requesting the reference
                            references_.push_back(Foundation::ResourceReference(tex_name, OgreTextureResource::GetTypeStatic()));
                            original_textures_.push_back(tex_name);
                            // Replace any / with \ in the material, then change the texture names back later, so that Ogre does not go nuts
                            ReplaceCharInplace(line, '/', '\\');
                            ReplaceCharInplace(line, ':', '@');
                        }
                    }

                    // Write line to the modified copy
                    if (!skip_until_next)
                        output << line << std::endl;
                }
                else
                {
                    // Write line to the modified copy
                    if (!skip_until_next)
                        output << line << std::endl;
                    if (brace_level <= skip_brace_level)
                        skip_until_next = false;
                }
            }
        }

        std::string output_str = output.str();
        Ogre::DataStreamPtr modified_data = Ogre::DataStreamPtr(new Ogre::MemoryDataStream((u8 *)(&output_str[0]), output_str.size()));

        matmgr.parseScript(modified_data, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        Ogre::MaterialPtr tempmat;
        tempmat = matmgr.getByName(tempname);
        if (tempmat.isNull())
        {
            OgreRenderingModule::LogWarning(std::string("Failed to create an Ogre material from material asset ") +
                                            source->GetId());

            return false;
        }
        if(!tempmat->getNumTechniques())
        {
            OgreRenderingModule::LogWarning("Failed to create an Ogre material from material asset "  +
                                            source->GetId());
            return false;
        }

        ogre_material_ = tempmat->clone(id_);
        tempmat.setNull();
        matmgr.remove(tempname);
        if (ogre_material_.isNull())
        {
            OgreRenderingModule::LogWarning("Failed to create an Ogre material from material asset "  +
                                            source->GetId());
            return false;
        }

        // Now go through all the texturenames and restore \ back to / and @ to :
        Ogre::Material::TechniqueIterator iter = ogre_material_->getTechniqueIterator();
        while (iter.hasMoreElements())
        {
            Ogre::Technique *tech = iter.getNext();
            Ogre::Technique::PassIterator passIter = tech->getPassIterator();
            while (passIter.hasMoreElements())
            {
                Ogre::Pass *pass = passIter.getNext();
                Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator();
                while (texIter.hasMoreElements())
                {
                    Ogre::TextureUnitState *texUnit = texIter.getNext();
                    std::string texname = texUnit->getTextureName();
                    if (texname.find('\\') != std::string::npos)
                    {
                        ReplaceCharInplace(texname, '\\', '/');
                        ReplaceCharInplace(texname, '@', ':');
                        texUnit->setTextureName(texname);
                    }
                }
            }
        }

        //workaround: if receives shadows, check the amount of shadowmaps. If only 1 specified, add 2 more to support 3 shadowmaps
        if(ogre_material_->getReceiveShadows() && shadowquality_ == Shadows_High && ogre_material_->getNumTechniques() > 0)
        {
            Ogre::Technique *tech = ogre_material_->getTechnique(0);
            if(tech)
            {
                Ogre::Technique::PassIterator passiterator = tech->getPassIterator();
                while(passiterator.hasMoreElements())
                {
                    Ogre::Pass* pass = passiterator.getNext();
                    Ogre::Pass::TextureUnitStateIterator texiterator = pass->getTextureUnitStateIterator();
                    int shadowmaps = 0;
                    while(texiterator.hasMoreElements())
                    {
                        Ogre::TextureUnitState* state = texiterator.getNext();
                        if(state->getContentType() == Ogre::TextureUnitState::CONTENT_SHADOW)
                        {
                            shadowmaps++;
                        }
                    }
                    if(shadowmaps>0 && shadowmaps<3)
                    {
                        Ogre::TextureUnitState* sm2 = pass->createTextureUnitState();
                        sm2->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW);

                        Ogre::TextureUnitState* sm3 = pass->createTextureUnitState();
                        sm3->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW);
                    }
                }
            }

        }

    } catch (Ogre::Exception &e)
    {
        OgreRenderingModule::LogWarning(e.what());
        OgreRenderingModule::LogWarning("Failed to parse Ogre material " + source->GetId() + ".");
        try
        {
            if (!matmgr.getByName(tempname).isNull())
                Ogre::MaterialManager::getSingleton().remove(tempname);
        }
        catch (...) {}

        return false;
    }
    return true;
}