#include "StdPluginsCppPCH.h" #include "MStandardPlusWireframeRenderingMode.h" #include using namespace Emergent::Gamebryo::SceneDesigner::StdPluginsCpp; //--------------------------------------------------------------------------- MStandardPlusWireframeRenderingMode::MStandardPlusWireframeRenderingMode() : m_pkAlphaAccumulator(NULL), m_pkErrors(NULL), m_pkShadowRenderStep(NULL), m_pkMaterial(NULL) { m_pkAlphaAccumulator = NiNew NiAlphaAccumulator(); MInitRefObject(m_pkAlphaAccumulator); m_pkErrors = NiNew NiDefaultErrorHandler(); MInitInterfaceReference(m_pkErrors); m_pkShadowRenderStep = NiNew NiDefaultClickRenderStep; MInitRefObject(m_pkShadowRenderStep); m_pkColor = NiNew NiColor(1.0f, 1.0f, 1.0f); m_pkBackupColor = NiNew NiColorA(); m_pkPropState = NiNew NiPropertyState(); m_pkPropState->IncRefCount(); NiWireframeProperty* pkWireProp = NiNew NiWireframeProperty(); pkWireProp->SetWireframe(true); NiMaterialProperty* pkMaterialProp = NiNew NiMaterialProperty(); m_pkPropState->SetProperty(pkWireProp); m_pkPropState->SetProperty(pkMaterialProp); } //--------------------------------------------------------------------------- void MStandardPlusWireframeRenderingMode::Do_Dispose(bool bDisposing) { MDisposeRefObject(m_pkMaterial); MDisposeRefObject(m_pkPropState); NiDelete m_pkBackupColor; NiDelete m_pkColor; MDisposeRefObject(m_pkShadowRenderStep); MDisposeInterfaceReference(m_pkErrors); MDisposeRefObject(m_pkAlphaAccumulator); } //--------------------------------------------------------------------------- String* MStandardPlusWireframeRenderingMode::get_Name() { MVerifyValidInstance; return "Standard + Wireframe (Unshaded)"; } //--------------------------------------------------------------------------- bool MStandardPlusWireframeRenderingMode::get_DisplayToUser() { MVerifyValidInstance; return true; } //--------------------------------------------------------------------------- void MStandardPlusWireframeRenderingMode::Update(float fTime) { MVerifyValidInstance; } //--------------------------------------------------------------------------- void MStandardPlusWireframeRenderingMode::Begin(MRenderingContext* pmRenderingContext) { MVerifyValidInstance; MAssert(pmRenderingContext != NULL, "Null rendering context provided to " "function!"); if (!m_pkMaterial) { m_pkMaterial = NiMaterialLibrary::CreateMaterial( "NiFlatWireframeMaterial"); MAssert(m_pkMaterial != NULL, "NiFlatWireframeMaterial is not found!"); if (m_pkMaterial) { MInitRefObject(m_pkMaterial); } } NiEntityRenderingContext* pkRenderingContext = pmRenderingContext->GetRenderingContext(); // Clear out error handler. m_pkErrors->ClearErrors(); // Clear out visible array. pkRenderingContext->m_pkCullingProcess->GetVisibleSet()->RemoveAll(); // Set wireframe color, backing up existing color. NiColorA kWireframeColor(m_pkColor->r, m_pkColor->g, m_pkColor->b, 1.0f); unsigned int uiDataSize = 0; const void* pvData = NULL; if (NiD3DShaderFactory::RetrieveGlobalShaderConstant("WireframeColor", uiDataSize, pvData)) { NIASSERT(uiDataSize == sizeof(NiColorA)); const float* pfData = (const float*) pvData; m_pkBackupColor->r = pfData[0]; m_pkBackupColor->g = pfData[1]; m_pkBackupColor->b = pfData[2]; m_pkBackupColor->a = pfData[3]; } else { *m_pkBackupColor = kWireframeColor; } NiD3DShaderFactory::UpdateGlobalShaderConstant("WireframeColor", sizeof(NiColorA), &kWireframeColor); m_pkPropState->GetMaterial()->SetEmittance(*(m_pkColor)); } //--------------------------------------------------------------------------- void MStandardPlusWireframeRenderingMode::Render(MEntity* pmEntity, MRenderingContext* pmRenderingContext) { MVerifyValidInstance; MAssert(pmEntity != NULL, "Null entity provided to function!"); MEntity* amEntities[] = {pmEntity}; Render(amEntities, pmRenderingContext); } //--------------------------------------------------------------------------- void MStandardPlusWireframeRenderingMode::Render(MEntity* amEntities[], MRenderingContext* pmRenderingContext) { MVerifyValidInstance; MAssert(amEntities != NULL, "Null entity array provided to function!"); MAssert(pmRenderingContext != NULL, "Null rendering context provided to " "function!"); NiEntityRenderingContext* pkRenderingContext = pmRenderingContext->GetRenderingContext(); for (int i = 0; i < amEntities->Length; i++) { MEntity* pmEntity = amEntities[i]; MAssert(pmEntity != NULL, "Null entity in array!"); pmEntity->GetNiEntityInterface()->BuildVisibleSet(pkRenderingContext, m_pkErrors); } } //--------------------------------------------------------------------------- void MStandardPlusWireframeRenderingMode::End(MRenderingContext* pmRenderingContext) { MVerifyValidInstance; MAssert(pmRenderingContext != NULL, "Null rendering context provided to " "function!"); NiEntityRenderingContext* pkRenderingContext = pmRenderingContext->GetRenderingContext(); // Activate the shadow manager and inform it to retain its current // shadow maps. //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(); //// Generate list of shadow render clicks. //NiShadowManager::SetSceneCamera(pkRenderingContext->m_pkCamera); //const NiTPointerList& kShadowClicks = // NiShadowManager::GenerateRenderClicks(); //m_pkShadowRenderStep->GetRenderClickList().RemoveAll(); //NiTListIterator kIter = kShadowClicks.GetHeadPos(); //while (kIter) //{ // m_pkShadowRenderStep->AppendRenderClick(kShadowClicks.GetNext(kIter)); //} //// Render shadow maps. //m_pkShadowRenderStep->Render(); //// Restore previous render target group. //if (pkRenderingContext->m_pkRenderer->IsRenderTargetGroupActive()) //{ // pkRenderingContext->m_pkRenderer->EndUsingRenderTargetGroup(); //} //pkRenderingContext->m_pkRenderer->BeginUsingRenderTargetGroup( // (NiRenderTargetGroup*) pkCurRenderTarget, NiRenderer::CLEAR_NONE); // 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); // Draw objects in the visible array. NiDrawVisibleArray(pkRenderingContext->m_pkCamera, *pkRenderingContext->m_pkCullingProcess->GetVisibleSet()); // Restore accumulator. pkRenderingContext->m_pkRenderer->SetSorter(spOldAccumulator); // Deactivate the shadow manager and inform it to retain its current // shadow maps. NiShadowManager::SetActive(false, true); // Wireframe 渲染 NiVisibleArray* pkVisibleSet = pkRenderingContext->m_pkCullingProcess ->GetVisibleSet(); NIASSERT(pkVisibleSet); if (m_pkMaterial) { NiRenderer* pkRenderer = NiRenderer::GetRenderer(); const unsigned int uiQuantity = pkVisibleSet->GetCount(); for (unsigned int ui = 0; ui < uiQuantity; ui++) { const NiMaterial* pkPrevMaterial = NULL; NiDynamicEffectStatePtr spPrevEffects = NULL; NiPropertyStatePtr spPrevProp = NULL; if (NiIsKindOf(NiTriBasedGeom, &pkVisibleSet->GetAt(ui))) { if (!pkVisibleSet->GetAt(ui).IsMaterialApplied(m_pkMaterial)) { pkVisibleSet->GetAt(ui).ApplyMaterial(m_pkMaterial); } pkPrevMaterial = pkVisibleSet->GetAt(ui).GetActiveMaterial(); pkVisibleSet->GetAt(ui).SetActiveMaterial(m_pkMaterial); } else if (NiIsKindOf(NiParticles, &pkVisibleSet->GetAt(ui))) { spPrevProp = pkVisibleSet->GetAt(ui).GetPropertyState(); spPrevEffects = pkVisibleSet->GetAt(ui).GetEffectState(); pkVisibleSet->GetAt(ui).SetPropertyState(m_pkPropState); pkVisibleSet->GetAt(ui).SetEffectState(NULL); } pkVisibleSet->GetAt(ui).RenderImmediate(pkRenderer); if (pkPrevMaterial || NiIsKindOf( NiTriBasedGeom, &pkVisibleSet->GetAt(ui) ) ) { pkVisibleSet->GetAt(ui).RemoveMaterial( m_pkMaterial ); pkVisibleSet->GetAt(ui).SetActiveMaterial(pkPrevMaterial); } if (spPrevEffects) { pkVisibleSet->GetAt(ui).SetEffectState(spPrevEffects); } if (spPrevProp) { pkVisibleSet->GetAt(ui).SetPropertyState(spPrevProp); } } } // Restore wireframe color. NiD3DShaderFactory::UpdateGlobalShaderConstant("WireframeColor", sizeof(NiColorA), m_pkBackupColor); // Report errors. MUtility::AddErrorInterfaceMessages(MessageChannelType::Errors, m_pkErrors); } //---------------------------------------------------------------------------