#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