Modifying texture on existing material Topic is solved

Problems building or running the engine, queries about how to use features etc.
slapin
Bronze Sponsor
Bronze Sponsor
Posts: 339
Joined: Fri May 23, 2025 5:04 pm
x 24

Modifying texture on existing material

Post by slapin »

Hi, all!
I use ogre-procedural and generate textures there. However when I destroy and create texture again the texture is not updated in the materials.
I need to fully reload application to update the texture in the materials however the texture itself has updated properly (checked by saving to file).
So the question is - how to force texture update in materials without texture name change, as the texture is in memory only?
The update is within editor and rare event. The texture is not dynamic.

rpgplayerrobin
Bugbear
Posts: 803
Joined: Wed Mar 18, 2009 3:03 am
x 462

Re: Modifying texture on existing material

Post by rpgplayerrobin »

If I were you, I would just loop through all materials using it currently, add them to a list, create the new texture, and then apply it to the materials:

Code: Select all

std::string tmpTextureName = !!!;

// Fetch all materials using the texture name
std::vector<TextureUnitState> tmpTextureUnitStates;
ResourceManager::ResourceMapIterator tmpResourceIterator = MaterialManager::getSingleton().getResourceIterator();
while (tmpResourceIterator.hasMoreElements())
{
	ResourcePtr tmpResourcePtr = tmpResourceIterator.getNext();

const Ogre::String& tmpResourceType = tmpResourcePtr->getCreator()->getResourceType();
if (tmpResourceType == "Material")
{
	MaterialPtr tmpMaterialPtr = Ogre::static_pointer_cast<Material>(tmpResourcePtr);
	if (tmpMaterialPtr)
	{
		for (unsigned short i = 0; i < tmpMaterialPtr->getNumTechniques(); i++)
		{
			Technique* tmpTechnique = tmpMaterialPtr->getTechnique(i);
			for (unsigned short j = 0; j < tmpTechnique->getNumPasses(); j++)
			{
				Pass* tmpPass = tmpTechnique->getPass(j);
				for (unsigned short n = 0; n < tmpPass->getNumTextureUnitStates(); n++)
				{
					TextureUnitState* tmpTextureUnitState = tmpPass->getTextureUnitState(n);
					if (tmpTextureUnitState->getTextureName() == tmpTextureName)
					{
						tmpTextureUnitStates.push_back(tmpTextureUnitState);

						// Also make sure to not use the texture anymore, so that it can be correctly destroyed if needed
						tmpTextureUnitState->SetTextureName("white.png"); !!! Make sure this texture exists somewhere in your application
					}
				}
			}
		}
	}
}
}

// Create your new texture
!!!

// Update the texture name if needed
tmpTextureName = !!!;

// Set the new texture to all materials again
for(size_t i = 0; i < tmpTextureUnitStates.size(); i++)
{
	TextureUnitState* tmpTextureUnitState = tmpTextureUnitStates[i];
	tmpTextureUnitState->SetTextureName(tmpTextureName);
}
slapin
Bronze Sponsor
Bronze Sponsor
Posts: 339
Joined: Fri May 23, 2025 5:04 pm
x 24

Re: Modifying texture on existing material

Post by slapin »

But can I do it without renaming? I have TexturePtr though... The material is only one at the moment...

paroj
OGRE Team Member
OGRE Team Member
Posts: 2274
Joined: Sun Mar 30, 2014 2:51 pm
x 1239

Re: Modifying texture on existing material

Post by paroj »

you can blit from the new to the old texture:
https://ogrecave.github.io/ogre/api/lat ... f64bb1cb17

slapin
Bronze Sponsor
Bronze Sponsor
Posts: 339
Joined: Fri May 23, 2025 5:04 pm
x 24

Re: Modifying texture on existing material

Post by slapin »

I found another way.

Code: Select all

        Ogre::String textureName =
            "proceduralTextureTown" +
            Ogre::StringConverter::toString(e.id());
        Ogre::TexturePtr townTexture =
            Ogre::TextureManager::getSingleton().getByName(
                textureName);
        if (townTexture) {
            Ogre::TexturePtr newTownTexture =
                colorAtlas.createTexture(textureName + "_copy");
            newTownTexture->copyToTexture(townTexture);
            Ogre::TextureManager::getSingleton().remove(
                newTownTexture);
        } else
            Ogre::TexturePtr townTexture =
                colorAtlas.createTexture(textureName);

And this works perfectly well, thanks!