Hi,
I can paste some code, how I load textures in my GameEngine:
Code: Select all
Ogre::String DatablockUnlitComponent::getUnlitTextureName(Ogre::HlmsUnlitDatablock* datablock, unsigned char textureIndex)
{
Ogre::TextureGpu* texture = datablock->getTexture(textureIndex);
if (nullptr != texture)
{
return texture->getNameStr();
}
return "";
}
void DatablockUnlitComponent::internalSetTextureName(unsigned char textureIndex, Ogre::CommonTextureTypes::CommonTextureTypes textureType, Variant* attribute, const Ogre::String& textureName)
{
Ogre::String previousTextureName = attribute->getString();
// If the data block component has just been created, get texture name from existing data block
Ogre::String tempTextureName = textureName;
if (true == newlyCreated && nullptr != this->datablock)
{
tempTextureName = this->getUnlitTextureName(this->datablock, textureIndex);
}
attribute->setValue(tempTextureName);
// Store the old texture name as user data
if (false == tempTextureName.empty())
{
attribute->addUserData(tempTextureName);
}
this->addAttributeFilePathData(attribute);
if (nullptr != this->datablock/* && false == newlyCreated*/)
{
// If no texture has been loaded, but still the data block has an internal one, get this one and remove it manually!
if (true == attribute->getUserDataValue("OldTexture").empty())
{
tempTextureName = this->getUnlitTextureName(this->datablock, textureIndex);
attribute->addUserData(tempTextureName);
this->addAttributeFilePathData(attribute);
// Retrieve the texture and remove it from data block
tempTextureName = "";
}
// createOrRetrieveTexture crashes, when texture alias name is empty
Ogre::String oldTextureName = attribute->getUserDataValue("OldTexture");
if (false == oldTextureName.empty())
{
if (false == Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(oldTextureName))
{
Ogre::LogManager::getSingletonPtr()->logMessage(Ogre::LML_CRITICAL, "[DatablockUnlitComponent] Cannot set texture: '" + oldTextureName +
"', because it does not exist in any resource group! for game object: " + this->gameObjectPtr->getName());
attribute->setValue(previousTextureName);
this->addAttributeFilePathData(attribute);
return;
}
Ogre::TextureGpuManager* hlmsTextureManager = Ogre::Root::getSingletonPtr()->getRenderSystem()->getTextureGpuManager();
// Attention: Which type here? for unlit?
Ogre::TextureGpu* texture = hlmsTextureManager->createOrRetrieveTexture(oldTextureName, Ogre::GpuPageOutStrategy::Discard,
textureType, Ogre::ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME, 0); // Attention: Poolid = 0, is that correct?
// hlmsTextureManager->getDefaultTextureParameters()[TEXTURE_TYPE_DIFFUSE].hwGammaCorrection = false
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::OnSystemRam);
texture->waitForData();
}
catch (const Ogre::Exception& exception)
{
Ogre::LogManager::getSingleton().logMessage(exception.getFullDescription(), Ogre::LML_CRITICAL);
Ogre::LogManager::getSingleton().logMessage("[DatablockUnlitComponent] Error: Could not set texture: '" + oldTextureName + "' For game object: " + this->gameObjectPtr->getName(), Ogre::LML_CRITICAL);
attribute->setValue(previousTextureName);
attribute->setDescription("Texture location: '" + getResourceFilePathName(previousTextureName) + "'");
return;
}
}
// Invalid texture skip
// Note: width may be 0, when create or retrieve is called, if its a heavy resolution texture. So the width/height becomes available after waitForData, if its still 0, texture is invalid!
if (0 == texture->getWidth())
{
attribute->setValue(previousTextureName);
this->addAttributeFilePathData(attribute);
return;
}
// If texture has been removed, set null texture, so that it will be removed from data block
if (true == tempTextureName.empty())
{
// Attention: Is that correct?
hlmsTextureManager->destroyTexture(texture);
texture = nullptr;
}
// Attention: Here with index, instead of type and name, is that correct, and in pbsdatablockcomponent its done differently, check it!
datablock->setTexture(textureIndex, oldTextureName);
}
else
{
attribute->setValue("");
attribute->removeUserData("OldTexture");
}
}
}
}
Best Regards
Lax