Example #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);
}
Example #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");
                 }
             }
         }
     }
 }
Example #3
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());
	}
}
Example #5
0
bool OgreMaterialProperties::CreateProperties()
{
    Ogre::MaterialPtr matPtr = material_->GetMaterial();
    if (matPtr.isNull())
        return false;

    // Material
    Ogre::Material::TechniqueIterator tIter = matPtr->getTechniqueIterator();
    while(tIter.hasMoreElements())
    {
        // Technique
        Ogre::Technique *tech = tIter.getNext();
        Ogre::Technique::PassIterator pIter = tech->getPassIterator();
        while(pIter.hasMoreElements())
        {
            // Pass
            Ogre::Pass *pass = pIter.getNext();
            if (!pass)
                continue;

            if(pass->hasVertexProgram())
            {
                // Vertex program
                const Ogre::GpuProgramPtr &verProg = pass->getVertexProgram();
                if (!verProg.isNull())
                {
                    Ogre::GpuProgramParametersSharedPtr verPtr = pass->getVertexProgramParameters();
                    if (verPtr->hasNamedParameters())
                    {
                        // Named parameters (constants)
                        Ogre::GpuConstantDefinitionIterator mapIter = verPtr->getConstantDefinitionIterator();
                        while(mapIter.hasMoreElements())
                        {
                            QString paramName = mapIter.peekNextKey().c_str();
                            const Ogre::GpuConstantDefinition &paramDef  = mapIter.getNext();

                            // Filter names that end with '[0]'
                            int found = paramName.indexOf("[0]");
                            if (found != -1)
                                continue;

                            // Ignore auto parameters
                            bool is_auto_param = false;
                            Ogre::GpuProgramParameters::AutoConstantIterator autoConstIter = verPtr->getAutoConstantIterator();
                            while(autoConstIter.hasMoreElements())
                            {
                                Ogre::GpuProgramParameters::AutoConstantEntry autoConstEnt = autoConstIter.getNext();
                                if (autoConstEnt.physicalIndex == paramDef.physicalIndex)
                                {
                                    is_auto_param = true;
                                    break;
                                }
                            }

                            if (is_auto_param)
                                continue;

                            if (!paramDef.isFloat())
                                continue;

                            size_t count = paramDef.elementSize * paramDef.arraySize;
                            QVector<float> paramValue;
                            QVector<float>::iterator iter;
                            paramValue.resize(count);
                            verPtr->_readRawConstants(paramDef.physicalIndex, count, &*paramValue.begin());

                            QTextStream vector_string;
                            QString string;
                            vector_string.setString(&string, QIODevice::WriteOnly);

                            for(iter = paramValue.begin(); iter != paramValue.end(); ++iter)
                                vector_string << *iter << " ";

                            // Add QPROPERTY. Add to "VP" to the end of the parameter name in order to identify VP parameters.
                            QMap<QString, QVariant> typeValuePair;
                            typeValuePair[GpuConstantTypeToString(paramDef.constType)] = *vector_string.string();
                            setProperty(paramName.append(" VP").toLatin1(), QVariant(typeValuePair));
                        }
                    }
                }
            }

            if(pass->hasFragmentProgram())
            {
                // Fragment program
                const Ogre::GpuProgramPtr fragProg = pass->getFragmentProgram();
                if (!fragProg.isNull())
                {
                    Ogre::GpuProgramParametersSharedPtr fragPtr = pass->getFragmentProgramParameters();
                    if (!fragPtr.isNull())
                    {
                        if (fragPtr->hasNamedParameters())
                        {
                            // Named parameters (constants)
                            Ogre::GpuConstantDefinitionIterator mapIter = fragPtr->getConstantDefinitionIterator();
                            while(mapIter.hasMoreElements())
                            {
                                QString paramName = mapIter.peekNextKey().c_str();
                                const Ogre::GpuConstantDefinition &paramDef  = mapIter.getNext();

                                // Filter names that end with '[0]'
                                int found = paramName.indexOf("[0]");
                                if (found != -1)
                                    continue;

                                // Ignore auto parameters
                                bool is_auto_param = false;
                                Ogre::GpuProgramParameters::AutoConstantIterator autoConstIter = fragPtr->getAutoConstantIterator();
                                while(autoConstIter.hasMoreElements())
                                {
                                    Ogre::GpuProgramParameters::AutoConstantEntry autoConstEnt = autoConstIter.getNext();
                                    if (autoConstEnt.physicalIndex == paramDef.physicalIndex)
                                    {
                                        is_auto_param = true;
                                        break;
                                    }
                                }

                                if (is_auto_param)
                                    continue;

                                if (!paramDef.isFloat())
                                    continue;

                                size_t count = paramDef.elementSize * paramDef.arraySize;
                                QVector<float> paramValue;
                                QVector<float>::iterator iter;
                                paramValue.resize(count);

                                fragPtr->_readRawConstants(paramDef.physicalIndex, count, &*paramValue.begin());

                                QTextStream vector_string;
                                QString string;
                                vector_string.setString(&string, QIODevice::WriteOnly);

                                for(iter = paramValue.begin(); iter != paramValue.end(); ++iter)
                                    vector_string << *iter << " ";

                                // Add QPROPERTY. Add to " FP" to the end of the parameter name in order to identify FP parameters
                                TypeValuePair typeValuePair;
                                typeValuePair[GpuConstantTypeToString(paramDef.constType)] = *vector_string.string();
                                setProperty(paramName.append(" FP").toLatin1(), QVariant(typeValuePair));
                            }
                        }
                    }
                }
            }

            Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator();
            while(texIter.hasMoreElements())
            {
                // Texture units
                const Ogre::TextureUnitState *tu = texIter.getNext();
                
                // Don't insert tu's with empty texture names (i.e. shadowMap)
                // add to " TU" to the end of the parameter name in order to identify texture units.
                if(tu->getTextureName().size() > 0)
                {
                    QString tuName(tu->getName().c_str());

                    // Add QPROPERTY
                    TypeValuePair typeValuePair;
                    typeValuePair[TextureTypeToString(tu->getTextureType())] = tu->getTextureName().c_str();
                    setProperty(tuName.append(" TU").toLatin1(), typeValuePair);
                }
            }
        }
    }

    return true;
}
Example #6
0
Ogre::MaterialPtr OgreMaterialProperties::ToOgreMaterial()
{
    // Make clone from the original and uset that for creating the new material.
    Ogre::MaterialPtr matPtr = material_->GetMaterial();
    Ogre::MaterialPtr matPtrClone = matPtr->clone(objectName().toStdString() + "Clone");

    // Material
    if (!matPtrClone.isNull())
    {
        // Technique
        Ogre::Material::TechniqueIterator tIter = matPtrClone->getTechniqueIterator();
        while(tIter.hasMoreElements())
        {
            Ogre::Technique *tech = tIter.getNext();
            Ogre::Technique::PassIterator pIter = tech->getPassIterator();
            while(pIter.hasMoreElements())
            {
                // Pass
                Ogre::Pass *pass = pIter.getNext();
                if (!pass)
                    continue;

                if (pass->hasVertexProgram())
                {
                    // Vertex program
                    const Ogre::GpuProgramPtr &verProg = pass->getVertexProgram();
                    if (!verProg.isNull())
                    {
                        Ogre::GpuProgramParametersSharedPtr verPtr = pass->getVertexProgramParameters();
                        if (verPtr->hasNamedParameters())
                        {
                            // Named parameters (constants)
                            Ogre::GpuConstantDefinitionIterator mapIter = verPtr->getConstantDefinitionIterator();
                            int constNum = 0;
                            while(mapIter.hasMoreElements())
                            {
                                QString paramName(mapIter.peekNextKey().c_str());
                                const Ogre::GpuConstantDefinition &paramDef  = mapIter.getNext();

                                // Filter names that end with '[0]'
                                if (paramName.lastIndexOf("[0]") != -1)
                                    continue;

                                if (!paramDef.isFloat())
                                    continue;

                                size_t size = paramDef.elementSize * paramDef.arraySize;
                                QVector<float> newParamValue;
                                QVector<float>::iterator it;
                                newParamValue.resize(size);

                                // Find the corresponding property value.
                                QVariant val = property(paramName.append(" VP").toLatin1());
                                if (!val.isValid() || val.isNull())
                                    continue;

                                TypeValuePair typeValuePair = val.toMap();
                                QString newValueString(typeValuePair.begin().value().toByteArray());
                                newValueString.trimmed();

                                // fill the float vector with new values
                                it = newParamValue.begin();
                                int i = 0, j = 0;
                                bool ok = true;
                                while(j != -1 && ok)
                                {
                                    j = newValueString.indexOf(' ', i);
                                    QString newValue = newValueString.mid(i, j == -1 ? j : j - i);
                                    if (!newValue.isEmpty())
                                    {
                                        *it = newValue.toFloat(&ok);
                                        ++it;
                                    }
                                    i = j + 1;
                                }

                                // Set the new value.
                                ///\todo use the exact count rather than just 4 values if needed.
                                if (size == 16)
                                {
                                    Ogre::Matrix4 matrix(newParamValue[0], newParamValue[1], newParamValue[2], newParamValue[3],
                                        newParamValue[4], newParamValue[5], newParamValue[6], newParamValue[7],
                                        newParamValue[8], newParamValue[9], newParamValue[10], newParamValue[11],
                                        newParamValue[12], newParamValue[13], newParamValue[14], newParamValue[15]);

#if OGRE_VERSION_MINOR <= 6 && OGRE_VERSION_MAJOR <= 1
                                    verPtr->_writeRawConstant(paramDef.physicalIndex, matrix);
#else
                                    verPtr->_writeRawConstant(paramDef.physicalIndex, matrix, size);
#endif
                                }
                                else
                                {
                                    Ogre::Vector4 vector(newParamValue[0], newParamValue[1], newParamValue[2], newParamValue[3]);
                                    verPtr->_writeRawConstant(paramDef.physicalIndex, vector);
                                }
                            }
                        }
                    }
                }

                if (pass->hasFragmentProgram())
                {
                    // Fragment program
                    const Ogre::GpuProgramPtr &fragProg = pass->getFragmentProgram();
                    if (!fragProg.isNull())
                    {
                        Ogre::GpuProgramParametersSharedPtr fragPtr = pass->getFragmentProgramParameters();
                        if (!fragPtr.isNull())
                        {
                            if (fragPtr->hasNamedParameters())
                            {
                                // Named parameters (constants)
                                Ogre::GpuConstantDefinitionIterator mapIter = fragPtr->getConstantDefinitionIterator();
                                while(mapIter.hasMoreElements())
                                {
                                    QString paramName(mapIter.peekNextKey().c_str());
                                    const Ogre::GpuConstantDefinition &paramDef  = mapIter.getNext();

                                    // Filter names that end with '[0]'
                                    if (paramName.lastIndexOf("[0]") != -1)
                                        continue;

                                    if (!paramDef.isFloat())
                                        continue;

                                    size_t size = paramDef.elementSize * paramDef.arraySize;
                                    QVector<float> newParamValue;
                                    QVector<float>::iterator it;
                                    newParamValue.resize(size);

                                    // Find the corresponding property value.
                                    QVariant val = property(paramName.append(" FP").toLatin1());
                                    if (!val.isValid() || val.isNull())
                                        continue;

                                    TypeValuePair typeValuePair = val.toMap();
                                    QString newValueString(typeValuePair.begin().value().toByteArray());
                                    newValueString.trimmed();

                                    // Fill the float vector with new values.
                                    it = newParamValue.begin();
                                    int i = 0, j = 0;
                                    bool ok = true;
                                    while(j != -1 && ok)
                                    {
                                        j = newValueString.indexOf(' ', i);
                                        QString newValue = newValueString.mid(i, j == -1 ? j : j - i);
                                        if (!newValue.isEmpty())
                                        {
                                            *it = *it = newValue.toFloat(&ok);
                                            ++it;
                                        }
                                        i = j + 1;
                                    }

                                    // Set the new value.
                                    ///\todo use the exact count rather than just 4 values if needed.
                                    if (size == 16)
                                    {
                                        Ogre::Matrix4 matrix(newParamValue[0], newParamValue[1], newParamValue[2], newParamValue[3],
                                            newParamValue[4], newParamValue[5], newParamValue[6], newParamValue[7],
                                            newParamValue[8], newParamValue[9], newParamValue[10], newParamValue[11],
                                            newParamValue[12], newParamValue[13], newParamValue[14], newParamValue[15]);

#if OGRE_VERSION_MINOR <= 6 && OGRE_VERSION_MAJOR <= 1
                                    fragPtr->_writeRawConstant(paramDef.physicalIndex, matrix);
#else
                                    fragPtr->_writeRawConstant(paramDef.physicalIndex, matrix, size);
#endif
                                    }
                                    else
                                    {
                                        Ogre::Vector4 vector(newParamValue[0], newParamValue[1], newParamValue[2], newParamValue[3]);
                                        fragPtr->_writeRawConstant(paramDef.physicalIndex, vector);
                                    }
                                }
                            }
                        }
                    }
                }

                Ogre::Pass::TextureUnitStateIterator texIter = pass->getTextureUnitStateIterator();
                while(texIter.hasMoreElements())
                {
                    // Texture units
                    Ogre::TextureUnitState *tu = texIter.getNext();

                    // Replace the texture name (uuid) with the new one
                    QString tu_name(tu->getName().c_str());

                    QVariant val = property(tu_name.append(" TU").toLatin1());
                    if (!val.isValid() || val.isNull())
                        continue;

                    TypeValuePair typeValuePair = val.toMap();
                    QString newValueString(typeValuePair.begin().value().toByteArray());
                    newValueString.trimmed();

                    tu->setTextureName(newValueString.toStdString());
                    /*
                    //QString new_texture_name = iter->second;
                    RexUUID new_name(iter->second);
                    // If new texture is UUID-based one, make sure the corresponding RexOgreTexture gets created,
                    // because we may not be able to load it later if load fails now
                    if (RexUUID::IsValid(new_texture_name))
                    {
                        RexUUID imageID(new_texture_name);
                        if (!imageID.IsNull())
                        {
                            image* image = imageList.getImage(imageID);
                            if (image)
                            {
                                image->getOgreTexture();
                            }
                        }
                    }
                    //tu->setTextureName(iter->second);
                    */
                }
            }
        }

        return matPtrClone;
    }

    matPtrClone.setNull();
    return matPtrClone;
}
Example #7
0
bool ModelBackgroundLoader::poll(const TimeFrame& timeFrame)
{
#if OGRE_THREAD_SUPPORT
	if (mState == LS_UNINITIALIZED) {
		//Start to load the meshes
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (meshPtr.isNull() || !meshPtr->isPrepared()) {
				try {
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MeshManager::getSingleton().getResourceType(), (*I_subModels)->getMeshName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						addTicket(ticket);
					}
				} catch (const std::exception& ex) {
					S_LOG_FAILURE("Could not load the mesh " << (*I_subModels)->getMeshName() << " when loading model " << mModel.getName() << "." << ex);
					continue;
				}
			}
		}
		mState = LS_MESH_PREPARING;
		return poll(timeFrame);
	} else if (mState == LS_MESH_PREPARING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MESH_PREPARED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MESH_PREPARED) {
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (!meshPtr.isNull()) {
				if (!meshPtr->isLoaded()) {
#if OGRE_THREAD_SUPPORT == 1
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MeshManager::getSingleton().getResourceType(), meshPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						//						meshPtr->setBackgroundLoaded(true);
						addTicket(ticket);
					}
#else
					if (!timeFrame.isTimeLeft()) {
						return false;
					}
					try {
						meshPtr->load();
					} catch (const std::exception& ex) {
						S_LOG_FAILURE("Could not load the mesh " << meshPtr->getName() << " when loading model " << mModel.getName() << "." << ex);
						continue;
					}
#endif
				}
			}
		}
		mState = LS_MESH_LOADING;
		return poll(timeFrame);
	} else if (mState == LS_MESH_LOADING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MESH_LOADED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MESH_LOADED) {

		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			if (!meshPtr.isNull()) {
				if (meshPtr->isLoaded()) {
					Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator();
					while (subMeshI.hasMoreElements()) {
						Ogre::SubMesh* submesh(subMeshI.getNext());
						Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName()));
						if (materialPtr.isNull() || !materialPtr->isPrepared()) {
//							S_LOG_VERBOSE("Preparing material " << materialPtr->getName());
							Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(),submesh->getMaterialName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
							if (ticket) {
								addTicket(ticket);
							}
						}
					}
				}
			}
			for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) {
				if ((*I_parts)->getSubEntityDefinitions().size() > 0) {
					for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) {
						const std::string& materialName = (*I_subEntities)->getMaterialName();
						if (materialName != "") {
							Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName));
							if (materialPtr.isNull() || !materialPtr->isPrepared()) {
//								S_LOG_VERBOSE("Preparing material " << materialName);
								Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().prepare(Ogre::MaterialManager::getSingleton().getResourceType(), materialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
								if (ticket) {
									addTicket(ticket);
								}
							}
						}
					}
				}
			}
		}

		mState = LS_MATERIAL_PREPARING;
		return poll(timeFrame);
	} else if (mState == LS_MATERIAL_PREPARING) {
		if (areAllTicketsProcessed()) {
			mState = LS_MATERIAL_PREPARED;
			return poll(timeFrame);
		}
	} else if (mState == LS_MATERIAL_PREPARED) {
		for (SubModelDefinitionsStore::const_iterator I_subModels = mModel.getDefinition()->getSubModelDefinitions().begin(); I_subModels != mModel.getDefinition()->getSubModelDefinitions().end(); ++I_subModels) {
			Ogre::MeshPtr meshPtr = static_cast<Ogre::MeshPtr> (Ogre::MeshManager::getSingleton().getByName((*I_subModels)->getMeshName()));
			Ogre::Mesh::SubMeshIterator subMeshI = meshPtr->getSubMeshIterator();
			while (subMeshI.hasMoreElements()) {
				Ogre::SubMesh* submesh(subMeshI.getNext());
				Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(submesh->getMaterialName()));
				if (!materialPtr.isNull() && !materialPtr->isLoaded()) {

#if OGRE_THREAD_SUPPORT == 1
					Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
					if (ticket) {
						//						materialPtr->setBackgroundLoaded(true);
						addTicket(ticket);
					}
#else
					Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator();
					while (techIter.hasMoreElements()) {
						Ogre::Technique* tech = techIter.getNext();
						Ogre::Technique::PassIterator passIter = tech->getPassIterator();
						while (passIter.hasMoreElements()) {
							Ogre::Pass* pass = passIter.getNext();
							Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator();
							while (tusIter.hasMoreElements()) {
								Ogre::TextureUnitState* tus = tusIter.getNext();
								unsigned int frames = tus->getNumFrames();
								for (unsigned int i = 0; i < frames; ++i) {
									if (!timeFrame.isTimeLeft()) {
										return false;
									}
									//This will automatically load the texture.
//									S_LOG_VERBOSE("Loading texture " << tus->getTextureName());
									Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i);
								}
							}
						}
					}
					if (!timeFrame.isTimeLeft()) {
						return false;
					}
//					S_LOG_VERBOSE("Loading material " << materialPtr->getName());
					materialPtr->load();
#endif

				}
			}
			for (PartDefinitionsStore::const_iterator I_parts = (*I_subModels)->getPartDefinitions().begin(); I_parts != (*I_subModels)->getPartDefinitions().end(); ++I_parts) {
				if ((*I_parts)->getSubEntityDefinitions().size() > 0) {
					for (SubEntityDefinitionsStore::const_iterator I_subEntities = (*I_parts)->getSubEntityDefinitions().begin(); I_subEntities != (*I_parts)->getSubEntityDefinitions().end(); ++I_subEntities) {
						const std::string& materialName = (*I_subEntities)->getMaterialName();
						if (materialName != "") {
							Ogre::MaterialPtr materialPtr = static_cast<Ogre::MaterialPtr> (Ogre::MaterialManager::getSingleton().getByName(materialName));
							if (!materialPtr.isNull() && !materialPtr->isLoaded()) {
#if OGRE_THREAD_SUPPORT == 1
								Ogre::BackgroundProcessTicket ticket = Ogre::ResourceBackgroundQueue::getSingleton().load(Ogre::MaterialManager::getSingleton().getResourceType(), materialPtr->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, false, 0, 0, createListener());
								if (ticket) {
									addTicket(ticket);
								}
#else
								Ogre::Material::TechniqueIterator techIter = materialPtr->getSupportedTechniqueIterator();
								while (techIter.hasMoreElements()) {
									Ogre::Technique* tech = techIter.getNext();
									Ogre::Technique::PassIterator passIter = tech->getPassIterator();
									while (passIter.hasMoreElements()) {
										Ogre::Pass* pass = passIter.getNext();
										Ogre::Pass::TextureUnitStateIterator tusIter = pass->getTextureUnitStateIterator();
										while (tusIter.hasMoreElements()) {
											Ogre::TextureUnitState* tus = tusIter.getNext();
											unsigned int frames = tus->getNumFrames();
											for (unsigned int i = 0; i < frames; ++i) {
												if (!timeFrame.isTimeLeft()) {
													return false;
												}
												//This will automatically load the texture.
//												S_LOG_VERBOSE("Loading texture " << tus->getTextureName());
												Ogre::TexturePtr texturePtr = tus->_getTexturePtr(i);
											}
										}
									}
								}
								if (!timeFrame.isTimeLeft()) {
									return false;
								}
//								S_LOG_VERBOSE("Loading material " << materialPtr->getName());
								materialPtr->load();
#endif
							}
						}
					}
				}
			}
		}

		mState = LS_MATERIAL_LOADING;
		return poll(timeFrame);
	} else if (mState == LS_MATERIAL_LOADING) {
		if (areAllTicketsProcessed()) {
			mState = LS_DONE;
			return true;
		}

	} else {
		return true;
	}
	return false;
#else
	//If there's no threading support, just return here.
	return true;
#endif
}
    //-----------------------------------------------------------------------
    void TerrainLiquidObject::_prepareProjector(void)
    {
        if (mProjectorName.empty() || !mProjectorSize)
            return;

        Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(mMaterialName);
        if (material.isNull())
            return;

        bool hasProjector = false;
        {
            Ogre::Material::TechniqueIterator ti = material->getTechniqueIterator();
            while (ti.hasMoreElements())
            {
                Ogre::Technique* technique = ti.getNext();
                Ogre::Technique::PassIterator pi = technique->getPassIterator();
                while (pi.hasMoreElements())
                {
                    Ogre::Pass* pass = pi.getNext();
                    Ogre::Pass::TextureUnitStateIterator tusi = pass->getTextureUnitStateIterator();
                    while (tusi.hasMoreElements())
                    {
                        Ogre::TextureUnitState* tus = tusi.getNext();
                        if (Ogre::StringUtil::startsWith(tus->getName(), "Fairy/Projector", false))
                        {
                            hasProjector = true;
                        }
                    }
                }
            }
        }
        if (!hasProjector)
            return;

        ObjectPtr object = mSystem->getSceneInfo()->findObjectByName(mProjectorName);
        if (!object)
            return;

        Variant directionValue = object->getProperty("direction");
        if (directionValue.empty() || directionValue.type() != typeid(Ogre::Vector3))
            return;

        Ogre::Vector3 direction = VariantCast<Ogre::Vector3>(directionValue);
        direction.normalise();

       Ogre::String name = material->getName() + Ogre::StringConverter::toString((Ogre::ulong)this);

        mProjectionCamera = mTerrainLiquid->getParentSceneNode()->getCreator()->createCamera(name);
        mProjectionCamera->setAutoAspectRatio(false);
        mProjectionCamera->setAspectRatio(1.0f);
        mProjectionCamera->setFixedYawAxis(false);
        mProjectionCamera->setProjectionType(Ogre::PT_ORTHOGRAPHIC);
        mProjectionCamera->setFOVy(Ogre::Degree(90));
        mProjectionCamera->setDirection(-direction);
        mProjectionCamera->setNearClipDistance(mProjectorSize / 2);
        mProjectionCamera->setFarClipDistance(mProjectorSize + 5000.0f);

        mTerrainLiquid->setProjectionCamera(mProjectionCamera);

        mProjectionMaterial = material->clone(name);
        {
            Ogre::Material::TechniqueIterator ti = mProjectionMaterial->getTechniqueIterator();
            while (ti.hasMoreElements())
            {
                Ogre::Technique* technique = ti.getNext();
                Ogre::Technique::PassIterator pi = technique->getPassIterator();
                while (pi.hasMoreElements())
                {
                    Ogre::Pass* pass = pi.getNext();
                    Ogre::Pass::TextureUnitStateIterator tusi = pass->getTextureUnitStateIterator();
                    while (tusi.hasMoreElements())
                    {
                        Ogre::TextureUnitState* tus = tusi.getNext();
                        if (Ogre::StringUtil::startsWith(tus->getName(), "Fairy/Projector", false))
                        {
                            tus->setProjectiveTexturing(true, mProjectionCamera);
                        }
                    }
                }
            }
        }
        mProjectionMaterial->load();
    }
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;
}