irrlicht deffered texture loader for asynchronous scene load
Posted: Fri Aug 07, 2015 1:39 pm
hi there, I just have a little idea to resolve the texture creation issue inside off main thread texture loading
I'm not sure if is possible/correct and not tested
and using it like this
what do you think ?
I'm not sure if is possible/correct and not tested
Code: Select all
namespace irr
{
namespace video
{
class IVideoDriver;
// maybe preload IImage ?
class FakeTexture : public ITexture
{
public:
FakeTexture(const io::path &n)
{
name = n;
}
FakeTexture(io::IReadFile *f)
{
f = file;
file->grab();
}
~FakeTexture()
{
//file not drop
//see bellow @getTexture(FakeTexture*)
}
public:
const io::path name;
io::IReadFile *file;
};
class ITextureLoader
{
public:
ITextureLoader(IVideoDriver*)
virtual irr::video::ITexture* getTexture(const io::path &filename) = 0;
virtual irr::video::ITexture* getTexture(io::IReadFile *file) = 0;
virtual void cleanup() = 0;
};
class IDeferredTextureLoader : public ITextureLoader
{
public:
virtual irr::video::ITexture* getTexture(const io::path &filename)
{
// check cache for existing @filename
FakeTexture *tmp = (FakeTexture*) ::operator new (driver->getDriverTextureSize());
tmp->(filename);
cache->push_back(tmp);
return tmp;
}
virtual irr::video::ITexture* getTexture(io::IReadFile *file)
{
// check cache for existing @file
FakeTexture *tmp = (FakeTexture*) ::operator new (driver->getDriverTextureSize());
tmp->(file);
cache->push_back(tmp);
return tmp;
}
virtual void cleanup()
{
for(int i = 0; i<cache.size(); ++i)
driver->getTexture(cache);
}
public:
core::array<FakeTexture*> cache;
}
class IVideoDriver
{
public:
virtual void setTextureLoader(ITextureLoader*) = 0;
virtual ITextureLoader* getTextureLoader() = 0;
virtual size_t getDriverTextureSize() const = 0;
virtual ITexture* getTexture(FakeTexture*) = 0;
};
class CNullVideoDriver
{
public:
virtual irr::video::ITexture* getTexture(const io::path &filename)
{
if(TextureLoader)
{
TextureLoader->getTexture(filename);
return;
}
// do normal stuff
}
virtual irr::video::ITexture* getTexture(io::IReadFile *file)
{
if(TextureLoader)
{
TextureLoader->getTexture(file);
return;
}
// do normal stuff
}
};
class COpenGLDriver
{
public:
virtual size_t getDriverTextureSize() const
{
return sizeof(COpenGLTexture);
}
virtual ITexture* getTexture(FakeTexture *fk)
{
io::IReadFile *file = tmp->file;
const io::path filename = tmp->filename;
ITexture *tmp2 = new (address) COpenglTexture(fk->blablabla);
tmp->~();
file->drop();
return tmp2;
}
};
}
}
Code: Select all
IDeferredTextureLoader *deferred = new IDeferredTextureLoader(driver);
driver->setTextureLoader(deferred);
std::async(std::launch::async, []{ smgr->loadScene("blabalba"); }));
//when thread end
driver->setTextureLoader(nullptr);
deferred->cleanup();