GL: Share depth and stencil to get similar behaviour to D3D driver
This commit is contained in:
parent
54f4d5bac3
commit
f9aa0bf7cc
3 changed files with 101 additions and 65 deletions
|
@ -1032,6 +1032,8 @@ bool CDriverGL::release()
|
||||||
// Call IDriver::release() before, to destroy textures, shaders and VBs...
|
// Call IDriver::release() before, to destroy textures, shaders and VBs...
|
||||||
IDriver::release();
|
IDriver::release();
|
||||||
|
|
||||||
|
nlassert(_DepthStencilFBOs.empty());
|
||||||
|
|
||||||
_SwapBufferCounter = 0;
|
_SwapBufferCounter = 0;
|
||||||
|
|
||||||
// delete querries
|
// delete querries
|
||||||
|
|
|
@ -146,6 +146,23 @@ public:
|
||||||
virtual uint getVisibleCount();
|
virtual uint getVisibleCount();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ***************************************************************************
|
||||||
|
class CDepthStencilFBO : public NLMISC::CRefCount
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CDepthStencilFBO(CDriverGL *driver, uint width, uint height);
|
||||||
|
~CDepthStencilFBO();
|
||||||
|
|
||||||
|
uint Width;
|
||||||
|
uint Height;
|
||||||
|
|
||||||
|
GLuint DepthFBOId;
|
||||||
|
GLuint StencilFBOId;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CDriverGL *m_Driver;
|
||||||
|
};
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
class CTextureDrvInfosGL : public ITextureDrvInfos
|
class CTextureDrvInfosGL : public ITextureDrvInfos
|
||||||
{
|
{
|
||||||
|
@ -173,12 +190,9 @@ public:
|
||||||
GLuint FBOId;
|
GLuint FBOId;
|
||||||
|
|
||||||
// depth stencil FBO id
|
// depth stencil FBO id
|
||||||
GLuint DepthFBOId;
|
|
||||||
GLuint StencilFBOId;
|
|
||||||
|
|
||||||
bool InitFBO;
|
|
||||||
bool AttachDepthStencil;
|
bool AttachDepthStencil;
|
||||||
bool UsePackedDepthStencil;
|
NLMISC::CSmartPtr<CDepthStencilFBO> DepthStencilFBO;
|
||||||
|
bool InitFBO;
|
||||||
|
|
||||||
// The current wrap modes assigned to the texture.
|
// The current wrap modes assigned to the texture.
|
||||||
ITexture::TWrapMode WrapS;
|
ITexture::TWrapMode WrapS;
|
||||||
|
@ -685,6 +699,7 @@ private:
|
||||||
friend class CTextureDrvInfosGL;
|
friend class CTextureDrvInfosGL;
|
||||||
friend class CVertexProgamDrvInfosGL;
|
friend class CVertexProgamDrvInfosGL;
|
||||||
friend class CPixelProgamDrvInfosGL;
|
friend class CPixelProgamDrvInfosGL;
|
||||||
|
friend class CDepthStencilFBO;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Version of the driver. Not the interface version!! Increment when implementation of the driver change.
|
// Version of the driver. Not the interface version!! Increment when implementation of the driver change.
|
||||||
|
@ -880,8 +895,11 @@ private:
|
||||||
// viewport before call to setRenderTarget, if BFO extension is supported
|
// viewport before call to setRenderTarget, if BFO extension is supported
|
||||||
CViewport _OldViewport;
|
CViewport _OldViewport;
|
||||||
|
|
||||||
|
// Current FBO render target
|
||||||
CSmartPtr<ITexture> _RenderTargetFBO;
|
CSmartPtr<ITexture> _RenderTargetFBO;
|
||||||
|
|
||||||
|
// Share the same backbuffer for FBO render targets with window size
|
||||||
|
std::vector<CDepthStencilFBO *> _DepthStencilFBOs;
|
||||||
|
|
||||||
// Num lights return by GL_MAX_LIGHTS
|
// Num lights return by GL_MAX_LIGHTS
|
||||||
uint _MaxDriverLight;
|
uint _MaxDriverLight;
|
||||||
|
|
|
@ -73,12 +73,8 @@ CTextureDrvInfosGL::CTextureDrvInfosGL(IDriver *drv, ItTexDrvInfoPtrMap it, CDri
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FBOId = 0;
|
FBOId = 0;
|
||||||
DepthFBOId = 0;
|
|
||||||
StencilFBOId = 0;
|
|
||||||
|
|
||||||
InitFBO = false;
|
InitFBO = false;
|
||||||
AttachDepthStencil = true;
|
AttachDepthStencil = true;
|
||||||
UsePackedDepthStencil = drvGl->supportPackedDepthStencil();
|
|
||||||
|
|
||||||
TextureUsedIdx = 0;
|
TextureUsedIdx = 0;
|
||||||
}
|
}
|
||||||
|
@ -98,9 +94,9 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL()
|
||||||
_Driver->_TextureUsed[TextureUsedIdx] = NULL;
|
_Driver->_TextureUsed[TextureUsedIdx] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(InitFBO)
|
|
||||||
{
|
|
||||||
#ifdef USE_OPENGLES
|
#ifdef USE_OPENGLES
|
||||||
|
if (InitFBO)
|
||||||
|
{
|
||||||
nglDeleteFramebuffersOES(1, &FBOId);
|
nglDeleteFramebuffersOES(1, &FBOId);
|
||||||
if(AttachDepthStencil)
|
if(AttachDepthStencil)
|
||||||
{
|
{
|
||||||
|
@ -108,24 +104,73 @@ CTextureDrvInfosGL::~CTextureDrvInfosGL()
|
||||||
if(!UsePackedDepthStencil)
|
if(!UsePackedDepthStencil)
|
||||||
nglDeleteRenderbuffersOES(1, &StencilFBOId);
|
nglDeleteRenderbuffersOES(1, &StencilFBOId);
|
||||||
}
|
}
|
||||||
#else
|
}
|
||||||
nglDeleteFramebuffersEXT(1, &FBOId);
|
|
||||||
if(AttachDepthStencil)
|
|
||||||
{
|
|
||||||
nglDeleteRenderbuffersEXT(1, &DepthFBOId);
|
|
||||||
if(!UsePackedDepthStencil)
|
|
||||||
nglDeleteRenderbuffersEXT(1, &StencilFBOId);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CDepthStencilFBO::CDepthStencilFBO(CDriverGL *driver, uint width, uint height)
|
||||||
|
{
|
||||||
|
nldebug("3D: Init shared FBO");
|
||||||
|
|
||||||
|
m_Driver = driver;
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
|
||||||
|
bool packedDepthStencil = driver->supportPackedDepthStencil();
|
||||||
|
nglGenRenderbuffersEXT(1, &DepthFBOId);
|
||||||
|
if (packedDepthStencil)
|
||||||
|
StencilFBOId = DepthFBOId;
|
||||||
|
else
|
||||||
|
nglGenRenderbuffersEXT(1, &StencilFBOId);
|
||||||
|
|
||||||
|
if (packedDepthStencil)
|
||||||
|
{
|
||||||
|
//nldebug("3D: using packed depth stencil");
|
||||||
|
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
|
||||||
|
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, width, height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthFBOId);
|
||||||
|
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, width, height);
|
||||||
|
/*
|
||||||
|
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
|
||||||
|
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, width, height);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
nlassert(DepthFBOId);
|
||||||
|
nlassert(StencilFBOId);
|
||||||
|
|
||||||
|
driver->_DepthStencilFBOs.push_back(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDepthStencilFBO::~CDepthStencilFBO()
|
||||||
|
{
|
||||||
|
// driver remove
|
||||||
|
m_Driver->_DepthStencilFBOs.erase(std::find(m_Driver->_DepthStencilFBOs.begin(), m_Driver->_DepthStencilFBOs.end(), this));
|
||||||
|
|
||||||
|
if (DepthFBOId)
|
||||||
|
{
|
||||||
|
nldebug("3D: Release shared FBO");
|
||||||
|
nglDeleteRenderbuffersEXT(1, &DepthFBOId);
|
||||||
|
if (StencilFBOId == DepthFBOId)
|
||||||
|
StencilFBOId = 0;
|
||||||
|
DepthFBOId = 0;
|
||||||
|
}
|
||||||
|
if (StencilFBOId)
|
||||||
|
{
|
||||||
|
nglDeleteRenderbuffersEXT(1, &StencilFBOId);
|
||||||
|
StencilFBOId = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
|
bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
|
||||||
{
|
{
|
||||||
if(!InitFBO)
|
if (!InitFBO)
|
||||||
{
|
{
|
||||||
if(tex->isBloomTexture())
|
if (tex->isBloomTexture())
|
||||||
{
|
{
|
||||||
AttachDepthStencil = !((CTextureBloom*)tex)->isMode2D();
|
AttachDepthStencil = !((CTextureBloom*)tex)->isMode2D();
|
||||||
}
|
}
|
||||||
|
@ -179,49 +224,33 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
|
||||||
#else
|
#else
|
||||||
// generate IDs
|
// generate IDs
|
||||||
nglGenFramebuffersEXT(1, &FBOId);
|
nglGenFramebuffersEXT(1, &FBOId);
|
||||||
if(AttachDepthStencil)
|
|
||||||
{
|
|
||||||
nglGenRenderbuffersEXT(1, &DepthFBOId);
|
|
||||||
if(UsePackedDepthStencil)
|
|
||||||
StencilFBOId = DepthFBOId;
|
|
||||||
else
|
|
||||||
nglGenRenderbuffersEXT(1, &StencilFBOId);
|
|
||||||
}
|
|
||||||
|
|
||||||
//nldebug("3D: using depth %d and stencil %d", DepthFBOId, StencilFBOId);
|
//nldebug("3D: using depth %d and stencil %d", DepthFBOId, StencilFBOId);
|
||||||
|
|
||||||
// initialize FBO
|
// initialize FBO
|
||||||
nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOId);
|
nglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBOId);
|
||||||
nglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TextureMode, ID, 0);
|
nglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TextureMode, ID, 0);
|
||||||
|
|
||||||
// attach depth/stencil render to FBO
|
// attach depth stencil
|
||||||
// note: for some still unkown reason it's impossible to add
|
if (AttachDepthStencil)
|
||||||
// a stencil buffer as shown in the respective docs (see
|
|
||||||
// opengl.org extension registry). Until a safe approach to add
|
|
||||||
// them is found, there will be no attached stencil for the time
|
|
||||||
// being, aside of using packed depth+stencil buffers.
|
|
||||||
if(AttachDepthStencil)
|
|
||||||
{
|
{
|
||||||
if(UsePackedDepthStencil)
|
for (std::vector<CDepthStencilFBO *>::iterator it(_Driver->_DepthStencilFBOs.begin()), end(_Driver->_DepthStencilFBOs.end()); it != end; ++it)
|
||||||
{
|
{
|
||||||
//nldebug("3D: using packed depth stencil");
|
if ((*it)->Width == tex->getWidth() && (*it)->Height == tex->getHeight())
|
||||||
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
|
{
|
||||||
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, tex->getWidth(), tex->getHeight());
|
DepthStencilFBO = (*it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
if (!DepthStencilFBO)
|
||||||
{
|
{
|
||||||
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, DepthFBOId);
|
DepthStencilFBO = new CDepthStencilFBO(_Driver, tex->getWidth(), tex->getHeight());
|
||||||
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, tex->getWidth(), tex->getHeight());
|
|
||||||
/*
|
|
||||||
nglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, StencilFBOId);
|
|
||||||
nglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, tex->getWidth(), tex->getHeight());
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
|
||||||
GL_RENDERBUFFER_EXT, DepthFBOId);
|
GL_RENDERBUFFER_EXT, DepthStencilFBO->DepthFBOId);
|
||||||
nldebug("3D: glFramebufferRenderbufferExt(depth:24) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
|
nldebug("3D: glFramebufferRenderbufferExt(depth:24) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
|
||||||
nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
|
nglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT,
|
||||||
GL_RENDERBUFFER_EXT, StencilFBOId);
|
GL_RENDERBUFFER_EXT, DepthStencilFBO->StencilFBOId);
|
||||||
nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
|
nldebug("3D: glFramebufferRenderbufferExt(stencil:8) = %X", nglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -339,17 +368,7 @@ bool CTextureDrvInfosGL::initFrameBufferObject(ITexture * tex)
|
||||||
#endif
|
#endif
|
||||||
if (AttachDepthStencil)
|
if (AttachDepthStencil)
|
||||||
{
|
{
|
||||||
#ifdef USE_OPENGLES
|
DepthStencilFBO = NULL;
|
||||||
nglDeleteRenderbuffersOES(1, &DepthFBOId);
|
|
||||||
#else
|
|
||||||
nglDeleteRenderbuffersEXT(1, &DepthFBOId);
|
|
||||||
#endif
|
|
||||||
if(!UsePackedDepthStencil)
|
|
||||||
#ifdef USE_OPENGLES
|
|
||||||
nglDeleteRenderbuffersOES(1, &StencilFBOId);
|
|
||||||
#else
|
|
||||||
nglDeleteRenderbuffersEXT(1, &StencilFBOId);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2260,11 +2279,8 @@ void CDriverGL::swapTextureHandle(ITexture &tex0, ITexture &tex1)
|
||||||
swap(t0->MinFilter, t1->MinFilter);
|
swap(t0->MinFilter, t1->MinFilter);
|
||||||
swap(t0->TextureMode, t1->TextureMode);
|
swap(t0->TextureMode, t1->TextureMode);
|
||||||
swap(t0->FBOId, t1->FBOId);
|
swap(t0->FBOId, t1->FBOId);
|
||||||
swap(t0->DepthFBOId, t1->DepthFBOId);
|
swap(t0->DepthStencilFBO, t1->DepthStencilFBO);
|
||||||
swap(t0->StencilFBOId, t1->StencilFBOId);
|
|
||||||
swap(t0->InitFBO, t1->InitFBO);
|
swap(t0->InitFBO, t1->InitFBO);
|
||||||
swap(t0->AttachDepthStencil, t1->AttachDepthStencil);
|
|
||||||
swap(t0->UsePackedDepthStencil, t1->UsePackedDepthStencil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue