// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION // // This software is supplied under the terms of a license agreement or // nondisclosure agreement with Emergent Game Technologies and may not // be copied or disclosed except in accordance with the terms of that // agreement. // // Copyright (c) 1996-2007 Emergent Game Technologies. // All Rights Reserved. // // Emergent Game Technologies, Chapel Hill, North Carolina 27517 // http://www.emergent.net // Precompiled Header #include "StdPluginsCppPCH.h" #include "MStandardRenderingMode.h" #pragma unmanaged #include #include "DepthAlphaEffectManager.h" #include "Terrain.h" #include "LightsManager.h" #include "Utility.h" #pragma managed using namespace Emergent::Gamebryo::SceneDesigner::StdPluginsCpp; //--------------------------------------------------------------------------- MStandardRenderingMode::MStandardRenderingMode() : m_pkAlphaAccumulator(NULL), m_pkErrors(NULL), m_pkShadowRenderStep(NULL) { m_pkAlphaAccumulator = NiNew NiAlphaAccumulator(); MInitRefObject(m_pkAlphaAccumulator); m_pkErrors = NiNew NiDefaultErrorHandler(); MInitInterfaceReference(m_pkErrors); m_pkShadowRenderStep = NiNew NiDefaultClickRenderStep; MInitRefObject(m_pkShadowRenderStep); } //--------------------------------------------------------------------------- void MStandardRenderingMode::Do_Dispose(bool bDisposing) { MDisposeRefObject(m_pkShadowRenderStep); MDisposeInterfaceReference(m_pkErrors); MDisposeRefObject(m_pkAlphaAccumulator); } //--------------------------------------------------------------------------- String* MStandardRenderingMode::get_Name() { MVerifyValidInstance; return "Standard"; } //--------------------------------------------------------------------------- bool MStandardRenderingMode::get_DisplayToUser() { MVerifyValidInstance; return true; } //--------------------------------------------------------------------------- void MStandardRenderingMode::Update(float fTime) { MVerifyValidInstance; } //--------------------------------------------------------------------------- void MStandardRenderingMode::Begin(MRenderingContext* pmRenderingContext) { MVerifyValidInstance; MAssert(pmRenderingContext != NULL, "Null rendering context provided to " "function!"); NiEntityRenderingContext* pkRenderingContext = pmRenderingContext->GetRenderingContext(); // Clear out error handler. m_pkErrors->ClearErrors(); // Clear out visible array. pkRenderingContext->m_pkCullingProcess->GetVisibleSet()->RemoveAll(); } //--------------------------------------------------------------------------- void MStandardRenderingMode::Render(MEntity* pmEntity, MRenderingContext* pmRenderingContext) { MVerifyValidInstance; MAssert(pmEntity != NULL, "Null entity provided to function!"); MEntity* amEntities[] = {pmEntity}; Render(amEntities, pmRenderingContext); } //--------------------------------------------------------------------------- void MStandardRenderingMode::Render(MEntity* amEntities[], MRenderingContext* pmRenderingContext) { MVerifyValidInstance; try { MAssert(amEntities != NULL, "Null entity array provided to function!"); MAssert(pmRenderingContext != NULL, "Null rendering context provided to " "function!"); if (amEntities==NULL || pmRenderingContext==NULL) { return; } NiEntityRenderingContext* pkRenderingContext = pmRenderingContext->GetRenderingContext(); for (int i = 0; i < amEntities->Length; i++) { MEntity* pmEntity = amEntities[i]; if (pmEntity==NULL) { continue; } MAssert(pmEntity != NULL, "Null entity in array!"); NiEntityInterface* pkEntity = pmEntity->GetNiEntityInterface(); if (pkEntity == NULL) { continue; } pkEntity->BuildVisibleSet(pkRenderingContext, m_pkErrors); } //MTerrain::Instance->BuildVisibleSet(pkRenderingContext); // 渲染测试水体 } catch (System::AccessViolationException* ) { } } //--------------------------------------------------------------------------- void MStandardRenderingMode::End(MRenderingContext* pmRenderingContext) { MVerifyValidInstance; MAssert(pmRenderingContext != NULL, "Null rendering context provided to " "function!"); NiEntityRenderingContext* pkRenderingContext = pmRenderingContext->GetRenderingContext(); // MTimeStamp::Instance->AddTimeStamp("StandardRenderingMode::End() Before Shadow Map Rendering."); NiVisibleArray* pkReceiveSet = NULL; // 接受阴影列表 NiVisibleArray* pkUnreveiveSet = NULL; // 不接受阴影列表 // 阴影渲染开始 { NiShadowManager::SetActive(true, true); // Backup current render target group. const NiRenderTargetGroup* pkCurRenderTarget = pkRenderingContext ->m_pkRenderer->GetCurrentRenderTargetGroup(); MAssert(pkCurRenderTarget != NULL, "No active render target group!"); pkRenderingContext->m_pkRenderer->EndUsingRenderTargetGroup(); // 获取当前场景的 visible array NiVisibleArray* pkVisibleArray = NULL; if (MTerrain::Instance->DynamicShadow && MFramework::Instance->Scene->GetRenderSceneObject() &&MTerrain::Instance->Terrain) { // 如果开启阴影渲染,构建 pkVisibleArray 作为 caster NiVisibleArray* pkOrigVisibleArray = pkRenderingContext->m_pkCullingProcess->GetVisibleSet(); pkVisibleArray = NiNew NiVisibleArray(pkOrigVisibleArray->GetCount(), 1); pkUnreveiveSet = NiNew NiVisibleArray(pkOrigVisibleArray->GetCount(), 1); pkReceiveSet = NiNew NiVisibleArray(pkOrigVisibleArray->GetCount(), 1); // 遍历 orig visible array. 找出其中不在 unaffectcaster 列表中的 geom 添加到 pkVisibleArray 中 CLightsManager* pLightMgr = MTerrain::Instance->Terrain->GetLightsManager(); MTimeStamp::Instance->AddTimeStamp("StandardRenderingMode::End() Before Build shadow caster list."); for (int i=0; iGetCount(); i++) { NiGeometry& kGeom = pkOrigVisibleArray->GetAt(i); if (!pLightMgr->IsUnaffectCaster(&kGeom)) { pkVisibleArray->Add(kGeom); } if (pLightMgr->IsUnaffectReceiver(&kGeom)) { // 添加到不接受列表中 pkUnreveiveSet->Add(kGeom); } else { pkReceiveSet->Add(kGeom); } } MTimeStamp::Instance->AddTimeStamp("StandardRenderingMode::End() Before Build shadow caster list."); } NiPoint3 kCamPos = pkRenderingContext->m_pkCamera->GetWorldLocation(); NiPoint3 kCamDir = pkRenderingContext->m_pkCamera->GetWorldDirection(); // 摄像机比较平 if (kCamDir.z > -0.2f) { kCamDir.z = -0.2f; kCamDir.Unitize(); } // 找到 kCamPos, kCamDir 直线与 z=0 平面的交点 NiPoint3 kLookAtOnZero = kCamPos + kCamDir * (kCamPos.z / (-kCamDir.z)); NiPoint3 kLookAt = kLookAtOnZero; if (MTerrain::Instance->Terrain != NULL) { // 获取该点的地形高度 NiPoint2 kTerrainPos(kLookAtOnZero.x, kLookAtOnZero.y); float fTerrainZ = MTerrain::Instance->Terrain->GetRawHeight(kTerrainPos); // 计算 kCamDir 与 fTerrainZ 平面的交点作为 look at kLookAt = kCamPos + kCamDir * ((kCamPos.z-fTerrainZ) / (-kCamDir.z)); } //// Generate list of shadow render clicks. NiShadowManager::SetSceneCamera(pkRenderingContext->m_pkCamera); const NiTPointerList& kShadowClicks = NiShadowManager::GenerateRenderClicks(pkVisibleArray, &kCamPos, &kLookAt); m_pkShadowRenderStep->GetRenderClickList().RemoveAll(); NiTListIterator kIter = kShadowClicks.GetHeadPos(); while (kIter) { m_pkShadowRenderStep->AppendRenderClick(kShadowClicks.GetNext(kIter)); } // Render shadow maps. m_pkShadowRenderStep->Render(); try { // Restore previous render target group. if (pkRenderingContext->m_pkRenderer->IsRenderTargetGroupActive()) { pkRenderingContext->m_pkRenderer->EndUsingRenderTargetGroup(); } } catch(Exception* e) { String* strE = e->ToString(); } if (pkVisibleArray) { pkVisibleArray->RemoveAll(); NiDelete pkVisibleArray; } pkRenderingContext->m_pkRenderer->BeginUsingRenderTargetGroup( (NiRenderTargetGroup*) pkCurRenderTarget, NiRenderer::CLEAR_NONE); } // MTimeStamp::Instance->AddTimeStamp("StandardRenderingMode::End() After Shadow Map Rendering."); // 阴影渲染结束 //// Set up the renderer's camera data. pkRenderingContext->m_pkRenderer->SetCameraData( pkRenderingContext->m_pkCamera); // Set accumulator. NiAccumulatorPtr spOldAccumulator = pkRenderingContext->m_pkRenderer ->GetSorter(); pkRenderingContext->m_pkRenderer->SetSorter(m_pkAlphaAccumulator); /*int iCount = 0; NiVisibleArray* pkVisibleArray = pkRenderingContext->m_pkCullingProcess->GetVisibleSet(); if (pkVisibleArray) for (int i=0; iGetCount(); i++) { NiGeometry& kGeom = pkVisibleArray->GetAt(i); const NiMaterial* pkMater = kGeom.GetActiveMaterial(); if (kGeom.GetConsistency() == NiGeometryData::STATIC) { iCount++; } }*/ if (MTerrain::Instance->DynamicShadow && MFramework::Instance->Scene->GetRenderSceneObject() &&MTerrain::Instance->Terrain) { // 有阴影的渲染 NiDrawVisibleArrayNoAlpha(pkRenderingContext->m_pkCamera, *pkReceiveSet); NiShadowManager::SetActive(false, false); NiDrawVisibleArray(pkRenderingContext->m_pkCamera, *pkUnreveiveSet); NiDrawVisibleArrayAlpha(pkRenderingContext->m_pkCamera, *pkReceiveSet); } else { // 分离 alpha 物件渲染 NiDrawVisibleArrayNoAlpha(pkRenderingContext->m_pkCamera, *pkRenderingContext->m_pkCullingProcess->GetVisibleSet()); NiShadowManager::SetActive(false, false); NiDrawVisibleArrayAlpha(pkRenderingContext->m_pkCamera, *pkRenderingContext->m_pkCullingProcess->GetVisibleSet()); } if (pkReceiveSet) // 接受阴影列表 { pkReceiveSet->RemoveAll(); NiDelete pkReceiveSet; } if (pkUnreveiveSet) { pkUnreveiveSet->RemoveAll(); NiDelete pkUnreveiveSet; } // Restore accumulator. pkRenderingContext->m_pkRenderer->SetSorter(spOldAccumulator); // Report errors. MUtility::AddErrorInterfaceMessages(MessageChannelType::Errors, m_pkErrors); } //---------------------------------------------------------------------------