#include "StdAfx.h" #include "Utility.h" #ifndef CODE_INGAME #include "DepthToTextureBaker.h" using namespace SceneCore; CDepthToTextureBaker::CDepthToTextureBaker(CTerrain* pkTerrain) : m_pkTerrain(pkTerrain) { } //----------------------------------------------------------------------------------------------------- CDepthToTextureBaker::~CDepthToTextureBaker(void) { m_spFogTexture = NULL; m_spSceneObjects.clear(); } //----------------------------------------------------------------------------------------------------- void CDepthToTextureBaker::AddSceneObject(NiAVObject* pkObj) { // 检查该物件是否已经添加过了 for (unsigned i=0; i param.kRUPoint.x || param.kLBPoint.y > param.kRUPoint.y) { Log("In CDepthToTextureBaker::Bake(). kLBPoint 必须在 kRUPoint 左下位置"); return false; } //--------------------------------------------------------------------- ////////////////////////// // 1. 创建 RTG ////////////////////////// NiRendererPtr pkRenderer = NiRenderer::GetRenderer(); if (pkRenderer == NULL) return false; NiTexture::FormatPrefs kColorPrefs; // RT0 kColorPrefs.m_ePixelLayout = NiTexture::FormatPrefs::TRUE_COLOR_32; kColorPrefs.m_eMipMapped = NiTexture::FormatPrefs::NO; NiRenderedTexturePtr spColorTexture = NiRenderedTexture::Create(param.uiTextureSize, param.uiTextureSize, pkRenderer, kColorPrefs, Ni2DBuffer::MULTISAMPLE_NONE); NiTexture::FormatPrefs kDepthPrefs; // RT1 kDepthPrefs.m_ePixelLayout = NiTexture::FormatPrefs::SINGLE_COLOR_32; // r32 kDepthPrefs.m_eMipMapped = NiTexture::FormatPrefs::NO; NiRenderedTexturePtr spDepthTexture = NiRenderedTexture::Create(param.uiTextureSize, param.uiTextureSize, pkRenderer, kDepthPrefs, Ni2DBuffer::MULTISAMPLE_NONE); NiRenderTargetGroupPtr pkRTG = NiRenderTargetGroup::Create(2, pkRenderer); pkRTG->AttachBuffer(spColorTexture->GetBuffer(), 0); pkRTG->AttachBuffer(spDepthTexture->GetBuffer(), 1); NiDepthStencilBufferPtr pkDSB = NiDepthStencilBuffer::Create( param.uiTextureSize, param.uiTextureSize, pkRenderer, NiPixelFormat::STENCILDEPTH824 ); pkRTG->AttachDepthStencilBuffer(pkDSB); //--------------------------------------------------------------------- ////////////////////////// // 2. 设置摄象机 ////////////////////////// NiCamera kCamera; kCamera.SetTranslate(0, 0, param.fStartZ); kCamera.LookAtWorldPoint(NiPoint3(0, 0, -1.0f), NiPoint3(0, 1, 0)); kCamera.Update(0.0f); NiFrustum kFrustum(param.kLBPoint.x, param.kRUPoint.x, param.kRUPoint.y, param.kLBPoint.y, 0.1f, 1000.0f, true); kCamera.SetViewFrustum(kFrustum); kCamera.Update(0.0f); //--------------------------------------------------------------------- ////////////////////////// // 3. backup renderer 初始设置 ////////////////////////// NiMaterialPtr spBackupDefaultMtl = pkRenderer->GetDefaultMaterial(); NiRenderTargetGroupPtr spBackupRTG = NULL; if (pkRenderer->IsRenderTargetGroupActive()) { spBackupRTG = (NiRenderTargetGroup*)pkRenderer->GetCurrentRenderTargetGroup(); pkRenderer->EndUsingRenderTargetGroup(); } //--------------------------------------------------------------------- ////////////////////////// // 4. 设置 material ////////////////////////// if (spBackupDefaultMtl->GetName() != "ColorDepthMaterial") { MRT_ColorDepthMaterialPtr spDefaultMat = NiNew MRT_ColorDepthMaterial; spDefaultMat->AddDefaultFallbacks(); pkRenderer->SetDefaultMaterial(spDefaultMat); } //--------------------------------------------------------------------- ////////////////////////// // 5. 渲染场景深度 ////////////////////////// pkRenderer->BeginOffScreenFrame(); pkRenderer->BeginUsingRenderTargetGroup(pkRTG, NiRenderer::CLEAR_ALL); pkRenderer->SetCameraData(&kCamera); NiVisibleArray kVisibleArray; NiCullingProcess kCullProcess(&kVisibleArray); NiEntityRenderingContext kRenderingContext; kRenderingContext.m_pkCamera = &kCamera; kRenderingContext.m_pkCullingProcess = &kCullProcess; kRenderingContext.m_pkRenderer = pkRenderer; for (unsigned i=0; iGetTerrainRootNode(), kCullProcess, kVisibleArray, false); NiDrawVisibleArray(&kCamera, kVisibleArray); pkRenderer->EndUsingRenderTargetGroup(); pkRenderer->EndOffScreenFrame(); //--------------------------------------------------------------------- ////////////////////////// // 6. 恢复 render 设置 ////////////////////////// pkRenderer->SetDefaultMaterial(spBackupDefaultMtl); if (spBackupRTG != NULL) { pkRenderer->BeginUsingRenderTargetGroup(spBackupRTG, NiRenderer::CLEAR_NONE); } //--------------------------------------------------------------------- ////////////////////////// // 7. 根据深度纹理创建 FogTexture ////////////////////////// NiSourceTexturePtr spSourceDepthTexture = ConvertRenderedTextureToSource(spDepthTexture); if (!spSourceDepthTexture) { Log("In CDepthToTextureBaker::Bake(). DepthTexture convert to source error."); return false; } NiPixelData *pDepthPixelData = spSourceDepthTexture->GetSourcePixelData(); NiPixelData *pFogPixelData = NiNew NiPixelData(param.uiTextureSize, param.uiTextureSize, NiPixelFormat::RGBA32); NiSourceTexture::SetDestroyAppDataFlag( false ); m_spFogTexture = NiSourceTexture::Create( pFogPixelData ); m_spFogTexture->SetStatic( false ); NiSourceTexture::SetDestroyAppDataFlag( true ); if ( !m_spFogTexture ) return false; float fTotalDepth = param.fStartZ - param.fEndZ; // 雾的最大深度 for (unsigned int y = 0; y < param.uiTextureSize; ++y ) { for (unsigned int x = 0; x < param.uiTextureSize; ++x ) { unsigned char *pPtr = ( *pFogPixelData )(x,y); pPtr[0] = (unsigned char)(param.kColor.r * 255); pPtr[1] = (unsigned char)(param.kColor.g * 255); pPtr[2] = (unsigned char)(param.kColor.b * 255); float* pfDepth = (float*)((*pDepthPixelData)(x, y)); pPtr[3] = (*pfDepth)>fTotalDepth ? 255 : (unsigned char)((*pfDepth)/fTotalDepth*255); } } pFogPixelData->MarkAsChanged(); //SaveTextureToDDS(m_spFogTexture, "e:\\fogTexture.dds"); return true; } //----------------------------------------------------------------------------------------------------- NiSourceTexture* CDepthToTextureBaker::GetDepthTexture() { return m_spFogTexture; } //----------------------------------------------------------------------------------------------------- #endif