Commit 76c4b0f8 authored by hybrid's avatar hybrid

Add access to miplevels in addTexture, texture->lock, and texture->regenerateMipMapLevels.

This allows to create custom mipmap textures manually, or provide them from certain image formats that come with precalculated mipmaps.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2912 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 978c768a
...@@ -101,7 +101,7 @@ public: ...@@ -101,7 +101,7 @@ public:
\return Returns a pointer to the pixel data. The format of the pixel can \return Returns a pointer to the pixel data. The format of the pixel can
be determined by using getColorFormat(). 0 is returned, if be determined by using getColorFormat(). 0 is returned, if
the texture cannot be locked. */ the texture cannot be locked. */
virtual void* lock(bool readOnly = false) = 0; virtual void* lock(bool readOnly = false, u32 mipmapLevel=0) = 0;
//! Unlock function. Must be called after a lock() to the texture. //! Unlock function. Must be called after a lock() to the texture.
/** One should avoid to call unlock more than once before another lock. */ /** One should avoid to call unlock more than once before another lock. */
...@@ -149,7 +149,7 @@ public: ...@@ -149,7 +149,7 @@ public:
//! Regenerates the mip map levels of the texture. //! Regenerates the mip map levels of the texture.
/** Required after modifying the texture, usually after calling unlock(). */ /** Required after modifying the texture, usually after calling unlock(). */
virtual void regenerateMipMapLevels() = 0; virtual void regenerateMipMapLevels(void* mipmapData=0) = 0;
//! Check whether the texture is a render target //! Check whether the texture is a render target
/** \return True if this is a render target, otherwise false. */ /** \return True if this is a render target, otherwise false. */
......
...@@ -380,10 +380,13 @@ namespace video ...@@ -380,10 +380,13 @@ namespace video
/** \param name A name for the texture. Later calls of /** \param name A name for the texture. Later calls of
getTexture() with this name will return this texture getTexture() with this name will return this texture
\param image Image the texture is created from. \param image Image the texture is created from.
\mipmapData Optional pointer to a set of images which build up the
whole mipmap set. Must be images of the same color type as image. If
this parameter is not given, the mipmaps are derived from image.
\return Pointer to the newly created texture. This pointer \return Pointer to the newly created texture. This pointer
should not be dropped. See IReferenceCounted::drop() for more should not be dropped. See IReferenceCounted::drop() for more
information. */ information. */
virtual ITexture* addTexture(const io::path& name, IImage* image) = 0; virtual ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData=0) = 0;
//! Adds a new render target texture to the texture cache. //! Adds a new render target texture to the texture cache.
/** \param size Size of the texture, in pixels. Width and /** \param size Size of the texture, in pixels. Width and
......
...@@ -674,9 +674,9 @@ void CD3D8Driver::setMaterial(const SMaterial& material) ...@@ -674,9 +674,9 @@ void CD3D8Driver::setMaterial(const SMaterial& material)
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
video::ITexture* CD3D8Driver::createDeviceDependentTexture(IImage* surface,const io::path& name) video::ITexture* CD3D8Driver::createDeviceDependentTexture(IImage* surface,const io::path& name, void* mipmapData)
{ {
return new CD3D8Texture(surface, this, TextureCreationFlags, name); return new CD3D8Texture(surface, this, TextureCreationFlags, name, mipmapData);
} }
......
...@@ -257,7 +257,7 @@ namespace video ...@@ -257,7 +257,7 @@ namespace video
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name); virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
// returns the current size of the screen or rendertarget // returns the current size of the screen or rendertarget
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const; virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const;
......
...@@ -50,7 +50,7 @@ CD3D8Texture::CD3D8Texture(CD3D8Driver* driver, const core::dimension2d<u32>& si ...@@ -50,7 +50,7 @@ CD3D8Texture::CD3D8Texture(CD3D8Driver* driver, const core::dimension2d<u32>& si
//! constructor //! constructor
CD3D8Texture::CD3D8Texture(IImage* image, CD3D8Driver* driver, CD3D8Texture::CD3D8Texture(IImage* image, CD3D8Driver* driver,
u32 flags, const io::path& name) u32 flags, const io::path& name, void* mipmapData)
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), : ITexture(name), Texture(0), RTTSurface(0), Driver(driver),
TextureSize(0,0), ImageSize(0,0), Pitch(0), TextureSize(0,0), ImageSize(0,0), Pitch(0),
HasMipMaps(false), IsRenderTarget(false) HasMipMaps(false), IsRenderTarget(false)
...@@ -59,7 +59,7 @@ HasMipMaps(false), IsRenderTarget(false) ...@@ -59,7 +59,7 @@ HasMipMaps(false), IsRenderTarget(false)
setDebugName("CD3D8Texture"); setDebugName("CD3D8Texture");
#endif #endif
const bool generateMipLevels = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); HasMipMaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
Device=driver->getExposedVideoData().D3D8.D3DDev8; Device=driver->getExposedVideoData().D3D8.D3DDev8;
if (Device) if (Device)
...@@ -67,26 +67,11 @@ HasMipMaps(false), IsRenderTarget(false) ...@@ -67,26 +67,11 @@ HasMipMaps(false), IsRenderTarget(false)
if (image) if (image)
{ {
if (createTexture(image, flags)) if (createTexture(flags, image))
{ {
if (copyTexture(image) && generateMipLevels) if (copyTexture(image))
{ {
// create mip maps. regenerateMipMapLevels(mipmapData);
#ifndef _IRR_USE_D3DXFilterTexture_
// The D3DXFilterTexture function seems to get linked wrong when
// compiling with both D3D8 and 9, causing it not to work in the D3D9 device.
// So mipmapgeneration is replaced with my own bad generation in d3d 8 when
// compiling with both D3D 8 and 9.
HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT , D3DX_DEFAULT );
if (FAILED(hr))
os::Printer::log("Could not create direct3d mip map levels.", ELL_WARNING);
else
HasMipMaps = true;
#else
createMipMaps();
HasMipMaps = true;
#endif
} }
} }
else else
...@@ -110,7 +95,7 @@ CD3D8Texture::~CD3D8Texture() ...@@ -110,7 +95,7 @@ CD3D8Texture::~CD3D8Texture()
//! creates the hardware texture //! creates the hardware texture
bool CD3D8Texture::createTexture(video::IImage* image, u32 flags) bool CD3D8Texture::createTexture(u32 flags, video::IImage* image)
{ {
ImageSize = image->getDimension(); ImageSize = image->getDimension();
...@@ -220,23 +205,30 @@ bool CD3D8Texture::copyTexture(video::IImage* image) ...@@ -220,23 +205,30 @@ bool CD3D8Texture::copyTexture(video::IImage* image)
//! lock function //! lock function
void* CD3D8Texture::lock(bool readOnly) void* CD3D8Texture::lock(bool readOnly, u32 mipmapLevel)
{ {
if (!Texture) if (!Texture)
return 0; return 0;
MipLevelLocked=mipmapLevel;
HRESULT hr; HRESULT hr;
D3DLOCKED_RECT rect; D3DLOCKED_RECT rect;
if(!IsRenderTarget) if(!IsRenderTarget)
{ {
hr = Texture->LockRect(0, &rect, 0, readOnly?D3DLOCK_READONLY:0); hr = Texture->LockRect(mipmapLevel, &rect, 0, readOnly?D3DLOCK_READONLY:0);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
return 0;
}
} }
else else
{ {
D3DSURFACE_DESC desc;
Texture->GetLevelDesc(0, &desc);
if (!RTTSurface) if (!RTTSurface)
{ {
// Make RTT surface large enough for all miplevels (including 0)
D3DSURFACE_DESC desc;
Texture->GetLevelDesc(0, &desc);
hr = Device->CreateImageSurface(desc.Width, desc.Height, desc.Format, &RTTSurface); hr = Device->CreateImageSurface(desc.Width, desc.Height, desc.Format, &RTTSurface);
if (FAILED(hr)) if (FAILED(hr))
{ {
...@@ -246,33 +238,26 @@ void* CD3D8Texture::lock(bool readOnly) ...@@ -246,33 +238,26 @@ void* CD3D8Texture::lock(bool readOnly)
} }
IDirect3DSurface8 *surface = 0; IDirect3DSurface8 *surface = 0;
hr = Texture->GetSurfaceLevel(0, &surface); hr = Texture->GetSurfaceLevel(mipmapLevel, &surface);
if (FAILED(hr)) if (FAILED(hr))
{ {
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D8 Texture.", "Could not get surface.", ELL_ERROR);
return 0; return 0;
} }
hr = Device->CopyRects(surface, 0, 0, RTTSurface, 0); hr = Device->CopyRects(surface, 0, 0, RTTSurface, 0);
surface->Release(); surface->Release();
if(FAILED(hr)) if(FAILED(hr))
{ {
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D8 Texture.", "Data copy failed.", ELL_ERROR);
return 0; return 0;
} }
hr = RTTSurface->LockRect(&rect, 0, readOnly?D3DLOCK_READONLY:0); hr = RTTSurface->LockRect(&rect, 0, readOnly?D3DLOCK_READONLY:0);
if(FAILED(hr)) if(FAILED(hr))
{ {
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D8 Texture.", "LockRect failed.", ELL_ERROR);
return 0; return 0;
} }
return rect.pBits;
} }
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
return 0;
}
return rect.pBits; return rect.pBits;
} }
...@@ -284,7 +269,7 @@ void CD3D8Texture::unlock() ...@@ -284,7 +269,7 @@ void CD3D8Texture::unlock()
return; return;
if (!IsRenderTarget) if (!IsRenderTarget)
Texture->UnlockRect(0); Texture->UnlockRect(MipLevelLocked);
else if (RTTSurface) else if (RTTSurface)
RTTSurface->UnlockRect(); RTTSurface->UnlockRect();
} }
...@@ -587,10 +572,59 @@ void CD3D8Texture::createRenderTarget() ...@@ -587,10 +572,59 @@ void CD3D8Texture::createRenderTarget()
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
void CD3D8Texture::regenerateMipMapLevels() void CD3D8Texture::regenerateMipMapLevels(void* mipmapData)
{ {
if (HasMipMaps) if (mipmapData)
{
core::dimension2du size = TextureSize;
u32 level=0;
do
{
if (size.Width>1)
size.Width /=2;
if (size.Height>1)
size.Height /=2;
++level;
IDirect3DSurface8* mipSurface = 0;
HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface);
if (FAILED(hr) || !mipSurface)
{
os::Printer::log("Could not get mipmap level", ELL_WARNING);
return;
}
D3DSURFACE_DESC mipDesc;
mipSurface->GetDesc(&mipDesc);
D3DLOCKED_RECT miplr;
// lock mipmap surface
if (FAILED(mipSurface->LockRect(&miplr, NULL, 0)))
{
mipSurface->Release();
os::Printer::log("Could not lock texture", ELL_WARNING);
return;
}
memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width);
mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width;
// unlock
mipSurface->UnlockRect();
// release
mipSurface->Release();
} while (size.Width != 1 || size.Height != 1);
}
else if (HasMipMaps)
{
// create mip maps.
#ifndef _IRR_USE_D3DXFilterTexture_
// The D3DXFilterTexture function seems to get linked wrong when
// compiling with both D3D8 and 9, causing it not to work in the D3D9 device.
// So mipmapgeneration is replaced with my own bad generation in d3d 8 when
// compiling with both D3D 8 and 9.
HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT , D3DX_DEFAULT );
if (FAILED(hr))
#endif
createMipMaps(); createMipMaps();
}
} }
......
...@@ -29,7 +29,7 @@ public: ...@@ -29,7 +29,7 @@ public:
//! constructor //! constructor
CD3D8Texture(IImage* image, CD3D8Driver* driver, CD3D8Texture(IImage* image, CD3D8Driver* driver,
u32 flags, const io::path& name); u32 flags, const io::path& name, void* mipmapData=0);
//! rendertarget constructor //! rendertarget constructor
CD3D8Texture(CD3D8Driver* driver, const core::dimension2d<u32>& size, const io::path& name); CD3D8Texture(CD3D8Driver* driver, const core::dimension2d<u32>& size, const io::path& name);
...@@ -38,7 +38,7 @@ public: ...@@ -38,7 +38,7 @@ public:
virtual ~CD3D8Texture(); virtual ~CD3D8Texture();
//! lock function //! lock function
virtual void* lock(bool readOnly = false); virtual void* lock(bool readOnly = false, u32 mipmapLevel=0);
//! unlock function //! unlock function
virtual void unlock(); virtual void unlock();
...@@ -66,7 +66,7 @@ public: ...@@ -66,7 +66,7 @@ public:
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
virtual void regenerateMipMapLevels(); virtual void regenerateMipMapLevels(void* mipmapData=0);
//! returns if it is a render target //! returns if it is a render target
virtual bool isRenderTarget() const; virtual bool isRenderTarget() const;
...@@ -80,7 +80,7 @@ private: ...@@ -80,7 +80,7 @@ private:
void createRenderTarget(); void createRenderTarget();
//! creates the hardware texture //! creates the hardware texture
bool createTexture(IImage* Image, u32 flags); bool createTexture(u32 flags, IImage* Image);
//! copies the image to the texture //! copies the image to the texture
bool copyTexture(IImage* Image); bool copyTexture(IImage* Image);
...@@ -103,7 +103,9 @@ private: ...@@ -103,7 +103,9 @@ private:
core::dimension2d<u32> TextureSize; core::dimension2d<u32> TextureSize;
core::dimension2d<u32> ImageSize; core::dimension2d<u32> ImageSize;
s32 Pitch; s32 Pitch;
u32 MipLevelLocked;
ECOLOR_FORMAT ColorFormat; ECOLOR_FORMAT ColorFormat;
bool HasMipMaps; bool HasMipMaps;
bool IsRenderTarget; bool IsRenderTarget;
}; };
......
...@@ -720,9 +720,9 @@ void CD3D9Driver::setMaterial(const SMaterial& material) ...@@ -720,9 +720,9 @@ void CD3D9Driver::setMaterial(const SMaterial& material)
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
video::ITexture* CD3D9Driver::createDeviceDependentTexture(IImage* surface,const io::path& name) video::ITexture* CD3D9Driver::createDeviceDependentTexture(IImage* surface,const io::path& name, void* mipmapData)
{ {
return new CD3D9Texture(surface, this, TextureCreationFlags, name); return new CD3D9Texture(surface, this, TextureCreationFlags, name, mipmapData);
} }
......
...@@ -326,7 +326,7 @@ namespace video ...@@ -326,7 +326,7 @@ namespace video
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name); virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
//! returns the current size of the screen or rendertarget //! returns the current size of the screen or rendertarget
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const; virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const;
......
...@@ -50,7 +50,7 @@ CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& si ...@@ -50,7 +50,7 @@ CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& si
//! constructor //! constructor
CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver,
u32 flags, const io::path& name) u32 flags, const io::path& name, void* mipmapData)
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0), : ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0),
TextureSize(0,0), ImageSize(0,0), Pitch(0), ColorFormat(ECF_UNKNOWN), TextureSize(0,0), ImageSize(0,0), Pitch(0), ColorFormat(ECF_UNKNOWN),
HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false) HasMipMaps(false), HardwareMipMaps(false), IsRenderTarget(false)
...@@ -59,7 +59,7 @@ CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, ...@@ -59,7 +59,7 @@ CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver,
setDebugName("CD3D9Texture"); setDebugName("CD3D9Texture");
#endif #endif
const bool generateMipLevels = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); HasMipMaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
Device=driver->getExposedVideoData().D3D9.D3DDev9; Device=driver->getExposedVideoData().D3D9.D3DDev9;
if (Device) if (Device)
...@@ -69,22 +69,9 @@ CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, ...@@ -69,22 +69,9 @@ CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver,
{ {
if (createTexture(flags, image)) if (createTexture(flags, image))
{ {
if (copyTexture(image) && generateMipLevels) if (copyTexture(image))
{ {
// create mip maps. regenerateMipMapLevels(mipmapData);
#ifdef _IRR_USE_D3DXFilterTexture_
// The D3DXFilterTexture function seems to get linked wrong when
// compiling with both D3D8 and 9, causing it not to work in the D3D9 device.
// So mipmapgeneration is replaced with my own bad generation
HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_DEFAULT);
if (FAILED(hr))
os::Printer::log("Could not create direct3d mip map levels.", ELL_WARNING);
else
HasMipMaps = true;
#else
createMipMaps();
HasMipMaps = true;
#endif
} }
} }
else else
...@@ -188,8 +175,8 @@ bool CD3D9Texture::createMipMaps(u32 level) ...@@ -188,8 +175,8 @@ bool CD3D9Texture::createMipMaps(u32 level)
Texture->GenerateMipSubLevels(); Texture->GenerateMipSubLevels();
return true; return true;
} }
// os::Printer::log("manual mipmap");
// manual mipmap generation
IDirect3DSurface9* upperSurface = 0; IDirect3DSurface9* upperSurface = 0;
IDirect3DSurface9* lowerSurface = 0; IDirect3DSurface9* lowerSurface = 0;
...@@ -396,30 +383,30 @@ bool CD3D9Texture::copyTexture(IImage * image) ...@@ -396,30 +383,30 @@ bool CD3D9Texture::copyTexture(IImage * image)
//! lock function //! lock function
void* CD3D9Texture::lock(bool readOnly) void* CD3D9Texture::lock(bool readOnly, u32 mipmapLevel)
{ {
if (!Texture) if (!Texture)
return 0; return 0;
MipLevelLocked=mipmapLevel;
HRESULT hr; HRESULT hr;
D3DLOCKED_RECT rect; D3DLOCKED_RECT rect;
if(!IsRenderTarget) if(!IsRenderTarget)
{ {
hr = Texture->LockRect(0, &rect, 0, readOnly?D3DLOCK_READONLY:0); hr = Texture->LockRect(mipmapLevel, &rect, 0, readOnly?D3DLOCK_READONLY:0);
if (FAILED(hr)) if (FAILED(hr))
{ {
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
return 0; return 0;
} }
return rect.pBits;
} }
else else
{ {
D3DSURFACE_DESC desc;
Texture->GetLevelDesc(0, &desc);
if (!RTTSurface) if (!RTTSurface)
{ {
// Make RTT surface large enough for all miplevels (including 0)
D3DSURFACE_DESC desc;
Texture->GetLevelDesc(0, &desc);
hr = Device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &RTTSurface, 0); hr = Device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &RTTSurface, 0);
if (FAILED(hr)) if (FAILED(hr))
{ {
...@@ -429,7 +416,7 @@ void* CD3D9Texture::lock(bool readOnly) ...@@ -429,7 +416,7 @@ void* CD3D9Texture::lock(bool readOnly)
} }
IDirect3DSurface9 *surface = 0; IDirect3DSurface9 *surface = 0;
hr = Texture->GetSurfaceLevel(0, &surface); hr = Texture->GetSurfaceLevel(mipmapLevel, &surface);
if (FAILED(hr)) if (FAILED(hr))
{ {
os::Printer::log("Could not lock DIRECT3D9 Texture", "Could not get surface.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D9 Texture", "Could not get surface.", ELL_ERROR);
...@@ -448,8 +435,8 @@ void* CD3D9Texture::lock(bool readOnly) ...@@ -448,8 +435,8 @@ void* CD3D9Texture::lock(bool readOnly)
os::Printer::log("Could not lock DIRECT3D9 Texture", "LockRect failed.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D9 Texture", "LockRect failed.", ELL_ERROR);
return 0; return 0;
} }
return rect.pBits;
} }
return rect.pBits;
} }
...@@ -460,7 +447,7 @@ void CD3D9Texture::unlock() ...@@ -460,7 +447,7 @@ void CD3D9Texture::unlock()
return; return;
if (!IsRenderTarget) if (!IsRenderTarget)
Texture->UnlockRect(0); Texture->UnlockRect(MipLevelLocked);
else if (RTTSurface) else if (RTTSurface)
RTTSurface->UnlockRect(); RTTSurface->UnlockRect();
} }
...@@ -602,10 +589,58 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt, ...@@ -602,10 +589,58 @@ void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
void CD3D9Texture::regenerateMipMapLevels() void CD3D9Texture::regenerateMipMapLevels(void* mipmapData)
{ {
if (HasMipMaps) if (mipmapData)
{
core::dimension2du size = TextureSize;
u32 level=0;
do
{
if (size.Width>1)
size.Width /=2;
if (size.Height>1)
size.Height /=2;
++level;
IDirect3DSurface9* mipSurface = 0;
HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface);
if (FAILED(hr) || !mipSurface)
{
os::Printer::log("Could not get mipmap level", ELL_WARNING);
return;
}
D3DSURFACE_DESC mipDesc;
mipSurface->GetDesc(&mipDesc);
D3DLOCKED_RECT miplr;
// lock mipmap surface
if (FAILED(mipSurface->LockRect(&miplr, NULL, 0)))
{
mipSurface->Release();
os::Printer::log("Could not lock texture", ELL_WARNING);
return;
}
memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width);
mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width;
// unlock
mipSurface->UnlockRect();
// release
mipSurface->Release();
} while (size.Width != 1 || size.Height != 1);
}
else if (HasMipMaps)
{
// create mip maps.
#ifdef _IRR_USE_D3DXFilterTexture_
// The D3DXFilterTexture function seems to get linked wrong when
// compiling with both D3D8 and 9, causing it not to work in the D3D9 device.
// So mipmapgeneration is replaced with my own bad generation
HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT, D3DX_DEFAULT);
if (FAILED(hr))
#endif
createMipMaps(); createMipMaps();
}
} }
...@@ -662,5 +697,3 @@ void CD3D9Texture::setPitch(D3DFORMAT d3dformat) ...@@ -662,5 +697,3 @@ void CD3D9Texture::setPitch(D3DFORMAT d3dformat)
} // end namespace irr } // end namespace irr
#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ #endif // _IRR_COMPILE_WITH_DIRECT3D_9_
...@@ -29,7 +29,7 @@ public: ...@@ -29,7 +29,7 @@ public:
//! constructor //! constructor
CD3D9Texture(IImage* image, CD3D9Driver* driver, CD3D9Texture(IImage* image, CD3D9Driver* driver,
u32 flags, const io::path& name); u32 flags, const io::path& name, void* mipmapData=0);
//! rendertarget constructor //! rendertarget constructor
CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size, const io::path& name, CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size, const io::path& name,
...@@ -39,7 +39,7 @@ public: ...@@ -39,7 +39,7 @@ public:
virtual ~CD3D9Texture(); virtual ~CD3D9Texture();
//! lock function //! lock function
virtual void* lock(bool readOnly = false); virtual void* lock(bool readOnly = false, u32 mipmapLevel=0);
//! unlock function //! unlock function
virtual void unlock(); virtual void unlock();
...@@ -67,7 +67,7 @@ public: ...@@ -67,7 +67,7 @@ public:
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
virtual void regenerateMipMapLevels(); virtual void regenerateMipMapLevels(void* mipmapData=0);
//! returns if it is a render target //! returns if it is a render target
virtual bool isRenderTarget() const; virtual bool isRenderTarget() const;
...@@ -108,6 +108,7 @@ private: ...@@ -108,6 +108,7 @@ private:
core::dimension2d<u32> TextureSize; core::dimension2d<u32> TextureSize;
core::dimension2d<u32> ImageSize; core::dimension2d<u32> ImageSize;
s32 Pitch; s32 Pitch;
u32 MipLevelLocked;
ECOLOR_FORMAT ColorFormat; ECOLOR_FORMAT ColorFormat;
bool HasMipMaps; bool HasMipMaps;
......
...@@ -486,12 +486,12 @@ video::ITexture* CNullDriver::findTexture(const io::path& filename) ...@@ -486,12 +486,12 @@ video::ITexture* CNullDriver::findTexture(const io::path& filename)
//! Creates a texture from a loaded IImage. //! Creates a texture from a loaded IImage.
ITexture* CNullDriver::addTexture(const io::path& name, IImage* image) ITexture* CNullDriver::addTexture(const io::path& name, IImage* image, void* mipmapData)
{ {
if ( 0 == name.size() || !image) if ( 0 == name.size() || !image)
return 0; return 0;
ITexture* t = createDeviceDependentTexture(image, name); ITexture* t = createDeviceDependentTexture(image, name, mipmapData);
if (t) if (t)
{ {
addTexture(t); addTexture(t);
...@@ -529,7 +529,7 @@ ITexture* CNullDriver::addTexture(const core::dimension2d<u32>& size, ...@@ -529,7 +529,7 @@ ITexture* CNullDriver::addTexture(const core::dimension2d<u32>& size,
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::path& name) ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
{ {
return new SDummyTexture(name); return new SDummyTexture(name);
} }
......
...@@ -585,11 +585,11 @@ namespace video ...@@ -585,11 +585,11 @@ namespace video
void addTexture(video::ITexture* surface); void addTexture(video::ITexture* surface);
//! Creates a texture from a loaded IImage. //! Creates a texture from a loaded IImage.
virtual ITexture* addTexture(const io::path& name, IImage* image); virtual ITexture* addTexture(const io::path& name, IImage* image, void* mipmapData=0);
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name); virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
//! checks triangle count and print warning if wrong //! checks triangle count and print warning if wrong
bool checkPrimitiveCount(u32 prmcnt) const; bool checkPrimitiveCount(u32 prmcnt) const;
...@@ -640,14 +640,14 @@ namespace video ...@@ -640,14 +640,14 @@ namespace video
{ {
SDummyTexture(const io::path& name) : ITexture(name), size(0,0) {}; SDummyTexture(const io::path& name) : ITexture(name), size(0,0) {};
virtual void* lock(bool readOnly = false) { return 0; }; virtual void* lock(bool readOnly = false, u32 mipmapLevel=0) { return 0; };
virtual void unlock(){} virtual void unlock(){}
virtual const core::dimension2d<u32>& getOriginalSize() const { return size; } virtual const core::dimension2d<u32>& getOriginalSize() const { return size; }
virtual const core::dimension2d<u32>& getSize() const { return size; } virtual const core::dimension2d<u32>& getSize() const { return size; }
virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; } virtual E_DRIVER_TYPE getDriverType() const { return video::EDT_NULL; }
virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; }; virtual ECOLOR_FORMAT getColorFormat() const { return video::ECF_A1R5G5B5; };
virtual u32 getPitch() const { return 0; } virtual u32 getPitch() const { return 0; }
virtual void regenerateMipMapLevels() {}; virtual void regenerateMipMapLevels(void* mipmapData=0) {};
core::dimension2d<u32> size; core::dimension2d<u32> size;
}; };
......
...@@ -2011,9 +2011,9 @@ inline void COpenGLDriver::createGLTextureMatrix(GLfloat *o, const core::matrix4 ...@@ -2011,9 +2011,9 @@ inline void COpenGLDriver::createGLTextureMatrix(GLfloat *o, const core::matrix4
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name) video::ITexture* COpenGLDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
{ {
return new COpenGLTexture(surface, name, this); return new COpenGLTexture(surface, name, mipmapData, this);
} }
......
...@@ -338,7 +338,7 @@ namespace video ...@@ -338,7 +338,7 @@ namespace video
//! inits the parts of the open gl driver used on all platforms //! inits the parts of the open gl driver used on all platforms
bool genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer); bool genericDriverInit(const core::dimension2d<u32>& screenSize, bool stencilBuffer);
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name); virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData);
//! creates a transposed matrix in supplied GLfloat array to pass to OpenGL //! creates a transposed matrix in supplied GLfloat array to pass to OpenGL
inline void createGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m); inline void createGLMatrix(GLfloat gl_matrix[16], const core::matrix4& m);
......
This diff is collapsed.
...@@ -51,13 +51,13 @@ class COpenGLTexture : public ITexture ...@@ -51,13 +51,13 @@ class COpenGLTexture : public ITexture
public: public:
//! constructor //! constructor
COpenGLTexture(IImage* surface, const io::path& name, COpenGLDriver* driver=0); COpenGLTexture(IImage* surface, const io::path& name, void* mipmapData=0, COpenGLDriver* driver=0);
//! destructor //! destructor
virtual ~COpenGLTexture(); virtual ~COpenGLTexture();
//! lock function //! lock function
virtual void* lock(bool readOnly = false); virtual void* lock(bool readOnly=false, u32 mipmapLevel=0);
//! unlock function //! unlock function
virtual void unlock(); virtual void unlock();
...@@ -83,9 +83,10 @@ public: ...@@ -83,9 +83,10 @@ public:
//! return whether this texture has mipmaps //! return whether this texture has mipmaps
virtual bool hasMipMaps() const; virtual bool hasMipMaps() const;
//! Regenerates the mip map levels of the texture. Useful after //! Regenerates the mip map levels of the texture.
//! locking and modifying the texture /** Useful after locking and modifying the texture
virtual void regenerateMipMapLevels(); \param mipmapData Pointer to raw mipmap data, including all necessary mip levels, in the same format as the main texture image. If not set the mipmaps are derived from the main image. */
virtual void regenerateMipMapLevels(void* mipmapData=0);
//! Is it a render target? //! Is it a render target?
virtual bool isRenderTarget() const; virtual bool isRenderTarget() const;
...@@ -114,24 +115,28 @@ protected: ...@@ -114,24 +115,28 @@ protected:
GLint getOpenGLFormatAndParametersFromColorFormat( GLint getOpenGLFormatAndParametersFromColorFormat(
ECOLOR_FORMAT format, GLint& filtering, GLenum& colorformat, GLenum& type); ECOLOR_FORMAT format, GLint& filtering, GLenum& colorformat, GLenum& type);
//! convert the image into an internal image with better properties for this driver. //! get important numbers of the image and hw texture
void getImageData(IImage* image); void getImageValues(IImage* image);
//! copies the texture into an OpenGL texture. //! copies the texture into an OpenGL texture.
//! \param: newTexture is true if method is called from a newly created texture for the first time. Otherwise call with false to improve memory handling. /** \param newTexture True if method is called for a newly created texture for the first time. Otherwise call with false to improve memory handling.
void copyTexture(bool newTexture=true); \param mipmapData Pointer to raw mipmap data, including all necessary mip levels, in the same format as the main texture image.
\param mipLevel If set to non-zero, only that specific miplevel is updated, using the MipImage member. */
void uploadTexture(bool newTexture=false, void* mipmapData=0, u32 mipLevel=0);
core::dimension2d<u32> ImageSize; core::dimension2d<u32> ImageSize;
core::dimension2d<u32> TextureSize; core::dimension2d<u32> TextureSize;
ECOLOR_FORMAT ColorFormat; ECOLOR_FORMAT ColorFormat;
COpenGLDriver* Driver; COpenGLDriver* Driver;
IImage* Image; IImage* Image;
IImage* MipImage;
GLuint TextureName; GLuint TextureName;
GLint InternalFormat; GLint InternalFormat;
GLenum PixelFormat; GLenum PixelFormat;
GLenum PixelType; GLenum PixelType;
u8 MipLevelStored;
bool HasMipMaps; bool HasMipMaps;
bool IsRenderTarget; bool IsRenderTarget;
bool AutomaticMipmapUpdate; bool AutomaticMipmapUpdate;
......
...@@ -241,9 +241,9 @@ bool CSoftwareDriver::endScene() ...@@ -241,9 +241,9 @@ bool CSoftwareDriver::endScene()
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const io::path& name) ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
{ {
return new CSoftwareTexture(surface, name); return new CSoftwareTexture(surface, name, false, mipmapData);
} }
......
...@@ -101,7 +101,7 @@ namespace video ...@@ -101,7 +101,7 @@ namespace video
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name); virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
//! Creates a render target texture. //! Creates a render target texture.
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size, virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
......
...@@ -2062,13 +2062,12 @@ IImage* CBurningVideoDriver::createScreenShot() ...@@ -2062,13 +2062,12 @@ IImage* CBurningVideoDriver::createScreenShot()
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
ITexture* CBurningVideoDriver::createDeviceDependentTexture(IImage* surface, const io::path& name) ITexture* CBurningVideoDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
{ {
return new CSoftwareTexture2( return new CSoftwareTexture2(
surface, name, surface, name,
(getTextureCreationFlag(ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0 ) | (getTextureCreationFlag(ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0 ) |
(getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2) ? 0 : CSoftwareTexture2::NP2_SIZE ) (getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2) ? 0 : CSoftwareTexture2::NP2_SIZE ), mipmapData);
);
} }
......
...@@ -168,7 +168,7 @@ namespace video ...@@ -168,7 +168,7 @@ namespace video
//! returns a device dependent texture from a software surface (IImage) //! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES //! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name); virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
video::CImage* BackBuffer; video::CImage* BackBuffer;
video::IImagePresenter* Presenter; video::IImagePresenter* Presenter;
......
...@@ -14,7 +14,8 @@ namespace video ...@@ -14,7 +14,8 @@ namespace video
{ {
//! constructor //! constructor
CSoftwareTexture::CSoftwareTexture(IImage* image, const io::path& name, bool renderTarget) CSoftwareTexture::CSoftwareTexture(IImage* image, const io::path& name,
bool renderTarget, void* mipmapData)
: ITexture(name), Texture(0), IsRenderTarget(renderTarget) : ITexture(name), Texture(0), IsRenderTarget(renderTarget)
{ {
#ifdef _DEBUG #ifdef _DEBUG
...@@ -57,7 +58,7 @@ CSoftwareTexture::~CSoftwareTexture() ...@@ -57,7 +58,7 @@ CSoftwareTexture::~CSoftwareTexture()
//! lock function //! lock function
void* CSoftwareTexture::lock(bool readOnly) void* CSoftwareTexture::lock(bool readOnly, u32 mipmapLevel)
{ {
return Image->lock(); return Image->lock();
} }
...@@ -132,7 +133,7 @@ u32 CSoftwareTexture::getPitch() const ...@@ -132,7 +133,7 @@ u32 CSoftwareTexture::getPitch() const
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
void CSoftwareTexture::regenerateMipMapLevels() void CSoftwareTexture::regenerateMipMapLevels(void* mipmapData)
{ {
// our software textures don't have mip maps // our software textures don't have mip maps
} }
......
...@@ -21,13 +21,14 @@ class CSoftwareTexture : public ITexture ...@@ -21,13 +21,14 @@ class CSoftwareTexture : public ITexture
public: public:
//! constructor //! constructor
CSoftwareTexture(IImage* surface, const io::path& name, bool renderTarget=false); CSoftwareTexture(IImage* surface, const io::path& name,
bool renderTarget=false, void* mipmapData=0);
//! destructor //! destructor
virtual ~CSoftwareTexture(); virtual ~CSoftwareTexture();
//! lock function //! lock function
virtual void* lock(bool readOnly = false); virtual void* lock(bool readOnly = false, u32 mipmapLevel=0);
//! unlock function //! unlock function
virtual void unlock(); virtual void unlock();
...@@ -55,7 +56,7 @@ public: ...@@ -55,7 +56,7 @@ public:
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
virtual void regenerateMipMapLevels(); virtual void regenerateMipMapLevels(void* mipmapData=0);
//! is it a render target? //! is it a render target?
virtual bool isRenderTarget() const; virtual bool isRenderTarget() const;
......
...@@ -16,8 +16,9 @@ namespace video ...@@ -16,8 +16,9 @@ namespace video
{ {
//! constructor //! constructor
CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags ) CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name,
: ITexture(name), MipMapLOD(0), Flags ( flags ) u32 flags, void* mipmapData)
: ITexture(name), MipMapLOD(0), Flags ( flags ), OriginalFormat(video::ECF_UNKNOWN)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSoftwareTexture2"); setDebugName("CSoftwareTexture2");
...@@ -32,6 +33,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl ...@@ -32,6 +33,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
if (image) if (image)
{ {
OrigSize = image->getDimension(); OrigSize = image->getDimension();
OriginalFormat = image->getColorFormat();
core::setbit_cond(Flags, core::setbit_cond(Flags,
image->getColorFormat () == video::ECF_A8R8G8B8 || image->getColorFormat () == video::ECF_A8R8G8B8 ||
...@@ -66,8 +68,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl ...@@ -66,8 +68,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
} }
} }
regenerateMipMapLevels(); regenerateMipMapLevels(mipmapData);
setCurrentMipMapLOD(0);
} }
...@@ -84,7 +85,7 @@ CSoftwareTexture2::~CSoftwareTexture2() ...@@ -84,7 +85,7 @@ CSoftwareTexture2::~CSoftwareTexture2()
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
void CSoftwareTexture2::regenerateMipMapLevels() void CSoftwareTexture2::regenerateMipMapLevels(void* mipmapData)
{ {
if ( !hasMipMaps () ) if ( !hasMipMaps () )
return; return;
...@@ -99,21 +100,48 @@ void CSoftwareTexture2::regenerateMipMapLevels() ...@@ -99,21 +100,48 @@ void CSoftwareTexture2::regenerateMipMapLevels()
} }
core::dimension2d<u32> newSize; core::dimension2d<u32> newSize;
core::dimension2d<u32> currentSize; core::dimension2d<u32> origSize=OrigSize;
i = 1; for (i=1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
CImage * c = MipMap[0];
while ( i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX )
{ {
currentSize = c->getDimension(); newSize = MipMap[i-1]->getDimension();
newSize.Width = core::s32_max ( 1, currentSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE ); newSize.Width = core::s32_max ( 1, newSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
newSize.Height = core::s32_max ( 1, currentSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE ); newSize.Height = core::s32_max ( 1, newSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
origSize.Width = core::s32_max(1, origSize.Width >> 1);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); origSize.Height = core::s32_max(1, origSize.Height >> 1);
MipMap[i]->fill ( 0 );
MipMap[0]->copyToScalingBoxFilter( MipMap[i], 0, false ); if (mipmapData)
c = MipMap[i]; {
++i; if (OriginalFormat != BURNINGSHADER_COLOR_FORMAT)
{
IImage* tmpImage = new CImage(OriginalFormat, origSize, mipmapData, true, false);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
if (origSize==newSize)
tmpImage->copyTo(MipMap[i]);
else
tmpImage->copyToScalingBoxFilter(MipMap[i]);
tmpImage->drop();
}
else
{
if (origSize==newSize)
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mipmapData, false);
else
{
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mipmapData, true, false);
tmpImage->copyToScalingBoxFilter(MipMap[i]);
tmpImage->drop();
}
}
mipmapData = (u8*)mipmapData+origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8;
}
else
{
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
MipMap[i]->fill ( 0 );
MipMap[0]->copyToScalingBoxFilter( MipMap[i], 0, false );
}
} }
} }
...@@ -122,4 +150,3 @@ void CSoftwareTexture2::regenerateMipMapLevels() ...@@ -122,4 +150,3 @@ void CSoftwareTexture2::regenerateMipMapLevels()
} // end namespace irr } // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
...@@ -25,19 +25,21 @@ public: ...@@ -25,19 +25,21 @@ public:
//! constructor //! constructor
enum eTex2Flags enum eTex2Flags
{ {
GEN_MIPMAP = 1, GEN_MIPMAP = 1,
IS_RENDERTARGET = 2, IS_RENDERTARGET = 2,
NP2_SIZE = 4, NP2_SIZE = 4,
HAS_ALPHA = 8 HAS_ALPHA = 8
}; };
CSoftwareTexture2( IImage* surface, const io::path& name, u32 flags ); CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags, void* mipmapData=0);
//! destructor //! destructor
virtual ~CSoftwareTexture2(); virtual ~CSoftwareTexture2();
//! lock function //! lock function
virtual void* lock(bool readOnly = false) virtual void* lock(bool readOnly = false, u32 mipmapLevel=0)
{ {
if (Flags & GEN_MIPMAP)
MipMapLOD=mipmapLevel;
return MipMap[MipMapLOD]->lock(); return MipMap[MipMapLOD]->lock();
} }
...@@ -99,14 +101,7 @@ public: ...@@ -99,14 +101,7 @@ public:
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
virtual void regenerateMipMapLevels(); virtual void regenerateMipMapLevels(void* mipmapData=0);
//! Select a Mipmap Level
virtual void setCurrentMipMapLOD ( s32 lod )
{
if ( Flags & GEN_MIPMAP )
MipMapLOD = lod;
}
//! support mipmaps //! support mipmaps
virtual bool hasMipMaps() const virtual bool hasMipMaps() const
...@@ -131,8 +126,9 @@ private: ...@@ -131,8 +126,9 @@ private:
CImage * MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX]; CImage * MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
s32 MipMapLOD; u32 MipMapLOD;
u32 Flags; u32 Flags;
ECOLOR_FORMAT OriginalFormat;
}; };
......
...@@ -10,11 +10,10 @@ ...@@ -10,11 +10,10 @@
namespace irr namespace irr
{ {
namespace video namespace video
{ {
const tFixPointu IBurningShader::dithermask[ 4 * 4] = const tFixPointu IBurningShader::dithermask[] =
{ {
0x00,0x80,0x20,0xa0, 0x00,0x80,0x20,0xa0,
0xc0,0x40,0xe0,0x60, 0xc0,0x40,0xe0,0x60,
...@@ -23,7 +22,7 @@ namespace video ...@@ -23,7 +22,7 @@ namespace video
}; };
IBurningShader::IBurningShader(IDepthBuffer* zbuffer) IBurningShader::IBurningShader(IDepthBuffer* zbuffer)
:RenderTarget(0),DepthBuffer(zbuffer) : RenderTarget(0),DepthBuffer(zbuffer)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("IBurningShader"); setDebugName("IBurningShader");
...@@ -70,7 +69,6 @@ namespace video ...@@ -70,7 +69,6 @@ namespace video
//(tVideoSample*)RenderTarget->lock() = (tVideoSample*)RenderTarget->lock(); //(tVideoSample*)RenderTarget->lock() = (tVideoSample*)RenderTarget->lock();
//(fp24*) DepthBuffer->lock() = DepthBuffer->lock(); //(fp24*) DepthBuffer->lock() = DepthBuffer->lock();
} }
} }
...@@ -91,9 +89,8 @@ namespace video ...@@ -91,9 +89,8 @@ namespace video
// select mignify and magnify ( lodLevel ) // select mignify and magnify ( lodLevel )
//SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS //SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS
it->lodLevel = lodLevel; it->lodLevel = lodLevel;
it->Texture->setCurrentMipMapLOD ( it->data = (tVideoSample*) it->Texture->lock(true,
core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 ) core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 ));
);
// prepare for optimal fixpoint // prepare for optimal fixpoint
it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() ); it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );
...@@ -101,12 +98,10 @@ namespace video ...@@ -101,12 +98,10 @@ namespace video
const core::dimension2d<u32> &dim = it->Texture->getSize(); const core::dimension2d<u32> &dim = it->Texture->getSize();
it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK; it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;
it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK; it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;
it->data = (tVideoSample*) it->Texture->lock();
} }
} }
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr
......
...@@ -9,34 +9,34 @@ bool testArchive(IFileSystem* fs, const io::path& archiveName) ...@@ -9,34 +9,34 @@ bool testArchive(IFileSystem* fs, const io::path& archiveName)
// make sure there is no archive mounted // make sure there is no archive mounted
if ( fs->getFileArchiveCount() ) if ( fs->getFileArchiveCount() )
{ {
logTestString("Already mounted archives found"); logTestString("Already mounted archives found\n");
return false; return false;
} }
if ( !fs->addFileArchive(archiveName, /*bool ignoreCase=*/true, /*bool ignorePaths=*/false) ) if ( !fs->addFileArchive(archiveName, /*bool ignoreCase=*/true, /*bool ignorePaths=*/false) )
{ {
logTestString("Mounting archive failed"); logTestString("Mounting archive failed\n");
return false; return false;
} }
// make sure there is an archive mounted // make sure there is an archive mounted
if ( !fs->getFileArchiveCount() ) if ( !fs->getFileArchiveCount() )
{ {
logTestString("Mounted archive not in list"); logTestString("Mounted archive not in list\n");
return false; return false;
} }
// mount again // mount again
if ( !fs->addFileArchive(archiveName, /*bool ignoreCase=*/true, /*bool ignorePaths=*/false) ) if ( !fs->addFileArchive(archiveName, /*bool ignoreCase=*/true, /*bool ignorePaths=*/false) )
{ {
logTestString("Mounting a second time failed"); logTestString("Mounting a second time failed\n");
return false; return false;
} }
// make sure there is exactly one archive mounted // make sure there is exactly one archive mounted
if ( fs->getFileArchiveCount() != 1 ) if ( fs->getFileArchiveCount() != 1 )
{ {
logTestString("Duplicate mount not recognized"); logTestString("Duplicate mount not recognized\n");
return false; return false;
} }
...@@ -52,21 +52,21 @@ bool testArchive(IFileSystem* fs, const io::path& archiveName) ...@@ -52,21 +52,21 @@ bool testArchive(IFileSystem* fs, const io::path& archiveName)
io::path filename("mypath/mypath/myfile.txt"); io::path filename("mypath/mypath/myfile.txt");
if (!fs->existFile(filename)) if (!fs->existFile(filename))
{ {
logTestString("existFile with deep path failed"); logTestString("existFile with deep path failed\n");
return false; return false;
} }
filename="test/test.txt"; filename="test/test.txt";
if (!fs->existFile(filename)) if (!fs->existFile(filename))
{ {
logTestString("existFile failed"); logTestString("existFile failed\n");
return false; return false;
} }
IReadFile* readFile = fs->createAndOpenFile(filename); IReadFile* readFile = fs->createAndOpenFile(filename);
if ( !readFile ) if ( !readFile )
{ {
logTestString("createAndOpenFilefailed"); logTestString("createAndOpenFilefailed\n");
return false; return false;
} }
...@@ -74,7 +74,7 @@ bool testArchive(IFileSystem* fs, const io::path& archiveName) ...@@ -74,7 +74,7 @@ bool testArchive(IFileSystem* fs, const io::path& archiveName)
readFile->read(tmp, 12); readFile->read(tmp, 12);
if (strncmp(tmp, "Hello world!", 12)) if (strncmp(tmp, "Hello world!", 12))
{ {
logTestString("Read bad data from archive: %s", tmp); logTestString("Read bad data from archive: %s\n", tmp);
return false; return false;
} }
if (!fs->removeFileArchive(fs->getFileArchiveCount()-1)) if (!fs->removeFileArchive(fs->getFileArchiveCount()-1))
......
...@@ -89,6 +89,7 @@ int main(int argumentCount, char * arguments[]) ...@@ -89,6 +89,7 @@ int main(int argumentCount, char * arguments[])
TEST(guiDisabledMenu); TEST(guiDisabledMenu);
TEST(makeColorKeyTexture); TEST(makeColorKeyTexture);
TEST(renderTargetTexture); TEST(renderTargetTexture);
TEST(textureFeatures);
TEST(textureRenderStates); TEST(textureRenderStates);
TEST(transparentAlphaChannelRef); TEST(transparentAlphaChannelRef);
// TODO: Needs to be fixed first. // TODO: Needs to be fixed first.
...@@ -103,7 +104,7 @@ int main(int argumentCount, char * arguments[]) ...@@ -103,7 +104,7 @@ int main(int argumentCount, char * arguments[])
unsigned int fails = 0; unsigned int fails = 0;
bool firstRun=true; bool firstRun=true;
const bool spawn=true; const bool spawn=false;
// args: [testNumber] [testCount] // args: [testNumber] [testCount]
if(argumentCount > 1) if(argumentCount > 1)
{ {
......
...@@ -310,6 +310,10 @@ ...@@ -310,6 +310,10 @@
RelativePath=".\testXML.cpp" RelativePath=".\testXML.cpp"
> >
</File> </File>
<File
RelativePath=".\textureFeatures.cpp"
>
</File>
<File <File
RelativePath=".\textureRenderStates.cpp" RelativePath=".\textureRenderStates.cpp"
> >
......
// Copyright (C) 2008-2009 Christian Stehno, Colin MacDonald
// No rights reserved: this software is in the public domain.
#include "testUtils.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
//! Tests locking miplevels
static bool lockAllMipLevels(E_DRIVER_TYPE driverType)
{
bool result=true;
IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
if (!device)
return result; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
IVideoDriver* driver = device->getVideoDriver();
ISceneManager * smgr = device->getSceneManager();
scene::ISceneNode* n = smgr->addCubeSceneNode();
if (n)
{
// create the texture and miplevels with distinct colors
u32 texData[16*16];
for (u32 i=0; i<16*16; ++i)
texData[i]=0xff0000ff;
video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, core::dimension2du(16,16), texData, false);
u32 mipdata[8*16];
u32 index=0;
for (u32 j=8; j>0; j/=2)
{
u32 val=(j==8?0x00ff00ff:(j==4?0x0000ffff:(j==2?0xc2c200ff:0x001212ff)));
for (u32 i=0; i<j; ++i)
{
for (u32 k=0; k<j; ++k)
mipdata[index++]=val;
}
}
ITexture* tex = driver->addTexture("miptest", image, mipdata);
if (!tex)
// is probably an error in the mipdata handling
return false;
else
n->setMaterialTexture(0, tex);
image->drop();
}
(void)smgr->addCameraSceneNode();
driver->beginScene(true, true, SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
video::ITexture* tex = driver->findTexture("miptest");
video::SColor* bits = (video::SColor*)tex->lock(true, 0);
result |= (bits[0].color==0xff0000ff);
tex->unlock();
bits = (video::SColor*)tex->lock(true, 1);
result |= (bits[0].color==0x00ff00ff);
tex->unlock();
bits = (video::SColor*)tex->lock(true, 2);
result |= (bits[0].color==0x0000ffff);
tex->unlock();
bits = (video::SColor*)tex->lock(true, 3);
result |= (bits[0].color==0xc2c200ff);
tex->unlock();
bits = (video::SColor*)tex->lock(true, 4);
result |= (bits[0].color==0x001212ff);
tex->unlock();
device->drop();
return result;
}
bool textureFeatures(void)
{
bool passed = true;
passed &= lockAllMipLevels(EDT_OPENGL);
passed &= lockAllMipLevels(EDT_SOFTWARE);
passed &= lockAllMipLevels(EDT_BURNINGSVIDEO);
passed &= lockAllMipLevels(EDT_DIRECT3D9);
passed &= lockAllMipLevels(EDT_DIRECT3D8);
return passed;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment