mirror of
https://bitbucket.org/Ryfon/mux.git
synced 2025-12-21 02:40:14 -06:00
281 lines
9.8 KiB
C++
281 lines
9.8 KiB
C++
#include "StdAfx.h"
|
|
#include "BloomEffect.h"
|
|
|
|
#ifndef CODE_INGAME
|
|
using namespace SceneCore;
|
|
|
|
CBloomEffect::CBloomEffect(void)
|
|
: m_spRTView(NULL),
|
|
m_spDrawSceneRTView(NULL),
|
|
m_pkRTViewTexProp(NULL),
|
|
m_spRTGroupDownPassHalf(NULL),
|
|
m_spTextureDownPassHalf(NULL),
|
|
m_spRTGroupDownPassQtr0(NULL),
|
|
m_spTextureDownPassQtr0(NULL),
|
|
m_spRTGroupDownPassQtr1(NULL),
|
|
m_spTextureDownPassQtr1(NULL),
|
|
m_spScaleDownMtl(NULL),
|
|
m_spBlurUMtl(NULL),
|
|
m_spBlurVMtl(NULL),
|
|
m_spBloomCombineMtl(NULL),
|
|
// add [5/27/2009 hemeng]
|
|
m_fBloom_Luminance(1.0f),
|
|
m_fBloom_Scale(0)
|
|
{
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
CBloomEffect::~CBloomEffect(void)
|
|
{
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
bool CBloomEffect::Init(NiRenderedTexturePtr pkSourceTexture)
|
|
{
|
|
if (!__super::Init(pkSourceTexture))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
NiRenderer* pkRenderer = NiRenderer::GetRenderer();
|
|
|
|
m_uiWidthSource = pkSourceTexture->GetWidth();
|
|
m_uiHeightSource = pkSourceTexture->GetHeight();
|
|
|
|
m_TexelSizeSource = NiPoint2(1.0f/m_uiWidthSource, 1.0f/m_uiHeightSource);
|
|
|
|
// RT
|
|
//m_spTextureDownPassHalf = NiRenderedTexture::Create(m_uiWidthSource>>1, m_uiHeightSource>>1, pkRenderer);
|
|
m_spSourceTexture = pkSourceTexture;
|
|
m_spTextureDownPassQtr0 = NiRenderedTexture::Create(256, 256, pkRenderer);
|
|
m_spTextureDownPassQtr1 = NiRenderedTexture::Create(256, 256, pkRenderer);
|
|
if (NULL==m_spTextureDownPassQtr0 || NULL==m_spTextureDownPassQtr1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// RTG
|
|
//m_spRTGroupDownPassHalf = NiRenderTargetGroup::Create(m_spTextureDownPassHalf->GetBuffer(), pkRenderer, true, true);
|
|
m_spOutputRenderTarget = NiRenderTargetGroup::Create( m_spSourceTexture->GetBuffer(), pkRenderer,true, true );
|
|
m_spRTGroupDownPassQtr0 = NiRenderTargetGroup::Create(m_spTextureDownPassQtr0->GetBuffer(), pkRenderer, true, true);
|
|
m_spRTGroupDownPassQtr1 = NiRenderTargetGroup::Create(m_spTextureDownPassQtr1->GetBuffer(), pkRenderer, true, true);
|
|
|
|
// 创建 material
|
|
m_spScaleDownMtl = NiSingleShaderMaterial::Create( "ScaleDown" );
|
|
m_spBlurUMtl = NiSingleShaderMaterial::Create( "BlurU" );
|
|
m_spBlurVMtl = NiSingleShaderMaterial::Create( "BlurV" );
|
|
m_spBloomCombineMtl = NiSingleShaderMaterial::Create( "BloomCombine" );
|
|
|
|
NIASSERT( m_spScaleDownMtl);
|
|
NIASSERT( m_spBlurUMtl);
|
|
NIASSERT( m_spBlurVMtl);
|
|
NIASSERT( m_spBloomCombineMtl);
|
|
|
|
_CreateScreenFillingRenderViews();
|
|
NIASSERT(m_spRTView);
|
|
|
|
// 1. Down pass 到 1/4 大小
|
|
NiViewRenderClick* pkRenderClick = NiNew NiViewRenderClick;
|
|
pkRenderClick->AppendRenderView(m_spRTView);
|
|
pkRenderClick->SetClearAllBuffers(true);
|
|
pkRenderClick->SetRenderTargetGroup(m_spRTGroupDownPassQtr0);
|
|
pkRenderClick->SetPreProcessingCallbackFunc(_PreScaleDownCallback, this);
|
|
m_spRenderStep->AppendRenderClick(pkRenderClick);
|
|
|
|
// 2. U Blur
|
|
pkRenderClick = NiNew NiViewRenderClick;
|
|
pkRenderClick->AppendRenderView(m_spRTView);
|
|
pkRenderClick->SetClearAllBuffers(true);
|
|
pkRenderClick->SetRenderTargetGroup(m_spRTGroupDownPassQtr1);
|
|
pkRenderClick->SetPreProcessingCallbackFunc(_PreBlurUCallback, this);
|
|
m_spRenderStep->AppendRenderClick(pkRenderClick);
|
|
|
|
// 3. V Blur
|
|
pkRenderClick = NiNew NiViewRenderClick;
|
|
pkRenderClick->AppendRenderView(m_spRTView);
|
|
pkRenderClick->SetClearAllBuffers(true);
|
|
pkRenderClick->SetRenderTargetGroup(m_spRTGroupDownPassQtr0);
|
|
pkRenderClick->SetPreProcessingCallbackFunc(_PreBlurVCallback, this);
|
|
m_spRenderStep->AppendRenderClick(pkRenderClick);
|
|
|
|
// 4. Bloom combine [6/15/2009 hemeng]
|
|
pkRenderClick = NiNew NiViewRenderClick;
|
|
pkRenderClick->AppendRenderView(m_spRTView);
|
|
pkRenderClick->SetClearAllBuffers(true);
|
|
pkRenderClick->SetRenderTargetGroup(m_spRTGroupDownPassQtr1);
|
|
pkRenderClick->SetPreProcessingCallbackFunc(_PreBloomCombineCallback, this);
|
|
m_spRenderStep->AppendRenderClick(pkRenderClick);
|
|
|
|
// 5. 渲染到 最终OutputRTG
|
|
pkRenderClick = NiNew NiViewRenderClick;
|
|
pkRenderClick->AppendRenderView(m_spDrawSceneRTView);
|
|
pkRenderClick->SetClearAllBuffers(false);
|
|
pkRenderClick->SetRenderTargetGroup(m_spOutputRenderTarget);
|
|
pkRenderClick->SetPreProcessingCallbackFunc(_PreDrawSceneCallback, this);
|
|
m_spRenderStep->AppendRenderClick(pkRenderClick);
|
|
|
|
m_bInitialized = true;
|
|
return true;
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
void CBloomEffect::Destory()
|
|
{
|
|
/// Render-to-texture全屏View
|
|
m_spRTView = NULL;
|
|
/// Texture Property
|
|
m_pkRTViewTexProp = NULL;
|
|
|
|
/// Render-to-Output RTG全屏View
|
|
m_spDrawSceneRTView = NULL;
|
|
|
|
/// down pass 到 一半尺寸的 RTG
|
|
m_spRTGroupDownPassHalf = NULL;
|
|
m_spTextureDownPassHalf = NULL;
|
|
|
|
/// down pass 到 1/4 尺寸的 RTG
|
|
m_spRTGroupDownPassQtr0 = NULL;
|
|
m_spTextureDownPassQtr0 = NULL;
|
|
m_spRTGroupDownPassQtr1 = NULL;
|
|
m_spTextureDownPassQtr1 = NULL;
|
|
|
|
/// 缩小
|
|
m_spScaleDownMtl = NULL;
|
|
/// BlurU材质
|
|
m_spBlurUMtl = NULL;
|
|
/// BlurV材质
|
|
m_spBlurVMtl = NULL;
|
|
/// 放大材质
|
|
m_spBloomCombineMtl = NULL;
|
|
|
|
__super::Destory();
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
const char* CBloomEffect::GetName()
|
|
{
|
|
return "Bloom";
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
void CBloomEffect::_CreateScreenFillingRenderViews()
|
|
{
|
|
// Create the render-to-texture object.
|
|
m_spRTView = NiNew NiScreenFillingRenderView;
|
|
|
|
m_spRTView->GetScreenFillingQuad().ApplyAndSetActiveMaterial( 0 );
|
|
m_pkRTViewTexProp = NiNew NiTexturingProperty;
|
|
m_pkRTViewTexProp->SetBaseTexture( m_spSourceTexture ); // 首先将原纹理 down pass 到 1/4尺寸
|
|
m_pkRTViewTexProp->SetBaseFilterMode( NiTexturingProperty::FILTER_BILERP );
|
|
m_pkRTViewTexProp->SetApplyMode( NiTexturingProperty::APPLY_REPLACE );
|
|
m_spRTView->AttachProperty( m_pkRTViewTexProp );
|
|
|
|
// Create the render-to-texture screen camera. The render target must
|
|
// be set before the creation of the camera since the camera grabs the
|
|
// current renderer's back buffer width and height.
|
|
|
|
// Create the render-to-backbuffer object.
|
|
m_spDrawSceneRTView = NiNew NiScreenFillingRenderView;
|
|
|
|
// Attach an alpha property and a texturing property.
|
|
NiTexturingProperty* pkTexProp = NiNew NiTexturingProperty;
|
|
pkTexProp->SetBaseTexture( m_spTextureDownPassQtr0 );
|
|
pkTexProp->SetBaseFilterMode(NiTexturingProperty::FILTER_BILERP);
|
|
pkTexProp->SetApplyMode(NiTexturingProperty::APPLY_REPLACE);
|
|
m_spDrawSceneRTView->AttachProperty(pkTexProp);
|
|
|
|
NiAlphaProperty* pkAlphaProp = NiNew NiAlphaProperty;
|
|
pkAlphaProp->SetAlphaBlending(true);
|
|
pkAlphaProp->SetSrcBlendMode(NiAlphaProperty::ALPHA_ONE);
|
|
pkAlphaProp->SetDestBlendMode(NiAlphaProperty::ALPHA_ONE);
|
|
m_spDrawSceneRTView->AttachProperty(pkAlphaProp);
|
|
}
|
|
|
|
// 回调
|
|
bool CBloomEffect::_PreScaleDownCallback( NiRenderClick* pkCurrentRenderClick, void* pvCallbackData )
|
|
{
|
|
CBloomEffect* pkThis = (CBloomEffect*) pvCallbackData;
|
|
NIASSERT(pkThis);
|
|
|
|
pkThis->m_spRTView->GetScreenFillingQuad().ApplyAndSetActiveMaterial( pkThis->m_spScaleDownMtl );
|
|
pkThis->m_pkRTViewTexProp->SetBaseTexture( pkThis->m_spSourceTexture );
|
|
|
|
return true;
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
|
|
// bloom combin 回调 [6/15/2009 hemeng]
|
|
bool CBloomEffect::_PreBloomCombineCallback(NiRenderClick* pkCurrentRenderClick, void* pvCallbackData)
|
|
{
|
|
CBloomEffect* pkThis = (CBloomEffect*)pvCallbackData;
|
|
NIASSERT(pkThis);
|
|
|
|
pkThis->m_spRTView->GetScreenFillingQuad().ApplyAndSetActiveMaterial( pkThis->m_spBloomCombineMtl );
|
|
pkThis->m_pkRTViewTexProp->SetBaseTexture(pkThis->m_spTextureDownPassQtr0);
|
|
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------------------------
|
|
// BlurU回调
|
|
bool CBloomEffect::_PreBlurUCallback( NiRenderClick* pkCurrentRenderClick, void* pvCallbackData )
|
|
{
|
|
CBloomEffect* pkThis = (CBloomEffect*) pvCallbackData;
|
|
NIASSERT(pkThis);
|
|
|
|
pkThis->m_spRTView->GetScreenFillingQuad().ApplyAndSetActiveMaterial( pkThis->m_spBlurUMtl );
|
|
pkThis->m_pkRTViewTexProp->SetBaseTexture( pkThis->m_spTextureDownPassQtr0 );
|
|
|
|
return true;
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
// BlurV回调
|
|
bool CBloomEffect::_PreBlurVCallback( NiRenderClick* pkCurrentRenderClick, void* pvCallbackData )
|
|
{
|
|
CBloomEffect* pkThis = (CBloomEffect*) pvCallbackData;
|
|
NIASSERT(pkThis);
|
|
|
|
pkThis->m_spRTView->GetScreenFillingQuad().ApplyAndSetActiveMaterial( pkThis->m_spBlurVMtl );
|
|
pkThis->m_pkRTViewTexProp->SetBaseTexture( pkThis->m_spTextureDownPassQtr1 );
|
|
|
|
return true;
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
// DrawScene/ScaleUp回调
|
|
bool CBloomEffect::_PreDrawSceneCallback( NiRenderClick* pkCurrentRenderClick, void* pvCallbackData )
|
|
{
|
|
CBloomEffect* pkThis = (CBloomEffect*) pvCallbackData;
|
|
NIASSERT(pkThis);
|
|
|
|
NiShaderFactory::UpdateGlobalShaderConstant( "Bloom_Luminance", sizeof(float), &pkThis->m_fBloom_Luminance
|
|
|
|
);
|
|
NiShaderFactory::UpdateGlobalShaderConstant( "Bloom_Scale", sizeof(float), &pkThis->m_fBloom_Scale );
|
|
|
|
NiShaderFactory::UpdateGlobalShaderConstant( "Bloom_TexSize", sizeof(float) * 2, &pkThis->m_TexelSizeSource);
|
|
|
|
return true;
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
//for test only
|
|
void CBloomEffect::PerformRendering()
|
|
{
|
|
NiShaderFactory::UpdateGlobalShaderConstant( "Bloom_Luminance", sizeof(float), &m_fBloom_Luminance
|
|
|
|
);
|
|
NiShaderFactory::UpdateGlobalShaderConstant( "Bloom_Scale", sizeof(float), &m_fBloom_Scale );
|
|
|
|
NiShaderFactory::UpdateGlobalShaderConstant( "Bloom_TexSize", sizeof(float) * 2, &m_TexelSizeSource);
|
|
|
|
__super::PerformRendering();
|
|
}
|
|
|
|
// add [5/27/2009 hemeng]
|
|
void CBloomEffect::UpDateLum(float fLum)
|
|
{
|
|
m_fBloom_Luminance = fLum;
|
|
}
|
|
|
|
void CBloomEffect::UpDateScale(float fScale)
|
|
{
|
|
m_fBloom_Scale = fScale;
|
|
}
|
|
//---------------------------------------------------------------------------------------------
|
|
#endif
|