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);
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)