irrlicht deffered texture loader for asynchronous scene load

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.

irrlicht deffered texture loader for asynchronous scene load

Postby Ovan » 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

cpp 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;
                }
        };
    }
} 

and using it like this
cpp 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();
 


what do you think ?
Last edited by Ovan on Fri Aug 07, 2015 5:37 pm, edited 2 times in total.
User avatar
Ovan
 
Posts: 67
Joined: Thu Dec 18, 2008 12:41 am

Re: irrlicht deffered texture loader for asynchronous scene

Postby devsh » Fri Aug 07, 2015 5:14 pm

you can't multi-thread irrlicht like that.. moreover if you want to do async loading, you can do it easily by executing the loadIImageFromFile in parallel and pass the IImage to createTextureFromImage() in the main thread.

If you want to completely multi-thread, then you need to look into proper Event-Driver Multithreading, fencing etc. with 2 or 3 OpenGL contexts sharing resources.
We chose to stream mesh data from Multiple OpenGL Contexts in many threads and do the other things, not because they are easy, but because they are hard! - JFK
User avatar
devsh
Competition winner
 
Posts: 1758
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK

Re: irrlicht deffered texture loader for asynchronous scene

Postby Ovan » Fri Aug 07, 2015 5:19 pm

this is exactly what he do, but in this way is work on all engine including quake3 and automatic texture loading from mesh
texture is virtually loaded on IDeferredTextureLoader from IVideoDriver and them "reloaded" when @cleanup is called on the main thread
User avatar
Ovan
 
Posts: 67
Joined: Thu Dec 18, 2008 12:41 am

Re: irrlicht deffered texture loader for asynchronous scene

Postby Ovan » Sat Aug 08, 2015 6:33 pm

I'm missing somethink on mt concept or somethink ? :)
User avatar
Ovan
 
Posts: 67
Joined: Thu Dec 18, 2008 12:41 am

Re: irrlicht deffered texture loader for asynchronous scene

Postby Ovan » Sun Aug 09, 2015 6:32 pm

cpp Code: Select all
Index: include/IVideoDriver.h
===================================================================
--- include/IVideoDriver.h  (revision 5114)
+++ include/IVideoDriver.h  (working copy)
@@ -19,6 +19,7 @@
 #include "EDriverTypes.h"
 #include "EDriverFeatures.h"
 #include "SExposedVideoData.h"
+#include "IImage.h"
 
 namespace irr
 {
@@ -467,7 +468,7 @@
        The value is a safe approximation, i.e. can be larger than the
        actual value of pixels. */
        virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const =0;
-      
+
        //! Create render target.
        virtual IRenderTarget* addRenderTarget() = 0;
 
@@ -1449,6 +1450,19 @@
        */
        virtual void convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN,
                void* dP, ECOLOR_FORMAT dF) const =0;
+
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */

+    virtual void setDeferredTextureLoader(bool) = 0;
+
+    /**
+    return the current state of "DefferedTextureLoader"
+    */

+    virtual bool useDeferredTextureLoader() const = 0;
    };
 
 } // end namespace video
Index: source/Irrlicht/CNullDriver.cpp
===================================================================
--- source/Irrlicht/CNullDriver.cpp (revision 5114)
+++ source/Irrlicht/CNullDriver.cpp (working copy)
@@ -23,6 +23,60 @@
 namespace video
 {
 
+    FakeTexture::FakeTexture(irr::video::IVideoDriver *driver, IImage* surface,
+        const io::path& name, void* mipmapData) :
+        ITexture(name), Image(surface), MipData(mipmapData), Driver(driver)
+    {
+        Image->grab();
+    }
+    FakeTexture::~FakeTexture()
+    {
+        // Image droped when this object is transformed to a driver dependent texture
+    }
+    void* FakeTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) _IRR_OVERRIDE_
+    {
+        return Image->lock();
+    }
+    void FakeTexture::unlock() _IRR_OVERRIDE_
+    {
+        return Image->unlock();
+    }
+    void FakeTexture::regenerateMipMapLevels(void* mipmapData)
+    {
+    }
+    const core::dimension2d<u32>& FakeTexture::getOriginalSize() const
+    {
+      return Image->getDimension();
+    }
+    const core::dimension2d<u32>& FakeTexture::getSize() const
+    {
+      return Image->getDimension();
+    }
+    E_DRIVER_TYPE FakeTexture::getDriverType() const
+    {
+      return Driver->getDriverType();
+    };
+    ECOLOR_FORMAT FakeTexture::getColorFormat() const
+    {
+      return Image->getColorFormat();
+    }
+    u32 FakeTexture::getPitch() const
+    {
+      return Image->getPitch();
+    }
+    bool FakeTexture::hasMipMaps() const
+    {
+      return MipData;
+    }
+    bool FakeTexture::hasAlpha() const
+    {
+      return true; /* ??? */
+    }
+    bool FakeTexture::isRenderTarget() const
+    {
+      return false;
+    }
+
 //! creates a loader which is able to load windows bitmaps
 IImageLoader* createImageLoaderBMP();
 
@@ -85,7 +139,7 @@
 CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
    : SharedRenderTarget(0), CurrentRenderTarget(0), CurrentRenderTargetSize(0, 0), FileSystem(io), MeshManipulator(0),
    ViewPort(0, 0, 0, 0), ScreenSize(screenSize), PrimitivesDrawn(0), MinVertexCountForVBO(500),
-   TextureCreationFlags(0), OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false)
+   TextureCreationFlags(0), OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false), DeferredLoader(false)
 {
    #ifdef _DEBUG
    setDebugName("CNullDriver");
@@ -626,6 +680,25 @@
 }
 
 
+/**
+Change who texture is loaded, if "DefferedTextureLoader" is used
+@getTexture(...) return a FakeTexture type and then cached
+when DefferedTextureLoader is returned to false, the cache is cleanup
+and all texture is reloaded at the same address by a driver dependent texture
+*/

+void CNullDriver::setDeferredTextureLoader(bool i)
+{
+    DeferredLoader = i;
+}
+
+/**
+return the current state of "DefferedTextureLoader"
+*/

+bool CNullDriver::useDeferredTextureLoader() const
+{
+    return DeferredLoader;
+}
+
 //! set a render target
 bool CNullDriver::setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, bool clearBackBuffer,
    bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor)
Index: source/Irrlicht/CNullDriver.h
===================================================================
--- source/Irrlicht/CNullDriver.h   (revision 5114)
+++ source/Irrlicht/CNullDriver.h   (working copy)
@@ -38,6 +38,44 @@
    class IImageLoader;
    class IImageWriter;
 
+
+  class IVideoDriver;
+
+  class FakeTexture : public ITexture
+  {
+  public:
+    FakeTexture(irr::video::IVideoDriver *driver, IImage* surface,
+        const io::path& name, void* mipmapData);
+
+    virtual ~FakeTexture();
+
+    virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_;
+
+    virtual void unlock() _IRR_OVERRIDE_;
+
+    virtual void regenerateMipMapLevels(void* mipmapData = 0);
+
+    virtual const core::dimension2d<u32>& getOriginalSize() const;
+
+    virtual const core::dimension2d<u32>& getSize() const;
+
+    virtual E_DRIVER_TYPE getDriverType() const;
+
+    virtual ECOLOR_FORMAT getColorFormat() const;
+
+    virtual u32 getPitch() const;
+
+    virtual bool hasMipMaps() const;
+
+    virtual bool hasAlpha() const;
+
+    virtual bool isRenderTarget() const;
+  public:
+    IImage* Image;
+    void* MipData;
+    IVideoDriver* Driver;
+  };
+
    class CNullDriver : public IVideoDriver, public IGPUProgrammingServices
    {
    public:
@@ -678,6 +716,19 @@
                const c8* name=0);
 
        virtual bool checkDriverReset() _IRR_OVERRIDE_ {return false;}
+
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */

+    virtual void setDeferredTextureLoader(bool);
+
+    /**
+    return the current state of "DefferedTextureLoader"
+    */

+    virtual bool useDeferredTextureLoader() const;
    protected:
 
        //! deletes all textures
@@ -880,6 +931,9 @@
        bool AllowZWriteOnTransparent;
 
        bool FeatureEnabled[video::EVDF_COUNT];
+    bool DeferredLoader;
+
+    core::list<FakeTexture*> CachedDefferedLoader;
    };
 
 } // end namespace video
Index: source/Irrlicht/COpenGLDriver.cpp
===================================================================
--- source/Irrlicht/COpenGLDriver.cpp   (revision 5114)
+++ source/Irrlicht/COpenGLDriver.cpp   (working copy)
@@ -2492,7 +2492,7 @@
    else if (texture->getDriverType() != EDT_OPENGL)
    {
        CurrentTexture.set(stage, 0);
-       os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
+       //os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
        return false;
    }
 
@@ -2549,10 +2549,49 @@
 //! returns a device dependent texture from a software surface (IImage)
 video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
 {
-   return new COpenGLTexture(surface, name, mipmapData, this);
+    if(DeferredLoader)
+    {
+        //! sizeof(FakeTexture) < sizeof(COpenGLTexture)
+        video::FakeTexture *tmp = (FakeTexture*) ::operator new (sizeof(COpenGLTexture));
+        new ((void*)tmp) FakeTexture(this, surface, name, mipmapData);
+        CachedDefferedLoader.push_back(tmp);
+        return tmp;
+    }
+    return new COpenGLTexture(surface, name, mipmapData, this);
 }
 
+/**
+Change who texture is loaded, if "DefferedTextureLoader" is used
+@getTexture(...) return a FakeTexture type and then cached
+when DefferedTextureLoader is returned to false, the cache is cleanup
+and all texture is reloaded at the same address by a driver dependent texture
+*/

+void COpenGLDriver::setDeferredTextureLoader(bool i)
+{
+    CNullDriver::setDeferredTextureLoader(i);
+    if(!i)
+    {
+        os::Printer::log("load deferred texture", ELL_WARNING);
 
+        for(core::list<FakeTexture*>::Iterator it = CachedDefferedLoader.begin();
+            it != CachedDefferedLoader.end(); ++it)
+        {
+            video::FakeTexture *tmp = *it;
+
+            IImage* Image = tmp->Image;
+            void* MipData = tmp->MipData;
+            const io::SNamedPath& name = tmp->getName();
+
+            tmp->~FakeTexture();
+
+            new ((void*)tmp) COpenGLTexture(Image, name, MipData, this);
+            Image->drop();
+        }
+        CachedDefferedLoader.clear();
+    }
+}
+
+
 //! Sets a material. All 3d drawing functions draw geometry now using this material.
 void COpenGLDriver::setMaterial(const SMaterial& material)
 {
Index: source/Irrlicht/COpenGLDriver.h
===================================================================
--- source/Irrlicht/COpenGLDriver.h (revision 5114)
+++ source/Irrlicht/COpenGLDriver.h (working copy)
@@ -425,6 +425,13 @@
        //! Get bridge calls.
        COpenGLCallBridge* getBridgeCalls() const;
 
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */

+    virtual void setDeferredTextureLoader(bool);
    private:
 
        bool updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
 


20min to do this simple stuff, work fine !
simply load your scene in async like
cpp Code: Select all
 
bool loading = true;
 
loadScreen.setVisible(true);
driver->setDeferredTextureLoader(true);
 
task = std::async(std::launch::async, [&]{
    smgr->loadScene("......");
    loading = false;
});
// then in your loading class or main while do
if(!loading)
{
    loadScreen.setVisible(false);
    driver->setDeferredTextureLoader(false);
    switchToGameState();
}
 


in future implementation, I think it's more usefull to check the thread id when the texture is binded ?
and then remove the defered texture cache by a live update on the main thread (I don't know about the portability)

(only opengl here)
User avatar
Ovan
 
Posts: 67
Joined: Thu Dec 18, 2008 12:41 am

Re: irrlicht deffered texture loader for asynchronous scene

Postby Ovan » Thu Nov 26, 2015 6:20 pm

a small update for the revision 5189 on the svn

cpp Code: Select all
 
Index: Irrlicht/include/IVideoDriver.h
===================================================================
--- Irrlicht/include/IVideoDriver.h (revision 5189)
+++ Irrlicht/include/IVideoDriver.h (working copy)
@@ -1494,6 +1494,18 @@
        */
        virtual void convertColor(const void* sP, ECOLOR_FORMAT sF, s32 sN,
                void* dP, ECOLOR_FORMAT dF) const =0;
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */

+    virtual void setDeferredTextureLoader(bool) = 0;
+
+    /**
+    return the current state of "DefferedTextureLoader"
+    */

+    virtual bool useDeferredTextureLoader() const = 0;
    };
 
 } // end namespace video
Index: Irrlicht/source/Irrlicht/CNullDriver.cpp
===================================================================
--- Irrlicht/source/Irrlicht/CNullDriver.cpp    (revision 5189)
+++ Irrlicht/source/Irrlicht/CNullDriver.cpp    (working copy)
@@ -81,11 +81,65 @@
 //! creates a writer which is able to save ppm images
 IImageWriter* createImageWriterPPM();
 
+    FakeTexture::FakeTexture(irr::video::IVideoDriver *driver, IImage* surface,
+        const io::path& name) :
+        ITexture(name), Image(surface), MipData(0), Driver(driver)
+    {
+        Image->grab();
+    }
+    FakeTexture::~FakeTexture()
+    {
+        // Image droped when this object is transformed to a driver dependent texture
+    }
+    void* FakeTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) _IRR_OVERRIDE_
+    {
+        return Image->getData();
+    }
+    void FakeTexture::unlock() _IRR_OVERRIDE_
+    {
+    }
+    void FakeTexture::regenerateMipMapLevels(void* data, u32 layer)
+    {
+        Image->setMipMapsData(data, true, false);
+    }
+    const core::dimension2d<u32>& FakeTexture::getOriginalSize() const
+    {
+      return Image->getDimension();
+    }
+    const core::dimension2d<u32>& FakeTexture::getSize() const
+    {
+      return Image->getDimension();
+    }
+    E_DRIVER_TYPE FakeTexture::getDriverType() const
+    {
+      return Driver->getDriverType();
+    };
+    ECOLOR_FORMAT FakeTexture::getColorFormat() const
+    {
+      return Image->getColorFormat();
+    }
+    u32 FakeTexture::getPitch() const
+    {
+      return Image->getPitch();
+    }
+    bool FakeTexture::hasMipMaps() const
+    {
+      return MipData;
+    }
+    bool FakeTexture::hasAlpha() const
+    {
+      return true; /* ??? */
+    }
+    bool FakeTexture::isRenderTarget() const
+    {
+      return false;
+    }
+
 //! constructor
 CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
    : SharedRenderTarget(0), CurrentRenderTarget(0), CurrentRenderTargetSize(0, 0), FileSystem(io), MeshManipulator(0),
    ViewPort(0, 0, 0, 0), ScreenSize(screenSize), PrimitivesDrawn(0), MinVertexCountForVBO(500),
-   TextureCreationFlags(0), OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false)
+   TextureCreationFlags(0), OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false), DeferredLoader(false)
 {
    #ifdef _DEBUG
    setDebugName("CNullDriver");
@@ -231,7 +285,25 @@
    removeAllHardwareBuffers();
 }
 
+/**
+Change who texture is loaded, if "DefferedTextureLoader" is used
+@getTexture(...) return a FakeTexture type and then cached
+when DefferedTextureLoader is returned to false, the cache is cleanup
+and all texture is reloaded at the same address by a driver dependent texture
+*/

+void CNullDriver::setDeferredTextureLoader(bool i)
+{
+    DeferredLoader = i;
+}
 
+/**
+return the current state of "DefferedTextureLoader"
+*/

+bool CNullDriver::useDeferredTextureLoader() const
+{
+    return DeferredLoader;
+}
+
 //! Adds an external surface loader to the engine.
 void CNullDriver::addExternalImageLoader(IImageLoader* loader)
 {
Index: Irrlicht/source/Irrlicht/CNullDriver.h
===================================================================
--- Irrlicht/source/Irrlicht/CNullDriver.h  (revision 5189)
+++ Irrlicht/source/Irrlicht/CNullDriver.h  (working copy)
@@ -38,6 +38,42 @@
    class IImageLoader;
    class IImageWriter;
 
+  class IVideoDriver;
+
+  class FakeTexture : public ITexture
+  {
+  public:
+    FakeTexture(irr::video::IVideoDriver *driver, IImage* surface, const io::path& name);
+
+    virtual ~FakeTexture();
+
+    virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0) _IRR_OVERRIDE_;
+
+    virtual void unlock() _IRR_OVERRIDE_;
+
+    virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0);
+
+    virtual const core::dimension2d<u32>& getOriginalSize() const;
+
+    virtual const core::dimension2d<u32>& getSize() const;
+
+    virtual E_DRIVER_TYPE getDriverType() const;
+
+    virtual ECOLOR_FORMAT getColorFormat() const;
+
+    virtual u32 getPitch() const;
+
+    virtual bool hasMipMaps() const;
+
+    virtual bool hasAlpha() const;
+
+    virtual bool isRenderTarget() const;
+  public:
+    IImage* Image;
+    void* MipData;
+    IVideoDriver* Driver;
+  };
+
    class CNullDriver : public IVideoDriver, public IGPUProgrammingServices
    {
    public:
@@ -669,6 +705,19 @@
                const c8* name=0);
 
        virtual bool checkDriverReset() _IRR_OVERRIDE_ {return false;}
+
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */

+    virtual void setDeferredTextureLoader(bool);
+
+    /**
+    return the current state of "DefferedTextureLoader"
+    */

+    virtual bool useDeferredTextureLoader() const;
    protected:
 
        //! deletes all textures
@@ -872,6 +921,9 @@
        bool RangeFog;
        bool AllowZWriteOnTransparent;
 
+    bool DeferredLoader;
+    core::list<FakeTexture*> CachedDefferedLoader;
+
        bool FeatureEnabled[video::EVDF_COUNT];
    };
 
Index: Irrlicht/source/Irrlicht/COpenGLDriver.cpp
===================================================================
--- Irrlicht/source/Irrlicht/COpenGLDriver.cpp  (revision 5189)
+++ Irrlicht/source/Irrlicht/COpenGLDriver.cpp  (working copy)
@@ -2554,20 +2554,64 @@
 //! returns a device dependent texture from a software surface (IImage)
 video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name)
 {
-   COpenGLTexture* texture = 0;
+    if(DeferredLoader)
+    {
+        //! sizeof(FakeTexture) < sizeof(COpenGLTexture)
+        video::FakeTexture *tmp = (FakeTexture*) ::operator new (sizeof(COpenGLTexture));
+        new ((void*)tmp) FakeTexture(this, surface, name);
+        CachedDefferedLoader.push_back(tmp);
+        return tmp;
+    }
+    else
+    {
+        COpenGLTexture* texture = 0;
 
-   if (surface && checkColorFormat(surface->getColorFormat(), surface->getDimension()))
-   {
-       core::array<IImage*> imageArray(1);
-       imageArray.push_back(surface);
+        if (surface && checkColorFormat(surface->getColorFormat(), surface->getDimension()))
+        {
+          core::array<IImage*> imageArray(1);
+          imageArray.push_back(surface);
 
-       texture = new COpenGLTexture(name, imageArray, this);
-   }
+          texture = new COpenGLTexture(name, imageArray, this);
+        }
 
-   return texture;
+        return texture;
+    }
 }
 
+/**
+Change who texture is loaded, if "DefferedTextureLoader" is used
+@getTexture(...) return a FakeTexture type and then cached
+when DefferedTextureLoader is returned to false, the cache is cleanup
+and all texture is reloaded at the same address by a driver dependent texture
+*/

+void COpenGLDriver::setDeferredTextureLoader(bool i)
+{
+    CNullDriver::setDeferredTextureLoader(i);
+    if(!i)
+    {
+        os::Printer::log("load deferred texture", ELL_WARNING);
 
+        for(core::list<FakeTexture*>::Iterator it = CachedDefferedLoader.begin();
+            it != CachedDefferedLoader.end(); ++it)
+        {
+            video::FakeTexture *tmp = *it;
+
+            IImage* Image = tmp->Image;
+            void* MipData = tmp->MipData;
+            const io::SNamedPath& name = tmp->getName();
+
+            tmp->~FakeTexture();
+
+            core::array<IImage*> imageArray(1);
+            imageArray.push_back(Image);
+
+            new ((void*)tmp) COpenGLTexture(name, imageArray, this);
+            Image->drop();
+        }
+        CachedDefferedLoader.clear();
+    }
+}
+
 //! Sets a material. All 3d drawing functions draw geometry now using this material.
 void COpenGLDriver::setMaterial(const SMaterial& material)
 {
@@ -4800,7 +4844,7 @@
    case ECF_G32R32F:
        if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_rg))
        {
-           internalFormat = GL_RG32F;         
+           internalFormat = GL_RG32F;
            pixelFormat = GL_RG;
            pixelType = GL_FLOAT;
        }
@@ -4810,7 +4854,7 @@
    case ECF_A32B32G32R32F:
        if (queryOpenGLFeature(COpenGLExtensionHandler::IRR_ARB_texture_float))
        {
-           internalFormat = GL_RGBA32F_ARB;           
+           internalFormat = GL_RGBA32F_ARB;
            pixelFormat = GL_RGBA;
            pixelType = GL_FLOAT;
        }
Index: Irrlicht/source/Irrlicht/COpenGLDriver.h
===================================================================
--- Irrlicht/source/Irrlicht/COpenGLDriver.h    (revision 5189)
+++ Irrlicht/source/Irrlicht/COpenGLDriver.h    (working copy)
@@ -411,6 +411,13 @@
 
        COpenGLCacheHandler* getCacheHandler() const;
 
+    /**
+    Change who texture is loaded, if "DefferedTextureLoader" is used
+    @getTexture(...) return a FakeTexture type and then cached
+    when DefferedTextureLoader is returned to false, the cache is cleanup
+    and all texture is reloaded at the same address by a driver dependent texture
+    */

+    virtual void setDeferredTextureLoader(bool);
    private:
 
        bool updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
 
User avatar
Ovan
 
Posts: 67
Joined: Thu Dec 18, 2008 12:41 am

Re: irrlicht deffered texture loader for asynchronous scene

Postby CuteAlien » Thu Nov 26, 2015 10:56 pm

Thanks for keeping your patch up-to-date! We probably should clean up some more stuff before adding next features. And more in Nadro's area of expertise than mine. But I really like it that you still care about a patch after posting it - that's rare :-)
IRC: #irrlicht on irc.freenode.net
Code snippets, patches&stuff: http://www.michaelzeilfelder.de/irrlicht.htm
Free racer created with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
User avatar
CuteAlien
Admin
 
Posts: 8291
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany

Re: irrlicht deffered texture loader for asynchronous scene

Postby Ovan » Fri Nov 27, 2015 11:04 pm

;)

yeah maybe some clean up. I don't know the irrlicht coding rules
i only read&found the "Enhancing Irrlicht" on the contribution section, no more

I have build some stuff on the gui, maybe with coding rule i can rewrite it quickly

thanks
User avatar
Ovan
 
Posts: 67
Joined: Thu Dec 18, 2008 12:41 am


Return to Open Discussion and Dev Announcements

Who is online

Users browsing this forum: No registered users and 1 guest