Removed: bloom_effect in client (the used version is in NeL)
parent
d5cb795113
commit
05f51ac50d
@ -1,617 +0,0 @@
|
|||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#include "stdpch.h"
|
|
||||||
#include "bloom_effect.h"
|
|
||||||
|
|
||||||
// NEL3D
|
|
||||||
#include "nel/3d/u_driver.h"
|
|
||||||
#include "nel/3d/u_scene.h"
|
|
||||||
#include "nel/3d/u_camera.h"
|
|
||||||
|
|
||||||
//3D
|
|
||||||
#include "nel/3d/driver_user.h"
|
|
||||||
#include "nel/3d/texture_bloom.h"
|
|
||||||
#include "nel/3d/texture_user.h"
|
|
||||||
|
|
||||||
//client
|
|
||||||
#include "client_cfg.h"
|
|
||||||
|
|
||||||
|
|
||||||
using namespace NLMISC;
|
|
||||||
using namespace NL3D;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
|
|
||||||
// EXTERN
|
|
||||||
extern UDriver *Driver;
|
|
||||||
extern UScene *Scene;
|
|
||||||
|
|
||||||
// vertex program used to blur texture
|
|
||||||
static const char *TextureOffset =
|
|
||||||
"!!VP1.0 \n\
|
|
||||||
MOV o[COL0].x, c[8].x; \n\
|
|
||||||
MOV o[COL0].y, c[8].y; \n\
|
|
||||||
MOV o[COL0].z, c[8].z; \n\
|
|
||||||
MOV o[COL0].w, c[8].w; \n\
|
|
||||||
MOV o[HPOS].x, v[OPOS].x; \n\
|
|
||||||
MOV o[HPOS].y, v[OPOS].y; \n\
|
|
||||||
MOV o[HPOS].z, v[OPOS].z; \n\
|
|
||||||
MOV o[HPOS].w, c[9].w; \n\
|
|
||||||
ADD o[TEX0], v[TEX0], c[10]; \n\
|
|
||||||
ADD o[TEX1], v[TEX0], c[11]; \n\
|
|
||||||
ADD o[TEX2], v[TEX0], c[12]; \n\
|
|
||||||
ADD o[TEX3], v[TEX0], c[13]; \n\
|
|
||||||
END \n";
|
|
||||||
|
|
||||||
|
|
||||||
static CVertexProgram TextureOffsetVertexProgram(TextureOffset);
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
CBloomEffect::CBloomEffect()
|
|
||||||
{
|
|
||||||
_Init = false;
|
|
||||||
_InitBloomEffect = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
CBloomEffect::~CBloomEffect()
|
|
||||||
{
|
|
||||||
if(_Init)
|
|
||||||
{
|
|
||||||
if(!_DisplayInitMat.empty())
|
|
||||||
{
|
|
||||||
_DisplayInitMat.getObjectPtr()->setTexture(0, NULL);
|
|
||||||
if (Driver) Driver->deleteMaterial(_DisplayInitMat);
|
|
||||||
}
|
|
||||||
_InitText = NULL;
|
|
||||||
|
|
||||||
if(!_DisplayBlurMat.empty())
|
|
||||||
{
|
|
||||||
_DisplayBlurMat.getObjectPtr()->setTexture(0, NULL);
|
|
||||||
if (Driver) Driver->deleteMaterial(_DisplayBlurMat);
|
|
||||||
}
|
|
||||||
if(!_DisplaySquareBlurMat.empty())
|
|
||||||
{
|
|
||||||
_DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL);
|
|
||||||
_DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL);
|
|
||||||
if (Driver) Driver->deleteMaterial(_DisplaySquareBlurMat);
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
_BlurHorizontalTex = NULL;
|
|
||||||
_BlurFinalTex = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CBloomEffect::init(bool initBloomEffect)
|
|
||||||
{
|
|
||||||
_InitBloomEffect = initBloomEffect;
|
|
||||||
|
|
||||||
if(ClientCfg.Bloom && ((CDriverUser *)Driver)->getDriver()->supportBloomEffect())
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CBloomEffect::init()
|
|
||||||
{
|
|
||||||
_WndWidth = Driver->getWindowWidth();
|
|
||||||
_WndHeight = Driver->getWindowHeight();
|
|
||||||
|
|
||||||
_BlurWidth = 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
|
|
||||||
_BlurMat = Driver->createMaterial();
|
|
||||||
CMaterial * matObject = _BlurMat.getObjectPtr();
|
|
||||||
_BlurMat.initUnlit();
|
|
||||||
_BlurMat.setColor(CRGBA::White);
|
|
||||||
_BlurMat.setBlend (false);
|
|
||||||
_BlurMat.setAlphaTest (false);
|
|
||||||
matObject->setBlendFunc (CMaterial::one, CMaterial::zero);
|
|
||||||
matObject->setZWrite(false);
|
|
||||||
matObject->setZFunc(CMaterial::always);
|
|
||||||
matObject->setDoubleSided(true);
|
|
||||||
|
|
||||||
// initialize stages of fixed pipeline
|
|
||||||
CRGBA constantCol1(85, 85, 85, 85);
|
|
||||||
CRGBA constantCol2(43, 43, 43, 43);
|
|
||||||
// stage 0
|
|
||||||
matObject->texConstantColor(0, constantCol1);
|
|
||||||
matObject->texEnvOpRGB(0, CMaterial::Modulate);
|
|
||||||
matObject->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
|
|
||||||
matObject->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor);
|
|
||||||
|
|
||||||
// stage 1
|
|
||||||
matObject->texConstantColor(1, constantCol2);
|
|
||||||
matObject->texEnvOpRGB(1, CMaterial::Mad);
|
|
||||||
matObject->texEnvArg0RGB(1, CMaterial::Texture, CMaterial::SrcColor);
|
|
||||||
matObject->texEnvArg1RGB(1, CMaterial::Constant, CMaterial::SrcColor);
|
|
||||||
matObject->texEnvArg2RGB(1, CMaterial::Previous, CMaterial::SrcColor);
|
|
||||||
|
|
||||||
// stage 2
|
|
||||||
matObject->texConstantColor(2, constantCol1);
|
|
||||||
matObject->texEnvOpRGB(2, CMaterial::Mad);
|
|
||||||
matObject->texEnvArg0RGB(2, CMaterial::Texture, CMaterial::SrcColor);
|
|
||||||
matObject->texEnvArg1RGB(2, CMaterial::Constant, CMaterial::SrcColor);
|
|
||||||
matObject->texEnvArg2RGB(2, CMaterial::Previous, CMaterial::SrcColor);
|
|
||||||
|
|
||||||
// stage 3
|
|
||||||
matObject->texConstantColor(3, constantCol2);
|
|
||||||
matObject->texEnvOpRGB(3, CMaterial::Mad);
|
|
||||||
matObject->texEnvArg0RGB(3, CMaterial::Texture, CMaterial::SrcColor);
|
|
||||||
matObject->texEnvArg1RGB(3, CMaterial::Constant, CMaterial::SrcColor);
|
|
||||||
matObject->texEnvArg2RGB(3, CMaterial::Previous, CMaterial::SrcColor);
|
|
||||||
|
|
||||||
// initialize display materials
|
|
||||||
if(_InitBloomEffect)
|
|
||||||
{
|
|
||||||
_DisplayInitMat = Driver->createMaterial();
|
|
||||||
CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr();
|
|
||||||
_DisplayInitMat.initUnlit();
|
|
||||||
_DisplayInitMat.setColor(CRGBA::White);
|
|
||||||
_DisplayInitMat.setBlend (false);
|
|
||||||
_DisplayInitMat.setAlphaTest (false);
|
|
||||||
matObjectInit->setBlendFunc (CMaterial::one, CMaterial::zero);
|
|
||||||
matObjectInit->setZWrite(false);
|
|
||||||
matObjectInit->setZFunc(CMaterial::always);
|
|
||||||
matObjectInit->setDoubleSided(true);
|
|
||||||
matObjectInit->setTexture(0, _InitText);
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize linear blur material
|
|
||||||
_DisplayBlurMat = Driver->createMaterial();
|
|
||||||
CMaterial * matObjectFinal = _DisplayBlurMat.getObjectPtr();
|
|
||||||
_DisplayBlurMat.initUnlit();
|
|
||||||
_DisplayBlurMat.setColor(CRGBA::White);
|
|
||||||
matObjectFinal->setBlend(true);
|
|
||||||
matObjectFinal->setBlendFunc(CMaterial::one, CMaterial::invsrccolor);
|
|
||||||
matObjectFinal->setZWrite(false);
|
|
||||||
matObjectFinal->setZFunc(CMaterial::always);
|
|
||||||
matObjectFinal->setDoubleSided(true);
|
|
||||||
|
|
||||||
matObjectFinal->setTexture(0, _BlurFinalTex);
|
|
||||||
matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate);
|
|
||||||
matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
|
|
||||||
matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor);
|
|
||||||
|
|
||||||
// initialize square blur material
|
|
||||||
_DisplaySquareBlurMat = Driver->createMaterial();
|
|
||||||
matObjectFinal = _DisplaySquareBlurMat.getObjectPtr();
|
|
||||||
_DisplaySquareBlurMat.initUnlit();
|
|
||||||
_DisplaySquareBlurMat.setColor(CRGBA::White);
|
|
||||||
matObjectFinal->setBlend(true);
|
|
||||||
matObjectFinal->setBlendFunc(CMaterial::one, CMaterial::invsrccolor);
|
|
||||||
matObjectFinal->setZWrite(false);
|
|
||||||
matObjectFinal->setZFunc(CMaterial::always);
|
|
||||||
matObjectFinal->setDoubleSided(true);
|
|
||||||
|
|
||||||
matObjectFinal->setTexture(0, _BlurFinalTex);
|
|
||||||
matObjectFinal->texEnvOpRGB(0, CMaterial::Modulate);
|
|
||||||
matObjectFinal->texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor);
|
|
||||||
matObjectFinal->texEnvArg1RGB(0, CMaterial::Constant, CMaterial::SrcColor);
|
|
||||||
|
|
||||||
matObjectFinal->setTexture(1, _BlurFinalTex);
|
|
||||||
matObjectFinal->texEnvOpRGB(1, CMaterial::Modulate);
|
|
||||||
matObjectFinal->texEnvArg0RGB(1, CMaterial::Texture, CMaterial::SrcColor);
|
|
||||||
matObjectFinal->texEnvArg1RGB(1, CMaterial::Previous, CMaterial::SrcColor);
|
|
||||||
|
|
||||||
// initialize quads
|
|
||||||
_DisplayQuad.V0 = CVector(0.f, 0.f, 0.5f);
|
|
||||||
_DisplayQuad.V1 = CVector(1.f, 0.f, 0.5f);
|
|
||||||
_DisplayQuad.V2 = CVector(1.f, 1.f, 0.5f);
|
|
||||||
_DisplayQuad.V3 = CVector(0.f, 1.f, 0.5f);
|
|
||||||
|
|
||||||
_BlurQuad.V0 = 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.V3 = CVector(-1.f, 1.f, 0.5f);
|
|
||||||
|
|
||||||
_Init = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CBloomEffect::initTexture(CSmartPtr<ITexture> & tex, bool isMode2D, uint32 width, uint32 height)
|
|
||||||
{
|
|
||||||
NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver();
|
|
||||||
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
if(!ClientCfg.Bloom || !((CDriverUser *)Driver)->getDriver()->supportBloomEffect())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(Driver->getWindowWidth()==0 || Driver->getWindowHeight()==0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!_Init)
|
|
||||||
init();
|
|
||||||
|
|
||||||
// if window resize, reinitialize textures
|
|
||||||
if(_WndWidth!=Driver->getWindowWidth() || _WndHeight!=Driver->getWindowHeight())
|
|
||||||
{
|
|
||||||
_WndWidth = Driver->getWindowWidth();
|
|
||||||
_WndHeight = Driver->getWindowHeight();
|
|
||||||
|
|
||||||
if(_InitBloomEffect)
|
|
||||||
{
|
|
||||||
// release old SmartPtr
|
|
||||||
_DisplayInitMat.getObjectPtr()->setTexture(0, NULL);
|
|
||||||
_InitText = NULL;
|
|
||||||
|
|
||||||
initTexture(_InitText, false, _WndWidth, _WndHeight);
|
|
||||||
|
|
||||||
_DisplayInitMat.getObjectPtr()->setTexture(0, _InitText);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool reinitBlurTextures = false;
|
|
||||||
if(_WndWidth<_BlurWidth || _WndHeight<_BlurHeight)
|
|
||||||
{
|
|
||||||
_BlurWidth = raiseToNextPowerOf2(_WndWidth)/2;
|
|
||||||
_BlurHeight = raiseToNextPowerOf2(_WndHeight)/2;
|
|
||||||
|
|
||||||
reinitBlurTextures = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_WndWidth>256 && _BlurWidth!=256)
|
|
||||||
{
|
|
||||||
_BlurWidth = 256;
|
|
||||||
reinitBlurTextures = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NL3D::CTextureUser *txt = (_InitBloomEffect) ? (new CTextureUser(_InitText)) : (new CTextureUser());
|
|
||||||
if(!((CDriverUser *) Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight))
|
|
||||||
{
|
|
||||||
nlwarning("setRenderTarget return false with initial texture for bloom effect\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delete txt;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CBloomEffect::endBloom()
|
|
||||||
{
|
|
||||||
if(!ClientCfg.Bloom || !Driver->supportBloomEffect() || !_Init)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(Driver->getWindowWidth()==0 || Driver->getWindowHeight()==0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CTextureUser *txt1 = (_InitBloomEffect) ? (new CTextureUser(_InitText)) : (new CTextureUser());
|
|
||||||
CTextureUser *txt2 = new CTextureUser(_BlurFinalTex);
|
|
||||||
CRect *rect1 = new CRect(0, 0, _WndWidth, _WndHeight);
|
|
||||||
CRect *rect2 = new CRect(0, 0, _BlurWidth, _BlurHeight);
|
|
||||||
// stretch rect
|
|
||||||
((CDriverUser *) Driver)->stretchRect(Scene, *txt1 , *rect1,
|
|
||||||
*txt2, *rect2);
|
|
||||||
|
|
||||||
// horizontal blur pass
|
|
||||||
doBlur(true);
|
|
||||||
|
|
||||||
// vertical blur pass
|
|
||||||
doBlur(false);
|
|
||||||
|
|
||||||
// apply blur with a blend operation
|
|
||||||
applyBlur();
|
|
||||||
delete txt1;
|
|
||||||
delete txt2;
|
|
||||||
delete rect1;
|
|
||||||
delete rect2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CBloomEffect::applyBlur()
|
|
||||||
{
|
|
||||||
NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver();
|
|
||||||
|
|
||||||
// in opengl, display in init texture
|
|
||||||
if(_InitBloomEffect)
|
|
||||||
{
|
|
||||||
CTextureUser *txt = new CTextureUser(_InitText);
|
|
||||||
if(!((CDriverUser *) Driver)->setRenderTarget(*txt, 0, 0, _WndWidth, _WndHeight))
|
|
||||||
{
|
|
||||||
nlwarning("setRenderTarget return false with initial texture for bloom effect\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delete txt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
drvInternal->activeVertexProgram(&TextureOffsetVertexProgram);
|
|
||||||
drvInternal->setConstant(8, 255.f, 255.f, 255.f, 255.f);
|
|
||||||
drvInternal->setConstant(9, 0.0f, 0.f, 0.f, 1.f);
|
|
||||||
|
|
||||||
// initialize blur material
|
|
||||||
UMaterial displayBlurMat;
|
|
||||||
if(ClientCfg.SquareBloom)
|
|
||||||
{
|
|
||||||
displayBlurMat = _DisplaySquareBlurMat;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
displayBlurMat = _DisplayBlurMat;
|
|
||||||
}
|
|
||||||
CMaterial * matObjectFinal = displayBlurMat.getObjectPtr();
|
|
||||||
|
|
||||||
uint8 d = (uint8)ClientCfg.DensityBloom;
|
|
||||||
CRGBA constCoeff(d, d, d, d);
|
|
||||||
matObjectFinal->texConstantColor(0, constCoeff);
|
|
||||||
|
|
||||||
// display quad
|
|
||||||
UCamera pCam = Scene->getCam();
|
|
||||||
Driver->setMatrixMode2D11();
|
|
||||||
Driver->drawQuad(_BlurQuad, displayBlurMat);
|
|
||||||
Driver->setMatrixMode3D(pCam);
|
|
||||||
|
|
||||||
// disable vertex program
|
|
||||||
drvInternal->activeVertexProgram(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CBloomEffect::endInterfacesDisplayBloom()
|
|
||||||
{
|
|
||||||
if(_InitBloomEffect)
|
|
||||||
{
|
|
||||||
if(!ClientCfg.Bloom || !Driver->supportBloomEffect() || !_Init)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(Driver->getWindowWidth()==0 || Driver->getWindowHeight()==0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver();
|
|
||||||
CTextureUser *txt = new CTextureUser();
|
|
||||||
((CDriverUser *)Driver)->setRenderTarget(*txt, 0, 0, 0, 0);
|
|
||||||
delete txt;
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void CBloomEffect::doBlur(bool horizontalBlur)
|
|
||||||
{
|
|
||||||
CVector2f blurVec;
|
|
||||||
ITexture * startTexture;
|
|
||||||
ITexture * endTexture;
|
|
||||||
|
|
||||||
// set displayed texture and render target texture of the pass
|
|
||||||
if(horizontalBlur)
|
|
||||||
{
|
|
||||||
blurVec = CVector2f(1.f, 0.f);
|
|
||||||
startTexture = _BlurFinalTex;
|
|
||||||
endTexture = _BlurHorizontalTex;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
blurVec = CVector2f(0.f, 1.f);
|
|
||||||
startTexture = _BlurHorizontalTex;
|
|
||||||
endTexture = _BlurFinalTex;
|
|
||||||
}
|
|
||||||
|
|
||||||
NL3D::IDriver *drvInternal = ((CDriverUser *) Driver)->getDriver();
|
|
||||||
CTextureUser *txt = new CTextureUser(endTexture);
|
|
||||||
// initialize render target
|
|
||||||
if(!((CDriverUser *) Driver)->setRenderTarget(*txt, 0, 0, _BlurWidth, _BlurHeight))
|
|
||||||
{
|
|
||||||
nlwarning("setRenderTarget return false with blur texture for bloom effect\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
delete txt;
|
|
||||||
|
|
||||||
// initialize vertex program
|
|
||||||
drvInternal->activeVertexProgram(&TextureOffsetVertexProgram);
|
|
||||||
drvInternal->setConstant(8, 255.f, 255.f, 255.f, 255.f);
|
|
||||||
drvInternal->setConstant(9, 0.0f, 0.f, 0.f, 1.f);
|
|
||||||
|
|
||||||
// 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.
|
|
||||||
float decalL, decal2L, decalR, decal2R;
|
|
||||||
if(_InitBloomEffect)
|
|
||||||
{
|
|
||||||
decalL = -0.5f;
|
|
||||||
decal2L = -1.5f;
|
|
||||||
decalR = 0.5f;
|
|
||||||
decal2R = 1.5f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
decalL = 0.f;
|
|
||||||
decal2L = -1.f;
|
|
||||||
decalR = 1.f;
|
|
||||||
decal2R = 2.f;
|
|
||||||
}
|
|
||||||
drvInternal->setConstant(10, (decalR/(float)_BlurWidth)*blurVec.x, (decalR/(float)_BlurHeight)*blurVec.y, 0.f, 0.f);
|
|
||||||
drvInternal->setConstant(11, (decal2R/(float)_BlurWidth)*blurVec.x, (decal2R/(float)_BlurHeight)*blurVec.y, 0.f, 0.f);
|
|
||||||
drvInternal->setConstant(12, (decalL/(float)_BlurWidth)*blurVec.x, (decalL/(float)_BlurHeight)*blurVec.y, 0.f, 0.f);
|
|
||||||
drvInternal->setConstant(13, (decal2L/(float)_BlurWidth)*blurVec.x, (decal2L/(float)_BlurHeight)*blurVec.y, 0.f, 0.f);
|
|
||||||
|
|
||||||
// initialize material textures
|
|
||||||
CMaterial * matObject = _BlurMat.getObjectPtr();
|
|
||||||
matObject->setTexture(0, startTexture);
|
|
||||||
matObject->setTexture(1, startTexture);
|
|
||||||
matObject->setTexture(2, 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
|
|
||||||
UCamera pCam = Scene->getCam();
|
|
||||||
Driver->setMatrixMode2D11();
|
|
||||||
Driver->drawQuad(_BlurQuad, _BlurMat);
|
|
||||||
|
|
||||||
// disable render target and vertex program
|
|
||||||
drvInternal->activeVertexProgram(NULL);
|
|
||||||
txt = new CTextureUser();
|
|
||||||
((CDriverUser *)Driver)->setRenderTarget(*txt, 0, 0, 0, 0);
|
|
||||||
Driver->setMatrixMode3D(pCam);
|
|
||||||
delete txt;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
|||||||
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
||||||
// Copyright (C) 2010 Winch Gate Property Limited
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU Affero General Public License as
|
|
||||||
// published by the Free Software Foundation, either version 3 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU Affero General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
#ifndef NL_BLOOM_EFFECT_H
|
|
||||||
#define NL_BLOOM_EFFECT_H
|
|
||||||
|
|
||||||
// Misc
|
|
||||||
#include "nel/misc/singleton.h"
|
|
||||||
#include "nel/misc/vector_2f.h"
|
|
||||||
|
|
||||||
// 3D
|
|
||||||
#include "nel/3d/texture.h"
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
//---------------------------------------- CBloomEffect -----------------------------------------------------
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
// CBloomEffect class apply a bloom effect on all scene appart from interfaces. All scene is rendered in a
|
|
||||||
// render target (a Frame Buffer Object on OpengL, the normal back buffer in Direct3D) which is stretched
|
|
||||||
// in a 256*256 another render target.
|
|
||||||
// We apply a horizontal blur on this 256*256 render target, then a vertical blur on the result of this first pass.
|
|
||||||
// The final blured render target is blend with the initial render target of scene, with a dest + src - dest*src
|
|
||||||
// blend operation.
|
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
|
||||||
class CBloomEffect : public NLMISC::CSingleton<CBloomEffect>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// Constructor
|
|
||||||
CBloomEffect();
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
~CBloomEffect();
|
|
||||||
|
|
||||||
// Called after the Driver initialization to indicate if OpenGL or Direct3D is used.
|
|
||||||
// They are some differences in bloom algorithm in function of this API choice.
|
|
||||||
// If bloom effect is activated and supported, private method init() is called to initialize
|
|
||||||
// textures and materials.
|
|
||||||
void init(bool initBloomEffect);
|
|
||||||
|
|
||||||
// Called at the beginning of renderAll method in the main loop, if window has been resized,
|
|
||||||
// reinitialize bloom textures according to new window size.
|
|
||||||
// The bloom texture (_InitText attribute) which is used as render target during scene render
|
|
||||||
// is reinitialized with window dimensions.
|
|
||||||
// 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
|
|
||||||
// power of 2, lower than this window dimension.
|
|
||||||
void initBloom();
|
|
||||||
|
|
||||||
// Called at the end of renderAll method in the main loop, recover stretched texture, apply
|
|
||||||
// the both blur passes, and the blending operation between initial render target and the blured one.
|
|
||||||
void endBloom();
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
// to keep correct Z tests.
|
|
||||||
// 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.
|
|
||||||
// NB : In Direct3D, the final render target is displayed at the end of endBloom call.
|
|
||||||
void endInterfacesDisplayBloom();
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// Initialize textures and materials.
|
|
||||||
void init();
|
|
||||||
|
|
||||||
// Initialize a bloom texture with new dimensions.
|
|
||||||
void initTexture(NLMISC::CSmartPtr<NL3D::ITexture> & tex, bool isMode2D, uint32 width, uint32 height);
|
|
||||||
|
|
||||||
// Called in endBloom method to build a blured texture. Two passes (then two calls)
|
|
||||||
// are necessary : horizontal and vertical.
|
|
||||||
// For the first pass, blur is applied horizontally to stretched texture _BlurFinalTex and recover in
|
|
||||||
// _BlurHorizontalTex render target texure.
|
|
||||||
// For the second pass, blur is applied vertically to precedent _BlurHorizontalTex texture and recover
|
|
||||||
// in _BlurFinalTex render target texture.
|
|
||||||
// For each pass, thanks to a vertex program, first texture is displayed with several little decals
|
|
||||||
// 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.
|
|
||||||
void doBlur(bool horizontalBlur);
|
|
||||||
|
|
||||||
// Called in endBloom method after the both doBlur passes. Apply blend operation between intial render target
|
|
||||||
// texture _InitText of scene and the blured texture _BlurFinalTex.
|
|
||||||
void applyBlur();
|
|
||||||
|
|
||||||
|
|
||||||
// render target textures
|
|
||||||
// used to display scene
|
|
||||||
NLMISC::CSmartPtr<NL3D::ITexture> _InitText;
|
|
||||||
// used as stretched texture from _InitText, as displayed texture in first blur pass,
|
|
||||||
// and as render target in second blur pass.
|
|
||||||
NLMISC::CSmartPtr<NL3D::ITexture> _BlurFinalTex;
|
|
||||||
// used as rander target in first blur pass, and as displayed texture on second blur pass.
|
|
||||||
NLMISC::CSmartPtr<NL3D::ITexture> _BlurHorizontalTex;
|
|
||||||
|
|
||||||
|
|
||||||
// materials
|
|
||||||
// used to display first texture in doBlur passes.
|
|
||||||
NL3D::UMaterial _BlurMat;
|
|
||||||
// used to display final render target texture in endInterfacesDisplayBloom call (OpenGL).
|
|
||||||
NL3D::UMaterial _DisplayInitMat;
|
|
||||||
// used to blend intial scene render target texture and blur texture according to a
|
|
||||||
// dest+src - dest*src blend operation.
|
|
||||||
NL3D::UMaterial _DisplayBlurMat;
|
|
||||||
// used to blend intial scene render target texture and blur texture according to a
|
|
||||||
// dest+src - dest*src blend operation, with a square stage operation.
|
|
||||||
NL3D::UMaterial _DisplaySquareBlurMat;
|
|
||||||
|
|
||||||
// quads
|
|
||||||
NLMISC::CQuadUV _BlurQuad;
|
|
||||||
NLMISC::CQuadUV _DisplayQuad;
|
|
||||||
|
|
||||||
// openGL or Direct3D?
|
|
||||||
bool _InitBloomEffect;
|
|
||||||
|
|
||||||
// textures and materials already initialized?
|
|
||||||
bool _Init;
|
|
||||||
|
|
||||||
// current window dimensions
|
|
||||||
uint32 _WndWidth;
|
|
||||||
uint32 _WndHeight;
|
|
||||||
|
|
||||||
// current blur texture dimensions
|
|
||||||
uint32 _BlurWidth;
|
|
||||||
uint32 _BlurHeight;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue