/** * 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); }
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"); } } } } }
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; }
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); } } }
//----------------------------------------------------------------------- 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); } }
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; }