#include "SceneDesignerFrameworkPCH.h" #include "MDistributeMapGenerator.h" #include #include "MFramework.h" #include "MTerrain.h" namespace Emergent{ namespace Gamebryo{ namespace SceneDesigner{ namespace Framework { MDistributeMapGenerator::MDistributeMapGenerator(float fLumPreSphere) : m_fLumPreSphere(fLumPreSphere) { } //-------------------------------------------------------------------------------- void MDistributeMapGenerator::SetTargetWnd(IntPtr hRendererWndPtr) { m_hTargetWnd = (HWND)hRendererWndPtr.ToInt32(); } //-------------------------------------------------------------------------------- // 生成光照分布图 System::Drawing::Bitmap* MDistributeMapGenerator::GenerateDistributeMap(EMapType eType) { // 检查目标窗口 if (m_hTargetWnd == NULL) { return NULL; } if (MTerrain::Instance == NULL) { return NULL; } // 获取 renderer NiRenderer* pkRenderer = NiRenderer::GetRenderer(); if (pkRenderer == NULL) { return NULL; } NiTPrimitiveArray kSphereArray; // 灯光球列表 // 获取场景灯光球 - 渲染对象 if (eType == MT_Lighting) { _GetSceneLightSpheres(kSphereArray); } else if (eType == MT_Entity) { _GetSceneEntitySpheres(kSphereArray); } // 设置摄像机 NiCamera kCamera; _SetCamera(kCamera); // 创建 RTG RECT rect; GetClientRect(m_hTargetWnd, &rect); int iWidth = rect.right - rect.left; int iHeight = rect.bottom - rect.top; m_DistributeMap = new System::Drawing::Bitmap(iWidth, iHeight);// NiTexture::FormatPrefs kPrefs; kPrefs.m_ePixelLayout = NiTexture::FormatPrefs::TRUE_COLOR_32; kPrefs.m_eMipMapped = NiTexture::FormatPrefs::NO; NiRenderedTexturePtr pkRTTexture = NiRenderedTexture::Create(iWidth, iHeight, pkRenderer, kPrefs, Ni2DBuffer::MULTISAMPLE_NONE); NiRenderTargetGroupPtr pkRTG = NiRenderTargetGroup::Create(pkRTTexture->GetBuffer(), pkRenderer, true, true); // 渲染灯光球到 RT if (!pkRenderer->BeginOffScreenFrame()) { return NULL; } NiVisibleArray kVisibleArray; NiCullingProcess kCullProcess(&kVisibleArray); NiEntityRenderingContext kRenderingContext; kRenderingContext.m_pkCamera = &kCamera; kRenderingContext.m_pkCullingProcess = &kCullProcess; kRenderingContext.m_pkRenderer = pkRenderer; // bakcup background color NiColorA kOldBG; pkRenderer->GetBackgroundColor(kOldBG); pkRenderer->SetBackgroundColor(NiColor::BLACK); pkRenderer->BeginUsingRenderTargetGroup(pkRTG, NiRenderer::CLEAR_ALL); pkRenderer->SetCameraData(&kCamera); for (unsigned int i=0; iEndUsingRenderTargetGroup(); pkRenderer->EndOffScreenFrame(); // restore background color pkRenderer->SetBackgroundColor(kOldBG); // 创建一个 sysmem 中的 surface, 将 pkRTTexture 的像素从显存中拷贝出来 LPDIRECT3DDEVICE9 pkDevice = ((NiDX9Renderer*)pkRenderer)->GetD3DDevice(); LPDIRECT3DSURFACE9 pTextureSurface = NULL; HRESULT hr = pkDevice->CreateOffscreenPlainSurface( iWidth, iHeight, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &pTextureSurface, NULL ); if (FAILED(hr)) { return NULL; } Ni2DBuffer* pkBuffer = pkRTTexture->GetBuffer(); NiDX92DBufferData* pkBufferData = (NiDX92DBufferData*)pkBuffer->GetRendererData(); LPDIRECT3DSURFACE9 pkSourceSurface = pkBufferData->GetSurface(); hr = D3DXLoadSurfaceFromSurface( pTextureSurface, NULL, NULL, pkSourceSurface, NULL, NULL, D3DX_FILTER_POINT, 0xFF000000 ); // 将 pTextureSurface lock, 获取像素值 D3DLOCKED_RECT lockedRect; pTextureSurface->LockRect(&lockedRect, 0, 0); DWORD* pImageData = (DWORD*)lockedRect.pBits; // 写像素到窗口 for (int i=0; iSetPixel(j, i, color); } } pTextureSurface->UnlockRect(); // 释放资源 SAFE_RELEASE(pTextureSurface); for (unsigned int i=0; i& kLightSpheres) { MEntity* arrEntities[] = MLightManager::Instance->GetSceneLights(); // 设置 material property NiMaterialProperty* pkMatProp = NiNew NiMaterialProperty(); pkMatProp->SetAmbientColor(NiColor::BLACK); pkMatProp->SetDiffuseColor(NiColor::BLACK); pkMatProp->SetSpecularColor(NiColor::BLACK); pkMatProp->SetEmittance(NiColor::WHITE); pkMatProp->SetAlpha(m_fLumPreSphere); NiAlphaProperty* pkAlphaProp = NiNew NiAlphaProperty(); pkAlphaProp->SetAlphaBlending(true); pkAlphaProp->SetAlphaTesting(false); pkAlphaProp->SetSrcBlendMode(NiAlphaProperty::ALPHA_SRCALPHA); pkAlphaProp->SetDestBlendMode(NiAlphaProperty::ALPHA_ONE); NiZBufferProperty* pkZProp = NiNew NiZBufferProperty(); pkZProp->SetZBufferTest(false); pkZProp->SetZBufferWrite(false); // 遍历所有 entity,找出所有灯光 for (int i=0; iLength; i++) { NiLight* pkLight = MLightManager::Instance->GetNiLight(arrEntities[i]->Name); if (pkLight && NiIsKindOf(NiPointLight, pkLight)) { NiPoint3 kPos = pkLight->GetWorldTranslate(); float fScale = pkLight->GetWorldScale(); //NiSphereBV* pkSphere = NiNew NiSphereBV(fScale, kPos); NiSphere kSphere; kSphere.m_fRadius = fScale; kSphere.m_kCenter = kPos; NiTriShape* pkGeom = NiDrawableBV::CreateFromSphere(kSphere, 1.0f); pkGeom->AttachProperty(pkMatProp); pkGeom->AttachProperty(pkAlphaProp); pkGeom->AttachProperty(pkZProp); pkGeom->UpdateProperties(); pkGeom->UpdateEffects(); pkGeom->Update(0.0f); kLightSpheres.Add(pkGeom); } } } //-------------------------------------------------------------------------------- void MDistributeMapGenerator::_GetSceneEntitySpheres(NiTPrimitiveArray& kEntitySpheres) { MEntity* arrEntities[] = MFramework::Instance->Scene->GetEntities(); // 设置 material property NiMaterialProperty* pkMatProp = NiNew NiMaterialProperty(); pkMatProp->SetAmbientColor(NiColor::BLACK); pkMatProp->SetDiffuseColor(NiColor::BLACK); pkMatProp->SetSpecularColor(NiColor::BLACK); pkMatProp->SetEmittance(NiColor::WHITE); pkMatProp->SetAlpha(m_fLumPreSphere); NiAlphaProperty* pkAlphaProp = NiNew NiAlphaProperty(); pkAlphaProp->SetAlphaBlending(true); pkAlphaProp->SetAlphaTesting(false); pkAlphaProp->SetSrcBlendMode(NiAlphaProperty::ALPHA_SRCALPHA); pkAlphaProp->SetDestBlendMode(NiAlphaProperty::ALPHA_ONE); NiZBufferProperty* pkZProp = NiNew NiZBufferProperty(); pkZProp->SetZBufferTest(false); pkZProp->SetZBufferWrite(false); // 遍历所有 entity,找出物件 for (int i=0; iLength; i++) { if (!MLightManager::Instance->EntityIsLight(arrEntities[i]) && !MCameraManager::Instance->EntityIsCamera(arrEntities[i])) { NiAVObject* pkSceneRoot = arrEntities[i]->GetSceneRootPointer(0); if (pkSceneRoot) { const NiBound& kBound = pkSceneRoot->GetWorldBound(); NiSphere kSphere; kSphere.m_fRadius = kBound.GetRadius(); kSphere.m_kCenter = kBound.GetCenter(); NiTriShape* pkGeom = NiDrawableBV::CreateFromSphere(kSphere, 1.0f); pkGeom->AttachProperty(pkMatProp); pkGeom->AttachProperty(pkAlphaProp); pkGeom->AttachProperty(pkZProp); pkGeom->UpdateProperties(); pkGeom->UpdateEffects(); pkGeom->Update(0.0f); kEntitySpheres.Add(pkGeom); } } } } //-------------------------------------------------------------------------------- void MDistributeMapGenerator::_SetCamera(NiCamera& kCamera) { // 设置摄像机为正交投影,向正下方拍摄整个场景 int iNumChunkX = MTerrain::Instance->GetNumChunkX(); int iNumChunkY = MTerrain::Instance->GetNumChunkY(); NiPoint3 kTranslate((iNumChunkX)*GRIDINCHUNK/2, (iNumChunkY)*GRIDINCHUNK/2, 1000); NiPoint3 kLookAt((iNumChunkX)*GRIDINCHUNK/2, (iNumChunkY)*GRIDINCHUNK/2, 0); NiMatrix3 kRotation = NiViewMath::LookAt(kLookAt, kTranslate, NiPoint3::UNIT_Y); kCamera.SetTranslate(kTranslate); kCamera.SetRotate(kRotation); kCamera.Update(0.0f); NiFrustum kFrustum(-(iNumChunkX)*GRIDINCHUNK/2, (iNumChunkX)*GRIDINCHUNK/2, (iNumChunkY)*GRIDINCHUNK/2, -(iNumChunkY)*GRIDINCHUNK/2, 0.1f, 2000.0f, true); kFrustum.m_bOrtho = true; kCamera.SetViewFrustum(kFrustum); kCamera.Update(0.0f); } //-------------------------------------------------------------------------------- }}}}