diff --git a/include/IRenderTarget.h b/include/IRenderTarget.h index 21e9dccd..ffe00a47 100644 --- a/include/IRenderTarget.h +++ b/include/IRenderTarget.h @@ -15,6 +15,17 @@ namespace video { class ITexture; + //! Enumeration of cube texture surfaces + enum E_CUBE_SURFACE + { + ECS_POSX = 0, + ECS_NEGX, + ECS_POSY, + ECS_NEGY, + ECS_POSZ, + ECS_NEGZ + }; + //! Interface of a Render Target. class IRenderTarget : public virtual IReferenceCounted { @@ -41,8 +52,10 @@ namespace video /** Set multiple textures for the render target. \param texture Array of texture objects. These textures are used for a color outputs. \param depthStencil Depth or packed depth-stencil texture. This texture is used as depth - or depth-stencil buffer. */ - virtual void setTexture(const core::array& texture, ITexture* depthStencil) = 0; + or depth-stencil buffer. + \param cubeSurfaces When rendering to cube textures, set the surface to be used for each texture. Can be empty otherwise. + */ + virtual void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces = core::array()) = 0; //! Set one texture. void setTexture(ITexture* texture, ITexture* depthStencil) @@ -53,6 +66,18 @@ namespace video setTexture(textureArray, depthStencil); } + //! Set one cube surface texture. + void setTexture(ITexture* texture, ITexture* depthStencil, E_CUBE_SURFACE cubeSurface) + { + core::array textureArray(1); + textureArray.push_back(texture); + + core::array cubeSurfaces(1); + cubeSurfaces.push_back(cubeSurface); + + setTexture(textureArray, depthStencil, cubeSurfaces); + } + //! Get driver type of render target. E_DRIVER_TYPE getDriverType() const { @@ -67,6 +92,9 @@ namespace video //! Depth or packed depth-stencil texture assigned to render target. ITexture* DepthStencil; + //! Active surface of cube textures + core::array CubeSurfaces; + //! Driver type of render target. E_DRIVER_TYPE DriverType; diff --git a/include/IVideoDriver.h b/include/IVideoDriver.h index db9522eb..87fe4712 100644 --- a/include/IVideoDriver.h +++ b/include/IVideoDriver.h @@ -391,6 +391,18 @@ namespace video virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, const io::path& name = "rt", const ECOLOR_FORMAT format = ECF_UNKNOWN) =0; + //! Adds a new render target texture with 6 sides for a cubemap map to the texture cache. + /** NOTE: Only supported on D3D9 so far. + \param sideLen Length of one cubemap side. + \param name A name for the texture. Later calls of getTexture() with this name will return this texture. + The name can _not_ be empty. + \param format The color format of the render target. Floating point formats are supported. + \return Pointer to the created texture or 0 if the texture + could not be created. This pointer should not be dropped. See + IReferenceCounted::drop() for more information. */ + virtual ITexture* addRenderTargetTextureCubemap(const irr::u32 sideLen, + const io::path& name = "rt", const ECOLOR_FORMAT format = ECF_UNKNOWN) =0; + //! Removes a texture from the texture cache and deletes it. /** This method can free a lot of memory! Please note that after calling this, the pointer to the diff --git a/source/Irrlicht/CD3D9Driver.cpp b/source/Irrlicht/CD3D9Driver.cpp index 2a55c7bb..4cdc64b6 100644 --- a/source/Irrlicht/CD3D9Driver.cpp +++ b/source/Irrlicht/CD3D9Driver.cpp @@ -3221,7 +3221,7 @@ ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d& size const io::path& name, const ECOLOR_FORMAT format) { - CD3D9Texture* tex = new CD3D9Texture(this, size, name, format); + CD3D9Texture* tex = new CD3D9Texture(this, size, name, ETT_2D, format); if (tex) { if (!tex->Texture) @@ -3236,6 +3236,24 @@ ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d& size return tex; } +ITexture* CD3D9Driver::addRenderTargetTextureCubemap(const irr::u32 sideLen, + const io::path& name, const ECOLOR_FORMAT format) +{ + CD3D9Texture* tex = new CD3D9Texture(this, core::dimension2d(sideLen, sideLen), name, ETT_CUBEMAP, format); + if (tex) + { + if (!tex->CubeTexture) + { + tex->drop(); + return 0; + } + + addTexture(tex); + tex->drop(); + } + return tex; +} + void CD3D9Driver::clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) { DWORD internalFlag = 0; diff --git a/source/Irrlicht/CD3D9Driver.h b/source/Irrlicht/CD3D9Driver.h index bd63abc1..437a86a5 100644 --- a/source/Irrlicht/CD3D9Driver.h +++ b/source/Irrlicht/CD3D9Driver.h @@ -266,6 +266,10 @@ namespace video virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_; + //! Creates a render target texture for a cubemap + ITexture* addRenderTargetTextureCubemap(const irr::u32 sideLen, + const io::path& name, const ECOLOR_FORMAT format) _IRR_OVERRIDE_; + virtual void clearBuffers(u16 flag, SColor color = SColor(255,0,0,0), f32 depth = 1.f, u8 stencil = 0) _IRR_OVERRIDE_; //! Returns an image created from the last rendered frame. diff --git a/source/Irrlicht/CD3D9RenderTarget.cpp b/source/Irrlicht/CD3D9RenderTarget.cpp index 6e42e658..28458e88 100644 --- a/source/Irrlicht/CD3D9RenderTarget.cpp +++ b/source/Irrlicht/CD3D9RenderTarget.cpp @@ -49,9 +49,9 @@ namespace irr DepthStencil->drop(); } - void CD3D9RenderTarget::setTexture(const core::array& texture, ITexture* depthStencil) + void CD3D9RenderTarget::setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces) { - bool textureUpdate = (Texture != texture) ? true : false; + bool textureUpdate = (Texture != texture) || (CubeSurfaces != cubeSurfaces) ? true : false; bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false; if (textureUpdate || depthStencilUpdate) @@ -60,6 +60,8 @@ namespace irr if (textureUpdate) { + CubeSurfaces = cubeSurfaces; + if (texture.size() > Driver->ActiveRenderTarget.size()) { core::stringc message = "This GPU supports up to "; @@ -92,13 +94,15 @@ namespace irr CD3D9Texture* currentTexture = (texture[i] && texture[i]->getDriverType() == DriverType) ? static_cast(texture[i]) : 0; IDirect3DTexture9* textureID = 0; + IDirect3DCubeTexture9* cubeTextureId = 0; + UINT level = 0; // no support for rendering to to other mip-levels so far if (currentTexture) { if (currentTexture->getType() == ETT_2D) textureID = currentTexture->getDX9Texture(); - else - os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING); + else if ( currentTexture->getType() == ETT_CUBEMAP ) + cubeTextureId = currentTexture->getDX9CubeTexture(); } if (textureID) @@ -107,7 +111,18 @@ namespace irr Texture[i]->grab(); IDirect3DSurface9* currentSurface = 0; - textureID->GetSurfaceLevel(0, ¤tSurface); + textureID->GetSurfaceLevel(level, ¤tSurface); + + Surface[i] = currentSurface; + } + else if ( cubeTextureId ) + { + Texture[i] = texture[i]; + Texture[i]->grab(); + + IDirect3DSurface9* currentSurface = 0; + D3DCUBEMAP_FACES face = (D3DCUBEMAP_FACES)CubeSurfaces[i]; // we use same numbering + cubeTextureId->GetCubeMapSurface(face, level, ¤tSurface); Surface[i] = currentSurface; } @@ -146,7 +161,7 @@ namespace irr if (currentTexture->getType() == ETT_2D) textureID = currentTexture->getDX9Texture(); else - os::Printer::log("This driver doesn't support render to cubemaps.", ELL_WARNING); + os::Printer::log("This driver doesn't support depth/stencil to cubemaps.", ELL_WARNING); } if (textureID) diff --git a/source/Irrlicht/CD3D9RenderTarget.h b/source/Irrlicht/CD3D9RenderTarget.h index 2d076b39..1f643f09 100644 --- a/source/Irrlicht/CD3D9RenderTarget.h +++ b/source/Irrlicht/CD3D9RenderTarget.h @@ -29,7 +29,7 @@ namespace irr CD3D9RenderTarget(CD3D9Driver* driver); virtual ~CD3D9RenderTarget(); - virtual void setTexture(const core::array& texture, ITexture* depthStencil) _IRR_OVERRIDE_; + virtual void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces) _IRR_OVERRIDE_; const core::dimension2d& getSize() const; diff --git a/source/Irrlicht/CD3D9Texture.cpp b/source/Irrlicht/CD3D9Texture.cpp index 74c4b6da..8753ea4a 100644 --- a/source/Irrlicht/CD3D9Texture.cpp +++ b/source/Irrlicht/CD3D9Texture.cpp @@ -74,10 +74,10 @@ CD3D9Texture::CD3D9Texture(const io::path& name, const core::array& ima switch (Type) { case ETT_2D: - Device->CreateTexture(Size.Width, Size.Height, HasMipMaps ? 0 : 1, flags, InternalFormat, D3DPOOL_MANAGED, &Texture, NULL); + hr = Device->CreateTexture(Size.Width, Size.Height, HasMipMaps ? 0 : 1, flags, InternalFormat, D3DPOOL_MANAGED, &Texture, NULL); break; case ETT_CUBEMAP: - Device->CreateCubeTexture(Size.Width, HasMipMaps ? 0 : 1, flags, InternalFormat, D3DPOOL_MANAGED, &CubeTexture, NULL); + hr = Device->CreateCubeTexture(Size.Width, HasMipMaps ? 0 : 1, flags, InternalFormat, D3DPOOL_MANAGED, &CubeTexture, NULL); break; default: _IRR_DEBUG_BREAK_IF(true) @@ -114,8 +114,8 @@ CD3D9Texture::CD3D9Texture(const io::path& name, const core::array& ima } } -CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d& size, const io::path& name, const ECOLOR_FORMAT format) - : ITexture(name, ETT_2D), Driver(driver), InternalFormat(D3DFMT_UNKNOWN), LockReadOnly(false), LockData(0), LockLayer(0), +CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d& size, const io::path& name, E_TEXTURE_TYPE type, const ECOLOR_FORMAT format) + : ITexture(name, type), Driver(driver), InternalFormat(D3DFMT_UNKNOWN), LockReadOnly(false), LockData(0), LockLayer(0), AutoGenerateMipMaps(false), Device(0), Texture(0), CubeTexture(0), RTTSurface(0) { #ifdef _DEBUG @@ -344,32 +344,44 @@ void CD3D9Texture::releaseTexture() void CD3D9Texture::generateRenderTarget() { - if (!Texture) + DWORD flags = (IImage::isDepthFormat(ColorFormat)) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET; + + HRESULT hr = 0; + + switch (Type) { - DWORD flag = (IImage::isDepthFormat(ColorFormat)) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET; + case ETT_2D: + hr = Device->CreateTexture(Size.Width, Size.Height, 1, flags, InternalFormat, D3DPOOL_DEFAULT, &Texture, NULL); + break; + case ETT_CUBEMAP: + hr = Device->CreateCubeTexture(Size.Width, 1, flags, InternalFormat, D3DPOOL_DEFAULT, &CubeTexture, NULL); + break; + default: + _IRR_DEBUG_BREAK_IF(true) + break; + } - HRESULT hr = Device->CreateTexture(Size.Width, Size.Height, 1, flag, InternalFormat, D3DPOOL_DEFAULT, &Texture, NULL); - - if (FAILED(hr)) - { - if (D3DERR_INVALIDCALL == hr) - os::Printer::log("Could not create render target texture", "Invalid Call", irr::ELL_ERROR); - else if (D3DERR_OUTOFVIDEOMEMORY == hr) - os::Printer::log("Could not create render target texture", "Out of Video Memory", irr::ELL_ERROR); - else if (E_OUTOFMEMORY == hr) - os::Printer::log("Could not create render target texture", "Out of Memory", irr::ELL_ERROR); - else - os::Printer::log("Could not create render target texture", irr::ELL_ERROR); - core::stringc params("Width:"); - params += (unsigned int)Size.Width; - params += " Height: "; - params += (unsigned int)Size.Height; - params += " flag: "; - params += (unsigned int)flag; - params += " format"; - params += (unsigned int)InternalFormat; - os::Printer::log(params.c_str(), irr::ELL_ERROR); - } + if (FAILED(hr)) + { + if (D3DERR_INVALIDCALL == hr) + os::Printer::log("Could not create render target texture", "Invalid Call", irr::ELL_ERROR); + else if (D3DERR_OUTOFVIDEOMEMORY == hr) + os::Printer::log("Could not create render target texture", "Out of Video Memory", irr::ELL_ERROR); + else if (E_OUTOFMEMORY == hr) + os::Printer::log("Could not create render target texture", "Out of Memory", irr::ELL_ERROR); + else + os::Printer::log("Could not create render target texture", irr::ELL_ERROR); + core::stringc params("Width:"); + params += (unsigned int)Size.Width; + params += " Height: "; + params += (unsigned int)Size.Height; + params += " flag: "; + params += (unsigned int)flags; + params += " format"; + params += (unsigned int)InternalFormat; + params += " Type: "; + params += (unsigned int)Type; + os::Printer::log(params.c_str(), irr::ELL_ERROR); } } diff --git a/source/Irrlicht/CD3D9Texture.h b/source/Irrlicht/CD3D9Texture.h index 3d8b1e01..aa09d4e0 100644 --- a/source/Irrlicht/CD3D9Texture.h +++ b/source/Irrlicht/CD3D9Texture.h @@ -28,7 +28,7 @@ class CD3D9Texture : public ITexture public: CD3D9Texture(const io::path& name, const core::array& image, E_TEXTURE_TYPE type, CD3D9Driver* driver); - CD3D9Texture(CD3D9Driver* driver, const core::dimension2d& size, const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN); + CD3D9Texture(CD3D9Driver* driver, const core::dimension2d& size, const io::path& name, E_TEXTURE_TYPE type, const ECOLOR_FORMAT format = ECF_UNKNOWN); virtual ~CD3D9Texture(); diff --git a/source/Irrlicht/CNullDriver.cpp b/source/Irrlicht/CNullDriver.cpp index de452f49..8a6384b8 100644 --- a/source/Irrlicht/CNullDriver.cpp +++ b/source/Irrlicht/CNullDriver.cpp @@ -2610,6 +2610,12 @@ ITexture* CNullDriver::addRenderTargetTexture(const core::dimension2d& size return 0; } +ITexture* CNullDriver::addRenderTargetTextureCubemap(const irr::u32 sideLen, + const io::path& name, const ECOLOR_FORMAT format) +{ + return 0; +} + void CNullDriver::clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) { } diff --git a/source/Irrlicht/CNullDriver.h b/source/Irrlicht/CNullDriver.h index 2154f2ed..eadbdb3f 100644 --- a/source/Irrlicht/CNullDriver.h +++ b/source/Irrlicht/CNullDriver.h @@ -319,6 +319,10 @@ namespace video virtual ITexture* addRenderTargetTexture(const core::dimension2d& size, const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_; + //! Creates a render target texture for a cubemap + ITexture* CNullDriver::addRenderTargetTextureCubemap(const irr::u32 sideLen, + const io::path& name, const ECOLOR_FORMAT format) _IRR_OVERRIDE_; + //! Creates an 1bit alpha channel of the texture based of an color key. virtual void makeColorKeyTexture(video::ITexture* texture, video::SColor color, bool zeroTexels) const _IRR_OVERRIDE_; diff --git a/source/Irrlicht/COpenGLCoreRenderTarget.h b/source/Irrlicht/COpenGLCoreRenderTarget.h index 10ef958f..f5107d60 100644 --- a/source/Irrlicht/COpenGLCoreRenderTarget.h +++ b/source/Irrlicht/COpenGLCoreRenderTarget.h @@ -58,7 +58,7 @@ public: DepthStencil->drop(); } - virtual void setTexture(const core::array& texture, ITexture* depthStencil) _IRR_OVERRIDE_ + virtual void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces) _IRR_OVERRIDE_ { bool textureUpdate = (Texture != texture) ? true : false; bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false; diff --git a/source/Irrlicht/CSoftwareTexture.cpp b/source/Irrlicht/CSoftwareTexture.cpp index 46460f7f..78a64cb5 100644 --- a/source/Irrlicht/CSoftwareTexture.cpp +++ b/source/Irrlicht/CSoftwareTexture.cpp @@ -129,7 +129,7 @@ CSoftwareRenderTarget::~CSoftwareRenderTarget() Texture[0]->drop(); } -void CSoftwareRenderTarget::setTexture(const core::array& texture, ITexture* depthStencil) +void CSoftwareRenderTarget::setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces) { if (Texture != texture) { diff --git a/source/Irrlicht/CSoftwareTexture.h b/source/Irrlicht/CSoftwareTexture.h index dc545a1d..55efb8c8 100644 --- a/source/Irrlicht/CSoftwareTexture.h +++ b/source/Irrlicht/CSoftwareTexture.h @@ -57,7 +57,7 @@ public: CSoftwareRenderTarget(CSoftwareDriver* driver); virtual ~CSoftwareRenderTarget(); - virtual void setTexture(const core::array& texture, ITexture* depthStencil) _IRR_OVERRIDE_; + virtual void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces) _IRR_OVERRIDE_; ITexture* getTexture() const; diff --git a/source/Irrlicht/CSoftwareTexture2.cpp b/source/Irrlicht/CSoftwareTexture2.cpp index cdd2659e..82cb51aa 100644 --- a/source/Irrlicht/CSoftwareTexture2.cpp +++ b/source/Irrlicht/CSoftwareTexture2.cpp @@ -181,7 +181,7 @@ CSoftwareRenderTarget2::~CSoftwareRenderTarget2() Texture[0]->drop(); } -void CSoftwareRenderTarget2::setTexture(const core::array& texture, ITexture* depthStencil) +void CSoftwareRenderTarget2::setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces) { if (Texture != texture) { diff --git a/source/Irrlicht/CSoftwareTexture2.h b/source/Irrlicht/CSoftwareTexture2.h index 63e010d7..42eb880f 100644 --- a/source/Irrlicht/CSoftwareTexture2.h +++ b/source/Irrlicht/CSoftwareTexture2.h @@ -101,7 +101,7 @@ public: CSoftwareRenderTarget2(CBurningVideoDriver* driver); virtual ~CSoftwareRenderTarget2(); - virtual void setTexture(const core::array& texture, ITexture* depthStencil) _IRR_OVERRIDE_; + virtual void setTexture(const core::array& texture, ITexture* depthStencil, const core::array& cubeSurfaces) _IRR_OVERRIDE_; ITexture* getTexture() const;