#include "StdAfx.h" #include "LayerFog.h" #include "DepthAlphaEffectManager.h" #include using namespace SceneCore; NiImplementRTTI(CLayerFog, NiAVObject); CLayerFog::CLayerFog(void) : m_pkSceneRoot(NULL), m_fDensity(0.1f), m_kColor(1.0f, 1.0f, 1.0f), m_spLayerFogMtl(NULL) { m_pkSceneRoot = NiNew NiNode; } //---------------------------------------------------------------------------------------------------- CLayerFog::~CLayerFog(void) { } //---------------------------------------------------------------------------------------------------- bool CLayerFog::Init(NiAVObjectPtr pkFogShapeSceneRoot, const NiPoint3& kTranslation, const NiMatrix3& kRotation, const float& fScale,const float fDensity, const NiColor& kColor) { // 属性拷贝 m_kTranslation = kTranslation; m_kRotation = kRotation; m_fScale = fScale; m_pkSceneRoot = pkFogShapeSceneRoot; m_fDensity = fDensity; m_kColor = kColor; // 载入 fog material m_spLayerFogMtl = NiSingleShaderMaterial::Create("LayerFog"); NIASSERT(m_spLayerFogMtl); // 将 layer fog material 赋给 pkForgShapeSceneRoot 中所有 NiGeometry if (m_pkSceneRoot != NULL) { _RecursiveFindAndSetLayerFogMaterial(m_pkSceneRoot); m_pkSceneRoot->SetTranslate(kTranslation); m_pkSceneRoot->SetScale(fScale); m_pkSceneRoot->SetRotate(kRotation); m_pkSceneRoot->Update(0.0f); m_pkSceneRoot->SetLocalTransform(m_pkSceneRoot->GetWorldTransform()); m_pkSceneRoot->Update(0.0f); // 设置 extra data //NiFloatsExtraData *pkColor = NiNew NiFloatsExtraData( 3, (float *)&m_kColor.r); //m_pkSceneRoot->AddExtraData("FogColor", pkColor); //NiFloatExtraData *pkFogDensity = NiNew NiFloatExtraData( m_fDensity ); //m_pkSceneRoot->AddExtraData("FogDensity", pkFogDensity); for (unsigned int i=0; iAddExtraData("FogColor", pkColor); NiFloatExtraData *pkFogDensity = NiNew NiFloatExtraData( m_fDensity ); m_GeometryList[i]->AddExtraData("FogDensity", pkFogDensity); m_GeometryList[i]->UpdateEffects(); m_GeometryList[i]->UpdateProperties(); m_GeometryList[i]->Update(0.0f); } m_pkSceneRoot->UpdateEffects(); m_pkSceneRoot->UpdateProperties(); m_pkSceneRoot->Update(0.0f); // 将layer fog 注册给 CDepthAlphaEffectManager, 获取 depth map,并且交由 manager 渲染 CDepthAlphaEffectManager::GetInstance()->RegisteEffect(this); } return true; } //---------------------------------------------------------------------------------------------------- /// 销毁 释放占用资源,智能指针置 NULL void CLayerFog::Destory() { m_pkSceneRoot = NULL; m_spLayerFogMtl = NULL; m_GeometryList.clear(); //m_pkDepthTexture = NULL; CDepthAlphaEffectManager::GetInstance()->UnregisteEffect(this); } //---------------------------------------------------------------------------------------------------- /// 获取材质 NiMaterialPtr CLayerFog::GetMaterial() { return m_spLayerFogMtl; } //---------------------------------------------------------------------------------------------------- /// 设置世界变换 void CLayerFog::SetTranslate(const NiPoint3& kTranslation) { if (m_kTranslation != kTranslation) { m_kTranslation = kTranslation; m_pkSceneRoot->SetTranslate(m_kTranslation); m_pkSceneRoot->Update(0.0f); m_pkSceneRoot->SetLocalTransform(m_pkSceneRoot->GetWorldTransform()); m_pkSceneRoot->Update(0.0f); } } //---------------------------------------------------------------------------------------------------- const NiPoint3& CLayerFog::GetTranslate() const { return m_kTranslation; } //---------------------------------------------------------------------------------------------------- void CLayerFog::SetRotate(const NiMatrix3& kRotation) { if (m_kRotation != kRotation) { m_kRotation = kRotation; m_pkSceneRoot->SetRotate(m_kRotation); m_pkSceneRoot->Update(0.0f); m_pkSceneRoot->SetLocalTransform(m_pkSceneRoot->GetWorldTransform()); m_pkSceneRoot->Update(0.0f); } } //---------------------------------------------------------------------------------------------------- const NiMatrix3& CLayerFog::GetRotate() const { return m_kRotation; } //---------------------------------------------------------------------------------------------------- void CLayerFog::SetScale(const float fScale) { if (m_fScale != fScale) { m_fScale = fScale; m_pkSceneRoot->SetScale(m_fScale); m_pkSceneRoot->Update(0.0f); m_pkSceneRoot->SetLocalTransform(m_pkSceneRoot->GetWorldTransform()); m_pkSceneRoot->Update(0.0f); } } //---------------------------------------------------------------------------------------------------- float CLayerFog::GetScale() const { return m_fScale; } //---------------------------------------------------------------------------------------------------- /// 设置雾的浓度 void CLayerFog::SetAlpha(const float fAlpha) { if (m_fDensity == fAlpha) { return; } m_fDensity = fAlpha; for (unsigned int i=0; iGetExtraData("FogDensity")); pkFogDensity->SetValue(m_fDensity); m_GeometryList[i]->UpdateEffects(); m_GeometryList[i]->UpdateProperties(); m_GeometryList[i]->Update(0.0f); } } //---------------------------------------------------------------------------------------------------- float CLayerFog::GetAlpha() const { return m_fDensity; } //---------------------------------------------------------------------------------------------------- /// 设置颜色 void CLayerFog::SetColor(const NiColor kColor) { if (m_kColor == kColor) { return; } m_kColor = kColor; for (unsigned int i=0; iGetExtraData("FogColor")); pkColor->SetArray(3, &(m_kColor.r)); m_GeometryList[i]->UpdateEffects(); m_GeometryList[i]->UpdateProperties(); m_GeometryList[i]->Update(0.0f); } } //---------------------------------------------------------------------------------------------------- const NiColor& CLayerFog::GetColor() const { return m_kColor; } //---------------------------------------------------------------------------------------------------- void CLayerFog::SetSceneRoot(NiAVObjectPtr pkSceneRoot) { if (m_pkSceneRoot != pkSceneRoot) { m_pkSceneRoot = pkSceneRoot; CDepthAlphaEffectManager::GetInstance()->UnregisteEffect(this); Init(pkSceneRoot, m_kTranslation, m_kRotation, m_fScale, m_fDensity, m_kColor); } } //---------------------------------------------------------------------------------------------------- NiAVObjectPtr CLayerFog::GetSceneRoot() { return m_pkSceneRoot; } //---------------------------------------------------------------------------------------------------- /// 设置深度纹理 void CLayerFog::SetDepthTexture(NiTexturePtr pkDepthTexture) { if (m_pkSceneRoot == NULL || pkDepthTexture == NULL) { return; } NiTexturingProperty* pkTexProp = (NiTexturingProperty*) m_pkSceneRoot->GetProperty(NiProperty::TEXTURING); if (NULL == pkTexProp) { pkTexProp = NiNew NiTexturingProperty(); m_pkSceneRoot->AttachProperty(pkTexProp); m_pkSceneRoot->UpdateProperties(); } NiTexturingProperty::ShaderMap* pkMap = NiNew NiTexturingProperty::ShaderMap(pkDepthTexture, 0, NiTexturingProperty::CLAMP_S_CLAMP_T, NiTexturingProperty::FILTER_NEAREST, 0); pkTexProp->SetShaderMap(0, pkMap); m_pkSceneRoot->UpdateProperties(); m_pkSceneRoot->UpdateEffects(); m_pkSceneRoot->Update(0.0f); } //---------------------------------------------------------------------------------------------------- /// 更新 void CLayerFog::Update(float fTime) { for (unsigned int i=0; iUpdateEffects(); m_GeometryList[i]->UpdateProperties(); m_GeometryList[i]->Update(0.0f); } m_pkSceneRoot->UpdateProperties(); m_pkSceneRoot->UpdateEffects(); m_pkSceneRoot->Update(fTime); } //---------------------------------------------------------------------------------------------------- ///构造可视集 void CLayerFog::BuildVisibleSet(NiEntityRenderingContextPtr pkRenderingCondtex) { if (m_pkSceneRoot != NULL) { NiCullScene(pkRenderingCondtex->m_pkCamera, m_pkSceneRoot, *(pkRenderingCondtex->m_pkCullingProcess), *(pkRenderingCondtex->m_pkCullingProcess->GetVisibleSet()), false); } } //---------------------------------------------------------------------------------------------------- // utility functor class MAIN_ENTRY RecursiveAddLayerFogMaterial { public: RecursiveAddLayerFogMaterial(CLayerFog* pkLayerFog, NiMaterial* spLayerFogMtl) : m_pkLayerFog(pkLayerFog), m_spLayerFogMtl(spLayerFogMtl) {} bool operator() (NiAVObject* pkAVObject) { // Add any particle systems found to soft particle system if (NiIsKindOf(NiGeometry, pkAVObject)) { NiGeometry* pkGeom = NiDynamicCast(NiGeometry, pkAVObject); pkGeom->GetPropertyList().RemoveAll(); pkGeom->RemoveAllExtraData(); pkGeom->ApplyAndSetActiveMaterial(m_spLayerFogMtl); m_pkLayerFog->AddGeometry(pkGeom); } return true; } protected: CLayerFog* m_pkLayerFog; NiMaterial* m_spLayerFogMtl; }; //---------------------------------------------------------------------------------------------------- void CLayerFog::_RecursiveFindAndSetLayerFogMaterial(NiAVObject* pkSceneRoot) { // 在 fog material 初始化完之后才能调用这个函数 NIASSERT(m_spLayerFogMtl!=NULL); if (pkSceneRoot != NULL) { RecursiveAddLayerFogMaterial kFunctor(this, m_spLayerFogMtl); NiTNodeTraversal::DepthFirst_AllObjects(pkSceneRoot, kFunctor); pkSceneRoot->UpdateEffects(); pkSceneRoot->UpdateProperties(); pkSceneRoot->Update(0.0f); } } //---------------------------------------------------------------------------------------------------- void CLayerFog::AddGeometry(NiGeometry* pkGeom) { for (unsigned int i=0; i