Commit 657fad23 authored by nadro's avatar nadro

- Added ability to set custom depth/stencil texture for render targets (currently OpenGL only).

- Added new color formats: ECF_D16, ECF_D32, ECF_D24S8 (currently OpenGL only).


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4984 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 46c24d2c
--------------------------
Changes in 1.9 (not yet released)
- Added ability to set custom depth/stencil texture for render targets.
- Added new color formats: ECF_R8, ECF_R8G8, ECF_D16, ECF_D32, ECF_D24S8.
- Can now enable/disable backround drawing for IGUITable.
- Bugfix: Cloning CBillboardSceneNode now copies colors and sizes.
- EditBox works now with numpad on X11
......
......@@ -125,6 +125,12 @@ public:
case ECF_DXT4:
case ECF_DXT5:
return 32;
case ECF_D16:
return 16;
case ECF_D32:
return 32;
case ECF_D24S8:
return 32;
case ECF_R8:
return 8;
case ECF_R8G8:
......@@ -166,6 +172,20 @@ public:
}
}
//! test if the color format is only viable for depth/stencil textures
static bool isDepthFormat(const ECOLOR_FORMAT format)
{
switch(format)
{
case ECF_D16:
case ECF_D32:
case ECF_D24S8:
return true;
default:
return false;
}
}
//! test if the color format is only viable for RenderTarget textures
/** Since we don't have support for e.g. floating point IImage formats
one should test if the color format can be used for arbitrary usage, or
......
......@@ -552,7 +552,7 @@ namespace video
information is multiplied.*/
virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const =0;
//! Sets a new render target.
//! Sets a new render target. (this prototype will be removed in future)
/** This will only work if the driver supports the
EVDF_RENDER_TO_TARGET feature, which can be queried with
queryFeature(). Usually, rendering to textures is done in this
......@@ -586,7 +586,32 @@ namespace video
\return True if sucessful and false if not. */
virtual bool setRenderTarget(video::ITexture* texture,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0)) =0;
SColor color=video::SColor(0,0,0,0),
video::ITexture* depthStencil = 0) =0;
//! Sets a new render target.
virtual bool setRenderTarget(video::ITexture* texture,
video::ITexture* depthStencil,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0))
{
return setRenderTarget(texture, clearBackBuffer, clearZBuffer, color, depthStencil);
}
//! Sets new multiple render targets. (this prototype will be removed in future)
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0),
video::ITexture* depthStencil = 0) =0;
//! Sets new multiple render targets.
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
video::ITexture* depthStencil,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0))
{
return setRenderTarget(texture, clearBackBuffer, clearZBuffer, color, depthStencil);
}
//! set or reset special render targets
/** This method enables access to special color buffers such as
......@@ -604,11 +629,6 @@ namespace video
bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0)) =0;
//! Sets new multiple render targets.
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0)) =0;
//! Sets a new viewport.
/** Every rendering operation is done into this new area.
\param area: Rectangle defining the new area of rendering
......
......@@ -50,6 +50,17 @@ namespace video
/** The following formats may only be used for render target textures. */
/** Depth and stencil formats. */
//! 16 bit format using 16 bits for depth.
ECF_D16,
//! 32 bit format using 32 bits for depth.
ECF_D32,
//! 32 bit format using 24 bits for depth and 8 bits for stencil.
ECF_D24S8,
/** Unsigned normalized integer formats. */
//! 8 bit format using 8 bits for the red channel.
......
......@@ -613,20 +613,9 @@ ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::p
}
//! set or reset special render targets
bool CNullDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color)
{
if (ERT_FRAME_BUFFER==target)
return setRenderTarget(0,clearTarget, clearZBuffer, color);
else
return false;
}
//! sets a render target
bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color)
bool clearZBuffer, SColor color, video::ITexture* depthStencil)
{
return false;
}
......@@ -634,12 +623,23 @@ bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer
//! Sets multiple render targets
bool CNullDriver::setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer, bool clearZBuffer, SColor color)
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil)
{
return false;
}
//! set or reset special render targets
bool CNullDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color)
{
if (ERT_FRAME_BUFFER==target)
return setRenderTarget(0,clearTarget, clearZBuffer, color, 0);
else
return false;
}
//! sets a viewport
void CNullDriver::setViewPort(const core::rect<s32>& area)
{
......
......@@ -102,16 +102,16 @@ namespace video
//! sets a render target
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color) _IRR_OVERRIDE_;
bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set or reset special render targets
virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color) _IRR_OVERRIDE_;
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=SColor(0,0,0,0)) _IRR_OVERRIDE_;
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
......
......@@ -4286,27 +4286,8 @@ ITexture* COpenGLDriver::addRenderTargetTexture(const core::dimension2d<u32>& si
if (queryFeature(EVDF_FRAMEBUFFER_OBJECT))
{
rtt = new COpenGLFBOTexture(size, name, this, format);
if (rtt)
{
bool success = false;
addTexture(rtt);
ITexture* tex = createDepthTexture(rtt);
if (tex)
{
success = static_cast<video::COpenGLFBODepthTexture*>(tex)->attach(rtt);
if ( !success )
{
removeDepthTexture(tex);
}
tex->drop();
}
rtt->drop();
if (!success)
{
removeTexture(rtt);
rtt=0;
}
}
addTexture(rtt);
rtt->drop();
}
else
#endif
......@@ -4338,61 +4319,9 @@ u32 COpenGLDriver::getMaximalPrimitiveCount() const
}
//! set or reset render target
bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color)
{
if (target != CurrentTarget)
setRenderTarget(0, false, false, 0x0);
if (ERT_RENDER_TEXTURE == target)
{
os::Printer::log("For render textures call setRenderTarget with the actual texture as first parameter.", ELL_ERROR);
return false;
}
if (ERT_MULTI_RENDER_TEXTURES == target)
{
os::Printer::log("For multiple render textures call setRenderTarget with the texture array as first parameter.", ELL_ERROR);
return false;
}
if (Params.Stereobuffer && (ERT_STEREO_RIGHT_BUFFER == target))
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK_RIGHT);
else
glDrawBuffer(GL_FRONT_RIGHT);
}
else if (Params.Stereobuffer && ERT_STEREO_BOTH_BUFFERS == target)
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK);
else
glDrawBuffer(GL_FRONT);
}
else if ((target >= ERT_AUX_BUFFER0) && (target-ERT_AUX_BUFFER0 < MaxAuxBuffers))
{
glDrawBuffer(GL_AUX0+target-ERT_AUX_BUFFER0);
}
else
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK_LEFT);
else
glDrawBuffer(GL_FRONT_LEFT);
// exit with false, but also with working color buffer
if (target != ERT_FRAME_BUFFER)
return false;
}
CurrentTarget=target;
clearBuffers(clearTarget, clearZBuffer, false, color);
return true;
}
//! set or reset render target
bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color)
bool clearZBuffer, SColor color, video::ITexture* depthStencil)
{
// check for right driver type
......@@ -4434,6 +4363,21 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff
// we want to set a new target. so do this.
BridgeCalls->setViewport(0, 0, texture->getSize().Width, texture->getSize().Height);
RenderTargetTexture = static_cast<COpenGLTexture*>(texture);
if (RenderTargetTexture->isFrameBufferObject())
{
if (depthStencil)
{
static_cast<COpenGLFBOTexture*>(RenderTargetTexture)->setDepthTexture(depthStencil);
}
else
{
ITexture* renderBuffer = createDepthTexture(RenderTargetTexture, true);
static_cast<COpenGLFBOTexture*>(RenderTargetTexture)->setDepthTexture(renderBuffer);
renderBuffer->drop();
}
}
// calls glDrawBuffer as well
RenderTargetTexture->bindRTT();
CurrentRendertargetSize = texture->getSize();
......@@ -4459,14 +4403,14 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff
//! Sets multiple render targets
bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& targets,
bool clearBackBuffer, bool clearZBuffer, SColor color)
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil)
{
// if simply disabling the MRT via array call
if (targets.size()==0)
return setRenderTarget(0, clearBackBuffer, clearZBuffer, color);
return setRenderTarget(0, clearBackBuffer, clearZBuffer, color, depthStencil);
// if disabling old MRT, but enabling new one as well
if ((MRTargets.size()!=0) && (targets != MRTargets))
setRenderTarget(0, clearBackBuffer, clearZBuffer, color);
setRenderTarget(0, clearBackBuffer, clearZBuffer, color, depthStencil);
// if no change, simply clear buffers
else if (targets == MRTargets)
{
......@@ -4537,13 +4481,13 @@ bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& tar
{
if (targets[i].TargetType==ERT_RENDER_TEXTURE)
{
setRenderTarget(targets[i].RenderTexture, false, false, 0x0);
setRenderTarget(targets[i].RenderTexture, false, false, 0x0, depthStencil);
break; // bind only first RTT
}
}
// init other main buffer, if necessary
if (targets[0].TargetType!=ERT_RENDER_TEXTURE)
setRenderTarget(targets[0].TargetType, false, false, 0x0);
setRenderTarget(targets[0].TargetType, false, false, 0x0, depthStencil);
// attach other textures and store buffers into array
if (maxMultipleRTTs > 1)
......@@ -4652,6 +4596,58 @@ bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& tar
}
//! set or reset render target
bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color)
{
if (target != CurrentTarget)
setRenderTarget(0, false, false, 0x0, 0);
if (ERT_RENDER_TEXTURE == target)
{
os::Printer::log("For render textures call setRenderTarget with the actual texture as first parameter.", ELL_ERROR);
return false;
}
if (ERT_MULTI_RENDER_TEXTURES == target)
{
os::Printer::log("For multiple render textures call setRenderTarget with the texture array as first parameter.", ELL_ERROR);
return false;
}
if (Params.Stereobuffer && (ERT_STEREO_RIGHT_BUFFER == target))
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK_RIGHT);
else
glDrawBuffer(GL_FRONT_RIGHT);
}
else if (Params.Stereobuffer && ERT_STEREO_BOTH_BUFFERS == target)
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK);
else
glDrawBuffer(GL_FRONT);
}
else if ((target >= ERT_AUX_BUFFER0) && (target-ERT_AUX_BUFFER0 < MaxAuxBuffers))
{
glDrawBuffer(GL_AUX0+target-ERT_AUX_BUFFER0);
}
else
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK_LEFT);
else
glDrawBuffer(GL_FRONT_LEFT);
// exit with false, but also with working color buffer
if (target != ERT_FRAME_BUFFER)
return false;
}
CurrentTarget=target;
clearBuffers(clearTarget, clearZBuffer, false, color);
return true;
}
// returns the current size of the screen or rendertarget
const core::dimension2d<u32>& COpenGLDriver::getCurrentRenderTargetSize() const
{
......@@ -4807,10 +4803,10 @@ ITexture* COpenGLDriver::createDepthTexture(ITexture* texture, bool shared)
return DepthTextures[i];
}
}
DepthTextures.push_back(new COpenGLFBODepthTexture(texture->getSize(), "depth1", this));
DepthTextures.push_back(new COpenGLRenderBuffer(texture->getSize(), "depth1", this));
return DepthTextures.getLast();
}
return (new COpenGLFBODepthTexture(texture->getSize(), "depth1", this));
return (new COpenGLRenderBuffer(texture->getSize(), "depth1", this));
}
......
......@@ -360,17 +360,17 @@ namespace video
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;
//! set or reset render target
virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color) _IRR_OVERRIDE_;
//! set or reset render target texture
//! sets a render target
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color) _IRR_OVERRIDE_;
bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true, SColor color=SColor(0,0,0,0)) _IRR_OVERRIDE_;
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set or reset special render targets
virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color) _IRR_OVERRIDE_;
//! Clears the ZBuffer.
virtual void clearZBuffer() _IRR_OVERRIDE_;
......
This diff is collapsed.
......@@ -116,6 +116,12 @@ public:
//! Is it a FrameBufferObject?
virtual bool isFrameBufferObject() const;
//! Is it a depth texture?
bool isDepthTexture() const _IRR_OVERRIDE_;
//! Is it a renderbuffer?
bool isRenderBuffer() const _IRR_OVERRIDE_;
//! Bind RenderTargetTexture
virtual void bindRTT();
......@@ -170,6 +176,9 @@ protected:
bool ReadOnlyLock;
bool KeepImage;
bool IsDepthTexture;
bool IsRenderBuffer;
mutable SStatesCache StatesCache;
};
......@@ -194,21 +203,28 @@ public:
//! Unbind RenderTargetTexture
virtual void unbindRTT() _IRR_OVERRIDE_;
ITexture* DepthTexture;
//! Return depth texture.
ITexture* getDepthTexture() const;
//! Set depth texture.
bool setDepthTexture(ITexture* depthTexture);
protected:
GLuint ColorFrameBuffer;
GLuint BufferID;
COpenGLTexture* DepthTexture;
};
//! OpenGL FBO depth texture.
class COpenGLFBODepthTexture : public COpenGLTexture
//! OpenGL Render Buffer.
class COpenGLRenderBuffer : public COpenGLTexture
{
public:
//! FrameBufferObject depth constructor
COpenGLFBODepthTexture(const core::dimension2d<u32>& size, const io::path& name, COpenGLDriver* driver=0, bool useStencil=false);
COpenGLRenderBuffer(const core::dimension2d<u32>& size, const io::path& name, COpenGLDriver* driver=0, bool useStencil=false);
//! destructor
virtual ~COpenGLFBODepthTexture();
virtual ~COpenGLRenderBuffer();
//! Bind RenderTargetTexture
virtual void bindRTT() _IRR_OVERRIDE_;
......@@ -216,12 +232,10 @@ public:
//! Unbind RenderTargetTexture
virtual void unbindRTT() _IRR_OVERRIDE_;
bool attach(ITexture*);
bool getBufferID() const;
protected:
GLuint DepthRenderBuffer;
GLuint StencilRenderBuffer;
bool UseStencil;
GLuint BufferID;
};
......
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