Commit 44b37a75 authored by hybrid's avatar hybrid

Added another texture type for OpenGL, namely the FBODepthRenderbuffer. This...

Added another texture type for OpenGL, namely the FBODepthRenderbuffer. This is only used internally for now, and also is still WIP as the current design has some bad smell :-(. However, it should allow for depthbuffer reuse for RTTs once the interface is made public.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1672 dfc29bdd-3216-0410-991c-e03cc46cb475
parent b8bb90cc
...@@ -2570,8 +2570,14 @@ ITexture* COpenGLDriver::addRenderTargetTexture(const core::dimension2d<s32>& si ...@@ -2570,8 +2570,14 @@ ITexture* COpenGLDriver::addRenderTargetTexture(const core::dimension2d<s32>& si
if (queryFeature(EVDF_FRAMEBUFFER_OBJECT)) if (queryFeature(EVDF_FRAMEBUFFER_OBJECT))
{ {
rtt = new COpenGLFBOTexture(size, name, this); rtt = new COpenGLFBOTexture(size, name, this);
addTexture(rtt); if (rtt)
rtt->drop(); {
addTexture(rtt);
ITexture* tex = getDepthTexture(rtt);
if (tex)
static_cast<video::COpenGLFBODepthTexture*>(tex)->attach(rtt);
rtt->drop();
}
} }
else else
#endif #endif
...@@ -2624,6 +2630,7 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff ...@@ -2624,6 +2630,7 @@ bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuff
if (texture) if (texture)
{ {
// we want to set a new target. so do this. // we want to set a new target. so do this.
glViewport(0, 0, texture->getSize().Width, texture->getSize().Height);
RenderTargetTexture = static_cast<COpenGLTexture*>(texture); RenderTargetTexture = static_cast<COpenGLTexture*>(texture);
RenderTargetTexture->bindRTT(); RenderTargetTexture->bindRTT();
CurrentRendertargetSize = texture->getSize(); CurrentRendertargetSize = texture->getSize();
...@@ -2736,6 +2743,46 @@ IImage* COpenGLDriver::createScreenShot() ...@@ -2736,6 +2743,46 @@ IImage* COpenGLDriver::createScreenShot()
} }
//! get depth texture for the given render target texture
ITexture* COpenGLDriver::getDepthTexture(ITexture* texture, bool shared)
{
if ((texture->getDriverType() != EDT_OPENGL) || (!texture->isRenderTarget()))
return 0;
COpenGLTexture* tex = static_cast<COpenGLTexture*>(texture);
if (!tex->isFrameBufferObject())
return 0;
if (shared)
{
for (u32 i=0; i<DepthTextures.size(); ++i)
{
if (DepthTextures[i]->getSize()==texture->getSize())
{
DepthTextures[i]->grab();
return DepthTextures[i];
}
}
DepthTextures.push_back(new COpenGLFBODepthTexture(texture->getSize(), "depth1", this));
return DepthTextures.getLast();
}
return (new COpenGLFBODepthTexture(texture->getSize(), "depth1", this));
}
void COpenGLDriver::removeDepthTexture(ITexture* texture)
{
for (u32 i=0; i<DepthTextures.size(); ++i)
{
if (texture==DepthTextures[i])
{
DepthTextures.erase(i);
return;
}
}
}
//! Set/unset a clipping plane. //! Set/unset a clipping plane.
bool COpenGLDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) bool COpenGLDriver::setClipPlane(u32 index, const core::plane3df& plane, bool enable)
{ {
......
...@@ -339,7 +339,10 @@ namespace video ...@@ -339,7 +339,10 @@ namespace video
virtual void enableClipPlane(u32 index, bool enable); virtual void enableClipPlane(u32 index, bool enable);
//! Returns the graphics card vendor name. //! Returns the graphics card vendor name.
virtual core::stringc getVendorInfo() {return vendorName;}; virtual core::stringc getVendorInfo() {return vendorName;}
ITexture* getDepthTexture(ITexture* texture, bool shared=true);
void removeDepthTexture(ITexture* texture);
private: private:
...@@ -390,6 +393,7 @@ namespace video ...@@ -390,6 +393,7 @@ namespace video
SMaterial Material, LastMaterial; SMaterial Material, LastMaterial;
COpenGLTexture* RenderTargetTexture; COpenGLTexture* RenderTargetTexture;
const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES]; const ITexture* CurrentTexture[MATERIAL_MAX_TEXTURES];
core::array<ITexture*> DepthTextures;
s32 LastSetLight; s32 LastSetLight;
core::array<core::plane3df> UserClipPlane; core::array<core::plane3df> UserClipPlane;
core::array<bool> UserClipPlaneEnabled; core::array<bool> UserClipPlaneEnabled;
...@@ -421,6 +425,3 @@ namespace video ...@@ -421,6 +425,3 @@ namespace video
#endif // _IRR_COMPILE_WITH_OPENGL_ #endif // _IRR_COMPILE_WITH_OPENGL_
#endif #endif
...@@ -399,12 +399,6 @@ void COpenGLTexture::regenerateMipMapLevels() ...@@ -399,12 +399,6 @@ void COpenGLTexture::regenerateMipMapLevels()
} }
bool COpenGLTexture::isFrameBufferObject() const
{
return false;
}
bool COpenGLTexture::isRenderTarget() const bool COpenGLTexture::isRenderTarget() const
{ {
return IsRenderTarget; return IsRenderTarget;
...@@ -417,10 +411,15 @@ void COpenGLTexture::setIsRenderTarget(bool isTarget) ...@@ -417,10 +411,15 @@ void COpenGLTexture::setIsRenderTarget(bool isTarget)
} }
bool COpenGLTexture::isFrameBufferObject() const
{
return false;
}
//! Bind Render Target Texture //! Bind Render Target Texture
void COpenGLTexture::bindRTT() void COpenGLTexture::bindRTT()
{ {
glViewport(0, 0, getSize().Width, getSize().Height);
} }
...@@ -445,11 +444,8 @@ static bool checkFBOStatus(COpenGLDriver* Driver); ...@@ -445,11 +444,8 @@ static bool checkFBOStatus(COpenGLDriver* Driver);
//! RTT ColorFrameBuffer constructor //! RTT ColorFrameBuffer constructor
COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<s32>& size, COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<s32>& size,
const char* name, const char* name,
COpenGLDriver* driver, COpenGLDriver* driver)
bool useStencil) : COpenGLTexture(name, driver), ColorFrameBuffer(0), DepthTexture(0)
: COpenGLTexture(name, driver),
ColorFrameBuffer(0), DepthRenderBuffer(0), StencilRenderBuffer(0),
UseStencil(useStencil)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("COpenGLTexture_FBO"); setDebugName("COpenGLTexture_FBO");
...@@ -462,6 +458,89 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<s32>& size, ...@@ -462,6 +458,89 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<s32>& size,
HasMipMaps = false; HasMipMaps = false;
IsRenderTarget = true; IsRenderTarget = true;
#ifdef GL_EXT_framebuffer_object
// generate frame buffer
Driver->extGlGenFramebuffers(1, &ColorFrameBuffer);
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, ColorFrameBuffer);
// generate color texture
glGenTextures(1, &TextureName);
glBindTexture(GL_TEXTURE_2D, TextureName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, ImageSize.Width,
ImageSize.Height, 0, PixelFormat, PixelType, 0);
// attach color texture to frame buffer
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D,
TextureName,
0);
#endif
unbindRTT();
}
//! destructor
COpenGLFBOTexture::~COpenGLFBOTexture()
{
if (DepthTexture)
if (DepthTexture->drop())
Driver->removeDepthTexture(DepthTexture);
if (ColorFrameBuffer)
Driver->extGlDeleteFramebuffers(1, &ColorFrameBuffer);
}
bool COpenGLFBOTexture::isFrameBufferObject() const
{
return true;
}
//! Bind Render Target Texture
void COpenGLFBOTexture::bindRTT()
{
#ifdef GL_EXT_framebuffer_object
if (ColorFrameBuffer != 0)
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, ColorFrameBuffer);
#endif
}
//! Unbind Render Target Texture
void COpenGLFBOTexture::unbindRTT()
{
#ifdef GL_EXT_framebuffer_object
if (ColorFrameBuffer != 0)
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
#endif
}
/* FBO Depth Textures */
//! RTT DepthBuffer constructor
COpenGLFBODepthTexture::COpenGLFBODepthTexture(
const core::dimension2d<s32>& size,
const char* name,
COpenGLDriver* driver,
bool useStencil)
: COpenGLFBOTexture(size, name, driver), DepthRenderBuffer(0),
StencilRenderBuffer(0), UseStencil(useStencil)
{
#ifdef _DEBUG
setDebugName("COpenGLTextureFBO_Depth");
#endif
ImageSize = size;
InternalFormat = GL_RGBA;
PixelFormat = GL_RGBA;
PixelType = GL_UNSIGNED_BYTE;
HasMipMaps = false;
if (useStencil) if (useStencil)
{ {
glGenTextures(1, &DepthRenderBuffer); glGenTextures(1, &DepthRenderBuffer);
...@@ -509,28 +588,31 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<s32>& size, ...@@ -509,28 +588,31 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<s32>& size,
GL_DEPTH_COMPONENT, ImageSize.Width, GL_DEPTH_COMPONENT, ImageSize.Width,
ImageSize.Height); ImageSize.Height);
} }
#endif
}
// generate frame buffer
Driver->extGlGenFramebuffers(1, &ColorFrameBuffer);
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, ColorFrameBuffer);
// generate color texture //! destructor
glGenTextures(1, &TextureName); COpenGLFBODepthTexture::~COpenGLFBODepthTexture()
glBindTexture(GL_TEXTURE_2D, TextureName); {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (DepthRenderBuffer && UseStencil)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glDeleteTextures(1, &DepthRenderBuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); else
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, ImageSize.Width, Driver->extGlDeleteRenderbuffers(1, &DepthRenderBuffer);
ImageSize.Height, 0, PixelFormat, PixelType, 0); if (StencilRenderBuffer && StencilRenderBuffer != DepthRenderBuffer)
glDeleteTextures(1, &StencilRenderBuffer);
}
// attach color texture to frame buffer
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D,
TextureName,
0);
if (useStencil) //combine depth texture and rtt
void COpenGLFBODepthTexture::attach(ITexture* renderTex)
{
if (!renderTex)
return;
video::COpenGLFBOTexture* rtt = static_cast<video::COpenGLFBOTexture*>(renderTex);
rtt->bindRTT();
#ifdef GL_EXT_framebuffer_object
if (UseStencil)
{ {
// attach stencil texture to stencil buffer // attach stencil texture to stencil buffer
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT,
...@@ -554,72 +636,25 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<s32>& size, ...@@ -554,72 +636,25 @@ COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<s32>& size,
GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_EXT,
DepthRenderBuffer); DepthRenderBuffer);
} }
#endif
glGetError(); rtt->DepthTexture=this;
renderTex->grab();
// check the status // check the status
if (!checkFBOStatus(Driver)) if (!checkFBOStatus(Driver))
{ os::Printer::log("FBO incomplete");
printf("FBO=%u, Color=%u, Depth=%u, Stencil=%u\n", rtt->unbindRTT();
ColorFrameBuffer, TextureName, DepthRenderBuffer, StencilRenderBuffer);
if (ColorFrameBuffer)
Driver->extGlDeleteFramebuffers(1, &ColorFrameBuffer);
if (DepthRenderBuffer)
{
if (useStencil)
glDeleteTextures(1, &DepthRenderBuffer);
else
Driver->extGlDeleteRenderbuffers(1, &DepthRenderBuffer);
}
if (StencilRenderBuffer && StencilRenderBuffer != DepthRenderBuffer)
glDeleteTextures(1, &StencilRenderBuffer);
ColorFrameBuffer = 0;
DepthRenderBuffer = 0;
StencilRenderBuffer = 0;
}
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
#endif
}
//! destructor
COpenGLFBOTexture::~COpenGLFBOTexture()
{
if (ColorFrameBuffer)
Driver->extGlDeleteFramebuffers(1, &ColorFrameBuffer);
if (DepthRenderBuffer && UseStencil)
glDeleteTextures(1, &DepthRenderBuffer);
else
Driver->extGlDeleteRenderbuffers(1, &DepthRenderBuffer);
if (StencilRenderBuffer && StencilRenderBuffer != DepthRenderBuffer)
glDeleteTextures(1, &StencilRenderBuffer);
}
bool COpenGLFBOTexture::isFrameBufferObject() const
{
return true;
} }
//! Bind Render Target Texture //! Bind Render Target Texture
void COpenGLFBOTexture::bindRTT() void COpenGLFBODepthTexture::bindRTT()
{ {
glViewport(0, 0, getSize().Width, getSize().Height);
#ifdef GL_EXT_framebuffer_object
if (ColorFrameBuffer != 0)
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, ColorFrameBuffer);
#endif
} }
//! Unbind Render Target Texture //! Unbind Render Target Texture
void COpenGLFBOTexture::unbindRTT() void COpenGLFBODepthTexture::unbindRTT()
{ {
#ifdef GL_EXT_framebuffer_object
if (ColorFrameBuffer != 0)
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
#endif
} }
......
...@@ -138,7 +138,7 @@ class COpenGLFBOTexture : public COpenGLTexture ...@@ -138,7 +138,7 @@ class COpenGLFBOTexture : public COpenGLTexture
public: public:
//! FrameBufferObject constructor //! FrameBufferObject constructor
COpenGLFBOTexture(const core::dimension2d<s32>& size, const char* name, COpenGLDriver* driver=0, bool useStencil=false); COpenGLFBOTexture(const core::dimension2d<s32>& size, const char* name, COpenGLDriver* driver=0);
//! destructor //! destructor
virtual ~COpenGLFBOTexture(); virtual ~COpenGLFBOTexture();
...@@ -152,9 +152,33 @@ public: ...@@ -152,9 +152,33 @@ public:
//! Unbind RenderTargetTexture //! Unbind RenderTargetTexture
virtual void unbindRTT(); virtual void unbindRTT();
GLuint ColorFrameBuffer; // for FBO path ITexture* DepthTexture;
GLuint DepthRenderBuffer; // for FBO path protected:
GLuint StencilRenderBuffer; // for FBO path GLuint ColorFrameBuffer;
};
//! OpenGL FBO depth texture.
class COpenGLFBODepthTexture : public COpenGLFBOTexture
{
public:
//! FrameBufferObject depth constructor
COpenGLFBODepthTexture(const core::dimension2d<s32>& size, const char* name, COpenGLDriver* driver=0, bool useStencil=false);
//! destructor
virtual ~COpenGLFBODepthTexture();
//! Bind RenderTargetTexture
virtual void bindRTT();
//! Unbind RenderTargetTexture
virtual void unbindRTT();
void attach(ITexture*);
protected:
GLuint DepthRenderBuffer;
GLuint StencilRenderBuffer;
bool UseStencil; bool UseStencil;
}; };
......
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