Files
mux/PlatformTools/SceneEditor/SceneCore/BloomEffect.cpp
2013-02-11 19:31:50 -06:00

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