Hi @dark_sylinc,
I would like to pre-load some necessary textures, at engine startup. E.g. for ParticleUniverse, because first time particle is played, it takes some time, the texture is shown and its sprite.
How is that possible?
Would be something like this possible:
Code: Select all
void Core::preLoadTextures(void)
{
std::vector<Ogre::String> filters = { "png", "jpg", "bmp", "tga", "gif", "tif", "dds" };
std::set<Ogre::String> textureNames;
Ogre::TextureGpuManager* textureManager = Ogre::Root::getSingleton().getRenderSystem()->getTextureGpuManager();
for (auto& resourceGroupName : this->resourceGroupNames)
{
if ("Vehicles" != resourceGroupName)
{
continue;
}
// Ogre::StringVector extensions = Ogre::Codec::getExtensions();
// for (Ogre::StringVector::iterator itExt = extensions.begin(); itExt != extensions.end(); ++itExt)
for (auto& filter : filters)
{
Ogre::StringVectorPtr names = Ogre::ResourceGroupManager::getSingletonPtr()->findResourceNames(resourceGroupName, "*." + filter/**itExt*/);
for (Ogre::StringVector::iterator itName = names->begin(); itName != names->end(); ++itName)
{
Ogre::String textureName = *itName;
// Idea was: If textures e.g. from vehicles are pre-loaded in simulation chaning a texturename at runtime is faster, but that was not the case :(
Ogre::Image2 image;
image.load(textureName, resourceGroupName);
Ogre::uint32 textureFlags = Ogre::TextureFlags::AutomaticBatching;
textureFlags &= ~Ogre::TextureFlags::AutomaticBatching;
textureFlags |= Ogre::TextureFlags::RenderToTexture;
textureFlags |= Ogre::TextureFlags::AllowAutomipmaps;
Ogre::uint32 filters = Ogre::TextureFilter::FilterTypes::TypeGenerateDefaultMipmaps;
// Really important: createOrRetrieveTexture when its created, its width/height is 0 etc. so the texture is just prepared
// it will be filled with correct data when setDataBlock is called
Ogre::TextureGpu* texture = textureManager->createOrRetrieveTexture(textureName,
Ogre::GpuPageOutStrategy::SaveToSystemRam, textureFlags, Ogre::TextureTypes::Type2D,
resourceGroupName, filters, 0u);
texture->setResolution(image.getWidth(), image.getHeight());
texture->setNumMipmaps(PixelFormatGpuUtils::getMaxMipmapCount(image.getWidth(), image.getHeight()));
// Check if its a valid texture
if (nullptr != texture)
{
// Really important: GpuResidency must be set to 'OnSystemRam', else cloning a datablock does not work!
if (texture->getResidencyStatus() != Ogre::GpuResidency::OnSystemRam)
{
try
{
texture->scheduleTransitionTo(Ogre::GpuResidency::Resident);
bool canUseSynchronousUpload = texture->getNextResidencyStatus() == Ogre::GpuResidency::Resident && texture->isDataReady();
if (false == canUseSynchronousUpload)
{
texture->waitForData();
}
}
catch (const Ogre::Exception& exception)
{
}
}
}
}
}
}
}
I'm testing it with the resource group "Vehicles", because I want to change a diffiuse texture name for a datablock at runtime. E.g. setting a different car color texture.
But now, If I use the preLoadTextures() and change a texture. It will not work anymore. The texture does look weird.
Best Regards
Lax