3D: Cleanup bloom effect

--HG--
branch : multipass-stereo
This commit is contained in:
kaetemi 2014-08-03 20:35:05 +02:00
parent 78ce8f4f25
commit 8af686f7ef
5 changed files with 169 additions and 319 deletions

View file

@ -31,6 +31,7 @@ namespace NL3D
class UDriver; class UDriver;
class UScene; class UScene;
class CTextureUser;
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
//---------------------------------------- CBloomEffect ----------------------------------------------------- //---------------------------------------- CBloomEffect -----------------------------------------------------
@ -52,19 +53,14 @@ public:
// Destructor // Destructor
~CBloomEffect(); ~CBloomEffect();
// Called after the Driver initialization to indicate if OpenGL or Direct3D is used. // Called after the Driver initialization.
// They are some differences in bloom algorithm depending on this API choice. void init();
// If bloom effect is activated and supported, private method init() is called to initialize
// textures and materials.
// initBloomEffect = false => directx
// initBloomEffect = true => opengl
void init(bool initBloomEffect);
// must be called before init // must be called before init
void setDriver(UDriver *driver) { _Driver = driver; } void setDriver(UDriver *driver) { _Driver = driver; }
UDriver* getDriver() const { return _Driver; } UDriver* getDriver() const { return _Driver; }
// must be called before initBloom // must be called before applyBloom
void setScene(UScene *scene) { _Scene = scene; } void setScene(UScene *scene) { _Scene = scene; }
UScene* getScene() const { return _Scene; } UScene* getScene() const { return _Scene; }
@ -76,6 +72,9 @@ public:
void setDensityBloom(uint8 densityBloom) { _DensityBloom = densityBloom; } void setDensityBloom(uint8 densityBloom) { _DensityBloom = densityBloom; }
uint8 getDensityBloom() const { return _DensityBloom; } uint8 getDensityBloom() const { return _DensityBloom; }
// Applies bloom to the current render target, if backbuffer is true the final image is rendered to the backbuffer instead of to a render target
void applyBloom(bool backbuffer);
// Called at the beginning of renderAll method in the main loop, if window has been resized, // Called at the beginning of renderAll method in the main loop, if window has been resized,
// reinitialize bloom textures according to new window size. // reinitialize bloom textures according to new window size.
// The bloom texture (_InitText attribute) which is used as render target during scene render // The bloom texture (_InitText attribute) which is used as render target during scene render
@ -83,11 +82,11 @@ public:
// If window size exceeds 256*256 the textures used to apply blur are reinitialized with // If window size exceeds 256*256 the textures used to apply blur are reinitialized with
// 256*256 size. If a dimension is less than 256, the texture is initialized with the nearer // 256*256 size. If a dimension is less than 256, the texture is initialized with the nearer
// power of 2, lower than this window dimension. // power of 2, lower than this window dimension.
void initBloom(); // void initBloom();
// Called at the end of renderAll method in the main loop, recover stretched texture, apply // Called at the end of renderAll method in the main loop, recover stretched texture, apply
// both blur passes, and the blending operation between initial render target and the blured one. // both blur passes, and the blending operation between initial render target and the blured one.
void endBloom(); // void endBloom();
// In OpenGL, the use of FBO implies that Z buffer values of scene render have been stored in // In OpenGL, the use of FBO implies that Z buffer values of scene render have been stored in
// a depth render target. Then, to display 3D interfaces, we must display them in the same FBO, // a depth render target. Then, to display 3D interfaces, we must display them in the same FBO,
@ -95,15 +94,12 @@ public:
// This method is called at the end of interfaces display in the main loop, to display final render target // This method is called at the end of interfaces display in the main loop, to display final render target
// (with added interfaces) in the color frame buffer. // (with added interfaces) in the color frame buffer.
// NB : In Direct3D, the final render target is displayed at the end of endBloom call. // NB : In Direct3D, the final render target is displayed at the end of endBloom call.
void endInterfacesDisplayBloom(); // void endInterfacesDisplayBloom();
private: private:
// Initialize textures and materials.
void init();
// Initialize a bloom texture with new dimensions. // Initialize a bloom texture with new dimensions.
void initTexture(NLMISC::CSmartPtr<NL3D::ITexture> & tex, bool isMode2D, uint32 width, uint32 height); // void initTexture(NLMISC::CSmartPtr<NL3D::ITexture> & tex, bool isMode2D, uint32 width, uint32 height);
// Called in endBloom method to build a blurred texture. Two passes (then two calls) // Called in endBloom method to build a blurred texture. Two passes (then two calls)
// are necessary : horizontal and vertical. // are necessary : horizontal and vertical.
@ -130,6 +126,7 @@ private:
// density of bloom // density of bloom
uint8 _DensityBloom; uint8 _DensityBloom;
/*
// render target textures // render target textures
// used to display scene // used to display scene
NLMISC::CSmartPtr<NL3D::ITexture> _InitText; NLMISC::CSmartPtr<NL3D::ITexture> _InitText;
@ -140,12 +137,13 @@ private:
NLMISC::CSmartPtr<NL3D::ITexture> _BlurHorizontalTex; NLMISC::CSmartPtr<NL3D::ITexture> _BlurHorizontalTex;
// original render target // original render target
NLMISC::CSmartPtr<NL3D::ITexture> _OriginalRenderTarget; NLMISC::CSmartPtr<NL3D::ITexture> _OriginalRenderTarget;
*/
// materials // materials
// used to display first texture in doBlur passes. // used to display first texture in doBlur passes.
NL3D::UMaterial _BlurMat; NL3D::UMaterial _BlurMat;
// used to display final render target texture in endInterfacesDisplayBloom call (OpenGL). // used to display final render target texture onto the backbuffer
NL3D::UMaterial _DisplayInitMat; NL3D::UMaterial _DisplayInitMat;
// used to blend initial scene render target texture and blur texture according to a // used to blend initial scene render target texture and blur texture according to a
// dest+src - dest*src blend operation. // dest+src - dest*src blend operation.
@ -158,19 +156,23 @@ private:
NLMISC::CQuadUV _BlurQuad; NLMISC::CQuadUV _BlurQuad;
NLMISC::CQuadUV _DisplayQuad; NLMISC::CQuadUV _DisplayQuad;
// openGL or Direct3D?
bool _InitBloomEffect;
// textures and materials already initialized? // textures and materials already initialized?
bool _Init; bool _Init;
// current window dimensions // current window dimensions
uint32 _WndWidth; /*uint32 _WndWidth;
uint32 _WndHeight; uint32 _WndHeight;*/
// Temporary variables used during applyBloom(...) ->
// current blur texture dimensions // current blur texture dimensions
uint32 _BlurWidth; uint32 _BlurWidth;
uint32 _BlurHeight; uint32 _BlurHeight;
// used as stretched texture from _InitText, as displayed texture in first blur pass,
// and as render target in second blur pass.
CTextureUser *_BlurFinalTex;
// used as render target in first blur pass, and as displayed texture on second blur pass.
CTextureUser *_BlurHorizontalTex;
// <-
}; };
} // NL3D } // NL3D

View file

@ -72,79 +72,49 @@ CBloomEffect::CBloomEffect()
_SquareBloom = true; _SquareBloom = true;
_DensityBloom = 128; _DensityBloom = 128;
_Init = false; _Init = false;
_InitBloomEffect = false;
_BlurFinalTex = NULL;
_BlurHorizontalTex = NULL;
} }
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
CBloomEffect::~CBloomEffect() CBloomEffect::~CBloomEffect()
{ {
if(_Init) if (_Init)
{ {
if(!_DisplayInitMat.empty()) if (!_DisplayInitMat.empty())
{ {
_DisplayInitMat.getObjectPtr()->setTexture(0, NULL);
if (_Driver) _Driver->deleteMaterial(_DisplayInitMat); if (_Driver) _Driver->deleteMaterial(_DisplayInitMat);
} }
_InitText = NULL;
if(!_DisplayBlurMat.empty()) if (!_DisplayBlurMat.empty())
{ {
_DisplayBlurMat.getObjectPtr()->setTexture(0, NULL);
if (_Driver) _Driver->deleteMaterial(_DisplayBlurMat); if (_Driver) _Driver->deleteMaterial(_DisplayBlurMat);
} }
if(!_DisplaySquareBlurMat.empty())
if (!_DisplaySquareBlurMat.empty())
{ {
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL);
if (_Driver) _Driver->deleteMaterial(_DisplaySquareBlurMat); if (_Driver) _Driver->deleteMaterial(_DisplaySquareBlurMat);
} }
if(!_BlurMat.empty()) if (!_BlurMat.empty())
{ {
_BlurMat.getObjectPtr()->setTexture(0, NULL);
_BlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(2, NULL);
_BlurMat.getObjectPtr()->setTexture(3, NULL);
if (_Driver) _Driver->deleteMaterial(_BlurMat); if (_Driver) _Driver->deleteMaterial(_BlurMat);
} }
_BlurHorizontalTex = NULL;
_BlurFinalTex = NULL;
} }
} }
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
void CBloomEffect::init(bool initBloomEffect)
{
_InitBloomEffect = initBloomEffect;
if(((CDriverUser *)_Driver)->getDriver()->supportBloomEffect())
init();
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::init() void CBloomEffect::init()
{ {
_WndWidth = _Driver->getWindowWidth(); if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect())
_WndHeight = _Driver->getWindowHeight(); return;
_BlurWidth = 256; _BlurWidth = 256;
_BlurHeight = 256; _BlurHeight = 256;
// initialize textures
_InitText = NULL;
_BlurHorizontalTex = NULL;
_BlurFinalTex = NULL;
if(_InitBloomEffect)
{
initTexture(_InitText, false, _WndWidth, _WndHeight);
}
initTexture(_BlurFinalTex, true, _BlurWidth, _BlurHeight);
initTexture(_BlurHorizontalTex, true, _BlurWidth, _BlurHeight);
// initialize blur material // initialize blur material
_BlurMat = _Driver->createMaterial(); _BlurMat = _Driver->createMaterial();
CMaterial * matObject = _BlurMat.getObjectPtr(); CMaterial * matObject = _BlurMat.getObjectPtr();
@ -188,20 +158,16 @@ void CBloomEffect::init()
matObject->texEnvArg2RGB(3, CMaterial::Previous, CMaterial::SrcColor); matObject->texEnvArg2RGB(3, CMaterial::Previous, CMaterial::SrcColor);
// initialize display materials // initialize display materials
if(_InitBloomEffect) _DisplayInitMat = _Driver->createMaterial();
{ CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr();
_DisplayInitMat = _Driver->createMaterial(); _DisplayInitMat.initUnlit();
CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr(); _DisplayInitMat.setColor(CRGBA::White);
_DisplayInitMat.initUnlit(); _DisplayInitMat.setBlend(false);
_DisplayInitMat.setColor(CRGBA::White); _DisplayInitMat.setAlphaTest (false);
_DisplayInitMat.setBlend (false); matObjectInit->setBlendFunc(CMaterial::one, CMaterial::zero);
_DisplayInitMat.setAlphaTest (false); matObjectInit->setZWrite(false);
matObjectInit->setBlendFunc (CMaterial::one, CMaterial::zero); matObjectInit->setZFunc(CMaterial::always);
matObjectInit->setZWrite(false); matObjectInit->setDoubleSided(true);
matObjectInit->setZFunc(CMaterial::always);
matObjectInit->setDoubleSided(true);
matObjectInit->setTexture(0, _InitText);
}
// initialize linear blur material // initialize linear blur material
_DisplayBlurMat = _Driver->createMaterial(); _DisplayBlurMat = _Driver->createMaterial();
@ -214,7 +180,7 @@ void CBloomEffect::init()
matObjectFinal->setZFunc(CMaterial::always); matObjectFinal->setZFunc(CMaterial::always);
matObjectFinal->setDoubleSided(true); matObjectFinal->setDoubleSided(true);
matObjectFinal->setTexture(0, _BlurFinalTex); // matObjectFinal->setTexture(0, _BlurFinalTex);
matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate); matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate);
matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor); matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor);
@ -230,12 +196,10 @@ void CBloomEffect::init()
matObjectFinal->setZFunc(CMaterial::always); matObjectFinal->setZFunc(CMaterial::always);
matObjectFinal->setDoubleSided(true); matObjectFinal->setDoubleSided(true);
matObjectFinal->setTexture(0, _BlurFinalTex);
matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate); matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate);
matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor); matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor);
matObjectFinal->setTexture(1, _BlurFinalTex);
matObjectFinal->texEnvOpRGB(1, CMaterial::Modulate); matObjectFinal->texEnvOpRGB(1, CMaterial::Modulate);
matObjectFinal->texEnvArg0RGB(1, CMaterial::Texture, CMaterial::SrcColor); matObjectFinal->texEnvArg0RGB(1, CMaterial::Texture, CMaterial::SrcColor);
matObjectFinal->texEnvArg1RGB(1, CMaterial::Previous, CMaterial::SrcColor); matObjectFinal->texEnvArg1RGB(1, CMaterial::Previous, CMaterial::SrcColor);
@ -245,148 +209,74 @@ void CBloomEffect::init()
_DisplayQuad.V1 = CVector(1.f, 0.f, 0.5f); _DisplayQuad.V1 = CVector(1.f, 0.f, 0.5f);
_DisplayQuad.V2 = CVector(1.f, 1.f, 0.5f); _DisplayQuad.V2 = CVector(1.f, 1.f, 0.5f);
_DisplayQuad.V3 = CVector(0.f, 1.f, 0.5f); _DisplayQuad.V3 = CVector(0.f, 1.f, 0.5f);
_DisplayQuad.Uv0 = CUV(0.f, 0.f);
_DisplayQuad.Uv1 = CUV(1.f, 0.f);
_DisplayQuad.Uv2 = CUV(1.f, 1.f);
_DisplayQuad.Uv3 = CUV(0.f, 1.f);
_BlurQuad.V0 = CVector(-1.f, -1.f, 0.5f); _BlurQuad.V0 = CVector(-1.f, -1.f, 0.5f);
_BlurQuad.V1 = CVector(1.f, -1.f, 0.5f); _BlurQuad.V1 = CVector(1.f, -1.f, 0.5f);
_BlurQuad.V2 = CVector(1.f, 1.f, 0.5f); _BlurQuad.V2 = CVector(1.f, 1.f, 0.5f);
_BlurQuad.V3 = CVector(-1.f, 1.f, 0.5f); _BlurQuad.V3 = CVector(-1.f, 1.f, 0.5f);
_BlurQuad.Uv0 = CUV(0.f, 0.f);
_BlurQuad.Uv1 = CUV(1.f, 0.f);
_BlurQuad.Uv2 = CUV(1.f, 1.f);
_BlurQuad.Uv3 = CUV(0.f, 1.f);
_Init = true; _Init = true;
} }
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
void CBloomEffect::initTexture(CSmartPtr<ITexture> & tex, bool isMode2D, uint32 width, uint32 height) void CBloomEffect::applyBloom(bool backbuffer)
{ {
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect())
tex = new CTextureBloom();
tex->setReleasable(false);
tex->resize(width, height);
tex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff);
tex->setWrapS(ITexture::Clamp);
tex->setWrapT(ITexture::Clamp);
((CTextureBloom *)tex.getPtr())->mode2D(isMode2D);
if(tex->TextureDrvShare==NULL || tex->TextureDrvShare->DrvTexture.getPtr()==NULL)
{
tex->setRenderTarget(true);
drvInternal->setupTexture(*tex);
}
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::initBloom() // clientcfg
{
if(!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect())
return; return;
// don't activate bloom when PolygonMode is different from Filled // don't activate bloom when PolygonMode is different from Filled
if (_Driver->getPolygonMode() != UDriver::Filled) return; if (_Driver->getPolygonMode() != UDriver::Filled) return;
if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0) if (_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0)
return; return;
if(!_Init) if (!_Init)
init(); init();
_OriginalRenderTarget = static_cast<CDriverUser *>(_Driver)->getDriver()->getRenderTarget(); CDriverUser *dru = static_cast<CDriverUser *>(_Driver);
IDriver *drv = dru->getDriver();
// if window resize, reinitialize textures NL3D::ITexture *renderTarget = drv->getRenderTarget();
if(_WndWidth!=_Driver->getWindowWidth() || _WndHeight!=_Driver->getWindowHeight()) nlassert(renderTarget);
{ nlassert(renderTarget->isBloomTexture());
_WndWidth = _Driver->getWindowWidth();
_WndHeight = _Driver->getWindowHeight();
if(_InitBloomEffect) uint width = renderTarget->getWidth();
{ uint height = renderTarget->getHeight();
// release old SmartPtr bool mode2D = static_cast<CTextureBloom *>(renderTarget)->isMode2D();
_DisplayInitMat.getObjectPtr()->setTexture(0, NULL); nlassert(renderTarget->getUploadFormat() == ITexture::Auto);
_InitText = NULL;
initTexture(_InitText, false, _WndWidth, _WndHeight); if (width >= 256) _BlurWidth = 256;
else _BlurWidth = raiseToNextPowerOf2(width) / 2;
if (height >= 256) _BlurHeight = 256;
else _BlurHeight = raiseToNextPowerOf2(height) / 2;
_DisplayInitMat.getObjectPtr()->setTexture(0, _InitText); nlassert(!_BlurFinalTex);
} _BlurFinalTex = _Driver->getRenderTargetManager().getRenderTarget(_BlurWidth, _BlurHeight, true);
nlassert(!_BlurHorizontalTex);
_BlurHorizontalTex = _Driver->getRenderTargetManager().getRenderTarget(_BlurWidth, _BlurHeight, true);
bool reinitBlurTextures = false; _DisplayBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex->getITexture());
if(_WndWidth<_BlurWidth || _WndHeight<_BlurHeight) _DisplaySquareBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex->getITexture());
{ _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, _BlurFinalTex->getITexture());
_BlurWidth = raiseToNextPowerOf2(_WndWidth)/2;
_BlurHeight = raiseToNextPowerOf2(_WndHeight)/2;
reinitBlurTextures = true; CTextureUser texNull;
} dru->setRenderTarget(texNull);
if(_WndWidth>256 && _BlurWidth!=256) // Stretch original render target into blur texture
{ CTextureUser txt1(renderTarget);
_BlurWidth = 256; CTextureUser txt2(_BlurFinalTex->getITexture());
reinitBlurTextures = true; CRect rect1(0, 0, width, height);
}
if(_WndHeight>256 && _BlurHeight!=256)
{
_BlurHeight = 256;
reinitBlurTextures = true;
}
if(reinitBlurTextures)
{
// release old SmartPtr
_DisplayBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(0, NULL);
_BlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(2, NULL);
_BlurMat.getObjectPtr()->setTexture(3, NULL);
_BlurHorizontalTex = NULL;
_BlurFinalTex = NULL;
initTexture(_BlurFinalTex, true, _BlurWidth, _BlurHeight);
initTexture(_BlurHorizontalTex, true, _BlurWidth, _BlurHeight);
_DisplayBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, _BlurFinalTex);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, _BlurFinalTex);
}
}
if (!_OriginalRenderTarget)
{
NL3D::CTextureUser txt = (_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser());
if(!(static_cast<CDriverUser *>(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)))
{
nlwarning("setRenderTarget return false with initial texture for bloom effect\n");
return;
}
}
}
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::endBloom() // clientcfg
{
if(!_Driver->supportBloomEffect() || !_Init)
return;
// don't activate bloom when PolygonMode is different from Filled
if (_Driver->getPolygonMode() != UDriver::Filled) return;
if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0)
return;
CTextureUser txt1 = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()));
CTextureUser txt2(_BlurFinalTex);
CRect rect1(0, 0, _WndWidth, _WndHeight);
CRect rect2(0, 0, _BlurWidth, _BlurHeight); CRect rect2(0, 0, _BlurWidth, _BlurHeight);
// stretch rect dru->stretchRect(_Scene, txt1, rect1, txt2, rect2);
((CDriverUser *) _Driver)->stretchRect(_Scene, txt1 , rect1,
txt2, rect2);
// horizontal blur pass // horizontal blur pass
doBlur(true); doBlur(true);
@ -395,7 +285,38 @@ void CBloomEffect::endBloom() // clientcfg
doBlur(false); doBlur(false);
// apply blur with a blend operation // apply blur with a blend operation
drv->setRenderTarget(renderTarget);
applyBlur(); applyBlur();
// draw final result to backbuffer if last effect
if (backbuffer)
{
CTextureUser texNull;
dru->setRenderTarget(texNull);
_DisplayInitMat.getObjectPtr()->setTexture(0, renderTarget);
UCamera pCam = _Scene->getCam();
_Driver->setMatrixMode2D11();
_Driver->drawQuad(_DisplayQuad, _DisplayInitMat);
_Driver->setMatrixMode3D(pCam);
}
// cleanup material texture references
_DisplayInitMat.getObjectPtr()->setTexture(0, NULL);
_DisplayBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL);
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(0, NULL);
_BlurMat.getObjectPtr()->setTexture(1, NULL);
_BlurMat.getObjectPtr()->setTexture(2, NULL);
_BlurMat.getObjectPtr()->setTexture(3, NULL);
// recycle render targets
_Driver->getRenderTargetManager().recycleRenderTarget(_BlurFinalTex);
_BlurFinalTex = NULL;
_Driver->getRenderTargetManager().recycleRenderTarget(_BlurHorizontalTex);
_BlurHorizontalTex = NULL;
} }
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
@ -404,49 +325,6 @@ void CBloomEffect::applyBlur()
{ {
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
/*if (_OriginalRenderTarget)
{
CTextureUser txt(_OriginalRenderTarget);
if(!(static_cast<CDriverUser *>(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)))
{
nlwarning("setRenderTarget return false with original render target for bloom effect\n");
return;
}
}
// in opengl, display in init texture
else if(_InitBloomEffect)
{
CTextureUser txt(_InitText);
if(!(static_cast<CDriverUser *>(_Driver)->setRenderTarget(txt, 0, 0, _WndWidth, _WndHeight)))
{
nlwarning("setRenderTarget return false with initial texture for bloom effect\n");
return;
}
}*/
CTextureUser txtApply = _OriginalRenderTarget ? CTextureUser(_OriginalRenderTarget) : ((_InitBloomEffect) ? (CTextureUser(_InitText)) : (CTextureUser()));
if(!(static_cast<CDriverUser *>(_Driver)->setRenderTarget(txtApply, 0, 0, _WndWidth, _WndHeight)))
{
nlwarning("setRenderTarget return false with initial texture for bloom effect\n");
return;
}
// display blur texture
// initialize blur texture coordinates
if(_InitBloomEffect)
{
_BlurQuad.Uv0 = CUV(0.f, 0.f);
_BlurQuad.Uv1 = CUV(1.f, 0.f);
_BlurQuad.Uv2 = CUV(1.f, 1.f);
_BlurQuad.Uv3 = CUV(0.f, 1.f);
}
else
{
_BlurQuad.Uv0 = CUV(0.f, 1.f);
_BlurQuad.Uv1 = CUV(1.f, 1.f);
_BlurQuad.Uv2 = CUV(1.f, 0.f);
_BlurQuad.Uv3 = CUV(0.f, 0.f);
}
// initialize vertex program // initialize vertex program
drvInternal->activeVertexProgram(TextureOffsetVertexProgram); drvInternal->activeVertexProgram(TextureOffsetVertexProgram);
drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f); drvInternal->setUniform4f(IDriver::VertexProgram, 8, 255.f, 255.f, 255.f, 255.f);
@ -478,50 +356,6 @@ void CBloomEffect::applyBlur()
drvInternal->activeVertexProgram(NULL); drvInternal->activeVertexProgram(NULL);
} }
//-----------------------------------------------------------------------------------------------------------
void CBloomEffect::endInterfacesDisplayBloom() // clientcfg
{
// Render from render target to screen if necessary.
// Don't do this when the blend was done to the screen or when rendering to a user provided rendertarget.
if ((_OriginalRenderTarget.getPtr() == NULL) && _InitBloomEffect)
{
if(!_Driver->supportBloomEffect() || !_Init)
return;
// don't activate bloom when PolygonMode is different from Filled
if (_Driver->getPolygonMode() != UDriver::Filled) return;
if(_Driver->getWindowWidth()==0 || _Driver->getWindowHeight()==0)
return;
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
CTextureUser txtNull;
((CDriverUser *)_Driver)->setRenderTarget(txtNull, 0, 0, 0, 0);
// initialize texture coordinates
float newU = drvInternal->isTextureRectangle(_InitText) ? (float)_WndWidth : 1.f;
float newV = drvInternal->isTextureRectangle(_InitText) ? (float)_WndHeight : 1.f;
_DisplayQuad.Uv0 = CUV(0.f, 0.f);
_DisplayQuad.Uv1 = CUV(newU, 0.f);
_DisplayQuad.Uv2 = CUV(newU, newV);
_DisplayQuad.Uv3 = CUV(0.f, newV);
// init material texture
// CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr();
// display
UCamera pCam = _Scene->getCam();
_Driver->setMatrixMode2D11();
_Driver->drawQuad(_DisplayQuad, _DisplayInitMat);
_Driver->setMatrixMode3D(pCam);
}
_OriginalRenderTarget = NULL;
}
//----------------------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------------------
void CBloomEffect::doBlur(bool horizontalBlur) void CBloomEffect::doBlur(bool horizontalBlur)
@ -531,17 +365,17 @@ void CBloomEffect::doBlur(bool horizontalBlur)
ITexture * endTexture; ITexture * endTexture;
// set displayed texture and render target texture of the pass // set displayed texture and render target texture of the pass
if(horizontalBlur) if (horizontalBlur)
{ {
blurVec = CVector2f(1.f, 0.f); blurVec = CVector2f(1.f, 0.f);
startTexture = _BlurFinalTex; startTexture = _BlurFinalTex->getITexture();
endTexture = _BlurHorizontalTex; endTexture = _BlurHorizontalTex->getITexture();
} }
else else
{ {
blurVec = CVector2f(0.f, 1.f); blurVec = CVector2f(0.f, 1.f);
startTexture = _BlurHorizontalTex; startTexture = _BlurHorizontalTex->getITexture();
endTexture = _BlurFinalTex; endTexture = _BlurFinalTex->getITexture();
} }
NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver(); NL3D::IDriver *drvInternal = ((CDriverUser *) _Driver)->getDriver();
@ -561,20 +395,20 @@ void CBloomEffect::doBlur(bool horizontalBlur)
// set several decal constants in order to obtain in the render target texture a mix of color // set several decal constants in order to obtain in the render target texture a mix of color
// of a texel and its neighbored texels on the axe of the pass. // of a texel and its neighbored texels on the axe of the pass.
float decalL, decal2L, decalR, decal2R; float decalL, decal2L, decalR, decal2R;
if(_InitBloomEffect) // if(_InitBloomEffect)
{ // {
decalL = -0.5f; decalL = -0.5f;
decal2L = -1.5f; decal2L = -1.5f;
decalR = 0.5f; decalR = 0.5f;
decal2R = 1.5f; decal2R = 1.5f;
} // }
else // else
{ // {
decalL = 0.f; // decalL = 0.f;
decal2L = -1.f; // decal2L = -1.f;
decalR = 1.f; // decalR = 1.f;
decal2R = 2.f; // decal2R = 2.f;
} // }
drvInternal->setUniform2f(IDriver::VertexProgram, 10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y); drvInternal->setUniform2f(IDriver::VertexProgram, 10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y);
drvInternal->setUniform2f(IDriver::VertexProgram, 11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y); drvInternal->setUniform2f(IDriver::VertexProgram, 11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y);
drvInternal->setUniform2f(IDriver::VertexProgram, 12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y); drvInternal->setUniform2f(IDriver::VertexProgram, 12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y);
@ -587,12 +421,6 @@ void CBloomEffect::doBlur(bool horizontalBlur)
matObject->setTexture(2, startTexture); matObject->setTexture(2, startTexture);
matObject->setTexture(3, startTexture); matObject->setTexture(3, startTexture);
// initialize quad
_BlurQuad.Uv0 = CUV(0.0f, 0.0f);
_BlurQuad.Uv1 = CUV(1.f, 0.0f);
_BlurQuad.Uv2 = CUV(1.f, 1.f);
_BlurQuad.Uv3 = CUV(0.0f, 1.f);
// display // display
UCamera pCam = _Scene->getCam(); UCamera pCam = _Scene->getCam();
_Driver->setMatrixMode2D11(); _Driver->setMatrixMode2D11();

View file

@ -1161,7 +1161,7 @@ void prelogInit()
CBloomEffect::getInstance().setDriver(Driver); CBloomEffect::getInstance().setDriver(Driver);
// init bloom effect // init bloom effect
CBloomEffect::getInstance().init(driver != UDriver::Direct3d); CBloomEffect::getInstance().init();
if (StereoDisplay) // VR_CONFIG if (StereoDisplay) // VR_CONFIG
{ {

View file

@ -43,6 +43,8 @@
#include "nel/3d/u_instance_material.h" #include "nel/3d/u_instance_material.h"
#include "nel/3d/u_cloud_scape.h" #include "nel/3d/u_cloud_scape.h"
#include "nel/3d/stereo_hmd.h" #include "nel/3d/stereo_hmd.h"
#include "nel/3d/render_target_manager.h"
#include "nel/3d/driver_user.h"
// game share // game share
#include "game_share/brick_types.h" #include "game_share/brick_types.h"
#include "game_share/light_cycle.h" #include "game_share/light_cycle.h"
@ -561,13 +563,18 @@ void clearBuffers()
void renderScene(bool forceFullDetail, bool bloom) void renderScene(bool forceFullDetail, bool bloom)
{ {
CTextureUser *effectRenderTarget = NULL;
if (bloom) if (bloom)
{ {
// set bloom parameters before applying bloom effect // set bloom parameters before applying bloom effect
CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom);
CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom);
// init bloom // init bloom
CBloomEffect::getInstance().initBloom(); // CBloomEffect::getInstance().initBloom();
uint32 winw, winh;
Driver->getWindowSize(winw, winh);
effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh);
static_cast<CDriverUser *>(Driver)->setRenderTarget(*effectRenderTarget);
} }
if (forceFullDetail) if (forceFullDetail)
{ {
@ -583,8 +590,9 @@ void renderScene(bool forceFullDetail, bool bloom)
if (bloom) if (bloom)
{ {
// apply bloom effect // apply bloom effect
CBloomEffect::getInstance().endBloom(); // CBloomEffect::getInstance().endBloom();
CBloomEffect::getInstance().endInterfacesDisplayBloom(); // CBloomEffect::getInstance().endInterfacesDisplayBloom();
CBloomEffect::getInstance().applyBloom(effectRenderTarget != NULL); // TODO
} }
} }
@ -1622,6 +1630,7 @@ bool mainLoop()
uint i = 0; uint i = 0;
uint bloomStage = 0; uint bloomStage = 0;
CTextureUser *effectRenderTarget = NULL;
while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass()))
{ {
++i; ++i;
@ -1664,14 +1673,20 @@ bool mainLoop()
{ {
if (Render) if (Render)
{ {
if (!StereoDisplay && ClientCfg.Bloom) // NO VR BLOOMZ if (ClientCfg.Bloom && bloomStage == 0)
{ {
nlassert(bloomStage == 0);
// set bloom parameters before applying bloom effect // set bloom parameters before applying bloom effect
CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom);
CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom);
// start bloom effect (just before the first scene element render) // start bloom effect (just before the first scene element render)
CBloomEffect::instance().initBloom(); if (!StereoDisplay) // FIXME: Assumes rendering to render target...!
{
uint32 winw, winh;
Driver->getWindowSize(winw, winh);
effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh);
static_cast<CDriverUser *>(Driver)->setRenderTarget(*effectRenderTarget);
}
// CBloomEffect::instance().initBloom();
bloomStage = 1; bloomStage = 1;
} }
} }
@ -1714,13 +1729,18 @@ bool mainLoop()
// Render // Render
if (Render) if (Render)
{ {
if (!StereoDisplay && ClientCfg.Bloom && bloomStage == 1) // NO VR BLOOMZ if (ClientCfg.Bloom && bloomStage == 1)
{ {
// End the actual bloom effect visible in the scene. // End the actual bloom effect visible in the scene.
if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
CBloomEffect::instance().endBloom(); CBloomEffect::instance().applyBloom(effectRenderTarget != NULL);
if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
bloomStage = 2; if (effectRenderTarget)
{
Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget);
effectRenderTarget = NULL;
}
bloomStage = 0;
} }
// for that frame and // for that frame and
@ -1841,14 +1861,14 @@ bool mainLoop()
// special case in OpenGL : all scene has been display in render target, // special case in OpenGL : all scene has been display in render target,
// now, final texture is display with a quad // now, final texture is display with a quad
if (!StereoDisplay && !ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) // NO VR BLOOMZ /*if (!ClientCfg.Light && ClientCfg.Bloom && Render && bloomStage == 2) // NO VR BLOOMZ
{ {
// End bloom effect system after drawing the 3d interface (z buffer related). // End bloom effect system after drawing the 3d interface (z buffer related).
if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
CBloomEffect::instance().endInterfacesDisplayBloom(); CBloomEffect::instance().endInterfacesDisplayBloom();
if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
bloomStage = 0; bloomStage = 0;
} }*/
} }
{ {

View file

@ -373,7 +373,7 @@ void initIngame()
// initialize bloom effect // initialize bloom effect
CBloomEffect::instance().setDriver(Driver); CBloomEffect::instance().setDriver(Driver);
CBloomEffect::instance().setScene(Scene); CBloomEffect::instance().setScene(Scene);
CBloomEffect::instance().init(ConfigFile->getVar("OpenGL").asInt() == 1); CBloomEffect::instance().init();
CConfiguration::setAndCallback("SquareBloom", cbSquareBloom); CConfiguration::setAndCallback("SquareBloom", cbSquareBloom);
CConfiguration::setAndCallback("DensityBloom", cbDensityBloom); CConfiguration::setAndCallback("DensityBloom", cbDensityBloom);
CConfiguration::setAndCallback("EnableBloom", cbEnableBloom); CConfiguration::setAndCallback("EnableBloom", cbEnableBloom);
@ -763,12 +763,12 @@ void loopIngame()
if (!StereoDisplay || StereoDisplay->wantClear()) if (!StereoDisplay || StereoDisplay->wantClear())
{ {
if (s_EnableBloom) /*if (s_EnableBloom)
{ {
nlassert(bloomStage == 0); nlassert(bloomStage == 0);
CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render)
bloomStage = 1; bloomStage = 1;
} }*/
// 01. Render Driver (background color) // 01. Render Driver (background color)
Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering
@ -788,14 +788,14 @@ void loopIngame()
if (!StereoDisplay || StereoDisplay->wantInterface3D()) if (!StereoDisplay || StereoDisplay->wantInterface3D())
{ {
if (s_EnableBloom && bloomStage == 1) /*if (s_EnableBloom && bloomStage == 1)
{ {
// End the actual bloom effect visible in the scene. // End the actual bloom effect visible in the scene.
if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
CBloomEffect::instance().endBloom(); CBloomEffect::instance().endBloom();
if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
bloomStage = 2; bloomStage = 2;
} }*/
// 06. Render Interface 3D (player names) // 06. Render Interface 3D (player names)
// ... // ...
@ -803,14 +803,14 @@ void loopIngame()
if (!StereoDisplay || StereoDisplay->wantInterface2D()) if (!StereoDisplay || StereoDisplay->wantInterface2D())
{ {
if (s_EnableBloom && bloomStage == 2) /*if (s_EnableBloom && bloomStage == 2)
{ {
// End bloom effect system after drawing the 3d interface (z buffer related). // End bloom effect system after drawing the 3d interface (z buffer related).
if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); if (StereoDisplay) Driver->setViewport(NL3D::CViewport());
CBloomEffect::instance().endInterfacesDisplayBloom(); CBloomEffect::instance().endInterfacesDisplayBloom();
if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport());
bloomStage = 0; bloomStage = 0;
} }*/
// 07. Render Interface 2D (chatboxes etc, optionally does have 3d) // 07. Render Interface 2D (chatboxes etc, optionally does have 3d)
updateCompass(); // Update the compass updateCompass(); // Update the compass