// Copyright 2018 RED Software, LLC. All Rights Reserved. #include "stdafx.h" #include "RenderSystem.h" #include "AppWindow.h" #include "MainApp.h" #include "OptionManager.h" RenderSystem* RenderSystem::mpSingleton = nullptr; bool g_Restore(bool bBeforeReset, void* pvData) { RenderSystem* render = (RenderSystem*)pvData; assert(render); if (bBeforeReset) { THEAPP->Invalidate(); render->GetWindowRef()->AdjustWindowForChange(render->IsFullScreenMode()); } else { THEAPP->Restore(); if (render->IsFullScreenMode() == false) { if (render->GetScreenWidth() > (unsigned int)GetSystemMetrics(SM_CXSCREEN) || render->GetScreenHeight() > (unsigned int)GetSystemMetrics(SM_CYSCREEN)) { render->mReCreateContinue = true; } } render->GetWindowRef()->AdjustWindowRect(render->GetScreenWidth(), render->GetScreenHeight()); //CAMERAMAN->Reset(render->GetScreenWidth(), render->GetScreenHeight()); /// ¿É¼Ç ³»¿ëÀº À©µµ¿ì ¸ðµåÀ϶§ GetClientRect¿¡ ÀÇÇØ º¯ÇÒ ¼ö ÀÕ´Ù. //UIMAN->UpdateScreenSize(render->GetScreenWidth(), render->GetScreenHeight()); } return true; } RenderSystem::RenderSystem(AppWindow* pwindow) : mpWindowRef(pwindow) { assert(mpSingleton == 0 && "bad singleton!"); mpSingleton = this; /// Áß°³ÀÚµéÀ» »ý¼º // mpFontAgent = new FontAgent; // mpLightAgent = new LightAgent; // mpFogAgent = new FogAgent; // postProcess = new PostProcess; mClearColor = NiColorA(0.2f, 0.1f, 0.1f, 0.0f); /// It can filter flat images into mipmap pyramids, and can convert /// from standard Gamebryo pixel formats (PAL8, PALA8, RGB24, RGBA32, etc) /// to non-standard formats, and from non-standard formats to a few standard formats NiImageConverter::SetImageConverter(NiNew NiDevImageConverter); NiTexture::SetMipmapByDefault(true); /// ÀåÄ¡ ¼³Á¤ mCurrentAdapter = 0; mCurrentDevice = 0; mCurrentMode = 0; mReCreateContinue = false; mReCreateTime = 0; mWorldRendering = true; } RenderSystem::~RenderSystem() { Exit(); mVideoCaptureTime = 0; //SAFE_DELETE(mPostProcess); // SAFE_DELETE(mpFogAgent); // SAFE_DELETE(mpLightAgent); // SAFE_DELETE(mpFontAgent); mRenderer = 0; mpSingleton = 0; } HWND RenderSystem::GetHWND() { return (mpWindowRef) ? mpWindowRef->GetHWND() : NULL; } bool RenderSystem::Init() { DEVMODE dm; ZeroMemory(&dm, sizeof(dm)); dm.dmSize = sizeof(dm); EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); mMonWidth = dm.dmPelsWidth; mMonHeight = dm.dmPelsHeight; mMonBpp = dm.dmBitsPerPel; if (!CreateRenderer()) { return false; } if (!mRenderer->Init()) { assert(0); return false; } // if (mPostProcess->Init(mRenderer) == false) // { // assert(0); // return false; // } // if (mpFontAgent->Init() == false) // { // return false; // } // if (mpLightAgent->Init() == false) // { // return false; // } mRenderer->AddResetNotificationFunc(g_Restore, this); // SetBrightness(OPTIONMAN->GetGammaPer()); return true; } void RenderSystem::Exit() { // if (mpFontAgent) // mpFontAgent->Exit(); } void RenderSystem::Render() { if (mReCreateContinue) { mReCreateTime += THEAPP->GetWorldDeltaTime(); if (mReCreateTime >= 30000) { NiMessageBox("Window reset fail. Game exit.", "Error"); ::SendMessage(THEAPP->GetHWND(), WM_CLOSE, 0, 0); } mReCreateContinue = false; THEAPP->UpdateScreenSize(mRenderOption.Width, mRenderOption.Height, mRenderOption.Bpp, OPTIONMAN->IsWindowed()); return; } if (!mRenderer->BeginFrame()) { assert(0); return; } { /// ¹öÆÛ Ŭ¸®¾î Ä÷¯ ÁöÁ¤ mRenderer->SetBackgroundColor(mClearColor); /// SCENEMAN->PreRender2D(); UIMAN->PreRender(); if (mRenderer->BeginUsingRenderTargetGroup(mPostProcess->GetRenderTarget(), NiRenderer::CLEAR_ALL) == true) { if (mWorldRendering) { /// D3DTS_VIEW & D3DTS_PROJECTION ¼ÂÆÃ mRenderer->SetCameraData(CAMERAMAN->GetCurrentNi()); WORLDMAN->RenderSkyDome(); WORLDMAN->Render(); SCENEMAN->Render(); } mRenderer->SetScreenSpaceCameraData(); SCENEMAN->Render2D(); mRenderer->SetCameraData(CAMERAMAN->GetCurrentNi()); SCENEMAN->RenderZFalseDamage(); mRenderer->EndUsingRenderTargetGroup(); mPostProcess->Render(mRenderer); } // mRenderer->EndFrame(); } mRenderer->EndFrame(); mRenderer->DisplayFrame(); } void RenderSystem::Invalidate() { // mpFontAgent->Invalidate(); mRenderer->OnLostDevice(); } void RenderSystem::Restore() { mRenderer->OnResetDevice(); // mpFontAgent->Restore(); } bool RenderSystem::Reset(unsigned int width, unsigned int height, unsigned char bpp, bool winmode) { NiDX9Renderer* pkD3drenderer = NiDynamicCast(NiDX9Renderer, NiDX9Renderer::GetRenderer()); if (pkD3drenderer == 0) { assert(0); return false; } NiWindowRef handle = mpWindowRef->GetHWND(); if (handle == 0) { assert(0); return false; } NiWindowRef kWndDevice, kWndFocus; pkD3drenderer->GetCreationParameters(mRenderOption.Width, mRenderOption.Height, mRenderOption.Flags, kWndDevice, kWndFocus, mRenderOption.Adapter, mRenderOption.DevDesc, mRenderOption.FBformat, mRenderOption.DSformat, mRenderOption.Interval, mRenderOption.SwapEffect, mRenderOption.FBmode, mRenderOption.Backbuffercount, mRenderOption.Refreshrate); mRenderOption.Width = width; mRenderOption.Height = height; mRenderOption.Bpp = bpp; /// if (winmode == false) { mRenderOption.Flags = mRenderOption.Flags | NiDX9Renderer::USE_FULLSCREEN; mRenderOption.Interval = NiDX9Renderer::PRESENT_INTERVAL_ONE; } else { if (mMonWidth < mRenderOption.Width || mMonHeight < mRenderOption.Height) { // OPTIONMAN->SetWindowedNoReset(false); mRenderOption.Flags = mRenderOption.Flags | NiDX9Renderer::USE_FULLSCREEN; mRenderOption.Interval = NiDX9Renderer::PRESENT_INTERVAL_ONE; } else { mRenderOption.Flags = mRenderOption.Flags & ~(NiDX9Renderer::USE_FULLSCREEN); mRenderOption.Interval = NiDX9Renderer::PRESENT_INTERVAL_IMMEDIATE; } } EnumResolutions(width, height, bpp, winmode); if (mCurrentMode == 0) { assert(0); return false; } mRenderOption.FBformat = NiDX9Renderer::GetNiFBFormat(mCurrentMode->m_eD3DFormat); mRenderOption.DSformat = NiDX9Renderer::DSFMT_UNKNOWN; mRenderOption.FBmode = NiDX9Renderer::FBMODE_LOCKABLE; // mRenderOption.Refreshrate = NiDX9Renderer::REFRESHRATE_DEFAULT; mRenderOption.Backbuffercount = 1; NiDX9Renderer::RecreateStatus eStatus = pkD3drenderer->Recreate(mRenderOption.Width, mRenderOption.Height, mRenderOption.Flags, handle, mRenderOption.FBformat, mRenderOption.DSformat, mRenderOption.Interval, mRenderOption.SwapEffect, mRenderOption.FBmode, mRenderOption.Backbuffercount, mRenderOption.Refreshrate); if (eStatus == NiDX9Renderer::RECREATESTATUS_FAILED) { mReCreateContinue = true; return false; } // mPostProcess->Recreate(mRenderer, mRenderOption.Width, mRenderOption.Height, bpp); mReCreateTime = 0; return true; } bool RenderSystem::CreateRenderer() { /// ·£´õ·¯ ÃʱâÈ­¸¦ À§ÇÑ ¿É¼ÇÁ¤º¸.. /// ´ÙÀÌ·ºÆ® ¿¢½º ÃʱâÈ­ /// °ÔÀӺ긮¿À ·£´õ·¯ ÃʱâÈ­ NiWindowRef handle = mpWindowRef->GetHWND(); mRenderOption.Width = OPTIONMAN->GetWindowWidth(); mRenderOption.Height = OPTIONMAN->GetWindowHeight(); mRenderOption.Bpp = OPTIONMAN->GetWindowBpp(); /// »ý¼º ¿É¼Ç Àû¿ë if (OPTIONMAN->IsWindowed() == false) { mRenderOption.Flags = mRenderOption.Flags | NiDX9Renderer::USE_FULLSCREEN; mRenderOption.Interval = NiDX9Renderer::PRESENT_INTERVAL_ONE; } else { if (mMonWidth < mRenderOption.Width || mMonHeight < mRenderOption.Height) { OPTIONMAN->SetWindowedNoReset(false); mRenderOption.Flags = mRenderOption.Flags | NiDX9Renderer::USE_FULLSCREEN; mRenderOption.Interval = NiDX9Renderer::PRESENT_INTERVAL_ONE; } else { mRenderOption.Flags = mRenderOption.Flags & ~(NiDX9Renderer::USE_FULLSCREEN); mRenderOption.Interval = NiDX9Renderer::PRESENT_INTERVAL_IMMEDIATE; } } /// main window update mpWindowRef->AdjustWindowForChange(IsFullScreenMode()); EnumAdapters(); EnumResolutions(mRenderOption.Width, mRenderOption.Height, mRenderOption.Bpp, OPTIONMAN->IsWindowed()); if (mCurrentAdapter == 0 || mCurrentDevice == 0 || mCurrentMode == 0) { /// message box ¶ç¿ìÀÚ!! Default°ªÀ¸·Î »ý¼ºÇÑ´Ù!! NiMessageBox("Failed Device create!! Default option create!!", "Error Info"); /// ±âº» ÇØ»óµµ·Î »ý¼ºÇØ º»´Ù. mRenderOption.Width = 1024; mRenderOption.Height = 768; mRenderOption.Bpp = 32; /// main window update EnumAdapters(); EnumResolutions(mRenderOption.Width, mRenderOption.Height, mRenderOption.Bpp, OPTIONMAN->IsWindowed()); if (mCurrentAdapter == 0 || mCurrentDevice == 0 || mCurrentMode == 0) { NiMessageBox("Failed Device create!! ShotDown Application.", "Error Info"); return false; } } NiDX9Renderer::DeviceDesc eDesc = NiDX9Renderer::DEVDESC_PURE; if (mCurrentDevice->GetDeviceType() == D3DDEVTYPE_REF) eDesc = NiDX9Renderer::DEVDESC_REF; /// Renderer Create mRenderer = Renderer::Create(1024, 768, static_cast(mRenderOption.Flags) &~NiDX9Renderer::USE_FULLSCREEN, handle, handle, mCurrentAdapter->GetAdapterIndex(), eDesc, NiDX9Renderer::GetNiFBFormat(mCurrentMode->m_eD3DFormat), NiDX9Renderer::DSFMT_UNKNOWN, NiDX9Renderer::PRESENT_INTERVAL_IMMEDIATE, NiDX9Renderer::SWAPEFFECT_DISCARD, mRenderOption.FBmode); LPDIRECT3DDEVICE9 device = mRenderer->GetD3DDevice(); device->SetDialogBoxMode(true); if (mRenderer == nullptr) { NiMessageBox("DX9 Renderer Creation Failed", "Error Info"); return false; } mRenderer->SetBackgroundColor(mClearColor); return true; } void RenderSystem::ToggleFullScreenMode() { if (IsFullScreenMode()) mRenderOption.Flags = mRenderOption.Flags & ~(NiDX9Renderer::USE_FULLSCREEN); else mRenderOption.Flags = mRenderOption.Flags | NiDX9Renderer::USE_FULLSCREEN; }