[2.1] Random texture loading errors when changing assigned material

Problems building or running the engine, queries about how to use features etc.
Post Reply
Boost113
Kobold
Posts: 35
Joined: Sun Sep 08, 2013 6:39 pm
x 6

[2.1] Random texture loading errors when changing assigned material

Post by Boost113 »

Ogre Version: 2.1 (22005:fa50ede7200b)
Operating System: Windows 10, Linux
Render System: OpenGL 3+

We have had a problem in a game, I'm working on, for a long while now where sometimes when we change the material on a mesh, and recreate an Item from it, the textures for that material fail to load.

This is what the log says (I omitted the startup, this happened roughly 10 minutes after starting the program):

Code: Select all

23:32:29: OGRE EXCEPTION(6:FileNotFoundException): Cannot open file: background/Thrive_iceshelf0.png in FileSystemArchive::open at c:\projects\leviathan\thirdparty\ogre\ogremain\src\ogrefilesystem.cpp (line 249)
23:32:29: Error loading texture background/Thrive_iceshelf0.png. Texture layer will be blank. Loading the texture failed with the following exception: OGRE EXCEPTION(6:FileNotFoundException): Cannot open file: background/Thrive_iceshelf0.png in FileSystemArchive::open at c:\projects\leviathan\thirdparty\ogre\ogremain\src\ogrefilesystem.cpp (line 249)
23:32:29: OGRE EXCEPTION(6:FileNotFoundException): Cannot open file: background/Thrive_iceshelf1.png in FileSystemArchive::open at c:\projects\leviathan\thirdparty\ogre\ogremain\src\ogrefilesystem.cpp (line 249)
23:32:29: Error loading texture background/Thrive_iceshelf1.png. Texture layer will be blank. Loading the texture failed with the following exception: OGRE EXCEPTION(6:FileNotFoundException): Cannot open file: background/Thrive_iceshelf1.png in FileSystemArchive::open at c:\projects\leviathan\thirdparty\ogre\ogremain\src\ogrefilesystem.cpp (line 249)
23:32:29: OGRE EXCEPTION(6:FileNotFoundException): Cannot open file: background/Thrive_iceshelf2.png in FileSystemArchive::open at c:\projects\leviathan\thirdparty\ogre\ogremain\src\ogrefilesystem.cpp (line 249)
23:32:29: Error loading texture background/Thrive_iceshelf2.png. Texture layer will be blank. Loading the texture failed with the following exception: OGRE EXCEPTION(6:FileNotFoundException): Cannot open file: background/Thrive_iceshelf2.png in FileSystemArchive::open at c:\projects\leviathan\thirdparty\ogre\ogremain\src\ogrefilesystem.cpp (line 249)
23:32:29: OGRE EXCEPTION(6:FileNotFoundException): Cannot open file: background/Thrive_iceshelf3.png in FileSystemArchive::open at c:\projects\leviathan\thirdparty\ogre\ogremain\src\ogrefilesystem.cpp (line 249)
23:32:29: Error loading texture background/Thrive_iceshelf3.png. Texture layer will be blank. Loading the texture failed with the following exception: OGRE EXCEPTION(6:FileNotFoundException): Cannot open file: background/Thrive_iceshelf3.png in FileSystemArchive::open at c:\projects\leviathan\thirdparty\ogre\ogremain\src\ogrefilesystem.cpp (line 249)
This is the material (most of the time it succeeds displaying fine):

Code: Select all

material Background_Iceshelf
{
    technique
    {
        pass
        {
            // scene_blend alpha_blend
            depth_write off
            depth_check off

            vertex_program_ref Background_VS
            {
            }
            fragment_program_ref Background_PS
            {
            }
            texture_unit 0
            {
            	tex_coord_set 0
                texture background/Thrive_iceshelf0.png 2d gamma
            }
            texture_unit 1
            {
            	tex_coord_set 1
                texture background/Thrive_iceshelf1.png 2d gamma
            }
            texture_unit 2
            {
            	tex_coord_set 2
                texture background/Thrive_iceshelf2.png 2d gamma
            }
            texture_unit 3
            {
            	tex_coord_set 3
                texture background/Thrive_iceshelf3.png 2d gamma
            }
        }
    }
}
Basically in our code we call

Code: Select all

subMesh->setMaterialName(material);
and then delete and create an Item from that mesh and then the texture is the error texture and it stays that way. Sometimes it fixes itself when another material is assigned.

This has happened for me once on Linux and for our Windows based developers and players this has happened many, many times.

The error seems very strange as the files have not changed on disk and nothing that we do in our game should prevent them from being read again.
So I guess maybe there is a bug in the Ogre file loading?

We have been tracking this issue on Github: https://github.com/Revolutionary-Games/ ... issues/639
And we made some changes to reduce the frequency at which the material is changed and the item is recreated and that seems to have made this happen less often.

Here is a screenshot of the single material having all of its layers be the error image:
Image

Any advice would be greatly appreciated.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Random texture loading errors when changing assigned material

Post by dark_sylinc »

Honestly I have no idea why that happens, at all. Sounds like a wrong group error.

Best I can say is that if you can repro the issue, to step in Renderable::setMaterialName and compare the differences in the codepath taken when it works vs when it fails.

Particularly step inside material->load() from Renderable::setMaterial, and get into TextureUnitState::_load.
Boost113
Kobold
Posts: 35
Joined: Sun Sep 08, 2013 6:39 pm
x 6

Re: [2.1] Random texture loading errors when changing assigned material

Post by Boost113 »

A small update: I've managed to get this to happen in visual studio debugger.

Here's what I have so far. The callstack:

Code: Select all

 	KernelBase.dll!00007fff5bd9a388()	Unknown
 	vcruntime140.dll!00007fff4def486d()	Unknown
 	OgreMain.dll!Ogre::ExceptionFactory::throwException(Ogre::Exception::ExceptionCodes code, int number, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & desc, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & src, const char * file, long line) Line 279	C++
>	OgreMain.dll!Ogre::FileSystemArchive::open(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & filename, bool readOnly) Line 325	C++
 	OgreMain.dll!Ogre::ResourceGroupManager::openResource(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & resourceName, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & groupName, bool searchGroupsIfNotFound, Ogre::Resource * resourceBeingLoaded) Line 763	C++
 	RenderSystem_GL3Plus.dll!Ogre::doImageIO(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & name, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & group, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & ext, std::vector<Ogre::Image,Ogre::STLAllocator<Ogre::Image,Ogre::CategorisedAllocPolicy<0> > > & images, Ogre::Resource * r) Line 51	C++
 	RenderSystem_GL3Plus.dll!Ogre::GL3PlusTexture::prepareImpl() Line 403	C++
 	OgreMain.dll!Ogre::Resource::prepare(bool background) Line 114	C++
 	OgreMain.dll!Ogre::TextureManager::prepare(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & name, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & group, Ogre::TextureType texType, int numMipmaps, float gamma, bool isAlpha, Ogre::PixelFormat desiredFormat, bool hwGamma) Line 107	C++
 	OgreMain.dll!Ogre::TextureUnitState::ensurePrepared(unsigned __int64 frame) Line 1061	C++
 	OgreMain.dll!Ogre::TextureUnitState::_prepare() Line 983	C++
 	OgreMain.dll!Ogre::Pass::_prepare() Line 916	C++
 	OgreMain.dll!Ogre::Technique::_prepare() Line 564	C++
 	OgreMain.dll!Ogre::Material::prepareImpl() Line 128	C++
 	OgreMain.dll!Ogre::Resource::load(bool background) Line 230	C++
 	OgreMain.dll!Ogre::Renderable::setMaterial(const Ogre::SharedPtr<Ogre::Material> & material) Line 186	C++
 	OgreMain.dll!Ogre::Renderable::setMaterialName(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & name, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & groupName) Line 178	C++
 	OgreMain.dll!Ogre::Renderable::setDatablockOrMaterialName(std::basic_string<char,std::char_traits<char>,std::allocator<char> > materialName, std::basic_string<char,std::char_traits<char>,std::allocator<char> > resourceGroup) Line 76	C++
 	OgreMain.dll!Ogre::Item::buildSubItems() Line 273	C++
 	OgreMain.dll!Ogre::Item::_initialise(bool forceReinitialise) Line 112	C++
 	OgreMain.dll!Ogre::Item::Item(unsigned int id, Ogre::ObjectMemoryManager * objectMemoryManager, Ogre::SceneManager * manager, const Ogre::SharedPtr<Ogre::Mesh> & mesh) Line 71	C++
 	OgreMain.dll!Ogre::ItemFactory::createInstanceImpl(unsigned int id, Ogre::ObjectMemoryManager * objectMemoryManager, Ogre::SceneManager * manager, const std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,Ogre::STLAllocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,Ogre::CategorisedAllocPolicy<0> > > * params) Line 375	C++
 	OgreMain.dll!Ogre::SceneManager::createMovableObject(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & typeName, Ogre::ObjectMemoryManager * objectMemMgr, const std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,Ogre::STLAllocator<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,Ogre::CategorisedAllocPolicy<0> > > * params) Line 4829	C++
 	OgreMain.dll!Ogre::SceneManager::createItem(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & meshName, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & groupName, Ogre::SceneMemoryMgrTypes sceneType) Line 479	C++
 	Thrive.exe!thrive::ThriveGame::Implementation::createBackgroundItem() Line 96	C++
 	Thrive.exe!thrive::ThriveGame::setBackgroundMaterial(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & material) Line 966	C++
 	Engine.dll!CallX64() Line 139	Unknown
 	Engine.dll!CallSystemFunctionNative(asCContext * context, asCScriptFunction * descr, void * obj, unsigned long * args, void * retPointer, unsigned __int64 & __formal, void * secondObject) Line 201	C++
 	Engine.dll!CallSystemFunction(int id, asCContext * context) Line 730	C++
 	Engine.dll!asCContext::ExecuteNext() Line 2557	C++
 	Engine.dll!asCContext::Execute() Line 1328	C++
 	Engine.dll!Leviathan::ScriptExecutor::RunScriptMethod<void>(Leviathan::ScriptRunningSetup & parameters, asIScriptFunction * func, void * obj) Line 203	C++
 	Engine.dll!Leviathan::ScriptSystemWrapper::Run() Line 107	C++
 	Engine.dll!Leviathan::GameWorld::_RunTickSystems() Line 689	C++
 	Engine.dll!Leviathan::StandardWorld::_RunTickSystems() Line 766	C++
 	Thrive.exe!thrive::CellStageWorld::_RunTickSystems() Line 737	C++
 	Engine.dll!Leviathan::GameWorld::Tick(int currenttick) Line 605	C++
 	Engine.dll!Leviathan::Engine::Tick() Line 882	C++
 	Engine.dll!Leviathan::LeviathanApplication::RunMessageLoop() Line 147	C++
 	Thrive.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, char * lpCmdLine, int nCmdShow) Line 221	C++
 	[External Code]	
And local variables:

Code: Select all

+		this	0x000002763f780b00 {...}	Ogre::FileSystemArchive *
		baseStream	Variable is optimized away and not available.	
+		filename	"background/Thrive_meso0.png"	const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &
+		full_path	"./Data/Textures//background/Thrive_meso0.png"	std::basic_string<char,std::char_traits<char>,std::allocator<char> >
		readOnly	Variable is optimized away and not available.	
+		roStream	ntdll.dll!0x00007fff5ee730c0 (load symbols for additional information) {_Filebuffer={_Pcvt=0x0010340f00040f09 {...} ...} }	std::basic_ifstream<char,std::char_traits<char> > *
+		rwStream	0x0000000000000000 <NULL>	std::basic_fstream<char,std::char_traits<char> > *
		stream	Variable is optimized away and not available.	
+		tagStat	{st_dev=2 st_ino=0 st_mode=33206 ...}	stat
So the file is correctly found and the path looks correct (other than the one extra /) but the stream object has the fail bit set and the loading throws an exception then and then the texture shows up as the error texture.

My only idea as to why this is happening is that something (antivirus?) is messing with the file just when Ogre wants to read it, but this issue happens to 4 texture layers in a row and it then keeps happening on subsequent loads as well, so this is probably not what's happening.

So does anyone have any idea as to what's wrong?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.1] Random texture loading errors when changing assigned material

Post by dark_sylinc »

It is possible you're running out of handles?

IIRC Windows only allows 512 opened at the same time.

If file descriptors/handles are leaking, it could explain this behavior.
Boost113
Kobold
Posts: 35
Joined: Sun Sep 08, 2013 6:39 pm
x 6

Re: [2.1] Random texture loading errors when changing assigned material

Post by Boost113 »

I think you were right about the open file limit. We are using a pretty bad audio library that seems to keep a ton of files open.

I added this code:

Code: Select all

_setmaxstdio(2048)
And everything seems to work. I'll test a bit more before calling this fixed.
Post Reply