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.
Post Reply
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

irrlicht deffered texture loader for asynchronous scene load

Post by Ovan »

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

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

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.
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Re: irrlicht deffered texture loader for asynchronous scene

Post by devsh »

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.
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: irrlicht deffered texture loader for asynchronous scene

Post by Ovan »

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
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: irrlicht deffered texture loader for asynchronous scene

Post by Ovan »

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

Re: irrlicht deffered texture loader for asynchronous scene

Post by Ovan »

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

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)
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: irrlicht deffered texture loader for asynchronous scene

Post by Ovan »

a small update for the revision 5189 on the svn

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);
 
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: irrlicht deffered texture loader for asynchronous scene

Post by CuteAlien »

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.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Ovan
Posts: 70
Joined: Thu Dec 18, 2008 12:41 am
Contact:

Re: irrlicht deffered texture loader for asynchronous scene

Post by Ovan »

;)

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
Post Reply